import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/spaces_cubit.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; 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/view/widgets/ACs/acs_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/lights/lights_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/lights_switches/light_switches.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_view.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/network_exception.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; part 'devices_state.dart'; class DevicesCubit extends Cubit { DevicesCubit() : super(DevicesInitial()) { fetchGroups(SpacesCubit.selectedSpace!); } static DevicesCubit get(context) => BlocProvider.of(context); static List allCategories = [ // DevicesCategoryModel( // devices: [ // DeviceModel( // name: "Living Room AC", // id: 0, // functions: [], // status: false, // temperature: 20, // fanSpeed: 0, // tempMode: 0, // coolTo: 20, // type: DeviceType.AC, // image: '', // timer: null, // bounds: Bounds( // min: 20, // max: 30, // ), // ), // DeviceModel( // name: "Master Bedroom AC", // id: 1, // functions: [], // status: false, // temperature: 20, // fanSpeed: 0, // tempMode: 0, // coolTo: 20, // type: DeviceType.AC, // image: '', // timer: null, // bounds: Bounds( // min: 20, // max: 30, // ), // ), // DeviceModel( // name: "Kitchen AC", // id: 2, // functions: [], // status: false, // temperature: 20, // fanSpeed: 0, // tempMode: 0, // coolTo: 20, // type: DeviceType.AC, // image: '', // timer: null, // bounds: Bounds( // min: 20, // max: 30, // ), // ), // DeviceModel( // name: "Bathroom AC", // id: 3, // functions: [], // status: false, // temperature: 20, // fanSpeed: 0, // tempMode: 0, // coolTo: 20, // type: DeviceType.AC, // image: '', // timer: null, // bounds: Bounds( // min: 20, // max: 30, // ), // ), // ], // icon: Assets.iconsAC, // name: 'ACs', // type: DeviceType.AC, // page: const ACsView(), // ), // DevicesCategoryModel( // devices: [ // DeviceModel( // name: "Living Room Light", // id: 0, // functions: [], // status: false, // color: 0, // brightness: 20, // lightingMode: 1, // timer: null, // type: DeviceType.Lights, // image: '', // recentColors: [ // 0xFF83D9FF, // 0xFFFC3E81, // 0xFFC0FF66, // 0xFFFDC242, // ], // ), // DeviceModel( // name: "Master Bedroom Light", // id: 1, // functions: [], // status: false, // color: 2, // brightness: 40, // lightingMode: 1, // timer: null, // type: DeviceType.Lights, // image: '', // recentColors: [ // 0xFF83D9FF, // 0xFFFC3E81, // 0xFFC0FF66, // 0xFFFDC242, // ], // ), // DeviceModel( // name: "Kitchen Light", // id: 2, // functions: [], // status: false, // color: 1, // brightness: 60, // lightingMode: 1, // timer: null, // type: DeviceType.Lights, // image: '', // recentColors: [ // 0xFF83D9FF, // 0xFFFC3E81, // 0xFFC0FF66, // 0xFFFDC242, // ], // ), // DeviceModel( // name: "Bathroom Light", // id: 3, // functions: [], // status: false, // color: 3, // brightness: 80, // lightingMode: 1, // timer: null, // type: DeviceType.Lights, // image: '', // recentColors: [ // 0xFF83D9FF, // 0xFFFC3E81, // 0xFFC0FF66, // 0xFFFDC242, // ], // ), // DeviceModel( // name: "Balcony Light", // id: 4, // functions: [], // status: false, // color: 4, // brightness: 100, // lightingMode: 1, // timer: null, // type: DeviceType.Lights, // image: '', // recentColors: [ // 0xFF83D9FF, // 0xFFFC3E81, // 0xFFC0FF66, // 0xFFFDC242, // ], // ), // ], // icon: Assets.iconsLight, // name: 'Lights', // type: DeviceType.Lights, // page: const LightsView(), // ), // DevicesCategoryModel( // devices: [], // icon: Assets.iconsDoorLock, // name: 'Doors', // type: DeviceType.DoorLock, // page: const DoorView(), // ), // DevicesCategoryModel( // devices: [ // DeviceModel( // openPercentage: 10, // id: 1, // functions: [], // name: "Living Room Curtain", // status: false, // type: DeviceType.Curtain, // image: '', // timer: null, // ), // DeviceModel( // openPercentage: 20, // id: 2, // functions: [], // name: "Master Bedroom Curtain", // status: false, // type: DeviceType.Curtain, // image: '', // timer: null, // ), // ], // icon: Assets.iconsCurtain, // name: 'Curtains', // type: DeviceType.Curtain, // page: const CurtainView(), // ), // DevicesCategoryModel( // devices: [], // icon: Assets.icons3GangSwitch, // name: 'Bedroom Lights', // type: DeviceType.ThreeGang, // page: const LightSwitchesView(), // ), // DevicesCategoryModel( // devices: [], // icon: Assets.iconsGateway, // name: 'Gateway', // type: DeviceType.Gateway, // page: const GateWayView(), // ), ]; selectCategory(int index) { for (var i = 0; i < allCategories.length; i++) { if (i == index) { allCategories[i].isSelected = true; } else { allCategories[i].isSelected = false; } } emit(DevicesCategoryChanged()); } unselectAllCategories() { for (var category in allCategories) { category.isSelected = false; } emit(DevicesCategoryChanged()); } Widget? get chosenCategoryView { for (var category in allCategories) { if (category.isSelected) { switch (category.type) { case DeviceType.AC: return const ACsView(); case DeviceType.Lights: return const LightsView(); case DeviceType.DoorLock: return const DoorView(); case DeviceType.Curtain: return const CurtainView(); case DeviceType.ThreeGang: return const LightSwitchesView(); case DeviceType.Gateway: return const GateWayView(); default: return null; } } } return null; } DevicesCategoryModel? get chosenCategory { for (var category in allCategories) { if (category.isSelected) { return category; } } return null; } selectDevice(DeviceModel device) { for (var category in allCategories) { if (category.devices != null) { for (var device in category.devices!) { if (device.isSelected) { category.isSelected = false; emit(DeviceSelected()); return; } } } } device.isSelected = !device.isSelected; emit(DeviceSelected()); } DeviceModel? getSelectedDevice() { for (var category in allCategories) { if (category.devices != null) { for (var device in category.devices!) { if (device.isSelected) { return device; } } } } return null; } changeCategorySwitchValue(DevicesCategoryModel category) { if (category.devicesStatus != null) { category.devicesStatus = !category.devicesStatus!; if (category.devices != null) { for (var device in category.devices!) { device.status = category.devicesStatus; } } } else { category.devicesStatus = true; if (category.devices != null) { for (var device in category.devices!) { device.status = true; } } } updateDevicesStatus(category); emit(CategorySwitchChanged()); } turnOnOffDevice(DeviceModel device) { device.status = !device.status!; DevicesCategoryModel category = allCategories.firstWhere((category) { if (category.devices != null) { return category.devices!.contains(device); } else { return false; } }); updateDevicesStatus(category); emit(DeviceSwitchChanged()); } updateDevicesStatus(DevicesCategoryModel category) { if (category.devices != null) { if (category.devices!.isNotEmpty) { bool? tempStatus = category.devices![0].status; for (var ac in category.devices!) { //check if there any ac have a different status than the initial ==> turn off the universal switch if (ac.status != tempStatus) { category.devicesStatus = null; emit(DeviceSwitchChanged()); return; } category.devicesStatus = tempStatus; emit(DeviceSwitchChanged()); } } else { category.devicesStatus = null; emit(DeviceSwitchChanged()); } } } turnAllDevicesOff(DevicesCategoryModel category) { if (category.devices != null) { if (category.devices!.isNotEmpty) { for (var device in category.devices!) { device.status = false; } changeCategorySwitchValue(category); updateDevicesStatus(category); emit(CategorySwitchChanged()); } } } turnAllDevicesOn(DevicesCategoryModel category) { if (category.devices != null) { if (category.devices!.isNotEmpty) { for (var device in category.devices!) { device.status = true; } changeCategorySwitchValue(category); updateDevicesStatus(category); emit(CategorySwitchChanged()); } } } areAllDevicesOff(DevicesCategoryModel category) { if (category.devices != null) { for (var device in category.devices!) { if (device.status ?? false) { category.devicesStatus = false; emit(CategorySwitchChanged()); return; } } } } clearCategoriesSelection(BuildContext context) { for (var category in allCategories) { category.isSelected = false; if (category.devices != null) { for (var device in category.devices!) { device.isSelected = false; } } } Navigator.popUntil(context, (route) => route.isFirst); emit(DevicesCategoryChanged()); } deviceControl(DeviceControlModel control) async { emit(DeviceControlLoading()); try { await DevicesAPI.controlDevice(control); emit(DeviceControlSuccess()); } on DioException catch (e) { emit(DeviceControlError(ServerFailure.fromDioError(e).errMessage)); } } fetchGroups( SpaceModel space, ) async { try { if (state is! DevicesCategoriesLoading) { emit(DevicesCategoriesLoading()); allCategories = await DevicesAPI.fetchGroups(space.id!); } else { return; } emit(DevicesCategoriesSuccess()); } on DioException catch (error) { emit( DevicesCategoriesError(ServerFailure.fromDioError(error).errMessage), ); } } ///Lights onHorizontalDragUpdate(DeviceModel light, double dx, double screenWidth) { double newBrightness = (dx / (screenWidth - 15) * 100); if (newBrightness > 100) { newBrightness = 100; } else if (newBrightness < 0) { newBrightness = 0; } // setBrightness(light, newBrightness); } Map lightModes = { 0: LightMode.Doze, 1: LightMode.Relax, 2: LightMode.Reading, 3: LightMode.Energizing, }; // setLightingMode(DeviceModel light, LightMode mode) { // light.lightingMode = // lightModes.entries.firstWhere((element) => element.value == mode).key; // emit(LightModeChanged(mode)); // } // // toggleLight(DeviceModel light) { // light.status != null ? light.status = !light.status! : light.status = true; // emit(LightToggled(light)); // } // // setColor(DeviceModel light, int color) { // light.color = color; // emit(LightColorChanged(color)); // } // // int getBrightness(DeviceModel light) { // return light.brightness.toInt(); // } // setBrightness(DeviceModel light, double value) { // value = (value / 5).ceil() * 5; // if (value != light.brightness) { // light.brightness = value; // emit(LightBrightnessChanged(value)); // } // } ///ACs // DeviceModel? getSelectedAC() { // for (var ac in category.devices) { // if (ac is DeviceModel && ac.isSelected) { // return ac; // } // } // return null; // } // // void setTempToAll(double temperature) { // for (DeviceModel ac in category.devices) { // if (ac is DeviceModel) { // if (ac.temperature != temperature && // ac.bounds.min <= temperature && // temperature <= ac.bounds.max) { // setACTemp(ac, temperature); // } // } // } // universalACTemp = temperature; // emit(ACsTempChanged(temperature)); // } // // void setACTemp(DeviceModel model, double temp) { // if (model.bounds.min <= temp && temp <= model.bounds.max) { // model.temperature = temp; // } // emit(ACsTempChanged(temp)); // } // // double getTemp(int index) { // var device = category.devices[index]; // if (device is DeviceModel) { // return device.temperature; // } // return 0.0; // or any default value you prefer // } } enum LightMode { Doze, Relax, Reading, Energizing, }