mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-16 01:56:19 +00:00
183 lines
7.3 KiB
Dart
183 lines
7.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
|
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart';
|
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
|
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart';
|
|
import 'package:syncrow_app/features/scene/view/widgets/scene_list_tile.dart';
|
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
|
|
|
import 'package:syncrow_app/generated/assets.dart';
|
|
import 'package:syncrow_app/utils/context_extension.dart';
|
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
|
|
|
class SceneControlDevicesView extends StatefulWidget {
|
|
const SceneControlDevicesView({super.key});
|
|
|
|
@override
|
|
State<SceneControlDevicesView> createState() =>
|
|
_SceneControlDevicesViewState();
|
|
}
|
|
|
|
class _SceneControlDevicesViewState extends State<SceneControlDevicesView>
|
|
with SingleTickerProviderStateMixin {
|
|
late final TabController _tabController;
|
|
List<RoomModel>? rooms = [];
|
|
|
|
@override
|
|
void initState() {
|
|
rooms = HomeCubit.getInstance().selectedSpace!.rooms!;
|
|
|
|
_tabController =
|
|
TabController(length: rooms!.length, vsync: this, initialIndex: 0);
|
|
_tabController.addListener(_handleTabSelection);
|
|
super.initState();
|
|
}
|
|
|
|
void _handleTabSelection() {
|
|
if (_tabController.indexIsChanging) {
|
|
context.read<TabBarBloc>().add(TabChanged(_tabController.index));
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
_tabController.dispose();
|
|
_tabController.removeListener(() {});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return DefaultScaffold(
|
|
title: StringsManager.createScene,
|
|
padding: EdgeInsets.zero,
|
|
child: BlocProvider(
|
|
create: (context) => DevicesCubit.getInstance(),
|
|
//TODO: remove the future builder for the first room call
|
|
//TODO: and replace it from a bloc call
|
|
child: FutureBuilder(
|
|
future: DevicesCubit.getInstance()
|
|
.fetchDevicesByRoomId(rooms![0].id!),
|
|
builder: (context, snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
return const Center(
|
|
child: CircularProgressIndicator(),
|
|
);
|
|
} else if (snapshot.hasError) {
|
|
return Text(snapshot.error.toString());
|
|
} else {
|
|
return SceneDevicesBody(
|
|
tabController: _tabController, rooms: rooms);
|
|
}
|
|
})),
|
|
);
|
|
}
|
|
}
|
|
|
|
class SceneDevicesBody extends StatelessWidget {
|
|
const SceneDevicesBody({
|
|
super.key,
|
|
required TabController tabController,
|
|
required this.rooms,
|
|
}) : _tabController = tabController;
|
|
|
|
final TabController _tabController;
|
|
final List<RoomModel>? rooms;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return BlocBuilder<TabBarBloc, TabBarState>(
|
|
builder: (context, state) {
|
|
return Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
TabBar(
|
|
controller: _tabController,
|
|
dividerColor: Colors.transparent,
|
|
indicatorColor: Colors.transparent,
|
|
tabs: List.generate(rooms!.length, (index) {
|
|
return Tab(
|
|
child: BodyLarge(
|
|
text: rooms![index].name ?? '',
|
|
style: context.bodyLarge.copyWith(
|
|
color: (state is TabSelected) &&
|
|
state.selectedTabIndex == index
|
|
? ColorsManager.textPrimaryColor
|
|
: ColorsManager.textPrimaryColor.withOpacity(0.2),
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
isScrollable: true,
|
|
onTap: (value) {
|
|
DevicesCubit.getInstance()
|
|
.fetchDevicesByRoomId(rooms![value].id!);
|
|
},
|
|
),
|
|
Expanded(
|
|
child: TabBarView(
|
|
controller: _tabController,
|
|
children: rooms!
|
|
.map((e) => BlocBuilder<DevicesCubit, DevicesState>(
|
|
builder: (context, state) {
|
|
if (state is GetDevicesLoading) {
|
|
return const Center(
|
|
child: CircularProgressIndicator());
|
|
} else if (state is GetDevicesSuccess) {
|
|
return ListView.builder(
|
|
itemCount: state.devices!.length,
|
|
itemBuilder: (context, index) {
|
|
final device = state.devices![index];
|
|
return DefaultContainer(
|
|
child: SceneListTile(
|
|
minLeadingWidth: 40,
|
|
leadingWidget: Image.network(
|
|
device.icon ?? '',
|
|
errorBuilder:
|
|
(context, error, stackTrace) =>
|
|
Image.asset(
|
|
Assets.assetsIconsLogo,
|
|
width: 20,
|
|
),
|
|
),
|
|
titleWidget: BodyMedium(
|
|
text: device.name ?? '',
|
|
style: context.titleSmall.copyWith(
|
|
color:
|
|
ColorsManager.secondaryTextColor,
|
|
fontWeight: FontWeight.w400,
|
|
fontSize: 20,
|
|
),
|
|
),
|
|
trailingWidget: const Icon(
|
|
Icons.arrow_forward_ios_rounded,
|
|
size: 16,
|
|
weight: 0.2,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
} else if (state is GetDevicesError) {
|
|
return Center(child: Text(state.errorMsg));
|
|
}
|
|
return const SizedBox();
|
|
},
|
|
))
|
|
.toList(),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|