connected all devices

This commit is contained in:
ashrafzarkanisala
2024-06-22 16:44:17 +03:00
parent 7c9b7fbb86
commit 1fe4603cbf
8 changed files with 169 additions and 144 deletions

View File

@ -16,6 +16,7 @@ import 'package:syncrow_app/features/devices/view/widgets/lights/lights_view.dar
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/doors_list_view.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/network_exception.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
@ -289,6 +290,9 @@ class DevicesCubit extends Cubit<DevicesState> {
fetchDevicesByRoomId(String? roomId) async {
if (roomId == null) return;
if (roomId == '-1') {
return fetchAllDevices();
}
emitSafe(GetDevicesLoading());
int roomIndex = HomeCubit.getInstance()
@ -316,6 +320,16 @@ class DevicesCubit extends Cubit<DevicesState> {
// }
}
void fetchAllDevices() async {
emitSafe(GetDevicesLoading());
try {
final allDevices = await HomeManagementAPI.fetchDevicesByUserId();
emitSafe(GetDevicesSuccess(allDevices));
} catch (e) {
emitSafe(GetDevicesError(e.toString()));
}
}
fetchDevicesStatues(String deviceUuid, int roomIndex, {String? code}) async {
emitSafe(GetDeviceStatusLoading(code: code));
int deviceIndex = HomeCubit.getInstance()

View File

@ -5,7 +5,8 @@ import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart
class TabBarBloc extends Bloc<TabBarEvent, TabBarState> {
TabBarBloc() : super(const Initial()) {
on<TabChanged>((event, emit) {
emit(TabSelected(event.tabIndex));
emit(TabSelected(
selectedTabIndex: event.selectedIndex, roomId: event.roomId));
});
}
}

View File

@ -3,6 +3,7 @@ abstract class TabBarEvent {
}
class TabChanged extends TabBarEvent {
final int tabIndex;
const TabChanged(this.tabIndex);
final int selectedIndex;
final String roomId;
const TabChanged({required this.selectedIndex, required this.roomId});
}

View File

@ -8,5 +8,6 @@ class Initial extends TabBarState {
class TabSelected extends TabBarState {
final int selectedTabIndex;
const TabSelected(this.selectedTabIndex);
final String roomId;
const TabSelected({required this.roomId, required this.selectedTabIndex});
}

View File

@ -12,7 +12,6 @@ import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class CreateSceneView extends StatelessWidget {
const CreateSceneView({super.key});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
@ -42,11 +41,7 @@ class CreateSceneView extends StatelessWidget {
titleString: StringsManager.whenDeviceStatusChanges,
subtitle: StringsManager.whenUnusualActivityIsDetected,
),
onTap: () => Navigator.pushNamed(
context,
Routes.sceneTasksRoute,
arguments: CreateSceneEnum.deviceStatusChanges,
),
onTap: () {},
),
],
),

View File

@ -5,16 +5,11 @@ 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/features/scene/view/widgets/scene_devices/scene_devices_body.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/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class SceneControlDevicesView extends StatefulWidget {
@ -32,17 +27,29 @@ class _SceneControlDevicesViewState extends State<SceneControlDevicesView>
@override
void initState() {
rooms = HomeCubit.getInstance().selectedSpace!.rooms!;
rooms = HomeCubit.getInstance().selectedSpace?.rooms;
rooms?.insert(
0,
RoomModel(
name: 'All Devices', devices: [], id: '-1', type: SpaceType.Room));
_tabController =
TabController(length: rooms!.length, vsync: this, initialIndex: 0);
_tabController.addListener(_handleTabSelection);
_tabController.addListener(_handleTabSwitched);
super.initState();
}
void _handleTabSelection() {
void _handleTabSwitched() {
if (_tabController.indexIsChanging) {
context.read<TabBarBloc>().add(TabChanged(_tabController.index));
final value = _tabController.index;
/// select tab
context.read<TabBarBloc>().add(
TabChanged(selectedIndex: value, roomId: rooms?[value].id ?? ''));
/// fetch devices
context.read<DevicesCubit>().fetchDevicesByRoomId(rooms![value].id!);
return;
}
}
@ -58,125 +65,7 @@ class _SceneControlDevicesViewState extends State<SceneControlDevicesView>
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(),
),
),
],
);
},
child: SceneDevicesBody(tabController: _tabController, rooms: rooms),
);
}
}

View File

@ -0,0 +1,115 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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_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/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';
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: [
/// Tab bar
TabBar(
controller: _tabController,
dividerColor: Colors.transparent,
indicatorColor: Colors.transparent,
tabs: [
...rooms!.map((e) => Tab(
child: BodyLarge(
text: e.name ?? '',
textAlign: TextAlign.start,
style: context.bodyLarge.copyWith(
color: (state is TabSelected) && state.roomId == e.id
? ColorsManager.textPrimaryColor
: ColorsManager.textPrimaryColor.withOpacity(0.2),
),
),
)),
],
isScrollable: true,
tabAlignment: TabAlignment.start,
),
/// Tab bar view
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(),
),
),
],
);
},
);
}
}

View File

@ -1,10 +1,12 @@
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/app_layout/view/app_layout.dart';
import 'package:syncrow_app/features/auth/view/otp_view.dart';
import 'package:syncrow_app/features/auth/view/login_view.dart';
import 'package:syncrow_app/features/auth/view/sign_up_view.dart';
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/layout/view/layout_view.dart';
import 'package:syncrow_app/features/menu/view/menu_view.dart';
import 'package:syncrow_app/features/menu/view/widgets/create_home/create_home_view.dart';
@ -72,8 +74,15 @@ class Router {
builder: (_) => const SceneAddTasksView(), settings: settings);
case Routes.sceneControlDevicesRoute:
return MaterialPageRoute(
builder: (_) => BlocProvider(
create: (context) => TabBarBloc()..add(const TabChanged(0)),
builder: (_) => MultiBlocProvider(
providers: [
BlocProvider<TabBarBloc>(
create: (BuildContext context) => TabBarBloc()
..add(const TabChanged(selectedIndex: 0, roomId: '')),
),
BlocProvider<DevicesCubit>(
create: (context) => DevicesCubit.getInstance()),
],
child: const SceneControlDevicesView(),
),
settings: settings);