From ea4dc852f86f78eec2d896556dd9b8f90cae7cfc Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 26 Jun 2024 11:53:32 +0300 Subject: [PATCH] update devices --- lib/features/app_layout/bloc/home_cubit.dart | 16 +++++ .../devices/view/widgets/ACs/acs_view.dart | 13 ++-- .../ceiling_sensor_interface.dart | 15 ++--- .../devices/view/widgets/device_appbar.dart | 45 +++++++++++++ .../view/widgets/gateway/gateway_view.dart | 14 ++-- .../view/widgets/popup_menu_widget.dart | 11 +++ .../view/widgets/room_page_switch.dart | 3 +- .../widgets/smart_door/door_interface.dart | 67 ++++++++++++++++--- .../three_gang/three_gang_interface.dart | 16 ++--- .../wall_sensor/wall_sensor_interface.dart | 12 ++-- lib/services/api/api_links_endpoints.dart | 1 + lib/services/api/devices_api.dart | 36 ++++++++-- 12 files changed, 190 insertions(+), 59 deletions(-) create mode 100644 lib/features/devices/view/widgets/device_appbar.dart create mode 100644 lib/features/devices/view/widgets/popup_menu_widget.dart diff --git a/lib/features/app_layout/bloc/home_cubit.dart b/lib/features/app_layout/bloc/home_cubit.dart index e0f5ce9..b22cf31 100644 --- a/lib/features/app_layout/bloc/home_cubit.dart +++ b/lib/features/app_layout/bloc/home_cubit.dart @@ -10,9 +10,11 @@ import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.dart'; import 'package:syncrow_app/features/auth/model/user_model.dart'; import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart'; +import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_state.dart'; import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/room_model.dart'; +import 'package:syncrow_app/features/devices/model/smart_door_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart'; @@ -20,6 +22,7 @@ import 'package:syncrow_app/features/menu/view/menu_view.dart'; import 'package:syncrow_app/features/scene/view/scene_view.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/navigation/navigation_service.dart'; +import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/spaces_api.dart'; import 'package:syncrow_app/utils/helpers/custom_page_route.dart'; import 'package:syncrow_app/utils/helpers/snack_bar.dart'; @@ -395,6 +398,19 @@ class HomeCubit extends Cubit { emitSafe(NavChangePage()); } + + void updateDevice(String deviceId) async { + try { + final response = await DevicesAPI.firmwareDevice( + deviceId:deviceId , + firmwareVersion: '0' + ); + if (response['success'] ?? false) { + CustomSnackBar.displaySnackBar('Update Success'); + } + } catch (_) {} + } + } BottomNavigationBarItem defaultBottomNavBarItem({required String icon, required String label}) { diff --git a/lib/features/devices/view/widgets/ACs/acs_view.dart b/lib/features/devices/view/widgets/ACs/acs_view.dart index 95f05c1..72a8b43 100644 --- a/lib/features/devices/view/widgets/ACs/acs_view.dart +++ b/lib/features/devices/view/widgets/ACs/acs_view.dart @@ -15,6 +15,8 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; +import '../device_appbar.dart'; + class ACsView extends StatelessWidget { final DeviceModel? deviceModel; const ACsView({this.deviceModel, super.key}); @@ -39,14 +41,9 @@ class ACsView extends StatelessWidget { backgroundColor: ColorsManager.backgroundColor, extendBodyBehindAppBar: true, extendBody: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - centerTitle: true, - title: BodyLarge( - text: deviceModel?.name ?? "", - fontColor: ColorsManager.primaryColor, - fontWeight: FontsManager.bold, - ), + appBar: DeviceAppbar( + deviceName: deviceModel!.name!, + deviceUuid: deviceModel!.uuid!, ), body: Container( width: MediaQuery.sizeOf(context).width, diff --git a/lib/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart b/lib/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart index 8f494c3..fd2aabc 100644 --- a/lib/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart +++ b/lib/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart @@ -20,6 +20,8 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; +import '../device_appbar.dart'; + class CeilingSensorInterface extends StatelessWidget { const CeilingSensorInterface({super.key, required this.ceilingSensor}); final DeviceModel ceilingSensor; @@ -49,15 +51,12 @@ class CeilingSensorInterface extends StatelessWidget { backgroundColor: ColorsManager.backgroundColor, extendBodyBehindAppBar: true, extendBody: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - centerTitle: true, - title: BodyLarge( - text: ceilingSensor.name ?? "", - fontColor: ColorsManager.primaryColor, - fontWeight: FontsManager.bold, - ), + appBar:DeviceAppbar( + deviceName: ceilingSensor.name!, + deviceUuid: ceilingSensor.uuid!, ), + + body: Container( width: MediaQuery.sizeOf(context).width, height: MediaQuery.sizeOf(context).height, diff --git a/lib/features/devices/view/widgets/device_appbar.dart b/lib/features/devices/view/widgets/device_appbar.dart new file mode 100644 index 0000000..0f065bd --- /dev/null +++ b/lib/features/devices/view/widgets/device_appbar.dart @@ -0,0 +1,45 @@ +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/view/widgets/popup_menu_widget.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; + +class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget { + final String deviceName; + final String deviceUuid; + final double appBarHeight = 56.0; + final void Function()? onPressed; + const DeviceAppbar({super.key, required this.deviceName, required this.deviceUuid,this.onPressed}); + + @override + Widget build(BuildContext context) { + return AppBar( + backgroundColor: Colors.transparent, + centerTitle: true, + title: BodyLarge( + text: deviceName ?? "", + fontColor: ColorsManager.primaryColor, + fontWeight: FontsManager.bold, + ), + actions: [ + IconButton(onPressed: () { + showPopupMenu(context: context, items: [ + PopupMenuItem( + onTap: () async { + + HomeCubit.getInstance().updateDevice(deviceUuid); + }, + value: 'Update', + child: const Text('Update'), + ) + ]); + }, icon: Icon(Icons.edit)) + ], + ); + } + + @override + Size get preferredSize => Size.fromHeight(appBarHeight); +} diff --git a/lib/features/devices/view/widgets/gateway/gateway_view.dart b/lib/features/devices/view/widgets/gateway/gateway_view.dart index 25e1bb6..9c90ea8 100644 --- a/lib/features/devices/view/widgets/gateway/gateway_view.dart +++ b/lib/features/devices/view/widgets/gateway/gateway_view.dart @@ -6,6 +6,7 @@ import 'package:syncrow_app/features/devices/bloc/gateway_bloc/gateway_bloc.dart import 'package:syncrow_app/features/devices/bloc/gateway_bloc/gateway_event.dart'; import 'package:syncrow_app/features/devices/bloc/gateway_bloc/gateway_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart'; import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.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'; @@ -37,15 +38,10 @@ class GateWayView extends StatelessWidget { backgroundColor: ColorsManager.backgroundColor, extendBodyBehindAppBar: true, extendBody: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - centerTitle: true, - title: const BodyLarge( - text: 'Gateway', - fontColor: ColorsManager.primaryColor, - fontWeight: FontsManager.bold, - ), - ), + appBar:DeviceAppbar( + deviceName: 'Gateway', + deviceUuid: gatewayObj.uuid!, + ), body: Container( width: MediaQuery.sizeOf(context).width, height: MediaQuery.sizeOf(context).height, diff --git a/lib/features/devices/view/widgets/popup_menu_widget.dart b/lib/features/devices/view/widgets/popup_menu_widget.dart new file mode 100644 index 0000000..bafa005 --- /dev/null +++ b/lib/features/devices/view/widgets/popup_menu_widget.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +void showPopupMenu( + {required BuildContext context, List>? items}) async { + await showMenu( + context: context, + position: RelativeRect.fromLTRB( MediaQuery.of(context).size.width/2 , 100, 0, 0), + items: items!, + elevation: 8.0, + ); +} diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index b550e68..3538f17 100644 --- a/lib/features/devices/view/widgets/room_page_switch.dart +++ b/lib/features/devices/view/widgets/room_page_switch.dart @@ -109,7 +109,8 @@ void showDeviceInterface(DeviceModel device, BuildContext context) { Navigator.push( context, PageRouteBuilder( - pageBuilder: (context, animation1, animation2) => DoorInterface(doorLock: device))); + pageBuilder: (context, animation1, animation2) => DoorInterface(doorLock: device)) + ); // navigateToInterface(DoorInterface(doorlock: device), context); break; case DeviceType.Gateway: diff --git a/lib/features/devices/view/widgets/smart_door/door_interface.dart b/lib/features/devices/view/widgets/smart_door/door_interface.dart index d6fea49..f808ab9 100644 --- a/lib/features/devices/view/widgets/smart_door/door_interface.dart +++ b/lib/features/devices/view/widgets/smart_door/door_interface.dart @@ -6,6 +6,8 @@ import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_eve import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/smart_door_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart'; +import 'package:syncrow_app/features/devices/view/widgets/popup_menu_widget.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_button.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_grid.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_status_bar.dart'; @@ -16,15 +18,18 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; class DoorInterface extends StatelessWidget { - const DoorInterface({super.key, required this.doorLock}); + + DoorInterface({super.key, required this.doorLock}); final DeviceModel doorLock; + final GlobalKey _menuKey = GlobalKey(); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => SmartDoorBloc(deviceId: doorLock.uuid ?? '')..add(InitialEvent()), - child: BlocConsumer(listener: (context, state) { + child: BlocConsumer( + listener: (context, state) { if (state is FailedState) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -33,6 +38,7 @@ class DoorInterface extends StatelessWidget { ), ); } + }, builder: (context, state) { SmartDoorModel smartDoorModel = SmartDoorModel( unlockFingerprint: 0, @@ -68,14 +74,9 @@ class DoorInterface extends StatelessWidget { backgroundColor: ColorsManager.backgroundColor, extendBodyBehindAppBar: true, extendBody: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - centerTitle: true, - title: BodyLarge( - text: doorLock.name ?? "", - fontColor: ColorsManager.primaryColor, - fontWeight: FontsManager.bold, - ), + appBar: DeviceAppbar( + deviceName: doorLock.name!, + deviceUuid: doorLock.uuid!, ), body: Container( width: MediaQuery.sizeOf(context).width, @@ -125,4 +126,50 @@ class DoorInterface extends StatelessWidget { }), ); } + } + + + // PopupMenuButton( + // icon: Container( + // width: 48, + // height: 48, + // padding: const EdgeInsets.all(6), + // alignment: AlignmentDirectional.center, + // decoration: BoxDecoration( + // shape: BoxShape.circle, + // color: bloc.settingIconClicked + // ? KeyperColors.settingIconBG + // : KeyperColors.whiteFont, + // ), + // child: Image.asset( + // ImageConstants.settingIcon, + // ), + // ), + // position: PopupMenuPosition.under, + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + // constraints: const BoxConstraints(), + // enableFeedback: false, + // onSelected: (String value) { + // if (value == 'logout') { + // if (mounted) { + // bloc.logoutDialog(context); + // } + // } + // if (value == 'delete account') { + // if (mounted) { + // bloc.deleteAccountDialog(context); + // } + // } + // }, + // itemBuilder: (context) { + // bloc.settingIcon(true); + // return bloc.displayMenuOption(context, bloc); + // }, + // onCanceled: () { + // bloc.settingIcon(false); + // }, + // ), + + + diff --git a/lib/features/devices/view/widgets/three_gang/three_gang_interface.dart b/lib/features/devices/view/widgets/three_gang/three_gang_interface.dart index 8507d6e..af95b87 100644 --- a/lib/features/devices/view/widgets/three_gang/three_gang_interface.dart +++ b/lib/features/devices/view/widgets/three_gang/three_gang_interface.dart @@ -2,12 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart'; import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_screen.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; -import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; class ThreeGangInterface extends StatelessWidget { const ThreeGangInterface({super.key, required this.gangSwitch}); @@ -24,15 +23,10 @@ class ThreeGangInterface extends StatelessWidget { backgroundColor: ColorsManager.backgroundColor, extendBodyBehindAppBar: true, extendBody: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - centerTitle: true, - title: BodyLarge( - text: gangSwitch.name ?? "", - fontColor: ColorsManager.primaryColor, - fontWeight: FontsManager.bold, - ), - ), + appBar:DeviceAppbar( + deviceName: gangSwitch.name!, + deviceUuid: gangSwitch.uuid!, + ), body: Container( width: MediaQuery.sizeOf(context).width, height: MediaQuery.sizeOf(context).height, diff --git a/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart b/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart index 2cf555e..bae19e2 100644 --- a/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart +++ b/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart @@ -8,6 +8,7 @@ import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_s import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/device_appbar.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'; @@ -56,14 +57,9 @@ class WallMountedInterface extends StatelessWidget { backgroundColor: ColorsManager.backgroundColor, extendBodyBehindAppBar: true, extendBody: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - centerTitle: true, - title: BodyLarge( - text: deviceModel.name ?? "", - fontColor: ColorsManager.primaryColor, - fontWeight: FontsManager.bold, - ), + appBar: DeviceAppbar( + deviceName: deviceModel.name!, + deviceUuid: deviceModel.uuid!, ), body: Container( width: MediaQuery.sizeOf(context).width, diff --git a/lib/services/api/api_links_endpoints.dart b/lib/services/api/api_links_endpoints.dart index 1555b5b..8987051 100644 --- a/lib/services/api/api_links_endpoints.dart +++ b/lib/services/api/api_links_endpoints.dart @@ -90,6 +90,7 @@ abstract class ApiEndpoints { static const String addDeviceToRoom = '$baseUrl/device/room'; static const String addDeviceToGroup = '$baseUrl/device/group'; static const String controlDevice = '$baseUrl/device/{deviceUuid}/control'; + static const String firmwareDevice = '$baseUrl/device/{deviceUuid}/firmware/{firmwareVersion}'; static const String getDevicesByUserId = '$baseUrl/device/user/{userId}'; //GET diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 64ce38c..3055e26 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -9,6 +9,27 @@ import 'package:syncrow_app/services/api/http_service.dart'; class DevicesAPI { static final HTTPService _httpService = HTTPService(); + static Future> firmwareDevice( + { + required String deviceId, + required String firmwareVersion}) async { + try { + final response = await _httpService.post( + path: ApiEndpoints.firmwareDevice + .replaceAll('{deviceUuid}', deviceId) + .replaceAll('{firmwareVersion}', firmwareVersion), + showServerMessage: false, + expectedResponseModel: (json) { + return json; + }, + ); + print('response==$response'); + return response; + } catch (e) { + rethrow; + } + } + static Future> controlDevice( DeviceControlModel controlModel, String deviceId) async { try { @@ -27,20 +48,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; @@ -68,7 +95,8 @@ class DevicesAPI { return response; } - static Future> getDevicesByGatewayId(String gatewayId) async { + static Future> getDevicesByGatewayId( + String gatewayId) async { final response = await _httpService.get( path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId), showServerMessage: false,