diff --git a/assets/icons/functions_icons/sensitivity.svg b/assets/icons/functions_icons/sensitivity.svg new file mode 100644 index 0000000..b75ebd3 --- /dev/null +++ b/assets/icons/functions_icons/sensitivity.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart b/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart index 033e57b..f648578 100644 --- a/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart +++ b/lib/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; @@ -9,7 +11,7 @@ import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/home_management_api.dart'; class DeviceManagerBloc extends Bloc { - DeviceManagerBloc() : super(DeviceManagerInitial()) { + DeviceManagerBloc() : super(DeviceManagerState.initial()) { on(_onFetchAllDevices); on(_onFetchDevicesByRoomId); on(_onSelectCategory); @@ -18,30 +20,30 @@ class DeviceManagerBloc extends Bloc { on(_onChangeCategorySwitchValue); on(_onTurnOnOffDevice); on(_onClearCategoriesSelection); - // on(_onDeviceControl); + on(_getDeviceFunctions); } static List? allCategories; Future _onFetchAllDevices( FetchAllDevices event, Emitter emit) async { - emit(GetDevicesLoading()); + emit(state.copyWith(loading: true)); try { final allDevices = await HomeManagementAPI.fetchDevicesByUserId(); - emit(GetDevicesSuccess(allDevices)); + emit(state.copyWith(devices: allDevices, loading: false)); } catch (e) { - emit(GetDevicesError(e.toString())); + emit(state.copyWith(error: e.toString(), loading: false)); } } Future _onFetchDevicesByRoomId( FetchDevicesByRoomId event, Emitter emit) async { - emit(GetDevicesLoading()); + emit(state.copyWith(loading: true)); try { final devices = await DevicesAPI.getDevicesByRoomId(event.roomId); - emit(GetDevicesSuccess(devices)); + emit(state.copyWith(devices: devices, loading: false)); } catch (e) { - emit(GetDevicesError(e.toString())); + emit(state.copyWith(error: e.toString(), loading: false)); } } @@ -50,7 +52,7 @@ class DeviceManagerBloc extends Bloc { for (var i = 0; i < allCategories!.length; i++) { allCategories![i].isSelected = i == event.index; } - emit(DevicesCategoryChanged()); + emit(state.copyWith(categoryChanged: true)); } void _onUnselectAllCategories( @@ -58,7 +60,7 @@ class DeviceManagerBloc extends Bloc { for (var category in allCategories!) { category.isSelected = false; } - emit(DevicesCategoryChanged()); + emit(state.copyWith(categoryChanged: true)); } void _onSelectDevice(SelectDevice event, Emitter emit) { @@ -67,14 +69,14 @@ class DeviceManagerBloc extends Bloc { for (var device in category.devices!) { if (device.isSelected) { category.isSelected = false; - emit(DeviceSelected()); + emit(state.copyWith(deviceSelected: true)); return; } } } } event.device.isSelected = !event.device.isSelected; - emit(DeviceSelected()); + emit(state.copyWith(deviceSelected: true)); } void _onChangeCategorySwitchValue( @@ -119,28 +121,9 @@ class DeviceManagerBloc extends Bloc { } } Navigator.popUntil(event.context, (route) => route.isFirst); - emit(DevicesCategoryChanged()); + emit(state.copyWith(categoryChanged: true)); // Set category changed state } - // Future _onDeviceControl( - // DeviceControl event, Emitter emit) async { - // emit(DeviceControlLoading(code: event.control.code)); - // try { - // var response = - // await DevicesAPI.controlDevice(event.control, event.deviceId); - // if (response['success'] ?? false) { - // emit(DeviceControlSuccess(code: event.control.code)); - // await Future.delayed(const Duration(milliseconds: 400), () { - // add(FetchDevicesByRoomId(event.deviceId)); - // }); - // } else { - // emit(DeviceControlError('Failed to control the device')); - // } - // } catch (e) { - // emit(DeviceControlError(e.toString())); - // } - // } - void _updateDevicesStatus( DevicesCategoryModel category, Emitter emit) { if (category.devices != null && category.devices!.isNotEmpty) { @@ -152,7 +135,20 @@ class DeviceManagerBloc extends Bloc { } category.devicesStatus = tempStatus; } - emit(CategorySwitchChanged()); + emit(state.copyWith(categoryChanged: true)); + } + } + + Future _getDeviceFunctions( + DeviceFunctionsEvent event, Emitter emit) async { + emit(state.copyWith(functionsLoading: true)); + try { + final deviceFunctions = await DevicesAPI.deviceFunctions(event.deviceId); + + emit(state.copyWith( + functionsLoading: false, deviceFunctions: deviceFunctions)); + } catch (e) { + emit(state.copyWith(functionsLoading: false, error: e.toString())); } } } diff --git a/lib/features/devices/bloc/device_manager_bloc/device_manager_event.dart b/lib/features/devices/bloc/device_manager_bloc/device_manager_event.dart index 44de0a2..867027d 100644 --- a/lib/features/devices/bloc/device_manager_bloc/device_manager_event.dart +++ b/lib/features/devices/bloc/device_manager_bloc/device_manager_event.dart @@ -78,3 +78,11 @@ class DeviceControl extends DeviceManagerEvent { @override List get props => [control, deviceId]; } + +class DeviceFunctionsEvent extends DeviceManagerEvent { + final String deviceId; + const DeviceFunctionsEvent(this.deviceId); + + @override + List get props => [deviceId]; +} diff --git a/lib/features/devices/bloc/device_manager_bloc/device_manager_state.dart b/lib/features/devices/bloc/device_manager_bloc/device_manager_state.dart index 1dc8099..d9780a8 100644 --- a/lib/features/devices/bloc/device_manager_bloc/device_manager_state.dart +++ b/lib/features/devices/bloc/device_manager_bloc/device_manager_state.dart @@ -1,112 +1,73 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/devices/model/device_category_model.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/functions.dart'; -abstract class DeviceManagerState extends Equatable { - const DeviceManagerState(); - - @override - List get props => []; -} - -class DeviceManagerInitial extends DeviceManagerState {} - -class DevicesCategoryChanged extends DeviceManagerState {} - -class DeviceSelected extends DeviceManagerState {} - -class DeviceControlLoading extends DeviceManagerState { - final String code; - - const DeviceControlLoading({required this.code}); - - @override - List get props => [code]; -} - -class DeviceControlSuccess extends DeviceManagerState { - final String code; - - const DeviceControlSuccess({required this.code}); - - @override - List get props => [code]; -} - -class DeviceControlError extends DeviceManagerState { - final String message; - - const DeviceControlError(this.message); - - @override - List get props => [message]; -} - -class DevicesCategoriesLoading extends DeviceManagerState {} - -class DevicesCategoriesSuccess extends DeviceManagerState {} - -class DevicesCategoriesError extends DeviceManagerState { - final String error; - - const DevicesCategoriesError(this.error); - - @override - List get props => [error]; -} - -class GetDevicesLoading extends DeviceManagerState {} - -class GetDevicesSuccess extends DeviceManagerState { +class DeviceManagerState extends Equatable { + final bool loading; + final String? error; + final List? allCategories; final List? devices; + final bool categoryChanged; + final bool deviceSelected; + final bool functionsLoading; + final FunctionsEntity? deviceFunctions; - const GetDevicesSuccess(this.devices); + const DeviceManagerState({ + required this.loading, + this.error, + this.allCategories, + this.devices, + this.categoryChanged = false, + this.deviceSelected = false, + this.functionsLoading = false, + this.deviceFunctions, + }); + + factory DeviceManagerState.initial() { + return const DeviceManagerState( + loading: false, + error: null, + allCategories: null, + devices: null, + categoryChanged: false, + deviceSelected: false, + functionsLoading: false, + deviceFunctions: null, + ); + } + + DeviceManagerState copyWith({ + bool? loading, + String? error, + List? allCategories, + List? devices, + bool? categoryChanged, + bool? deviceSelected, + bool? functionsLoading, + FunctionsEntity? deviceFunctions, + }) { + return DeviceManagerState( + loading: loading ?? this.loading, + error: error ?? this.error, + allCategories: allCategories ?? this.allCategories, + devices: devices ?? this.devices, + categoryChanged: categoryChanged ?? this.categoryChanged, + deviceSelected: deviceSelected ?? this.deviceSelected, + functionsLoading: functionsLoading ?? this.functionsLoading, + deviceFunctions: deviceFunctions ?? this.deviceFunctions, + ); + } @override - List get props => [devices ?? []]; + List get props => [ + loading, + error, + allCategories, + devices, + categoryChanged, + deviceSelected, + functionsLoading, + deviceFunctions, + ]; } - -class GetDevicesError extends DeviceManagerState { - final String error; - - const GetDevicesError(this.error); - - @override - List get props => [error]; -} - -class GetDeviceStatusLoading extends DeviceManagerState { - final String? code; - - const GetDeviceStatusLoading({this.code}); - - @override - List get props => [code ?? '']; -} - -class GetDeviceStatusSuccess extends DeviceManagerState { - final String? code; - - const GetDeviceStatusSuccess({this.code}); - - @override - List get props => [code ?? '']; -} - -class GetDeviceStatusError extends DeviceManagerState { - final String error; - - const GetDeviceStatusError(this.error); - - @override - List get props => [error]; -} - -class CategorySwitchChanged extends DeviceManagerState {} - -class DeviceSwitchChanged extends DeviceManagerState {} - -class CurtainsIsOpening extends DeviceManagerState {} - -class CurtainsIsClosing extends DeviceManagerState {} - -class CurtainsStopped extends DeviceManagerState {} diff --git a/lib/features/devices/bloc/devices_cubit.dart b/lib/features/devices/bloc/devices_cubit.dart index 79bf03b..2efb06d 100644 --- a/lib/features/devices/bloc/devices_cubit.dart +++ b/lib/features/devices/bloc/devices_cubit.dart @@ -331,18 +331,6 @@ class DevicesCubit extends Cubit { // } } - void fetchAllDevices() async { - emitSafe(GetDevicesLoading()); - try { - final allDevices = await HomeManagementAPI.fetchDevicesByUserId(); - - emitSafe(GetDevicesSuccess(allDevices)); - } catch (e) { - emitSafe(GetDevicesError(e.toString())); - return; - } - } - fetchDevicesStatues(String deviceUuid, int roomIndex, {String? code}) async { emitSafe(GetDeviceStatusLoading(code: code)); int deviceIndex = HomeCubit.getInstance() diff --git a/lib/features/devices/model/functions.dart b/lib/features/devices/model/functions.dart new file mode 100644 index 0000000..cd1b209 --- /dev/null +++ b/lib/features/devices/model/functions.dart @@ -0,0 +1,58 @@ +class FunctionsEntity { + final String productUuid; + final String productType; + final List functions; + + FunctionsEntity({ + required this.productUuid, + required this.productType, + required this.functions, + }); + + factory FunctionsEntity.fromJson(Map json) => + FunctionsEntity( + productUuid: json["productUuid"], + productType: json["productType"], + functions: List.from( + json["functions"].map((x) => DeviceFunction.fromJson(x)), + ), + ); + + Map toJson() => { + "productUuid": productUuid, + "productType": productType, + "functions": List.from(functions.map((x) => x.toJson())), + }; +} + +class DeviceFunction { + final String code; + final String values; + final String dataType; + + DeviceFunction({ + required this.code, + required this.values, + required this.dataType, + }); + + factory DeviceFunction.fromJson(Map json) => DeviceFunction( + code: _formatCode(json["code"]), + values: json["values"], + dataType: json["dataType"], + ); + + Map toJson() => { + "code": code, + "values": values, + "dataType": dataType, + }; + + static String _formatCode(String originalCode) { + return originalCode + .replaceAll('_', ' ') + .split(' ') + .map((word) => word[0].toUpperCase() + word.substring(1)) + .join(' '); + } +} diff --git a/lib/features/scene/bloc/create_scene/create_scene_bloc.dart b/lib/features/scene/bloc/create_scene/create_scene_bloc.dart index 95a29b8..f3b03e4 100644 --- a/lib/features/scene/bloc/create_scene/create_scene_bloc.dart +++ b/lib/features/scene/bloc/create_scene/create_scene_bloc.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; @@ -6,8 +8,6 @@ part 'create_scene_state.dart'; class CreateSceneBloc extends Bloc { CreateSceneBloc() : super(CreateSceneInitial()) { - on((event, emit) { - // TODO: implement event handler - }); + on((event, emit) => null as FutureOr); } } diff --git a/lib/features/scene/bloc/create_scene/create_scene_event.dart b/lib/features/scene/bloc/create_scene/create_scene_event.dart index 24b7430..80ee709 100644 --- a/lib/features/scene/bloc/create_scene/create_scene_event.dart +++ b/lib/features/scene/bloc/create_scene/create_scene_event.dart @@ -6,3 +6,5 @@ sealed class CreateSceneEvent extends Equatable { @override List get props => []; } + + diff --git a/lib/features/scene/bloc/create_scene/create_scene_state.dart b/lib/features/scene/bloc/create_scene/create_scene_state.dart index a0fa4d3..f3bb61e 100644 --- a/lib/features/scene/bloc/create_scene/create_scene_state.dart +++ b/lib/features/scene/bloc/create_scene/create_scene_state.dart @@ -8,3 +8,7 @@ sealed class CreateSceneState extends Equatable { } final class CreateSceneInitial extends CreateSceneState {} + +class CreateSceneLoading extends CreateSceneState {} + + diff --git a/lib/features/scene/helper/scene_helper.dart b/lib/features/scene/helper/scene_helper.dart new file mode 100644 index 0000000..2c93067 --- /dev/null +++ b/lib/features/scene/helper/scene_helper.dart @@ -0,0 +1,50 @@ +import 'package:syncrow_app/features/devices/model/function_model.dart'; +import 'package:syncrow_app/utils/resource_manager/constants.dart'; + +mixin SceneHelper { + get lightBulbFunctions => null; + + get wallSensorFunctions => null; + + get acFunctions => null; + + get doorLockFunctions => null; + + get curtainFunctions => null; + + get threeGangFunctions => null; + + get gatewayFunctions => null; + + getFunctionsWithIcons( + {DeviceType? type, required List functions}) { + switch (type) { + case DeviceType.LightBulb: + return lightBulbFunctions; + case DeviceType.CeilingSensor: + return ceilingSensorFunctions(functions); + case DeviceType.WallSensor: + return wallSensorFunctions; + case DeviceType.AC: + return acFunctions; + case DeviceType.DoorLock: + return doorLockFunctions; + case DeviceType.Curtain: + return curtainFunctions; + case DeviceType.ThreeGang: + return threeGangFunctions; + case DeviceType.Gateway: + return gatewayFunctions; + default: + return lightBulbFunctions; + } + } + + ceilingSensorFunctions(List functions) { + List temp = []; + for (var item in functions) { + + } + return temp; + } +} diff --git a/lib/features/scene/view/device_functions_view.dart b/lib/features/scene/view/device_functions_view.dart new file mode 100644 index 0000000..6e7ebb8 --- /dev/null +++ b/lib/features/scene/view/device_functions_view.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/scene/helper/scene_helper.dart'; +import 'package:syncrow_app/features/scene/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_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 DeviceFunctionsView extends StatelessWidget with SceneHelper { + const DeviceFunctionsView({super.key}); + + @override + Widget build(BuildContext context) { + final device = ModalRoute.of(context)?.settings.arguments as DeviceModel; + // var functions = []; + // if (device.functions.isNotEmpty) { + // functions = getFunctionsWithIcons( + // type: device.productType, functions: device.functions); + // } + + return DefaultScaffold( + title: '${device.name} ${StringsManager.functions}', + actions: [ + TextButton( + onPressed: () {}, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.normal, + fontColor: ColorsManager.secondaryColor.withOpacity(0.6), + ), + ), + ], + leading: TextButton( + onPressed: () => Navigator.pop(context), + child: BodyMedium( + text: 'Cancel', + fontWeight: FontWeight.normal, + fontColor: ColorsManager.textPrimaryColor.withOpacity(0.6), + ), + ), + leadingWidth: 80, + padding: EdgeInsets.zero, + child: DefaultContainer( + margin: const EdgeInsets.only(top: 24), + child: ListView.builder( + shrinkWrap: true, + itemCount: device.functions.length, + itemBuilder: (context, index) { + final function = device.functions[index]; + return SceneListTile( + assetPath: null, + minLeadingWidth: 40, + leadingWidget: Image.asset( + Assets.assetsIconsLogo, + width: 20, + ), + titleWidget: BodyMedium( + text: function.code ?? '', + style: context.titleSmall.copyWith( + color: ColorsManager.secondaryTextColor, + fontWeight: FontWeight.w400, + fontSize: 15, + ), + ), + trailingWidget: const Icon( + Icons.arrow_forward_ios_rounded, + color: ColorsManager.greyColor, + size: 16, + ), + onPressed: () {}, + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/scene/view/scene_add_tasks.dart b/lib/features/scene/view/scene_add_tasks.dart index 0f0fc66..5843323 100644 --- a/lib/features/scene/view/scene_add_tasks.dart +++ b/lib/features/scene/view/scene_add_tasks.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart'; import 'package:syncrow_app/features/scene/widgets/if_then_containers/if_container.dart'; import 'package:syncrow_app/features/scene/widgets/if_then_containers/then_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; @@ -34,24 +36,27 @@ class SceneAddTasksView extends StatelessWidget { ], child: Stack( children: [ - const SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - height: 24, - ), - // IF - IFDefaultContainer(), - SizedBox( - height: 8, - ), - // THEN - ThenDefaultContainer(), - SizedBox( - height: 100, - ), - ], + SingleChildScrollView( + child: BlocProvider( + create: (context) => CreateSceneBloc(), + child: const Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 24, + ), + // IF + IFDefaultContainer(), + SizedBox( + height: 8, + ), + // THEN + ThenDefaultContainer(), + SizedBox( + height: 100, + ), + ], + ), ), ), Positioned( diff --git a/lib/features/scene/widgets/if_then_containers/then_container.dart b/lib/features/scene/widgets/if_then_containers/then_container.dart index c0e8fd0..fd701de 100644 --- a/lib/features/scene/widgets/if_then_containers/then_container.dart +++ b/lib/features/scene/widgets/if_then_containers/then_container.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart'; import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart'; import 'package:syncrow_app/features/scene/widgets/bottom_sheet_widget.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -44,12 +46,16 @@ class ThenDefaultContainer extends StatelessWidget { padding: EdgeInsets.zero, ), const LightDivider(), - SceneListTile( - titleString: '+ Add Task', - textAlign: TextAlign.center, - onPressed: () => context.customBottomSheet( - child: const CustomBottomSheetWidget(), - ), + BlocBuilder( + builder: (context, state) { + return SceneListTile( + titleString: '+ Add Task', + textAlign: TextAlign.center, + onPressed: () => context.customBottomSheet( + child: const CustomBottomSheetWidget(), + ), + ); + }, ) ], ), diff --git a/lib/features/scene/widgets/scene_devices/scene_devices_body.dart b/lib/features/scene/widgets/scene_devices/scene_devices_body.dart index d26a502..fc82b2a 100644 --- a/lib/features/scene/widgets/scene_devices/scene_devices_body.dart +++ b/lib/features/scene/widgets/scene_devices/scene_devices_body.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.dart'; import 'package:syncrow_app/features/devices/model/room_model.dart'; @@ -9,7 +10,7 @@ import 'package:syncrow_app/features/scene/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/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/context_extension.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; @@ -18,7 +19,7 @@ class SceneDevicesBody extends StatelessWidget { super.key, required TabController tabController, required this.rooms, - }) : _tabController = tabController; + }) : _tabController = tabController; final TabController _tabController; final List? rooms; @@ -66,23 +67,17 @@ class SceneDevicesBody extends StatelessWidget { Widget _buildRoomTab(RoomModel room, BuildContext context) { return BlocBuilder( builder: (context, state) { - if (state is GetDevicesLoading) { + if (state.loading && state.devices == null) { return const Center(child: CircularProgressIndicator()); - } else if (state is GetDevicesSuccess) { + } else if (state.devices != null && state.devices!.isNotEmpty) { return ListView.builder( - itemCount: state.devices?.length ?? 0, + 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, - ), - ), + leadingWidget: SvgPicture.asset(device.icon ?? ''), titleWidget: BodyMedium( text: device.name ?? '', style: context.titleSmall.copyWith( @@ -93,20 +88,25 @@ class SceneDevicesBody extends StatelessWidget { ), trailingWidget: const Icon( Icons.arrow_forward_ios_rounded, + color: ColorsManager.greyColor, size: 16, - weight: 0.2, ), onPressed: () { - + Navigator.pushNamed( + context, + Routes.deviceFunctionsRoute, + arguments: device, + ); }, ), ); }, ); - } else if (state is GetDevicesError) { - return Center(child: Text(state.error)); + } else if (state.error != null) { + return Center(child: Text(state.error!)); + } else { + return const SizedBox(); } - return const SizedBox(); }, ); } diff --git a/lib/features/shared_widgets/default_scaffold.dart b/lib/features/shared_widgets/default_scaffold.dart index 679f654..1829ebe 100644 --- a/lib/features/shared_widgets/default_scaffold.dart +++ b/lib/features/shared_widgets/default_scaffold.dart @@ -15,6 +15,8 @@ class DefaultScaffold extends StatelessWidget { this.appBar, this.bottomNavBar, this.padding, + this.leading, + this.leadingWidth, }); final Widget child; @@ -23,6 +25,8 @@ class DefaultScaffold extends StatelessWidget { final PreferredSizeWidget? appBar; final Widget? bottomNavBar; final EdgeInsetsGeometry? padding; + final Widget? leading; + final double? leadingWidth; @override Widget build(BuildContext context) { return AnnotatedRegion( @@ -45,6 +49,8 @@ class DefaultScaffold extends StatelessWidget { fontWeight: FontsManager.bold, ), actions: actions, + leading: leading, + leadingWidth: leadingWidth, ), body: Container( width: MediaQuery.sizeOf(context).width, diff --git a/lib/navigation/router.dart b/lib/navigation/router.dart index dcd78e9..2d5e3ea 100644 --- a/lib/navigation/router.dart +++ b/lib/navigation/router.dart @@ -13,6 +13,7 @@ import 'package:syncrow_app/features/menu/view/widgets/create_home/create_home_v import 'package:syncrow_app/features/menu/view/widgets/profile/profile_view.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/view/device_functions_view.dart'; import 'package:syncrow_app/features/scene/view/scene_add_tasks.dart'; import 'package:syncrow_app/features/scene/view/scene_control_devices.dart'; import 'package:syncrow_app/features/scene/view/scene_view.dart'; @@ -89,6 +90,11 @@ class Router { child: const SceneControlDevicesView(), ), settings: settings); + case Routes.deviceFunctionsRoute: + return MaterialPageRoute( + builder: (_) => const DeviceFunctionsView(), + settings: settings, + ); default: return MaterialPageRoute( builder: (_) => Scaffold( diff --git a/lib/navigation/routing_constants.dart b/lib/navigation/routing_constants.dart index 3726c16..86826ca 100644 --- a/lib/navigation/routing_constants.dart +++ b/lib/navigation/routing_constants.dart @@ -19,4 +19,6 @@ class Routes { static const String createUnit = '/create-unit'; static const String sceneTasksRoute = '/scene-tasks'; static const String sceneControlDevicesRoute = '/scene-control-devices'; +static const String deviceFunctionsRoute = '/device-functions'; + } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 94a3984..29eb9cd 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:syncrow_app/features/devices/model/device_category_model.dart'; import 'package:syncrow_app/features/devices/model/device_control_model.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/functions.dart'; import 'package:syncrow_app/services/api/api_links_endpoints.dart'; import 'package:syncrow_app/services/api/http_service.dart'; @@ -27,20 +28,26 @@ class DevicesAPI { } static Future> fetchGroups(String spaceId) async { - Map params = {"homeId": spaceId, "pageSize": 100, "pageNo": 1}; + Map params = { + "homeId": spaceId, + "pageSize": 100, + "pageNo": 1 + }; final response = await _httpService.get( path: ApiEndpoints.groupBySpace.replaceAll("{spaceUuid}", spaceId), queryParameters: params, showServerMessage: false, - expectedResponseModel: (json) => DevicesCategoryModel.fromJsonList(json['groups']), + expectedResponseModel: (json) => + DevicesCategoryModel.fromJsonList(json['groups']), ); return response; } static Future> getDeviceStatus(String deviceId) async { final response = await _httpService.get( - path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId), + path: ApiEndpoints.deviceFunctionsStatus + .replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { return json; @@ -49,6 +56,19 @@ class DevicesAPI { return response; } + /// Get Device Functions + static Future deviceFunctions(String deviceId) async { + final response = await _httpService.get( + path: ApiEndpoints.deviceFunctions.replaceAll('{deviceUuid}', deviceId), + showServerMessage: false, + expectedResponseModel: (json) { + final functions = FunctionsEntity.fromJson(json); + return functions; + }, + ); + return response; + } + static Future> getDevicesByRoomId(String roomId) async { // print("Room ID: $roomId"); final response = await _httpService.get( diff --git a/lib/utils/resource_manager/strings_manager.dart b/lib/utils/resource_manager/strings_manager.dart index b861668..c805232 100644 --- a/lib/utils/resource_manager/strings_manager.dart +++ b/lib/utils/resource_manager/strings_manager.dart @@ -39,4 +39,5 @@ class StringsManager { static const whenDeviceStatusChanges = 'When device status changes'; static const whenUnusualActivityIsDetected = 'Example: when an unusual activity is detected.'; + static const functions = "Functions"; }