diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 4f6986bda..f3bf9a074 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -9,7 +9,7 @@ on: env: flutter_channel: 'stable' # or: 'dev' or 'beta' - flutter_version: '3.13.6' + flutter_version: '3.16.5' jobs: build: diff --git a/lib/domain/connections_service.dart b/lib/domain/connections_service.dart index c00f47679..05e55b684 100644 --- a/lib/domain/connections_service.dart +++ b/lib/domain/connections_service.dart @@ -1,12 +1,28 @@ import 'dart:async'; import 'dart:collection'; +import 'dart:convert'; +import 'dart:io'; import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:cybearjinni/infrastructure/core/injection.dart'; +import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:cybearjinni/infrastructure/network_utilities_flutter.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flutter/foundation.dart'; +import 'package:grpc/grpc.dart'; +import 'package:location/location.dart'; +import 'package:network_info_plus/network_info_plus.dart'; +import 'package:network_tools_flutter/network_tools_flutter.dart'; +import 'package:permission_handler/permission_handler.dart' + as permission_handler; +import 'package:rxdart/rxdart.dart'; part 'package:cybearjinni/infrastructure/connection_service/app_connection_service.dart'; +part 'package:cybearjinni/infrastructure/connection_service/hub_connection_service.dart'; part 'package:cybearjinni/infrastructure/connection_service/demo_connection_service.dart'; part 'package:cybearjinni/infrastructure/connection_service/none_connection_service.dart'; +part 'package:cybearjinni/infrastructure/connection_service/remote_pipes_connection_service.dart'; enum ConnectionType { appAsHub, @@ -26,39 +42,41 @@ abstract interface class ConnectionsService { static ConnectionType _currentConnectionType = ConnectionType.appAsHub; - static void setCurrentConnectionType(ConnectionType? connectionType) { + static void setCurrentConnectionType(ConnectionType connectionType) { if (connectionType == _currentConnectionType) { return; } - final ConnectionsService? oldInstance = _instance; + _instance?.dispose(); + + _currentConnectionType = connectionType; + switch (connectionType) { case ConnectionType.appAsHub: _instance = _AppConnectionService(); - _currentConnectionType = ConnectionType.appAsHub; - case ConnectionType.demo: case ConnectionType.hub: + _instance = _HubConnectionService(); case ConnectionType.remotePipes: + _instance = _RemotePipesConnectionService(); + case ConnectionType.demo: _instance = _DemoConnectionService(); - _currentConnectionType = ConnectionType.demo; case ConnectionType.none: - case null: _instance = _NoneConnectionService(); - _currentConnectionType = ConnectionType.none; } - oldInstance?.dispose(); } static ConnectionType getCurrentConnectionType() => _currentConnectionType; + Future connect({String? address}); + Future searchDevices(); - void setEntityState(ActionObject action); + void setEntityState(RequestActionObject action); Future setEtitiesToArea(String areaId, HashSet entities); - Future> get getAllEntities; + Future> get getEntities; - Future> get getAllAreas; + Future> get getAreas; Stream> watchEntities(); @@ -68,9 +86,13 @@ abstract interface class ConnectionsService { Future setNewArea(AreaEntity area); - Future> getScenes(); + Future> get getScenes; Future activateScene(String id); Future addScene(SceneCbjEntity scene); + + Future loginVendor(VendorLoginEntity value); + + Future> getVendors(); } diff --git a/lib/domain/device/devices_errors.dart b/lib/domain/device/devices_errors.dart deleted file mode 100644 index 8a3a820df..000000000 --- a/lib/domain/device/devices_errors.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:cybearjinni/domain/device/devices_failures.dart'; - -class DevicesUnexpectedValueError extends Error { - DevicesUnexpectedValueError(this.deviceValueFailure); - - final DevicesFailure deviceValueFailure; - - @override - String toString() { - const explanation = - 'Encountered a ValueFailure at an unrecoverable point. Terminating.'; - return Error.safeToString('$explanation Failure was: $deviceValueFailure'); - } -} diff --git a/lib/domain/device/devices_failures.dart b/lib/domain/device/devices_failures.dart deleted file mode 100644 index 08bf7b7e8..000000000 --- a/lib/domain/device/devices_failures.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'devices_failures.freezed.dart'; - -@freezed -class DevicesFailure { - const factory DevicesFailure.empty({ - required T failedValue, - }) = _Empty; - - const factory DevicesFailure.actionExcecuter({ - required T failedValue, - }) = _ActionExcecuter; - - const factory DevicesFailure.exceedingLength({ - required T failedValue, - required int max, - }) = _ExceedingLength; - - const factory DevicesFailure.unexpected() = _Unexpected; - - const factory DevicesFailure.insufficientPermission() = - _InsufficientPermission; - - const factory DevicesFailure.unableToUpdate() = _UnableToUpdate; - - const factory DevicesFailure.powerConsumptionIsNotNumber() = - _PowerConsumptionIsNotNumber; - - const factory DevicesFailure.deviceActionDoesNotExist() = - _DeviceActionDoesNotExist; - - const factory DevicesFailure.deviceTypeDoesNotExist() = - _DeviceTypeDoesNotExist; -} diff --git a/lib/domain/device/devices_validators.dart b/lib/domain/device/devices_validators.dart deleted file mode 100644 index 070184919..000000000 --- a/lib/domain/device/devices_validators.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/devices_failures.dart'; -import 'package:dartz/dartz.dart'; - -Either, String> validateDeviceNotEmpty(String input) { - if (input.isNotEmpty) { - return right(input); - } else { - return left( - DevicesFailure.empty( - failedValue: input, - ), - ); - } -} - -Either, String> validateLastKnownIpNotEmpty( - String input, -) { - if (input.isNotEmpty) { - return right(input); - } else { - return left( - DevicesFailure.empty( - failedValue: input, - ), - ); - } -} - -Either, String> validatePowerConsumptionNotEmpty( - String input, -) { - if (double.tryParse(input) != null) { - return right(input); - } else { - return left(const DevicesFailure.powerConsumptionIsNotNumber()); - } -} - -Either, String> validateAreaNameNotEmpty(String input) { - return right(input); -} - -Either, String> validateMdnsNameNotEmpty(String input) { - return right(input); -} - -Either, String> validateWiFiNameNotEmpty(String input) { - return right(input); -} - -Either, String> validateDeviceMaxNameLength( - String input, - int maxLength, -) { - if (input.length <= maxLength) { - return right(input); - } else { - return left( - DevicesFailure.exceedingLength( - failedValue: input, - max: maxLength, - ), - ); - } -} - -Either, String> validateDeviceStateExist(String input) { - if (EntityUtils.stringToDeviceState(input) != null) { - return right(input); - } - return left(const DevicesFailure.deviceActionDoesNotExist()); -} - -Either, String> validateDeviceActionExist(String input) { - if (EntityUtils.stringToDeviceAction(input) != null) { - return right(input); - } - return left(const DevicesFailure.deviceActionDoesNotExist()); -} - -Either, String> validateDeviceTypeExist(String input) { - if (EntityUtils.stringToDt(input) != null) { - return right(input); - } - return left(const DevicesFailure.deviceTypeDoesNotExist()); -} diff --git a/lib/domain/device/i_device_repository.dart b/lib/domain/device/i_device_repository.dart deleted file mode 100644 index 537a93577..000000000 --- a/lib/domain/device/i_device_repository.dart +++ /dev/null @@ -1,145 +0,0 @@ -import 'dart:async'; -import 'dart:collection'; -import 'dart:io'; - -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/devices_failures.dart'; -import 'package:cybearjinni/infrastructure/core/logger.dart'; -import 'package:cybearjinni/infrastructure/hub_client/hub_requests_routing.dart'; -import 'package:dartz/dartz.dart'; -import 'package:device_info_plus/device_info_plus.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; -import 'package:kt_dart/kt.dart'; -import 'package:multicast_dns/multicast_dns.dart'; -import 'package:network_info_plus/network_info_plus.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'package:rxdart/rxdart.dart'; - -part 'package:cybearjinni/infrastructure/device_repository.dart'; - -@Deprecated('Old architecture. Replaced by EntitiesService') -abstract interface class IDeviceRepository { - static IDeviceRepository? _instance; - - static IDeviceRepository get instance { - return _instance ??= _DeviceRepository(); - } - - void addOrUpdateDevice(DeviceEntityBase deviceEntity); - - void addOrUpdateDeviceAndStateToWaiting(DeviceEntityBase deviceEntity); - - Future initiateHubConnection(); - - Future>> getAllEntites(); - - Stream>> watchAll(); - - Stream>> watchAllDevices(); - - Stream>> watchLights(); - - Stream>> watchBlinds(); - - Stream>> watchBoilers(); - - Stream>> watchSmartTv(); - - Stream>> watchSwitches(); - - Stream>> watchSmartPlugs(); - - Stream>> - watchSmartComputers(); - - Stream>> watchPrinters(); - - Stream>> watchUncompleted(); - - Future> create( - DeviceEntityBase deviceEntity, - ); - - Future> updateWithDeviceEntity({ - required DeviceEntityBase deviceEntity, - }); - - Future> turnOnDevices({ - required List? devicesId, - }); - - Future> turnOffDevices({ - required List? devicesId, - }); - - Future> changeColorTemperatureDevices({ - required List? devicesId, - required int colorTemperatureToChange, - }); - - Future> changeHsvColorDevices({ - required List? devicesId, - required HSVColor hsvColorToChange, - }); - - Future> changeBrightnessDevices({ - required List? devicesId, - required int brightnessToChange, - }); - - Future> moveUpStateDevices({ - required List? devicesId, - }); - - Future> stopStateDevices({ - required List? devicesId, - }); - - Future> moveDownStateDevices({ - required List? devicesId, - }); - - Future> suspendDevices({ - required List? devicesId, - }); - - Future> shutdownDevices({ - required List? devicesId, - }); - - Future> closeStateDevices({ - required List? devicesId, - }); - - Future> pauseStateDevices({ - required List? devicesId, - }); - - Future> playStateDevices({ - required List? devicesId, - }); - - Future> changeVolumeDevices({ - required List? devicesId, - }); - - Future> queuePrevStateDevices({ - required List? devicesId, - }); - - Future> queueNextStateDevices({ - required List? devicesId, - }); - - BehaviorSubject> allResponseFromTheHubStreamController = - BehaviorSubject>(); - - BehaviorSubject> areasResponseFromTheHubStreamController = - BehaviorSubject>(); - - BehaviorSubject> - devicesResponseFromTheHubStreamController = - BehaviorSubject>(); -} diff --git a/lib/domain/i_hub_connection_repository.dart b/lib/domain/i_hub_connection_repository.dart deleted file mode 100644 index 40cd72a88..000000000 --- a/lib/domain/i_hub_connection_repository.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:cybearjinni/domain/i_local_db_repository.dart'; -import 'package:cybearjinni/infrastructure/core/injection.dart'; -import 'package:dartz/dartz.dart'; -import 'package:flutter/foundation.dart' show kIsWeb; -import 'package:location/location.dart'; -import 'package:multicast_dns/multicast_dns.dart'; -import 'package:network_info_plus/network_info_plus.dart'; -import 'package:permission_handler/permission_handler.dart' - as permission_handler; -import 'package:wifi_iot/wifi_iot.dart'; - -part 'package:cybearjinni/infrastructure/hub_client/hub_connection_repository.dart'; - -@Deprecated( - 'Old architecture. Replaced with ConnectionsService. Delete after Re adding Hub comunication', -) -abstract class IHubConnectionRepository { - static IHubConnectionRepository? _instance; - - static IHubConnectionRepository get instance { - return _instance ??= _HubConnectionRepository(); - } - - static HubEntity? hubEntity; - - Future connectWithHub({bool demoMod = false}); - - Future> getHubCompInfo( - CompHubInfo appInfoForHub, - ); - - Future closeConnection(); - - Future> searchForHub({ - String? deviceIpOnTheNetwork, - bool? isThatTheIpOfTheHub, - }); - - Future saveHubIP(String hubIP); -} diff --git a/lib/domain/i_local_db_repository.dart b/lib/domain/i_local_db_repository.dart index 92e4c29df..af3283501 100644 --- a/lib/domain/i_local_db_repository.dart +++ b/lib/domain/i_local_db_repository.dart @@ -16,7 +16,7 @@ abstract interface class ILocalDbRepository { return _instance ??= _IsarRepository(); } - Future asyncConstructor(); + Future asyncConstructor(); Future> saveHubEntity({ required String hubNetworkBssid, diff --git a/lib/domain/software_info/i_software_info_repository.dart b/lib/domain/software_info/i_software_info_repository.dart index 75792e1a0..bbe487adf 100644 --- a/lib/domain/software_info/i_software_info_repository.dart +++ b/lib/domain/software_info/i_software_info_repository.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/i_hub_connection_repository.dart'; import 'package:cybearjinni/domain/security_bear/i_security_bear_connection_repository.dart'; import 'package:cybearjinni/domain/security_bear/security_bear_failures.dart'; import 'package:cybearjinni/domain/software_info/software_info_entity.dart'; diff --git a/lib/infrastructure/cbj_app_server_d.dart b/lib/infrastructure/cbj_app_server_d.dart index 32c440b10..4ff328c95 100644 --- a/lib/infrastructure/cbj_app_server_d.dart +++ b/lib/infrastructure/cbj_app_server_d.dart @@ -25,7 +25,7 @@ class _CBJAppServerD extends CyBearJinniAppServiceBase { return Future.value(CompAppInfo()); } -// Future cBJAppGetSmartDeviceInformationAsync( +// Future cBJAppGetSmartDeviceInformationAsync( // SmartDeviceInfo smartDevice) async { // final String smartDeviceIp = smartDevice.smartDeviceIP; // @@ -54,14 +54,14 @@ class CreateTheCBJAppServer { Server? server; /// This function will create the server - Future createServer(StreamController compInfoStream) async { + Future createServer(StreamController compInfoStream) async { await server?.shutdown(); server = Server.create(services: [_CBJAppServerD(compInfoStream)]); await server!.serve(port: 30055); logger.i('App server listening on port ${server!.port}...'); } - Future shutdownServer() async { + Future shutdownServer() async { await server?.shutdown(); return; } diff --git a/lib/infrastructure/connection_service/app_connection_service.dart b/lib/infrastructure/connection_service/app_connection_service.dart index a1b7a82f3..dc042a966 100644 --- a/lib/infrastructure/connection_service/app_connection_service.dart +++ b/lib/infrastructure/connection_service/app_connection_service.dart @@ -9,11 +9,11 @@ class _AppConnectionService implements ConnectionsService { late SearchDevices searchDevicesInstance; @override - Future> get getAllEntities async => + Future> get getEntities async => IcSynchronizer().getEntities(); @override - Future> get getAllAreas async => + Future> get getAreas async => IcSynchronizer().getAreas(); @override @@ -29,7 +29,7 @@ class _AppConnectionService implements ConnectionsService { IcSynchronizer().areasChangesStream.stream; @override - void setEntityState(ActionObject action) => + void setEntityState(RequestActionObject action) => IcSynchronizer().setEntitiesState(action); @override @@ -45,7 +45,7 @@ class _AppConnectionService implements ConnectionsService { IcSynchronizer().setEtitiesToArea(areaId, entities); @override - Future> getScenes() async => + Future> get getScenes async => IcSynchronizer().getScenes(); @override @@ -53,4 +53,15 @@ class _AppConnectionService implements ConnectionsService { @override Future addScene(SceneCbjEntity scene) => IcSynchronizer().addScene(scene); + + @override + Future loginVendor(VendorLoginEntity value) async => + IcSynchronizer().loginVendor(value); + + @override + Future> getVendors() async => + IcSynchronizer().getVendors(); + + @override + Future connect({String? address}) async => true; } diff --git a/lib/infrastructure/connection_service/demo_connection_service.dart b/lib/infrastructure/connection_service/demo_connection_service.dart index 555dfcb09..b0f17ddac 100644 --- a/lib/infrastructure/connection_service/demo_connection_service.dart +++ b/lib/infrastructure/connection_service/demo_connection_service.dart @@ -10,17 +10,17 @@ class _DemoConnectionService implements ConnectionsService { } @override - Future> get getAllEntities async => + Future> get getEntities async => DemoConnectionController.getAllEntities(); @override - Future> get getAllAreas async => HashMap(); + Future> get getAreas async => HashMap(); @override Future searchDevices() async {} @override - void setEntityState(ActionObject action) {} + void setEntityState(RequestActionObject action) {} @override Stream> watchEntities() { @@ -48,8 +48,18 @@ class _DemoConnectionService implements ConnectionsService { Future addScene(SceneCbjEntity scene) async {} @override - Future> getScenes() async => HashMap(); + Future> get getScenes async => HashMap(); @override Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => + IcSynchronizer().getVendors(); + + @override + Future connect({String? address}) async => true; } diff --git a/lib/infrastructure/connection_service/hub_connection_service.dart b/lib/infrastructure/connection_service/hub_connection_service.dart new file mode 100644 index 000000000..70bb08beb --- /dev/null +++ b/lib/infrastructure/connection_service/hub_connection_service.dart @@ -0,0 +1,390 @@ +part of 'package:cybearjinni/domain/connections_service.dart'; + +class _HubConnectionService implements ConnectionsService { + _HubConnectionService() { + if (currentEnvApp == EnvApp.prod) { + hubPort = 50055; + } else { + hubPort = 60055; + } + } + + /// Port to connect to the cbj hub, will change according to the current + /// running environment + late int hubPort; + + String? hubIp; + String? networkBssid; + String? networkName; + + ClientChannel? channel; + CbjHubClient? stub; + + StreamController>? entitiesStream; + StreamController>? areasStream; + + BehaviorSubject hubMessagesToApp = + BehaviorSubject(); + + // StreamController appMessagesToHub = + // StreamController(); + + BehaviorSubject appMessagesToHub = BehaviorSubject(); + + @override + Future dispose() async { + entitiesStream?.close(); + } + + @override + Future> get getEntities async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allEntities.name), + ); + final HashMap entities = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allEntities) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + entities.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + DeviceHelper.convertJsonStringToDomain(e.value), + ), + ), + ); + } catch (e) { + logger.e('Error converting entities\n$e'); + } + break; + } + + return entities; + } + + @override + Future> get getAreas async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allAreas.name), + ); + + final HashMap areas = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allAreas) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + areas.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + AreaEntityDtos.fromJson( + jsonDecode(e.value) as Map, + ).toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting areas\n$e'); + } + break; + } + + return areas; + } + + @override + Future> get getScenes async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allScenes.name), + ); + + final HashMap scenesMap = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allScenes) { + continue; + } + + try { + final Map entities = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + scenesMap.addEntries( + entities.entries.map( + (e) => MapEntry( + e.key, + SceneCbjDtos.fromJson(jsonDecode(e.value) as Map) + .toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting scenes\n$e'); + } + break; + } + + return scenesMap; + } + + @override + Future searchDevices() async { + try { + final Either locationRequest = + await askLocationPermissionAndLocationOn(); + + if (locationRequest.isLeft()) { + return locationRequest; + } + + logger.i('searchForHub'); + String? appDeviceIp; + if (await Connectivity().checkConnectivity() == ConnectivityResult.wifi && + !kIsWeb) { + final NetworkInfo networkInfo = NetworkInfo(); + networkName = await networkInfo.getWifiName(); + appDeviceIp = await networkInfo.getWifiIP(); + networkBssid = await networkInfo.getWifiBSSID(); + } else { + return false; + // if (deviceIpOnTheNetwork == null) { + // // Issue https://github.com/CyBear-Jinni/cbj_app/issues/256 + // return left( + // const HubFailures + // .findingHubWhenConnectedToEthernetCableIsNotSupported(), + // ); + // } + + // currentDeviceIP = deviceIpOnTheNetwork; + // networkBSSID = 'no:Network:Bssid:Found'; + // networkName = 'noNetworkNameFound'; + // if (isThatTheIpOfTheHub != null && isThatTheIpOfTheHub) { + // return insertHubInfo( + // networkIp: currentDeviceIP, + // networkBSSID: networkBSSID, + // networkName: networkName, + // ); + // } + } + if (appDeviceIp == null) { + return false; + } + final String subnet = + appDeviceIp.substring(0, appDeviceIp.lastIndexOf('.')); + + logger.i('Hub Search subnet IP $subnet'); + + // TODO: Search for hub + final Stream devicesWithPort = + HostScanner.scanDevicesForSinglePort( + subnet, + hubPort, + + /// TODO: return this settings when can use with the await for loop + // resultsInIpAscendingOrder: false, + timeout: const Duration(milliseconds: 600), + ); + + await for (final ActiveHost activeHost in devicesWithPort) { + logger.i('Found Cbj Hub device: ${activeHost.address}'); + hubIp = activeHost.address; + return true; + // if (networkBSSID != null && networkName != null) { + // return insertHubInfo( + // networkIp: activeHost.address, + // networkBSSID: networkBSSID, + // networkName: networkName, + // ); + // } + } + } catch (e) { + logger.w('Exception searchForHub\n$e'); + } + } + + @override + void setEntityState(RequestActionObject action) { + appMessagesToHub.sink.add( + ClientStatusRequests( + sendingType: SendingType.setEntitiesAction.name, + allRemoteCommands: action.toInfrastructure().toJsonString(), + ), + ); + } + + @override + Stream> watchEntities() { + entitiesStream?.close(); + + entitiesStream = StreamController.broadcast(); + return entitiesStream!.stream; + } + + @override + Stream> watchAreas() { + areasStream?.close(); + + areasStream = StreamController.broadcast(); + return areasStream!.stream; + } + + @override + Future setNewArea(AreaEntity area) async {} + + @override + Future setEtitiesToArea(String areaId, HashSet entities) async {} + + @override + Future addScene(SceneCbjEntity scene) async {} + + @override + Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => + IcSynchronizer().getVendors(); + + @override + Future connect({String? address}) async { + searchDevices(); + if (hubIp == null) { + return false; + } + + connectDirectlyToHub(); + + return true; + } + + Future> askLocationPermissionAndLocationOn() async { + final Location location = Location(); + + bool serviceEnabled; + PermissionStatus permissionGranted; + + int permissionCounter = 0; + int disabledCounter = 0; + + // Get location permission is not supported on Linux + if (Platform.isLinux || Platform.isWindows) { + return right(unit); + } + + while (true) { + permissionGranted = await location.hasPermission(); + if (permissionGranted == PermissionStatus.denied) { + permissionGranted = await location.requestPermission(); + if (permissionGranted != PermissionStatus.granted) { + logger.e('Permission to use location is denied'); + await Future.delayed(const Duration(seconds: 10)); + + permissionCounter++; + if (permissionCounter > 5) { + permission_handler.openAppSettings(); + } else if (permissionCounter > 7) { + return const Left(HubFailures.unexpected()); + } + continue; + } + } + + serviceEnabled = await location.serviceEnabled(); + if (!serviceEnabled) { + serviceEnabled = await location.requestService(); + if (!serviceEnabled) { + disabledCounter++; + if (disabledCounter > 2) { + return const Left(HubFailures.unexpected()); + } + logger.w('Location is disabled'); + await Future.delayed(const Duration(seconds: 5)); + continue; + } + } + break; + } + return right(unit); + } + + /// Connect directly to the Hub if possible + Future connectDirectlyToHub() async { + if (hubIp == null) { + return; + } + + // Socket? testHubConnection; + // try { + // testHubConnection = await Socket.connect( + // hubIP, + // hubPort, + // timeout: const Duration(milliseconds: 500), + // ); + // await testHubConnection.close(); + // testHubConnection.destroy(); + // testHubConnection = null; + // } catch (e) { + // await testHubConnection?.close(); + // testHubConnection?.destroy(); + // } + + try { + // // TODO: DELTE + // await HubClient.createStreamWithHub( + // hubIp!, + // hubPort, + // ); + + channel = ClientChannel( + hubIp!, + port: hubPort, + options: + const ChannelOptions(credentials: ChannelCredentials.insecure()), + ); + + channel!.onConnectionStateChanged.listen((event) { + logger.i('gRPC connection state $event'); + }); + + stub = CbjHubClient(channel!); + + final ResponseStream response = + stub!.clientTransferEntities( + appMessagesToHub.stream, + ); + + // appMessagesToHub.sink + // .add(ClientStatusRequests(sendingType: SendingType.firstConnection)); + + hubMessagesToApp.addStream(response); + await Future.delayed(const Duration(seconds: 3)); + } catch (e) { + logger.e('Caught error while stream with hub\n$e'); + await channel?.shutdown(); + } + } +} diff --git a/lib/infrastructure/connection_service/none_connection_service.dart b/lib/infrastructure/connection_service/none_connection_service.dart index dabda1bdb..7908507ee 100644 --- a/lib/infrastructure/connection_service/none_connection_service.dart +++ b/lib/infrastructure/connection_service/none_connection_service.dart @@ -10,17 +10,16 @@ class _NoneConnectionService implements ConnectionsService { } @override - Future> get getAllEntities async => - HashMap(); + Future> get getEntities async => HashMap(); @override - Future> get getAllAreas async => HashMap(); + Future> get getAreas async => HashMap(); @override Future searchDevices() async {} @override - void setEntityState(ActionObject action) {} + void setEntityState(RequestActionObject action) {} @override Stream> watchEntities() { @@ -45,11 +44,20 @@ class _NoneConnectionService implements ConnectionsService { Future setEtitiesToArea(String areaId, HashSet entities) async {} @override - Future> getScenes() async => HashMap(); + Future> get getScenes async => HashMap(); @override Future addScene(SceneCbjEntity scene) async {} @override Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => []; + + @override + Future connect({String? address}) async => true; } diff --git a/lib/infrastructure/connection_service/remote_pipes_connection_service.dart b/lib/infrastructure/connection_service/remote_pipes_connection_service.dart new file mode 100644 index 000000000..3b0920734 --- /dev/null +++ b/lib/infrastructure/connection_service/remote_pipes_connection_service.dart @@ -0,0 +1,239 @@ +part of 'package:cybearjinni/domain/connections_service.dart'; + +class _RemotePipesConnectionService implements ConnectionsService { + /// Port to connect to the cbj hub, will change according to the current + /// running environment + int hubPort = 50051; + + String? address; + String? networkBssid; + String? networkName; + + ClientChannel? channel; + CbjHubClient? stub; + + StreamController>? entitiesStream; + StreamController>? areasStream; + + BehaviorSubject hubMessagesToApp = + BehaviorSubject(); + + // StreamController appMessagesToHub = + // StreamController(); + + BehaviorSubject appMessagesToHub = BehaviorSubject(); + + @override + Future dispose() async { + entitiesStream?.close(); + } + + @override + Future> get getEntities async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allEntities.name), + ); + final HashMap entities = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allEntities) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + entities.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + DeviceHelper.convertJsonStringToDomain(e.value), + ), + ), + ); + } catch (e) { + logger.e('Error converting entities\n$e'); + } + break; + } + + return entities; + } + + @override + Future> get getAreas async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allAreas.name), + ); + + final HashMap areas = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allAreas) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + areas.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + AreaEntityDtos.fromJson( + jsonDecode(e.value) as Map, + ).toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting areas\n$e'); + } + break; + } + + return areas; + } + + @override + Future> get getScenes async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allScenes.name), + ); + + final HashMap scenesMap = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allScenes) { + continue; + } + + try { + final Map entities = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + scenesMap.addEntries( + entities.entries.map( + (e) => MapEntry( + e.key, + SceneCbjDtos.fromJson(jsonDecode(e.value) as Map) + .toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting scenes\n$e'); + } + break; + } + + return scenesMap; + } + + @override + Future searchDevices() async {} + + @override + void setEntityState(RequestActionObject action) { + appMessagesToHub.sink.add( + ClientStatusRequests( + sendingType: SendingType.setEntitiesAction.name, + allRemoteCommands: action.toInfrastructure().toJsonString(), + ), + ); + } + + @override + Stream> watchEntities() { + entitiesStream?.close(); + + entitiesStream = StreamController.broadcast(); + return entitiesStream!.stream; + } + + @override + Stream> watchAreas() { + areasStream?.close(); + + areasStream = StreamController.broadcast(); + return areasStream!.stream; + } + + @override + Future setNewArea(AreaEntity area) async {} + + @override + Future setEtitiesToArea(String areaId, HashSet entities) async {} + + @override + Future addScene(SceneCbjEntity scene) async {} + + @override + Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => + IcSynchronizer().getVendors(); + + @override + Future connect({String? address}) async { + this.address = address; + if (this.address == null) { + return false; + } + + connectHelper(); + + return true; + } + + /// Connect directly to the Hub if possible + Future connectHelper() async { + if (address == null) { + return; + } + + try { + channel = ClientChannel( + address!, + port: hubPort, + options: + const ChannelOptions(credentials: ChannelCredentials.insecure()), + ); + + channel!.onConnectionStateChanged.listen((event) { + logger.i('gRPC connection state $event'); + }); + + stub = CbjHubClient(channel!); + + final ResponseStream response = + stub!.clientTransferEntities( + appMessagesToHub.stream, + ); + + // appMessagesToHub.sink + // .add(ClientStatusRequests(sendingType: SendingType.firstConnection)); + + hubMessagesToApp.addStream(response); + await Future.delayed(const Duration(seconds: 3)); + } catch (e) { + logger.e('Caught error while stream with hub\n$e'); + await channel?.shutdown(); + } + } +} diff --git a/lib/infrastructure/core/injection.dart b/lib/infrastructure/core/injection.dart index 512fd02b2..45e0fe6e9 100644 --- a/lib/infrastructure/core/injection.dart +++ b/lib/infrastructure/core/injection.dart @@ -1,4 +1,4 @@ -import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/infrastructure/core/injection.config.dart'; import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:get_it/get_it.dart'; import 'package:injectable/injectable.dart'; diff --git a/lib/infrastructure/device_repository.dart b/lib/infrastructure/device_repository.dart deleted file mode 100644 index f2da21549..000000000 --- a/lib/infrastructure/device_repository.dart +++ /dev/null @@ -1,1160 +0,0 @@ -part of 'package:cybearjinni/domain/device/i_device_repository.dart'; - -class _DeviceRepository implements IDeviceRepository { - // final DeviceRemoteService _deviceRemoteService; - // final DeviceLocalService _deviceLocalService; - HashMap allDevices = - HashMap(); - - // @override - // void addOrUpdateFromApp(dynamic entity) { - // if (entity is AreaEntity) { - // _addOrUpdateArea(entity); - // } else if (entity is DeviceEntityBase) { - // _addOrUpdateDevice(entity); - // } else { - // logger.w('Entity type to update ${entity.runtimeType} is not supported'); - // } - // allResponseFromTheHubStreamController.sink - // .add(entity); - // } - - @override - void addOrUpdateDevice(DeviceEntityBase deviceEntity) { - allDevices[deviceEntity.cbjDeviceVendor.getOrCrash()] = deviceEntity; - devicesResponseFromTheHubStreamController.sink - .add(allDevices.values.toImmutableList()); - } - - @override - void addOrUpdateDeviceAndStateToWaiting(DeviceEntityBase deviceEntity) { - addOrUpdateDevice( - deviceEntity.copyWithDeviceState( - EntityStateGRPC.waitingInComp, - ), - ); - } - - @override - Future initiateHubConnection() async { - AppRequestsToHub.listenToApp(); - - HubRequestRouting.navigateRequest(); - } - - @override - Future>> - getAllEntites() async { - try { - return right(allDevices.values.toImmutableList()); - } catch (e) { - if (e is PlatformException && e.message!.contains('PERMISSION_DENIED')) { - logger.w('Insufficient permission while getting all devices'); - return left(const DevicesFailure.insufficientPermission()); - } else { - logger.e('Unexpected error while getting all devices'); - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - } - - @override - Stream> watchAll() async* { - yield* allResponseFromTheHubStreamController.map((event) => right(event)); - } - - @override - Stream>> - watchAllDevices() async* { - yield* devicesResponseFromTheHubStreamController.stream - .map((event) => right(event)); - } - - @override - Stream>> - watchLights() async* { - // Using watchAll devices from server function and filtering out only the - // Light device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.light.toString() || - element.entityTypes.getOrCrash() == - EntityTypes.dimmableLight.toString() || - element.entityTypes.getOrCrash() == - EntityTypes.rgbwLights.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSwitches() async* { - // Using watchAll devices from server function and filtering out only the - // Switches device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.switch_.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSmartPlugs() async* { - // Using watchAll devices from server function and filtering out only the - // Smart Plugs device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.smartPlug.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSmartComputers() async* { - // Using watchAll devices from server function and filtering out only the - // Smart Computers device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.smartComputer.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchBlinds() async* { - // Using watchAll devices from server function and filtering out only the - // Blinds device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.blinds.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchBoilers() async* { - // Using watchAll devices from server function and filtering out only the - // Boilers device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.boiler.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSmartTv() async* { - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.smartTV.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchPrinters() async* { - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.printer.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> watchUncompleted() { - // TODO: implement watchUncompleted - throw UnimplementedError(); - } - - @override - Future> create( - DeviceEntityBase deviceEntity, - ) async { - try { - String deviceModelString = 'No Model found'; - final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - if (Platform.isAndroid) { - final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; - logger.i(androidInfo.model); - deviceModelString = androidInfo.model; - } else if (Platform.isIOS) { - final IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - logger.i(iosInfo.utsname.machine); - deviceModelString = iosInfo.model; - } - - const String currentUserId = 'user id'; - - deviceEntity - .copyWithStateMassage('Setting up device') - .copyWithSenderDeviceOs(Platform.operatingSystem) - .copyWithDeviceSenderDeviceModel(deviceModelString) - .copyWithSenderId(currentUserId); - - DeviceEntityDtoBase.fromDomain(); - - return right(unit); - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - } - - @override - Future> updateWithDeviceEntity({ - required DeviceEntityBase deviceEntity, - }) async { - return left(const DevicesFailure.unexpected()); - } - - @override - Future> turnOnDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericLightDE) { - deviceEntity.lightSwitchState = - GenericLightSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericDimmableLightDE) { - deviceEntity.lightSwitchState = - GenericDimmableLightSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightSwitchState = - GenericRgbwLightSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericSwitchDE) { - deviceEntity.switchState = - GenericSwitchSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericBoilerDE) { - deviceEntity.boilerSwitchState = - GenericBoilerSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericSmartPlugDE) { - deviceEntity.smartPlugState = - GenericSmartPlugState(EntityActions.on.toString()); - } else { - logger.w( - 'On action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> turnOffDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericLightDE) { - deviceEntity.lightSwitchState = - GenericLightSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericDimmableLightDE) { - deviceEntity.lightSwitchState = - GenericDimmableLightSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightSwitchState = - GenericRgbwLightSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericSwitchDE) { - deviceEntity.switchState = - GenericSwitchSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericBoilerDE) { - deviceEntity.boilerSwitchState = - GenericBoilerSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericSmartPlugDE) { - deviceEntity.smartPlugState = - GenericSmartPlugState(EntityActions.off.toString()); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeColorTemperatureDevices({ - required List? devicesId, - required int colorTemperatureToChange, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightColorTemperature = GenericRgbwLightColorTemperature( - colorTemperatureToChange.toString(), - ); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - try { - if (!deviceEntity.doesWaitingToSendTemperatureColorRequest) { - deviceEntity.doesWaitingToSendTemperatureColorRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: - deviceEntity.sendNewTemperatureColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendTemperatureColorRequest = false; - - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: - deviceEntity.sendNewTemperatureColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendTemperatureColorRequest = false; - return left(const DevicesFailure.unexpected()); - } - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeHsvColorDevices({ - required List? devicesId, - required HSVColor hsvColorToChange, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericRgbwLightDE) { - deviceEntity - ..lightColorAlpha = - GenericRgbwLightColorAlpha(hsvColorToChange.alpha.toString()) - ..lightColorHue = - GenericRgbwLightColorHue(hsvColorToChange.hue.toString()) - ..lightColorSaturation = GenericRgbwLightColorSaturation( - hsvColorToChange.saturation.toString(), - ) - ..lightColorValue = - GenericRgbwLightColorValue(hsvColorToChange.value.toString()); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - try { - if (!deviceEntity.doesWaitingToSendHsvColorRequest) { - deviceEntity.doesWaitingToSendHsvColorRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewHsvColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendHsvColorRequest = false; - - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewHsvColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendHsvColorRequest = false; - return left(const DevicesFailure.unexpected()); - } - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeBrightnessDevices({ - required List? devicesId, - required int brightnessToChange, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - Either totalActionResult = right(unit); - - try { - Either actionResult; - - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } else if (deviceEntity is GenericDimmableLightDE) { - deviceEntity.lightBrightness = - GenericDimmableLightBrightness(brightnessToChange.toString()); - actionResult = await dimDimmableLight(deviceEntity); - } else if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightBrightness = - GenericRgbwLightBrightness(brightnessToChange.toString()); - actionResult = await dimRgbwLight(deviceEntity); - } else { - logger.w( - 'Brightness action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - if (actionResult.isLeft()) { - totalActionResult = actionResult; - } - } - return totalActionResult; - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - } - - Future> dimDimmableLight( - GenericDimmableLightDE deviceEntity, - ) async { - try { - if (!deviceEntity.doesWaitingToSendBrightnessRequest) { - deviceEntity.doesWaitingToSendBrightnessRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return left(const DevicesFailure.unexpected()); - } - return right(unit); - } - - Future> dimRgbwLight( - GenericRgbwLightDE deviceEntity, - ) async { - try { - if (!deviceEntity.doesWaitingToSendBrightnessRequest) { - deviceEntity.doesWaitingToSendBrightnessRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return left(const DevicesFailure.unexpected()); - } - return right(unit); - } - - @override - Future> moveUpStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.moveUp.toString()); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> stopStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.stop.toString()); - } else if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.stop.toString(), - ); - } else { - logger.w( - 'Stop action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> moveDownStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.moveDown.toString()); - } else { - logger.w( - 'Move down action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> suspendDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartComputerDE) { - deviceEntity.smartComputerSuspendState = - GenericSmartComputerSuspendState( - EntityActions.suspend.toString(), - ); - } else { - logger.w( - 'Suspend action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> shutdownDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartComputerDE) { - deviceEntity.smartComputerShutDownState = - GenericSmartComputerShutdownState( - EntityActions.shutdown.toString(), - ); - } else { - logger.w( - 'Shutdown action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeVolumeDevices({ - required List? devicesId, - }) async { - // TODO: implement changeVolumeDevices - throw UnimplementedError(); - } - - @override - Future> closeStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.close.toString()); - } else { - logger.w( - 'Close action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> pauseStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.pause.toString(), - ); - } else { - logger.w( - 'Pause action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> playStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.play.toString(), - ); - } else { - logger.w( - 'Play action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> queuePrevStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.skipPreviousVid.toString(), - ); - } else { - logger.w( - 'Skip prev vid action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> queueNextStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.skipNextVid.toString(), - ); - } else { - logger.w( - 'Skip next vid action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - Future> updateComputer( - DeviceEntityBase deviceEntity, - ) async { - try { - addOrUpdateDeviceAndStateToWaiting(deviceEntity); - - try { - deviceEntity.copyWithDeviceState(EntityStateGRPC.waitingInCloud); - - final String deviceDtoAsString = - DeviceHelper.convertDomainToJsonString(deviceEntity); - final ClientStatusRequests clientStatusRequests = ClientStatusRequests( - allRemoteCommands: deviceDtoAsString, - sendingType: SendingType.entityType, - ); - AppRequestsToHub.appRequestsToHubStreamController - .add(clientStatusRequests); - } catch (e) { - logger.e('This is the error\n$e'); - - // final DocumentReference homeDoc = - // await _firestore.currentHomeDocument(); - // final CollectionReference devicesCollection = - // homeDoc.devicesCollecttion; - // final DocumentReference deviceDocumentReference = - // devicesCollection.doc(deviceEntity.id!.getOrCrash()); - // updateDatabase(documentPath: deviceDocumentReference, fieldsToUpdate: { - // 'lastKnownIp': lastKnownIp, - // }); - } - - return right(unit); - } catch (e) { - logger.w('Probably ip of device was not inserted into the device object'); - return left(const DevicesFailure.unexpected()); - } - } - - Future> getDeviceEntityListFromId( - List deviceIdList, - ) async { - final List deviceEntityList = []; - - if (allDevices.isEmpty) { - return []; - } - - for (final deviceId in deviceIdList) { - final DeviceEntityBase? device = allDevices[deviceId]; - if (device == null) { - continue; - } - deviceEntityList.add(device); - } - return deviceEntityList; - } - - /// Search device IP by computer Avahi (mdns) name - Future getDeviceIpByDeviceAvahiName(String mDnsName) async { - String deviceIp = ''; - final String fullMdnsName = '$mDnsName.local'; - - final MDnsClient client = MDnsClient( - rawDatagramSocketFactory: ( - dynamic host, - int port, { - bool? reuseAddress, - bool? reusePort, - int? ttl, - }) { - return RawDatagramSocket.bind(host, port, ttl: ttl!); - }, - ); - // Start the client with default options. - - await client.start(); - await for (final IPAddressResourceRecord record - in client.lookup( - ResourceRecordQuery.addressIPv4(fullMdnsName), - )) { - deviceIp = record.address.address; - logger.t('Found address (${record.address}).'); - } - - // await for (final IPAddressResourceRecord record - // in client.lookup( - // ResourceRecordQuery.addressIPv6(fullMdnsName))) { - // logger.t('Found address (${record.address}).'); - // } - - client.stop(); - - logger.t('Done.'); - - return deviceIp; - } - - /// How to send the data, in the local network or the remote server/cloud - Future whereToUpdateDevicesData( - String? forceUpdateLocation, - String? deviceSecondWifiName, - ) async { - String updateLocation; - - try { - if (forceUpdateLocation == null) { - final status = await Permission.location.status; - if (status.isDenied) { - Permission.location.request(); - } - - final String? wifiName = await NetworkInfo().getWifiName(); - - if (deviceSecondWifiName != null && - deviceSecondWifiName.isNotEmpty && - deviceSecondWifiName == wifiName) { - updateLocation = 'L'; // L for local network - } else { - updateLocation = 'R'; // R for remote - } - } else { - updateLocation = forceUpdateLocation; - } - } catch (exception) { - updateLocation = 'L'; - } - - return updateLocation; - } - - /// Stream controller of the app request for the hub - @override - BehaviorSubject allResponseFromTheHubStreamController = - BehaviorSubject(); - - @override - BehaviorSubject> - devicesResponseFromTheHubStreamController = - BehaviorSubject>(); - - @override - BehaviorSubject> areasResponseFromTheHubStreamController = - BehaviorSubject>(); -} diff --git a/lib/infrastructure/hub_client/hub_connection_repository.dart b/lib/infrastructure/hub_client/hub_connection_repository.dart deleted file mode 100644 index 2c2b24a4b..000000000 --- a/lib/infrastructure/hub_client/hub_connection_repository.dart +++ /dev/null @@ -1,582 +0,0 @@ -part of 'package:cybearjinni/domain/i_hub_connection_repository.dart'; - -@Deprecated( - 'Old architecture. Replaced with ConnectionsService. Delete after Re adding Hub comunication', -) -class _HubConnectionRepository implements IHubConnectionRepository { - _HubConnectionRepository() { - if (currentEnvApp == EnvApp.prod) { - hubPort = 50055; - } else { - hubPort = 60055; - } - } - - /// Port to connect to the cbj hub, will change according to the current - /// running environment - late int hubPort; - - int tryAgainConnectToTheHubOnceMore = 0; - - bool cancelConnectionWithHub = false; - - bool appInDemoMod = false; - - @override - Future connectWithHub({bool demoMod = false}) async { - if (cancelConnectionWithHub && !demoMod) { - return; - } - appInDemoMod = demoMod; - - if (appInDemoMod) { - cancelConnectionWithHub = true; - return streamFromDemoMode(); - } - - /// Load network information from local db - if (IHubConnectionRepository.hubEntity == null) { - await loadNetworkInformationFromDb(); - } - - ConnectivityResult? connectivityResult; - try { - connectivityResult = await Connectivity().checkConnectivity(); - } catch (e) { - icLogger.w('Cant check connectivity this is probably PC, error\n$e'); - } - - // Last Number of bssid can change fix?, need to check if more numbers - // can do that - final String? savedWifiBssid = - IHubConnectionRepository.hubEntity?.hubNetworkBssid.getOrCrash(); - final String? savedWifiBssidWithoutLastNumber = - savedWifiBssid?.substring(0, savedWifiBssid.lastIndexOf(':')); - String? wifiBSSID; - String? wifiBSSIDWithoutLastNumber; - try { - wifiBSSID = await NetworkInfo().getWifiBSSID(); - wifiBSSIDWithoutLastNumber = - wifiBSSID?.substring(0, wifiBSSID.lastIndexOf(':')); - } catch (e) { - icLogger.w("Can't get WiFi BSSID"); - } - final Either remotePipesInformation = - await ILocalDbRepository.instance.getRemotePipesDnsName(); - - // Check if you are connected to the home local network for direct - // communication with the Hub. - // This block can be false also if user does not approve some permissions - // or #256 if the app run on the computer and connected with ethernet cable - // (not effecting connection with WiFi) - if (remotePipesInformation.isLeft() || - (connectivityResult != null && - connectivityResult == ConnectivityResult.wifi && - savedWifiBssidWithoutLastNumber != null && - wifiBSSIDWithoutLastNumber != null && - savedWifiBssidWithoutLastNumber == wifiBSSIDWithoutLastNumber) || - (connectivityResult != null && - connectivityResult == ConnectivityResult.ethernet && - savedWifiBssidWithoutLastNumber == 'no:Network:Bssid') || - (kIsWeb && savedWifiBssidWithoutLastNumber == 'no:Network:Bssid')) { - (await openAndroidWifiSettingIfPossible()).fold( - (l) { - icLogger - .w('No way to establish connection with the Hub, WiFi or location' - ' permission is closed for here'); - return; - }, - (r) async {}, - ); - icLogger.i('Connect using direct connection to Hub'); - - await connectDirectlyToHub(); - return; - } else { - await connectionUsingRemotePipes(); - } - } - - @override - Future> getHubCompInfo( - CompHubInfo appInfoForHub, - ) async { - if (IHubConnectionRepository.hubEntity == null) { - try { - String? hubNetworkBssid; - (await ILocalDbRepository.instance.getHubEntityNetworkBssid()).fold( - (l) => throw 'Error getting Hub network Bssid', - (r) => hubNetworkBssid = r, - ); - - String? hubNetworkName; - (await ILocalDbRepository.instance.getHubEntityNetworkName()).fold( - (l) => throw 'Error getting Hub network name', - (r) => hubNetworkName = r, - ); - - String? hubNetworkIp; - (await ILocalDbRepository.instance.getHubEntityLastKnownIp()).fold( - (l) => throw 'Error getting Hub network IP', - (r) => hubNetworkIp = r, - ); - IHubConnectionRepository.hubEntity = HubDtos( - hubNetworkBssid: hubNetworkBssid!, - lastKnownIp: hubNetworkIp!, - networkName: hubNetworkName!, - ).toDomain(); - } catch (e) { - icLogger.e('Crashed while setting Hub info from local db\n$e'); - } - } - - ConnectivityResult? connectivityResult; - try { - connectivityResult = await Connectivity().checkConnectivity(); - } catch (e) { - icLogger.w('Cant check connectivity this is probably PC, error\n$e'); - } - - // Last Number of bssid can change fix?, need to check if more numbers - // can do that - final String? savedWifiBssid = - IHubConnectionRepository.hubEntity?.hubNetworkBssid.getOrCrash(); - final String? savedWifiBssidWithoutLastNumber = - savedWifiBssid?.substring(0, savedWifiBssid.lastIndexOf(':')); - - final String? wifiBSSID = await NetworkInfo().getWifiBSSID(); - final String? wifiBSSIDWithoutLastNumber = - wifiBSSID?.substring(0, wifiBSSID.lastIndexOf(':')); - - // Check if you are connected to the home local network for direct - // communication with the Hub. - // This block can be false also if user does not improve some permissions - // or #256 if the app run on the computer and connected with ethernet cable - // (not effecting connection with WiFi) - if (connectivityResult != null && - connectivityResult == ConnectivityResult.wifi && - savedWifiBssidWithoutLastNumber != null && - wifiBSSIDWithoutLastNumber != null && - savedWifiBssidWithoutLastNumber == wifiBSSIDWithoutLastNumber) { - icLogger.i('Connect using direct connection to Hub'); - - if (IHubConnectionRepository.hubEntity?.lastKnownIp.getOrCrash() != - null) { - Socket? testHubConnection; - try { - testHubConnection = await Socket.connect( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - timeout: const Duration(milliseconds: 500), - ); - testHubConnection.destroy(); - } catch (e) { - testHubConnection?.destroy(); - - await searchForHub(); - } - } else { - await searchForHub(); - } - - try { - final CompHubInfo? compHubInfo = await HubClient.getHubCompInfo( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - appInfoForHub, - ); - - if (compHubInfo == null) { - return left(const HubFailures.unexpected()); - } - return right(compHubInfo); - } catch (e) { - icLogger.e('Error getting hubInfo\n$e'); - return left(const HubFailures.unexpected()); - } - - // return; - } else { - icLogger.i('Connect using Remote Pipes'); - return (await ILocalDbRepository.instance.getRemotePipesDnsName()).fold( - (l) { - icLogger.e('Cant find local Remote Pipes Dns name'); - return left(const HubFailures.unexpected()); - }, (r) async { - try { - final CompHubInfo? compHubInfo = - await HubClient.getHubCompInfo(r, 50056, appInfoForHub); - - if (compHubInfo == null) { - return left(const HubFailures.unexpected()); - } - return right(compHubInfo); - } catch (e) { - icLogger.e('Error getting hubInfo\n$e'); - return left(const HubFailures.unexpected()); - } - }); - // Here for easy find and local testing - // HubClient.createStreamWithHub('127.0.0.1', 50056); - } - } - - @override - Future closeConnection() async { - cancelConnectionWithHub = true; - } - - /// Search device IP by computer Avahi (mdns) name - Future getDeviceIpByDeviceAvahiName(String mDnsName) async { - String deviceIp = ''; - // final String fullMdnsName = '$mDnsName.local'; - - final MDnsClient client = MDnsClient( - rawDatagramSocketFactory: ( - dynamic host, - int port, { - bool? reuseAddress, - bool? reusePort, - int? ttl, - }) { - return RawDatagramSocket.bind(host, port, ttl: ttl!); - }, - ); - - // Start the client with default options. - await client.start(); - await for (final IPAddressResourceRecord record - in client.lookup( - ResourceRecordQuery.addressIPv4(mDnsName), - )) { - deviceIp = record.address.address; - icLogger.i('Found address (${record.address}).'); - } - - // await for (final IPAddressResourceRecord record - // in client.lookup( - // ResourceRecordQuery.addressIPv6(fullMdnsName))) { - // logger.t('Found address (${record.address}).'); - // } - - client.stop(); - - icLogger.t('Done.'); - - return deviceIp; - } - - @override - Future> searchForHub({ - String? deviceIpOnTheNetwork, - bool? isThatTheIpOfTheHub, - }) async { - try { - final Either locationRequest = - await askLocationPermissionAndLocationOn(); - - if (locationRequest.isLeft()) { - return locationRequest; - } - - icLogger.i('searchForHub'); - - String? currentDeviceIP; - String? networkBSSID; - String? networkName; - if (await Connectivity().checkConnectivity() == ConnectivityResult.wifi && - !kIsWeb) { - final NetworkInfo networkInfo = NetworkInfo(); - networkName = await networkInfo.getWifiName(); - currentDeviceIP = await networkInfo.getWifiIP(); - networkBSSID = await networkInfo.getWifiBSSID(); - } else { - if (deviceIpOnTheNetwork == null) { - // Issue https://github.com/CyBear-Jinni/cbj_app/issues/256 - return left( - const HubFailures - .findingHubWhenConnectedToEthernetCableIsNotSupported(), - ); - } - - currentDeviceIP = deviceIpOnTheNetwork; - networkBSSID = 'no:Network:Bssid:Found'; - networkName = 'noNetworkNameFound'; - if (isThatTheIpOfTheHub != null && isThatTheIpOfTheHub) { - return insertHubInfo( - networkIp: currentDeviceIP, - networkBSSID: networkBSSID, - networkName: networkName, - ); - } - } - - final String subnet = - currentDeviceIP!.substring(0, currentDeviceIP.lastIndexOf('.')); - - icLogger.i('Hub Search subnet IP $subnet'); - - // TODO: Search for hub - // final Stream devicesWithPort = - // HostScanner.scanDevicesForSinglePort( - // subnet, - // hubPort, - - // /// TODO: return this settings when can use with the await for loop - // // resultsInIpAscendingOrder: false, - // timeout: const Duration(milliseconds: 600), - // ); - - // await for (final ActiveHost activeHost in devicesWithPort) { - // icLogger.i('Found Cbj Hub device: ${activeHost.address}'); - // if (networkBSSID != null && networkName != null) { - // return insertHubInfo( - // networkIp: activeHost.address, - // networkBSSID: networkBSSID, - // networkName: networkName, - // ); - // } - // } - } catch (e) { - icLogger.w('Exception searchForHub\n$e'); - } - await Future.delayed(const Duration(seconds: 5)); - return left(const HubFailures.cantFindHubInNetwork()); - } - - @override - Future saveHubIP(String hubIP) async { - icLogger.w('saveHubIP'); - } - - Future> askLocationPermissionAndLocationOn() async { - final Location location = Location(); - - bool serviceEnabled; - PermissionStatus permissionGranted; - - int permissionCounter = 0; - int disabledCounter = 0; - - // Get location permission is not supported on Linux - if (Platform.isLinux || Platform.isWindows) { - return right(unit); - } - - while (true) { - permissionGranted = await location.hasPermission(); - if (permissionGranted == PermissionStatus.denied) { - permissionGranted = await location.requestPermission(); - if (permissionGranted != PermissionStatus.granted) { - icLogger.e('Permission to use location is denied'); - await Future.delayed(const Duration(seconds: 10)); - - permissionCounter++; - if (permissionCounter > 5) { - permission_handler.openAppSettings(); - } else if (permissionCounter > 7) { - return const Left(HubFailures.unexpected()); - } - continue; - } - } - - serviceEnabled = await location.serviceEnabled(); - if (!serviceEnabled) { - serviceEnabled = await location.requestService(); - if (!serviceEnabled) { - disabledCounter++; - if (disabledCounter > 2) { - return const Left(HubFailures.unexpected()); - } - icLogger.w('Location is disabled'); - await Future.delayed(const Duration(seconds: 5)); - continue; - } - } - break; - } - return right(unit); - } - - /// Will save hub info both on ram and to the local database - Future> insertHubInfo({ - required String networkIp, - required String networkName, - required String networkBSSID, - }) async { - IHubConnectionRepository.hubEntity = HubEntity( - hubNetworkBssid: HubNetworkBssid(networkBSSID), - networkName: HubNetworkName(networkName), - lastKnownIp: HubNetworkIp(networkIp), - ); - - final HubDtos hubDtos = - IHubConnectionRepository.hubEntity!.toInfrastructure(); - - (await ILocalDbRepository.instance.saveHubEntity( - hubNetworkBssid: hubDtos.hubNetworkBssid, - networkName: hubDtos.networkName, - lastKnownIp: hubDtos.lastKnownIp, - )) - .fold( - (l) => icLogger.e('Cant find local Remote Pipes Dns name'), - (r) => icLogger.i('Found CyBear Jinni Hub'), - ); - return right(unit); - } - - Future streamFromDemoMode() async { - await HubClientDemo.createStreamWithHub(); - } - - /// Load saved Hub network information and load it to - /// IHubConnectionRepository.hubEntity - Future loadNetworkInformationFromDb() async { - try { - String? hubNetworkBssid; - (await ILocalDbRepository.instance.getHubEntityNetworkBssid()).fold( - (l) => throw 'Error getting Hub network Bssid', - (r) => hubNetworkBssid = r, - ); - - String? hubNetworkName; - (await ILocalDbRepository.instance.getHubEntityNetworkName()).fold( - (l) => throw 'Error getting Hub network name', - (r) => hubNetworkName = r, - ); - - String? hubNetworkIp; - (await ILocalDbRepository.instance.getHubEntityLastKnownIp()).fold( - (l) => throw 'Error getting Hub network IP', - (r) => hubNetworkIp = r, - ); - IHubConnectionRepository.hubEntity = HubDtos( - hubNetworkBssid: hubNetworkBssid!, - lastKnownIp: hubNetworkIp!, - networkName: hubNetworkName!, - ).toDomain(); - } catch (e) { - icLogger.e('Crashed while setting Hub info from local db\n$e'); - } - } - - /// Connect directly to the Hub if possible - Future connectDirectlyToHub() async { - Socket? testHubConnection; - try { - testHubConnection = await Socket.connect( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - timeout: const Duration(milliseconds: 500), - ); - await testHubConnection.close(); - testHubConnection.destroy(); - testHubConnection = null; - } catch (e) { - await testHubConnection?.close(); - testHubConnection?.destroy(); - - Either foundAHub = await searchForHub(); - // If can't find hub in local network - if (foundAHub.isLeft()) { - // Connect using Remote pipes if connection information exists - if ((await ILocalDbRepository.instance.getRemotePipesDnsName()) - .isRight()) { - await connectionUsingRemotePipes(); - return; - } - while (true) { - foundAHub = await searchForHub(); - if (foundAHub.isRight()) { - break; - } - } - } - } - - tryAgainConnectToTheHubOnceMore = 0; - await HubClient.createStreamWithHub( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - ); - } - - /// Connect to the Hub using the Remote Pipes - Future connectionUsingRemotePipes() async { - (await ILocalDbRepository.instance.getRemotePipesDnsName()).fold( - (l) async { - (await openAndroidWifiSettingIfPossible()).fold( - (l) { - icLogger.w( - 'No way to establish connection with the Hub, WiFi or location' - ' permission is closed'); - }, - (r) async { - await connectWithHub(); - }, - ); - }, - (r) { - icLogger.i('Connect using Remote Pipes'); - HubClient.createStreamWithHub(r, 50056); - tryAgainConnectToTheHubOnceMore = 0; - }, - ); - } - - Future> openAndroidWifiSettingIfPossible() async { - final bool wifiEnabled = await WiFiForIoTPlugin.isEnabled(); - final Location location = Location(); - - if (wifiEnabled && await location.serviceEnabled()) { - final bool wifiEnabled = await WiFiForIoTPlugin.isConnected(); - if (wifiEnabled) { - return right(unit); - } - // while (true) { - // if (wifiEnabled) { - // if (tryAgainConnectToTheHubOnceMore <= 10) { - // // Even if WiFi got enabled it still takes time for the - // // device to complete the automatic connection to previous - // // WiFi network, so we give it a little time before stop trying - // tryAgainConnectToTheHubOnceMore += 1; - // await Future.delayed(const Duration(seconds: 5)); - // } else { - // logger.w( - // "User cannot connect to home as he is A. Not in his home B. Didn't set Remote Pipes", - // ); - // } - // } else { - // logger.t('User not connected to any WiFi, Will try again.'); - // tryAgainConnectToTheHubOnceMore = 0; - // await Future.delayed(const Duration(milliseconds: 500)); - // - // return right(unit); - // } - // } - } else { - icLogger.w( - 'Will ask the user to open WiFi and gps to try local connection', - ); - final bool wifiEnabled = await WiFiForIoTPlugin.isEnabled(); - if (!wifiEnabled) { - WiFiForIoTPlugin.setEnabled(true, shouldOpenSettings: true); - tryAgainConnectToTheHubOnceMore = 0; - await Future.delayed(const Duration(milliseconds: 500)); - return right(unit); - } - - (await askLocationPermissionAndLocationOn()).fold((l) { - icLogger.e( - 'User does not allow opening location and does not have remote pipes info', - ); - }, (r) async { - // Try to connect again because there is a chance user without - // remote pipes info but is in his home - return right(unit); - }); - } - return const Left(HubFailures.unexpected()); - } -} diff --git a/lib/infrastructure/hub_client/hub_requests_routing.dart b/lib/infrastructure/hub_client/hub_requests_routing.dart deleted file mode 100644 index 32cd31130..000000000 --- a/lib/infrastructure/hub_client/hub_requests_routing.dart +++ /dev/null @@ -1,221 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:cybearjinni/domain/device/i_device_repository.dart'; -import 'package:cybearjinni/domain/i_hub_connection_repository.dart'; -import 'package:cybearjinni/infrastructure/core/injection.dart'; -import 'package:cybearjinni/infrastructure/core/logger.dart'; -import 'package:grpc/grpc.dart'; - -@Deprecated( - 'Old architecture. Replaced with ConnectionsService. Delete after Re adding Hub comunication', -) -class HubRequestRouting { - static StreamSubscription? requestsFromHubSubscription; - - static Stream? connectivityChangedStream; - - static bool areWeRunning = false; - - // static int numberOfCrashes = 0; - static int numberOfConnectivityChange = 0; - - static Future navigateRequest() async { - if (areWeRunning) { - return; - } - - await Future.delayed(const Duration(milliseconds: 100)); - - if (areWeRunning) { - return; - } - areWeRunning = true; - - // await requestsFromHubSubscription?.cancel(); - // requestsFromHubSubscription = null; - connectivityChangedStream = null; - - requestsFromHubSubscription = HubRequestsToApp.streamRequestsToApp.stream - .listen((dynamic requestsAndStatusFromHub) { - if (requestsAndStatusFromHub is! RequestsAndStatusFromHub) { - return; - } - if (requestsAndStatusFromHub.sendingType == SendingType.entityType) { - navigateDeviceRequest(requestsAndStatusFromHub.allRemoteCommands); - } else if (requestsAndStatusFromHub.sendingType == SendingType.areaType) { - navigateAreaRequest(requestsAndStatusFromHub.allRemoteCommands); - } else if (requestsAndStatusFromHub.sendingType == - SendingType.sceneType) { - navigateSceneRequest(requestsAndStatusFromHub.allRemoteCommands); - } else { - logger.i( - 'Got from Hub unsupported massage type: ' - '${requestsAndStatusFromHub.sendingType}', - ); - } - }); - requestsFromHubSubscription?.onError((error) async { - if (error is GrpcError && error.code == 1) { - logger.t('Hub have been disconnected'); - } - // else if (error is GrpcError && error.code == 2) { - // logger.t('Hub have been terminated'); - // } - else { - logger.e('Hub stream error: $error'); - if (error.toString().contains('errorCode: 10')) { - areWeRunning = false; - - navigateRequest(); - } - } - }); - - connectivityChangedStream = Connectivity().onConnectivityChanged; - connectivityChangedStream?.listen((ConnectivityResult event) async { - numberOfConnectivityChange++; - logger.i('Connectivity changed ${event.name} And $event'); - if (event == ConnectivityResult.none || numberOfConnectivityChange <= 1) { - return; - } - areWeRunning = false; - navigateRequest(); - }); - - await IHubConnectionRepository.instance.connectWithHub(); - } - - static Future navigateAreaRequest( - String allRemoteCommands, - ) async { - // final Map requestAsJson = - // jsonDecode(allRemoteCommands) as Map; - - // final AreaEntityDtos areaEntityDtos = AreaEntityDtos( - // uniqueId: requestAsJson['uniqueId'] as String, - // cbjEntityName: requestAsJson['cbjEntityName'] as String, - // background: requestAsJson['background'] as String, - // areaTypes: Set.from(requestAsJson['areaTypes'] as Set), - // areaDevicesId: - // Set.from(requestAsJson['areaDevicesId'] as Set), - // areaScenesId: - // Set.from(requestAsJson['areaScenesId'] as Set), - // areaRoutinesId: - // Set.from(requestAsJson['areaRoutinesId'] as Set), - // areaBindingsId: - // Set.from(requestAsJson['areaBindingsId'] as Set), - // areaMostUsedBy: - // Set.from(requestAsJson['areaMostUsedBy'] as Set), - // areaPermissions: - // Set.from(requestAsJson['areaPermissions'] as Set), - // ); - - // final AreaEntity areaEntity = areaEntityDtos.toDomain(); - - // IAreaRepository.instance.addOrUpdateArea(areaEntity); - } - - static Future navigateDeviceRequest( - String allRemoteCommands, - ) async { - final Map requestAsJson = - jsonDecode(allRemoteCommands) as Map; - final String? deviceTypeAsString = requestAsJson['entityTypes'] as String?; - - final String? deviceStateAsString = - requestAsJson['entityStateGRPC'] as String?; - if (deviceTypeAsString == null || deviceStateAsString == null) { - return; - } - - ///TODO: add request type login support - - final EntityTypes? deviceType = EntityUtils.stringToDt(deviceTypeAsString); - - final EntityStateGRPC? entityStateGRPC = - EntityUtils.stringToDeviceState(deviceStateAsString); - - if (deviceType == null || entityStateGRPC == null) { - return; - } - - late DeviceEntityBase deviceEntity; - - switch (deviceType) { - case EntityTypes.light: - deviceEntity = - GenericLightDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Light device type'); - case EntityTypes.dimmableLight: - deviceEntity = - GenericDimmableLightDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Dimmable Light device type'); - case EntityTypes.rgbwLights: - deviceEntity = - GenericRgbwLightDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding rgbW light device type'); - case EntityTypes.blinds: - deviceEntity = - GenericBlindsDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Blinds device type'); - case EntityTypes.boiler: - deviceEntity = - GenericBoilerDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Boiler device type'); - case EntityTypes.smartTV: - deviceEntity = - GenericSmartTvDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart TV device type'); - case EntityTypes.switch_: - deviceEntity = - GenericSwitchDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Addin' - 'g Switch device type'); - case EntityTypes.smartPlug: - deviceEntity = - GenericSmartPlugDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart Plug device type'); - case EntityTypes.smartComputer: - deviceEntity = - GenericSmartComputerDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart Plug device type'); - case EntityTypes.printer: - deviceEntity = - GenericPrinterDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart printer device type'); - case EntityTypes.securityCamera: - deviceEntity = - GenericSecurityCameraDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart camera device type'); - default: - if (entityStateGRPC == EntityStateGRPC.pingNow) { - deviceEntity = - GenericPingDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.t('Got Ping request'); - return; - } else { - logger.w( - 'Entity type is $deviceType is not supported $entityStateGRPC ', - ); - deviceEntity = - GenericUnsupportedDeviceDtos.fromJson(requestAsJson).toDomain(); - } - break; - } - IDeviceRepository.instance.addOrUpdateDevice(deviceEntity); - } - - static Future navigateSceneRequest( - String allRemoteCommands, - ) async { - final Map requestAsJson = - jsonDecode(allRemoteCommands) as Map; - final SceneCbjDtos sceneCbjDtos = SceneCbjDtos.fromJson(requestAsJson); - - getIt() - .addOrUpdateNewSceneInApp(sceneCbjDtos.toDomain()); - } -} diff --git a/lib/infrastructure/isar_local_db/isar_repository.dart b/lib/infrastructure/isar_local_db/isar_repository.dart index ad3e9678e..127a91753 100644 --- a/lib/infrastructure/isar_local_db/isar_repository.dart +++ b/lib/infrastructure/isar_local_db/isar_repository.dart @@ -3,7 +3,7 @@ part of 'package:cybearjinni/domain/i_local_db_repository.dart'; class _IsarRepository implements ILocalDbRepository { late Isar isar; @override - Future asyncConstructor() async { + Future asyncConstructor() async { final dir = await getApplicationDocumentsDirectory(); isar = await Isar.open( [ diff --git a/lib/infrastructure/mqtt.dart b/lib/infrastructure/mqtt.dart index 281bc2bbe..27a67a14a 100644 --- a/lib/infrastructure/mqtt.dart +++ b/lib/infrastructure/mqtt.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:mqtt_client/mqtt_client.dart'; @@ -13,10 +11,10 @@ class MqttServerRepository extends IMqttServerRepository { } @override - Future allHubDevicesSubscriptions() async {} + Future allHubDevicesSubscriptions() async {} @override - Future asyncConstructor() async {} + Future asyncConstructor() async {} @override Future connect() async { @@ -45,25 +43,25 @@ class MqttServerRepository extends IMqttServerRepository { String getScenesTopicTypeName() => ''; @override - Future postSmartDeviceToAppMqtt({ + Future postSmartDeviceToAppMqtt({ required DeviceEntityBase entityFromTheHub, }) async { - HubRequestsToApp.streamRequestsToApp.sink.add( - RequestsAndStatusFromHub( - sendingType: SendingType.entityType, - allRemoteCommands: - DeviceHelper.convertDomainToJsonString(entityFromTheHub), - ), - ); + // HubRequestsToApp.streamRequestsToApp.sink.add( + // RequestsAndStatusFromHub( + // sendingType: SendingType.entityType.name, + // allRemoteCommands: + // DeviceHelper.convertDomainToJsonString(entityFromTheHub), + // ), + // ); } @override - Future postToAppMqtt({ + Future postToAppMqtt({ required DeviceEntityBase entityFromTheHub, }) async {} @override - Future postToHubMqtt({ + Future postToHubMqtt({ required dynamic entityFromTheApp, bool? gotFromApp, }) async { @@ -87,24 +85,24 @@ class MqttServerRepository extends IMqttServerRepository { // ISavedAreasRepo.instance.addOrUpdateArea(entityFromTheApp.toDomain()); /// Sends directly to device connector conjecture - HubRequestsToApp.streamRequestsToApp.add( - RequestsAndStatusFromHub( - sendingType: SendingType.areaType, - allRemoteCommands: jsonEncode(entityFromTheApp.toJson()), - ), - ); + // HubRequestsToApp.streamRequestsToApp.add( + // RequestsAndStatusFromHub( + // sendingType: SendingType.areaType.name, + // allRemoteCommands: jsonEncode(entityFromTheApp.toJson()), + // ), + // ); return; } logger.i('Type interaction support is missing $entityFromTheApp'); } @override - Future publishDeviceEntity( + Future publishDeviceEntity( DeviceEntityBase deviceEntityDtoAbstract, ) async {} @override - Future publishMessage(String topic, String message) async {} + Future publishMessage(String topic, String message) async {} @override Future?> readingFromMqttOnce(String topic) async { @@ -112,7 +110,7 @@ class MqttServerRepository extends IMqttServerRepository { } @override - Future sendToApp() async {} + Future sendToApp() async {} @override Stream>> @@ -150,5 +148,5 @@ class MqttServerRepository extends IMqttServerRepository { } @override - Future subscribeToTopic(String topic) async {} + Future subscribeToTopic(String topic) async {} } diff --git a/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart b/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart index ad290f5dc..67904fa2a 100644 --- a/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart +++ b/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart @@ -16,7 +16,7 @@ class _SecurityBearConnectionRepository static SecurityBearEntity? securityBearEntity; - // Future connectWithSecurityBear() async { + // Future connectWithSecurityBear() async { // if (securityBearEntity == null) { // try { // String? securityBearNetworkBssid; diff --git a/lib/infrastructure/software_info/software_info_repository.dart b/lib/infrastructure/software_info/software_info_repository.dart index 9f528ee2a..b18f06aea 100644 --- a/lib/infrastructure/software_info/software_info_repository.dart +++ b/lib/infrastructure/software_info/software_info_repository.dart @@ -44,19 +44,19 @@ class _SoftwareInfoRepository implements ISoftwareInfoRepository { appInfoForHub ??= CompHubInfo(); - final Either hubResponse = - await IHubConnectionRepository.instance.getHubCompInfo(appInfoForHub); - - return hubResponse.fold( - (l) => left(const SoftwareInfoFailures.unexpected()), - (r) { - return right(SoftwareInfoEntity.compHubInfo(r)); - }, - ); + // final Either hubResponse = + // await IHubConnectionRepository.instance.getHubCompInfo(appInfoForHub); + + // return hubResponse.fold( + // (l) => left(const SoftwareInfoFailures.unexpected()), + // (r) { + // return right(SoftwareInfoEntity.compHubInfo(r)); + // }, + // ); } catch (e) { logger.e('Software info from hub error\n$e'); - return left(const SoftwareInfoFailures.unexpected()); } + return left(const SoftwareInfoFailures.unexpected()); } @override diff --git a/lib/main.dart b/lib/main.dart index c28244d98..a370484f6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,3 @@ -import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/infrastructure/core/injection.dart'; import 'package:cybearjinni/presentation/core/app_widget.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.dart'; @@ -8,7 +7,6 @@ import 'package:flutter/material.dart'; Future main() async { configureDependencies(EnvApp.dev); - configureInjection(Env.devPc); WidgetsFlutterBinding.ensureInitialized(); diff --git a/lib/presentation/atoms/atoms.dart b/lib/presentation/atoms/atoms.dart index 862f071d9..35d150994 100644 --- a/lib/presentation/atoms/atoms.dart +++ b/lib/presentation/atoms/atoms.dart @@ -9,3 +9,4 @@ export 'scene_atom.dart'; export 'separator_atom.dart'; export 'switch_atom.dart'; export 'text_atom.dart'; +export 'text_form_field_atom.dart'; diff --git a/lib/presentation/atoms/scene_atom.dart b/lib/presentation/atoms/scene_atom.dart index 8f6d8a49e..658d228e0 100644 --- a/lib/presentation/atoms/scene_atom.dart +++ b/lib/presentation/atoms/scene_atom.dart @@ -17,7 +17,7 @@ class SceneAtom extends StatefulWidget { class _SceneAtomState extends State { late SceneCbjEntity sceneCbj; - Future _activateScene() async => ConnectionsService.instance + Future _activateScene() async => ConnectionsService.instance .activateScene(widget.currentScene.uniqueId.getOrCrash()); @override diff --git a/lib/presentation/atoms/switch_atom.dart b/lib/presentation/atoms/switch_atom.dart index 95b9d296d..f75cd69e5 100644 --- a/lib/presentation/atoms/switch_atom.dart +++ b/lib/presentation/atoms/switch_atom.dart @@ -75,6 +75,9 @@ class _SwitchAtomState extends State { case SwitchVariant.switchVariant: activeIcon = MdiIcons.lightSwitch; inactiveIcon = MdiIcons.lightSwitch; + case SwitchVariant.ac: + activeIcon = MdiIcons.airConditioner; + inactiveIcon = MdiIcons.airConditioner; } return SizedBox( @@ -115,5 +118,6 @@ enum SwitchVariant { boiler, smartPlug, switchVariant, + ac, ; } diff --git a/lib/presentation/atoms/text_form_field_atom.dart b/lib/presentation/atoms/text_form_field_atom.dart new file mode 100644 index 000000000..981245608 --- /dev/null +++ b/lib/presentation/atoms/text_form_field_atom.dart @@ -0,0 +1,26 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +class TextFormFieldAtom extends StatelessWidget { + const TextFormFieldAtom({ + required this.onChanged, + this.labelText, + this.prefixIcon, + }); + + final Function(String) onChanged; + final String? labelText; + final Widget? prefixIcon; + + @override + Widget build(BuildContext context) { + return TextFormField( + decoration: InputDecoration( + prefixIcon: prefixIcon, + labelText: labelText?.tr(), + ), + autocorrect: false, + onChanged: onChanged, + ); + } +} diff --git a/lib/presentation/core/entities_utils.dart b/lib/presentation/core/entities_utils.dart index 9ecb5a5bc..e3ef9a371 100644 --- a/lib/presentation/core/entities_utils.dart +++ b/lib/presentation/core/entities_utils.dart @@ -10,40 +10,12 @@ class EntitiesUtils { return FontAwesomeIcons.alignJustify; case EntityTypes.boiler: return FontAwesomeIcons.temperatureThreeQuarters; - case EntityTypes.browserApp: - // TODO: Handle this case. - break; - case EntityTypes.button: - return Icons.smart_button; - case EntityTypes.computerApp: - return Icons.computer; - case EntityTypes.emptyEntity: - // TODO: Handle this case. - break; - case EntityTypes.hub: - // TODO: Handle this case. - break; case EntityTypes.light: case EntityTypes.dimmableLight: - case EntityTypes.rgbLights: - case EntityTypes.rgbcctLights: case EntityTypes.rgbwLights: - case EntityTypes.cctLight: return FontAwesomeIcons.lightbulb; - case EntityTypes.phoneApp: - return Icons.phone; - case EntityTypes.pingEntity: - // TODO: Handle this case. - break; - case EntityTypes.playerEntity: - // TODO: Handle this case. - break; case EntityTypes.printer: - case EntityTypes.scanner: - case EntityTypes.printerWithScanner: return Icons.print; - case EntityTypes.routerEntity: - return Icons.router; case EntityTypes.securityCamera: return Icons.camera; case EntityTypes.smartComputer: @@ -52,14 +24,14 @@ class EntitiesUtils { return MdiIcons.powerSocketAu; case EntityTypes.smartTV: return Icons.tv; - case EntityTypes.smartTypeNotSupported: - // TODO: Handle this case. - break; case EntityTypes.switch_: return MdiIcons.lightSwitch; - case EntityTypes.voiceAssistant: - return MdiIcons.voicemail; + case EntityTypes.ac: + return MdiIcons.airConditioner; + case EntityTypes.emptyEntity: + case EntityTypes.pingEntity: + case EntityTypes.undefined: + return Icons.question_mark; } - return Icons.question_mark; } } diff --git a/lib/presentation/core/routes/app_router.dart b/lib/presentation/core/routes/app_router.dart index cda391abf..beda6cc66 100644 --- a/lib/presentation/core/routes/app_router.dart +++ b/lib/presentation/core/routes/app_router.dart @@ -24,9 +24,6 @@ class AppRouter extends $AppRouter { AutoRoute(page: AddActionRoute.page), AutoRoute(page: ChooseAutomationTypeToAddRoute.page), AutoRoute(page: ChooseDeviceVendorToAddRoute.page), - AutoRoute(page: AddLifxVendorRoute.page), - AutoRoute(page: AddEspHomeVendorRoute.page), - AutoRoute(page: AddEwelinkVendorRoute.page), AutoRoute(page: ConnectToHomeWifiRoute.page), AutoRoute(page: OpenAccessPointRoute.page), AutoRoute(page: ScanForNewCBJCompsRoute.page), @@ -34,6 +31,8 @@ class AppRouter extends $AppRouter { AutoRoute(page: ComputerConnectionCheckRoute.page), AutoRoute(page: EntitiesInNetworkRoute.page), AutoRoute(page: EntitiesInAreaRoute.page), + AutoRoute(page: LoginVendorRoute.page), + AutoRoute(page: ComunicationMethodRoute.page), // Pages from packages AutoRoute(page: SmartCameraContainerRoute.page), diff --git a/lib/presentation/molecules/device_by_type_molecule.dart b/lib/presentation/molecules/device_by_type_molecule.dart index a9560ecb8..17f6d75ac 100644 --- a/lib/presentation/molecules/device_by_type_molecule.dart +++ b/lib/presentation/molecules/device_by_type_molecule.dart @@ -1,5 +1,4 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; import 'package:flutter/material.dart'; @@ -36,9 +35,13 @@ class DeviceByTypeMolecule extends StatelessWidget { return DimmableLightMolecule(entity as GenericDimmableLightDE); case EntityTypes.securityCamera: return SecurityCameraMolecule(entity as GenericSecurityCameraDE); - - default: - return TextAtom('Entity type is unsupported ${type?.name ?? 'null'}'); + case EntityTypes.ac: + return AcMolecule(entity as GenericAcDE); + case EntityTypes.undefined: + case EntityTypes.emptyEntity: + case EntityTypes.pingEntity: + case null: + return const SizedBox(); } } } diff --git a/lib/presentation/molecules/device_name_row.dart b/lib/presentation/molecules/device_name_row_molecule.dart similarity index 81% rename from lib/presentation/molecules/device_name_row.dart rename to lib/presentation/molecules/device_name_row_molecule.dart index bf383ef47..8c28ee585 100644 --- a/lib/presentation/molecules/device_name_row.dart +++ b/lib/presentation/molecules/device_name_row_molecule.dart @@ -2,8 +2,8 @@ import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -class DeviceNameRow extends StatelessWidget { - const DeviceNameRow(this.name, this.second); +class DeviceNameRowMolecule extends StatelessWidget { + const DeviceNameRowMolecule(this.name, this.second); final String name; final Widget second; diff --git a/lib/presentation/molecules/devices/ac_molecule.dart b/lib/presentation/molecules/devices/ac_molecule.dart new file mode 100644 index 000000000..bfd215bc8 --- /dev/null +++ b/lib/presentation/molecules/devices/ac_molecule.dart @@ -0,0 +1,73 @@ +import 'dart:collection'; + +import 'package:another_flushbar/flushbar_helper.dart'; +import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:cybearjinni/presentation/molecules/molecules.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +class AcMolecule extends StatefulWidget { + const AcMolecule(this.entity); + + final GenericAcDE entity; + + @override + State createState() => _AcMoleculeState(); +} + +class _AcMoleculeState extends State { + Future _turnOnAllAcs() async { + FlushbarHelper.createLoading( + message: 'Turning_On_ac'.tr(), + linearProgressIndicator: const LinearProgressIndicator(), + ).show(context); + + setEntityState(EntityActions.on); + // IDeviceRepository.instance.moveUpStateDevices(devicesId: blindsIdToTurnUp); + } + + void setEntityState(EntityActions action) { + final HashSet entitiesId = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); + + ConnectionsService.instance.setEntityState( + RequestActionObject( + entityIds: entitiesId, + property: EntityProperties.acSwitchState, + actionType: action, + ), + ); + } + + Future _turnOffAllAcs() async { + FlushbarHelper.createLoading( + message: 'Turning_Off_ac'.tr(), + linearProgressIndicator: const LinearProgressIndicator(), + ).show(context); + + setEntityState(EntityActions.off); + } + + void _onChange(bool value) { + if (value) { + _turnOnAllAcs(); + } else { + _turnOffAllAcs(); + } + } + + @override + Widget build(BuildContext context) { + return DeviceNameRowMolecule( + widget.entity.cbjEntityName.getOrCrash()!, + SwitchAtom( + variant: SwitchVariant.ac, + onToggle: _onChange, + action: widget.entity.acSwitchState.action!, + state: widget.entity.entityStateGRPC.state, + ), + ); + } +} diff --git a/lib/presentation/molecules/devices/blind_molecule.dart b/lib/presentation/molecules/devices/blind_molecule.dart index 3e2aa0f98..a8af44ec7 100644 --- a/lib/presentation/molecules/devices/blind_molecule.dart +++ b/lib/presentation/molecules/devices/blind_molecule.dart @@ -21,7 +21,7 @@ class BlindMolecule extends StatefulWidget { } class _BlindMoleculeState extends State { - Future _moveUpAllBlinds() async { + Future _moveUpAllBlinds() async { FlushbarHelper.createLoading( message: 'Pulling_Up_all_blinds'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -31,34 +31,19 @@ class _BlindMoleculeState extends State { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: EntityProperties.blindsSwitchState, actionType: action, ), ); } - Future _stopAllBlinds(List blindsIdToStop) async { + Future _stopAllBlinds(List blindsIdToStop) async { FlushbarHelper.createLoading( message: 'Stopping_all_blinds'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -67,7 +52,7 @@ class _BlindMoleculeState extends State { setEntityState(EntityActions.stop); } - Future _moveDownAllBlinds(List blindsIdToTurnDown) async { + Future _moveDownAllBlinds(List blindsIdToTurnDown) async { FlushbarHelper.createLoading( message: 'Pulling_down_all_blinds'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -100,7 +85,7 @@ class _BlindMoleculeState extends State { } } - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, Row( children: [ diff --git a/lib/presentation/molecules/devices/boiler_molecule.dart b/lib/presentation/molecules/devices/boiler_molecule.dart index cdd8583cd..8a6fec90b 100644 --- a/lib/presentation/molecules/devices/boiler_molecule.dart +++ b/lib/presentation/molecules/devices/boiler_molecule.dart @@ -18,7 +18,7 @@ class BoilerMolecule extends StatefulWidget { } class _BoilerMoleculeState extends State { - Future _turnOnAllBoilers() async { + Future _turnOnAllBoilers() async { FlushbarHelper.createLoading( message: 'Turning_On_boiler'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -29,33 +29,19 @@ class _BoilerMoleculeState extends State { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: EntityProperties.boilerSwitchState, actionType: action, ), ); } - Future _turnOffAllBoilers() async { + Future _turnOffAllBoilers() async { FlushbarHelper.createLoading( message: 'Turning_Off_boiler'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -74,7 +60,7 @@ class _BoilerMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.boiler, diff --git a/lib/presentation/molecules/devices/dimmable_light_molecule.dart b/lib/presentation/molecules/devices/dimmable_light_molecule.dart index e410d97fc..e1f034f02 100644 --- a/lib/presentation/molecules/devices/dimmable_light_molecule.dart +++ b/lib/presentation/molecules/devices/dimmable_light_molecule.dart @@ -21,20 +21,41 @@ class DimmableLightMolecule extends StatefulWidget { class _DimmableLightMoleculeState extends State { double brightness = 100; - Future _changeBrightness(double value) async { + @override + void initState() { + super.initState(); + _initialized(); + } + + Future _initialized() async { + final GenericDimmableLightDE rgbwLightDe = widget.entity; + + double lightBrightness = + double.parse(rgbwLightDe.lightBrightness.getOrCrash()); + + if (lightBrightness > 100) { + lightBrightness = 100; + } + + setState(() { + brightness = lightBrightness; + }); + } + + Future _changeBrightness(double value) async { setState(() { brightness = value; }); - final HashMap hashValue = - HashMap() + final HashMap hashValue = + HashMap() ..addEntries([ - MapEntry(ActionValues.brightness, value.round().toString()), + MapEntry(ActionValues.brightness, value.round()), ]); setEntityState( EntityProperties.lightBrightness, - EntityActions.actionNotSupported, + EntityActions.undefined, value: hashValue, ); } @@ -51,26 +72,12 @@ class _DimmableLightMoleculeState extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: property, actionType: action, value: value, @@ -86,7 +93,7 @@ class _DimmableLightMoleculeState extends State { return Column( children: [ - DeviceNameRow( + DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.light, diff --git a/lib/presentation/molecules/devices/light_card_molecule.dart b/lib/presentation/molecules/devices/light_card_molecule.dart index eb6d16c2c..bf5cb74f5 100644 --- a/lib/presentation/molecules/devices/light_card_molecule.dart +++ b/lib/presentation/molecules/devices/light_card_molecule.dart @@ -1,5 +1,4 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/i_device_repository.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:flutter/material.dart'; @@ -8,19 +7,19 @@ class LightCardMolecule extends StatelessWidget { final GenericLightDE? entity; - Future _onChange(bool value) async { - final GenericLightDE tempDeviceEntity = entity! - ..entityStateGRPC = EntityState.state(EntityStateGRPC.waitingInCloud) - ..lightSwitchState = GenericLightSwitchState(value.toString()); + Future _onChange(bool value) async { + // final GenericLightDE tempDeviceEntity = entity! + // ..entityStateGRPC = EntityState.state(EntityStateGRPC.waitingInCloud) + // ..lightSwitchState = GenericLightSwitchState(value.toString()); if (value) { - await IDeviceRepository.instance.turnOnDevices( - devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], - ); + // await IDeviceRepository.instance.turnOnDevices( + // devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], + // ); } else { - await IDeviceRepository.instance.turnOffDevices( - devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], - ); + // await IDeviceRepository.instance.turnOffDevices( + // devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], + // ); } } diff --git a/lib/presentation/molecules/devices/light_molecule.dart b/lib/presentation/molecules/devices/light_molecule.dart index 5ed44e2d2..9772c14a2 100644 --- a/lib/presentation/molecules/devices/light_molecule.dart +++ b/lib/presentation/molecules/devices/light_molecule.dart @@ -18,25 +18,12 @@ class LightMolecule extends StatelessWidget { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet()..addAll([entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, ), @@ -45,7 +32,7 @@ class LightMolecule extends StatelessWidget { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.light, diff --git a/lib/presentation/molecules/devices/printer_molecule.dart b/lib/presentation/molecules/devices/printer_molecule.dart index a6e4efcb8..de2d9f15d 100644 --- a/lib/presentation/molecules/devices/printer_molecule.dart +++ b/lib/presentation/molecules/devices/printer_molecule.dart @@ -18,22 +18,23 @@ class PrinterMolecule extends StatefulWidget { } class _PrinterMoleculeState extends State { - Future _openPrintersWebPage() async { + Future _openPrintersWebPage() async { FlushbarHelper.createLoading( message: 'Opening printers Web Page', linearProgressIndicator: const LinearProgressIndicator(), ).show(context); - final String printerIp = widget.entity.deviceLastKnownIp.getOrCrash()!; + final String printerAddress = widget.entity.srvTarget.getOrCrash() ?? + widget.entity.deviceLastKnownIp.getOrCrash()!; launchUrl( - Uri.parse('http://$printerIp'), + Uri.parse('http://$printerAddress'), mode: LaunchMode.externalApplication, ); } @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, TextButton( style: ButtonStyle( diff --git a/lib/presentation/molecules/devices/rgb_light_molecule.dart b/lib/presentation/molecules/devices/rgb_light_molecule.dart index b06e2c2e5..c8539aa40 100644 --- a/lib/presentation/molecules/devices/rgb_light_molecule.dart +++ b/lib/presentation/molecules/devices/rgb_light_molecule.dart @@ -30,7 +30,7 @@ class _RgbwLightMoleculeState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final GenericRgbwLightDE rgbwLightDe = widget.entity; int lightColorTemperature = @@ -65,26 +65,12 @@ class _RgbwLightMoleculeState extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: entityProperties, actionType: action, value: value, @@ -92,13 +78,13 @@ class _RgbwLightMoleculeState extends State { ); } - Future _changeBrightness(double value) async { + Future _changeBrightness(double value) async { setState(() { brightness = value; }); setEntityState( EntityProperties.lightBrightness, - EntityActions.actionNotSupported, + EntityActions.undefined, value: HashMap.from({ActionValues.brightness: value.round()}), ); } @@ -111,7 +97,7 @@ class _RgbwLightMoleculeState extends State { return Column( children: [ - DeviceNameRow( + DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.light, @@ -174,17 +160,22 @@ class _LightColorMods extends State { late int colorTemperature; late HSVColor hsvColor; late double brightness; + late ColorMode colorMode; + late Widget colorModeWidget; @override void initState() { super.initState(); + colorMode = widget.entity.colorMode.mode; hsvColor = widget.hsvColor ?? HSVColor.fromColor(Colors.white); colorTemperature = widget.colorTemperature; brightness = widget.brightness; + colorModeWidget = getColorModeWidget(colorMode); + _initialized(); } - Future _initialized() async { + Future _initialized() async { final GenericRgbwLightDE rgbwLightDe = widget.entity; int lightColorTemperature = @@ -212,26 +203,12 @@ class _LightColorMods extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: entityProperties, actionType: action, value: value, @@ -239,18 +216,18 @@ class _LightColorMods extends State { ); } - Future _changeColorTemperature(int newColorTemperature) async { + Future _changeColorTemperature(int newColorTemperature) async { setState(() { colorTemperature = newColorTemperature; }); setEntityState( EntityProperties.lightColorTemperature, EntityActions.changeTemperature, - value: HashMap.from({ActionValues.temperature: newColorTemperature}), + value: HashMap.from({ActionValues.colorTemperature: newColorTemperature}), ); } - Future _changeHsvColor(HSVColor newHsvColor) async { + Future _changeHsvColor(HSVColor newHsvColor) async { setState(() { hsvColor = newHsvColor; }); @@ -262,14 +239,11 @@ class _LightColorMods extends State { ActionValues.alpha: newHsvColor.alpha, ActionValues.hue: newHsvColor.hue, ActionValues.saturation: newHsvColor.saturation, - ActionValues.value: newHsvColor.value, + ActionValues.colorValue: newHsvColor.value, }), ); } - late Widget colorModeWidget; - int colorModFocus = 0; - Widget getWhiteModeWidget() { return Container( height: 100, @@ -309,21 +283,27 @@ class _LightColorMods extends State { ); } - Future _showWhiteMode() async { - setState(() { - colorModFocus = 0; - colorModeWidget = getWhiteModeWidget(); - }); + Widget getColorModeWidget(ColorMode colorMode) { + switch (colorMode) { + case ColorMode.undefined: + return const SizedBox(); + case ColorMode.rgb: + return getHsvColorModeWidget(); + case ColorMode.white: + return getWhiteModeWidget(); + } } - Future _showColorMode() async { + void setColorModeState(ColorMode colorMode) { + final Widget colorModeWidget = getColorModeWidget(colorMode); setState(() { - colorModFocus = 1; - colorModeWidget = getHsvColorModeWidget(); + this.colorMode = colorMode; + this.colorModeWidget = colorModeWidget; }); } - Widget lightModBarFocus() { + @override + Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); final ColorScheme colorScheme = themeData.colorScheme; @@ -338,44 +318,29 @@ class _LightColorMods extends State { child: TextAtom( 'White', style: TextStyle( - color: (colorModFocus == 0) + color: (colorMode == ColorMode.white) ? colorScheme.primary : colorScheme.onBackground, fontSize: 18, ), ), - onPressed: () { - _showWhiteMode(); - }, + onPressed: () => setColorModeState(ColorMode.white), ), OutlinedButton( child: TextAtom( 'Color', style: TextStyle( - color: (colorModFocus == 1) + color: (colorMode == ColorMode.rgb) ? colorScheme.primary : colorScheme.onBackground, fontSize: 18, ), ), - onPressed: () { - _showColorMode(); - }, + onPressed: () => setColorModeState(ColorMode.rgb), ), ], ), ], ); } - - @override - Widget build(BuildContext context) { - if (colorModFocus == 0) { - colorModeWidget = getWhiteModeWidget(); - } else { - colorModeWidget = getHsvColorModeWidget(); - } - - return lightModBarFocus(); - } } diff --git a/lib/presentation/molecules/devices/security_camera_molecule.dart b/lib/presentation/molecules/devices/security_camera_molecule.dart index a0d481b80..ec964caea 100644 --- a/lib/presentation/molecules/devices/security_camera_molecule.dart +++ b/lib/presentation/molecules/devices/security_camera_molecule.dart @@ -19,7 +19,7 @@ class SecurityCameraMolecule extends StatefulWidget { } class _SecurityCameraMoleculeState extends State { - Future _openCameraPage() async { + Future _openCameraPage() async { FlushbarHelper.createLoading( message: 'Opening Camera', linearProgressIndicator: const LinearProgressIndicator(), @@ -33,7 +33,7 @@ class _SecurityCameraMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, TextButton( style: ButtonStyle( diff --git a/lib/presentation/molecules/devices/smart_computer_molecule.dart b/lib/presentation/molecules/devices/smart_computer_molecule.dart index d10599095..7328aecad 100644 --- a/lib/presentation/molecules/devices/smart_computer_molecule.dart +++ b/lib/presentation/molecules/devices/smart_computer_molecule.dart @@ -1,6 +1,5 @@ import 'package:another_flushbar/flushbar_helper.dart'; import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/i_device_repository.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; import 'package:flutter/material.dart'; @@ -18,22 +17,22 @@ class SmartComputerMolecule extends StatefulWidget { } class _SmartComputerMoleculeState extends State { - Future _suspendAllSmartComputers(List smartComputersId) async { + Future _suspendAllSmartComputers(List smartComputersId) async { FlushbarHelper.createLoading( message: 'Suspending all Smart Computers', linearProgressIndicator: const LinearProgressIndicator(), ).show(context); - IDeviceRepository.instance.suspendDevices(devicesId: smartComputersId); + // IDeviceRepository.instance.suspendDevices(deviDscesId: smartComputersId); } - Future _shutdownAllSmartComputers(List smartComputersId) async { + Future _shutdownAllSmartComputers(List smartComputersId) async { FlushbarHelper.createLoading( message: 'Suspending all Smart Computers', linearProgressIndicator: const LinearProgressIndicator(), ).show(context); - IDeviceRepository.instance.shutdownDevices(devicesId: smartComputersId); + // IDeviceRepository.instance.shutdownDevices(devicesId: smartComputersId); } void suspendComputer(BuildContext context) { @@ -48,7 +47,7 @@ class _SmartComputerMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/presentation/molecules/devices/smart_plug_molecule.dart b/lib/presentation/molecules/devices/smart_plug_molecule.dart index 2e6481417..834879de6 100644 --- a/lib/presentation/molecules/devices/smart_plug_molecule.dart +++ b/lib/presentation/molecules/devices/smart_plug_molecule.dart @@ -23,30 +23,17 @@ class _SmartPlugsMoleculeState extends State { Timer? timeFromLastColorChange; HSVColor? lastColoredPicked; - Future _changeAction(bool value) async { + Future _changeAction(bool value) async { setEntityState(value ? EntityActions.on : EntityActions.off); } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); + ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, ), @@ -55,7 +42,7 @@ class _SmartPlugsMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.smartPlug, diff --git a/lib/presentation/molecules/devices/smart_tv_molecule.dart b/lib/presentation/molecules/devices/smart_tv_molecule.dart index 524292140..6d47ee669 100644 --- a/lib/presentation/molecules/devices/smart_tv_molecule.dart +++ b/lib/presentation/molecules/devices/smart_tv_molecule.dart @@ -77,25 +77,12 @@ class _SmartTvMoleculeState extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); + ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: property, actionType: action, value: value, @@ -280,7 +267,7 @@ class _SmartTvMoleculeState extends State { Widget build(BuildContext context) { return Column( children: [ - DeviceNameRow( + DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, const SizedBox(), ), diff --git a/lib/presentation/molecules/devices/switch_molecule.dart b/lib/presentation/molecules/devices/switch_molecule.dart index 77bee7513..68a546d70 100644 --- a/lib/presentation/molecules/devices/switch_molecule.dart +++ b/lib/presentation/molecules/devices/switch_molecule.dart @@ -23,30 +23,17 @@ class _SwitchMoleculeState extends State { Timer? timeFromLastColorChange; HSVColor? lastColoredPicked; - Future _changeAction(bool value) async { + Future _changeAction(bool value) async { setEntityState(value ? EntityActions.on : EntityActions.off); } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); + ConnectionsService.instance.setEntityState( - ActionObject( - uniqueIdByVendor: uniqueIdByVendor, + RequestActionObject( + entityIds: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, ), @@ -55,7 +42,7 @@ class _SwitchMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.switchVariant, diff --git a/lib/presentation/molecules/insert_login_molecule.dart b/lib/presentation/molecules/insert_login_molecule.dart new file mode 100644 index 000000000..bf48c7701 --- /dev/null +++ b/lib/presentation/molecules/insert_login_molecule.dart @@ -0,0 +1,104 @@ +import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:flutter/material.dart'; + +class InsertLoginMolecule extends StatefulWidget { + const InsertLoginMolecule({ + required this.type, + required this.vendorsAndServices, + required this.onChange, + }); + + final InsertloginMoleculeType type; + final VendorsAndServices vendorsAndServices; + final Function(VendorLoginEntity) onChange; + + @override + State createState() => _InsertLoginMoleculeState(); +} + +class _InsertLoginMoleculeState extends State { + late VendorLoginEntity loginEntity; + + @override + void initState() { + super.initState(); + loginEntity = VendorLoginEntity(widget.vendorsAndServices); + } + + void onEmailChange(String value) { + loginEntity = loginEntityCopyWith(loginEntity: loginEntity, email: value); + + widget.onChange(loginEntity); + } + + void onPasswordChange(String value) { + loginEntity = + loginEntityCopyWith(loginEntity: loginEntity, password: value); + + widget.onChange(loginEntity); + } + + void onApiKeyChange(String value) { + loginEntity = loginEntityCopyWith(loginEntity: loginEntity, apiKey: value); + + widget.onChange(loginEntity); + } + + void onAuthTokenChange(String value) { + loginEntity = + loginEntityCopyWith(loginEntity: loginEntity, authToken: value); + + widget.onChange(loginEntity); + } + + VendorLoginEntity loginEntityCopyWith({ + required VendorLoginEntity loginEntity, + String? apiKey, + String? authToken, + String? email, + String? password, + }) => + VendorLoginEntity( + loginEntity.vendor, + apiKey: apiKey ?? loginEntity.apiKey, + authToken: authToken ?? loginEntity.authToken, + email: email ?? loginEntity.email, + password: password ?? loginEntity.password, + ); + + @override + Widget build(BuildContext context) { + switch (widget.type) { + case InsertloginMoleculeType.authToken: + return TextFormFieldAtom( + onChanged: onAuthTokenChange, + labelText: 'Auth Token', + ); + case InsertloginMoleculeType.apiKey: + return TextFormFieldAtom( + onChanged: onApiKeyChange, + labelText: 'Api Key', + ); + case InsertloginMoleculeType.emailAndPassword: + return Column( + children: [ + TextFormFieldAtom( + onChanged: onEmailChange, + labelText: 'Email', + ), + TextFormFieldAtom( + onChanged: onPasswordChange, + labelText: 'Password', + ), + ], + ); + } + } +} + +enum InsertloginMoleculeType { + authToken, + apiKey, + emailAndPassword, +} diff --git a/lib/presentation/molecules/molecules.dart b/lib/presentation/molecules/molecules.dart index 7343aac46..fedd80a82 100644 --- a/lib/presentation/molecules/molecules.dart +++ b/lib/presentation/molecules/molecules.dart @@ -1,6 +1,7 @@ export 'bottom_navigation_bar_molecule.dart'; export 'device_by_type_molecule.dart'; -export 'device_name_row.dart'; +export 'device_name_row_molecule.dart'; +export 'devices/ac_molecule.dart'; export 'devices/blind_molecule.dart'; export 'devices/blinds_card_molecule.dart'; export 'devices/boiler_molecule.dart'; @@ -14,8 +15,9 @@ export 'devices/smart_computer_molecule.dart'; export 'devices/smart_plug_molecule.dart'; export 'devices/smart_tv_molecule.dart'; export 'devices/switch_molecule.dart'; +export 'insert_login_molecule.dart'; export 'list_tile_molecule.dart'; export 'list_view_molecule.dart'; export 'loading_page_molecule.dart'; +export 'scenes_grid_molecule.dart'; export 'top_bar_molecule.dart'; -export 'scenes_grid.dart'; diff --git a/lib/presentation/molecules/scenes_grid.dart b/lib/presentation/molecules/scenes_grid_molecule.dart similarity index 82% rename from lib/presentation/molecules/scenes_grid.dart rename to lib/presentation/molecules/scenes_grid_molecule.dart index 131fbb10a..3fcb78b1a 100644 --- a/lib/presentation/molecules/scenes_grid.dart +++ b/lib/presentation/molecules/scenes_grid_molecule.dart @@ -2,16 +2,16 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:flutter/material.dart'; -class ScenesGrid extends StatefulWidget { - const ScenesGrid({required this.scenes}); +class ScenesGridMolecule extends StatefulWidget { + const ScenesGridMolecule({required this.scenes}); final List scenes; @override - State createState() => _ScenesGridState(); + State createState() => _ScenesGridMoleculeState(); } -class _ScenesGridState extends State { +class _ScenesGridMoleculeState extends State { late AreaEntity folderOfScenes; @override diff --git a/lib/presentation/organisms/devices_list_view.dart b/lib/presentation/organisms/devices_list_view.dart index 98811f2c2..600f48916 100644 --- a/lib/presentation/organisms/devices_list_view.dart +++ b/lib/presentation/organisms/devices_list_view.dart @@ -14,15 +14,11 @@ class DevicesListView extends StatelessWidget { HashSet getReleatedTypes(EntityTypes type) { if (type == EntityTypes.light || - type == EntityTypes.rgbLights || type == EntityTypes.rgbwLights || - type == EntityTypes.cctLight || type == EntityTypes.dimmableLight) { return HashSet.from({ EntityTypes.light, - EntityTypes.rgbLights, EntityTypes.rgbwLights, - EntityTypes.cctLight, EntityTypes.dimmableLight, }); } diff --git a/lib/presentation/pages/add_action_page.dart b/lib/presentation/pages/add_action_page.dart index 61b19e623..c405ad665 100644 --- a/lib/presentation/pages/add_action_page.dart +++ b/lib/presentation/pages/add_action_page.dart @@ -28,13 +28,13 @@ class _AddActionPageState extends State { }); } - Future onActionSelected(String value) async { + Future onActionSelected(String value) async { setState(() { selectedAction = EntityActions.values.elementAt(int.parse(value)); }); } - Future _onPropertySelected(String property) async { + Future _onPropertySelected(String property) async { setState(() { selectedProperty = EntityProperties.values.elementAt(int.parse(property)); }); diff --git a/lib/presentation/pages/add_bindings/add_binding_page.dart b/lib/presentation/pages/add_bindings/add_binding_page.dart index b0a4e67a3..ef654864e 100644 --- a/lib/presentation/pages/add_bindings/add_binding_page.dart +++ b/lib/presentation/pages/add_bindings/add_binding_page.dart @@ -42,16 +42,16 @@ class _AddBindingPageState extends State { bool showErrorMessages = false; bool isSubmitting = false; - Future initialzeEntities() async { + Future initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; }); } - Future _sendBindingToHub() async { + Future _sendBindingToHub() async { // IBindingCbjRepository.instance // .addOrUpdateNewBindingInHubFromDevicesPropertyActionList( // bindingName, @@ -59,7 +59,7 @@ class _AddBindingPageState extends State { // ); } - Future _addFullAction(EntityActionObject value) async { + Future _addFullAction(EntityActionObject value) async { setState(() { allDevicesWithNewAction.add(value); }); diff --git a/lib/presentation/pages/add_new_area_page.dart b/lib/presentation/pages/add_new_area_page.dart index 8b6331dc1..c1fc037f3 100644 --- a/lib/presentation/pages/add_new_area_page.dart +++ b/lib/presentation/pages/add_new_area_page.dart @@ -34,7 +34,7 @@ class _AddNewAreaFormState extends State { AreaBackground background = AreaBackground( 'https://live.staticflickr.com/5220/5486044345_f67abff3e9_h.jpg', ); - AreaTypes areaTypes = AreaTypes(const {}); + AreaPurposes areaTypes = AreaPurposes(const {}); AreaEntitiesId areaDevicesId = AreaEntitiesId(const {}); AreaScenesId areaScenesId = AreaScenesId(const {}); AreaRoutinesId areaRoutinesId = AreaRoutinesId(const {}); @@ -44,7 +44,7 @@ class _AddNewAreaFormState extends State { bool showErrorMessages = false; bool isSubmitting = false; - // Future _initialized() async { + // Future _initialized() async { // IAreaRepository.instance.getAllAreas().fold((l) => null, (r) { // _allAreas = Set.from(r.iter); // }); @@ -60,32 +60,32 @@ class _AddNewAreaFormState extends State { // }); // } - Future _createArea() async { + Future _createArea() async { final AreaEntity areaEntity = AreaEntity( uniqueId: AreaUniqueId.fromUniqueString(areaUniqueId.getOrCrash()), - cbjEntityName: AreaDefaultName(cbjEntityName.getOrCrash()), - background: AreaBackground(background.getOrCrash()), - areaTypes: AreaTypes(areaTypes.getOrCrash()), - entitiesId: AreaEntitiesId(areaDevicesId.getOrCrash()), - areaScenesId: AreaScenesId(areaScenesId.getOrCrash()), - areaRoutinesId: AreaRoutinesId(areaRoutinesId.getOrCrash()), - areaBindingsId: AreaBindingsId(areaBindingsId.getOrCrash()), - areaMostUsedBy: AreaMostUsedBy(areaMostUsedBy.getOrCrash()), - areaPermissions: AreaPermissions(areaPermissions.getOrCrash()), + cbjEntityName: cbjEntityName, + background: background, + purposes: areaTypes, + entitiesId: areaDevicesId, + scenesId: areaScenesId, + routinesId: areaRoutinesId, + bindingsId: areaBindingsId, + areaMostUsedBy: areaMostUsedBy, + areaPermissions: areaPermissions, ); ConnectionsService.instance.setNewArea(areaEntity); } - Future _defaultNameChanged(String value) async { + Future _defaultNameChanged(String value) async { setState(() { cbjEntityName = AreaDefaultName(value); }); } - Future _areaTypesChanged(Set value) async { + Future _areaTypesChanged(Set value) async { setState(() { - areaTypes = AreaTypes(value); + areaTypes = AreaPurposes(value); }); } @@ -148,15 +148,13 @@ class _AddNewAreaFormState extends State { } return MultiSelectItem( - areaPurposeType.value, + areaPurposeType, areaNameEdited, ); }).toList(), listType: MultiSelectListType.CHIP, - onConfirm: (List values) { - _areaTypesChanged( - values.map((e) => e.toString()).toSet(), - ); + onConfirm: (List values) { + _areaTypesChanged(values.toSet()); }, ), ], diff --git a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart index e14224e23..cc5ce96b9 100644 --- a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart @@ -7,41 +7,25 @@ import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; class VendorWidget extends StatelessWidget { - const VendorWidget(this.vendor); + const VendorWidget(this.vendorInformation); - final VendorData vendor; + final VendorEntityInformation vendorInformation; @override Widget build(BuildContext context) { return GestureDetector( onTap: () { - final String vendorName = vendor.name - .getOrCrash() - .toLowerCase() - .replaceAll(' ', '') - .replaceAll('_', ''); - - if (vendorName == VendorsAndServices.lifx.name.toLowerCase()) { - context.router.push(AddLifxVendorRoute(vendor: vendor)); - } else if (vendorName == - VendorsAndServices.espHome.name.toLowerCase()) { - context.router.push(AddEspHomeVendorRoute(vendor: vendor)); - } else if (vendorName == - VendorsAndServices.sonoffEweLink.name.toLowerCase()) { - context.router.push(AddEwelinkVendorRoute(vendor: vendor)); - } else if (vendorName == - VendorsAndServices.philipsHue.name.toLowerCase()) { + if (vendorInformation.loginType == VendorLoginTypes.notNeeded) { SnackBarService().show( context, - 'Please press the button on top of the Philips Hue Hub for and wait 20s', - ); - } else { - SnackBarService().show( - context, - '${vendor.name.getOrCrash()} devices will be add automatically' + '${vendorInformation.displayName} devices will be add automatically' ' for you', ); + return; } + + context.router + .push(LoginVendorRoute(vendorInformation: vendorInformation)); }, child: Container( height: 100, @@ -54,10 +38,7 @@ class VendorWidget extends StatelessWidget { height: 180, decoration: BoxDecoration( image: DecorationImage( - image: NetworkImage( - vendor.image ?? - 'http://www.clker.com/cliparts/f/Z/G/4/h/Q/no-image-available-th.png', - ), + image: NetworkImage(vendorInformation.imageUrl), fit: BoxFit.fitHeight, ), ), @@ -66,7 +47,7 @@ class VendorWidget extends StatelessWidget { width: 10, ), TextAtom( - vendor.name.getOrCrash(), + vendorInformation.displayName, style: const TextStyle( color: Colors.black, fontSize: 22, diff --git a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart index f14efa690..f59c6113f 100644 --- a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart +++ b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart @@ -1,7 +1,8 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart'; import 'package:flutter/material.dart'; -import 'package:kt_dart/kt.dart'; class VendorsList extends StatefulWidget { @override @@ -9,7 +10,7 @@ class VendorsList extends StatefulWidget { } class _VendorsListState extends State { - KtList vendorsList = [].toImmutableList(); + List? vendorsList; @override void initState() { @@ -17,11 +18,11 @@ class _VendorsListState extends State { initializeVendors(); } - Future initializeVendors() async { - final KtList temp = - (await IVendorsRepository.instance.getVendors()).fold( - (f) => [].toImmutableList(), - (vendorsListSuccess) => vendorsListSuccess, + Future initializeVendors() async { + final List temp = + await ConnectionsService.instance.getVendors(); + temp.removeWhere( + (element) => element.vendorsAndServices == VendorsAndServices.undefined, ); setState(() { vendorsList = temp; @@ -30,6 +31,10 @@ class _VendorsListState extends State { @override Widget build(BuildContext context) { + if (vendorsList == null) { + return const CircularProgressIndicatorAtom(); + } + return ListView.separated( separatorBuilder: (_, __) => const SizedBox( height: 16, @@ -37,12 +42,10 @@ class _VendorsListState extends State { reverse: true, padding: EdgeInsets.zero, itemBuilder: (context, index) { - final vendor = vendorsList[index]; - return VendorWidget( - vendor, - ); + final vendor = vendorsList![index]; + return VendorWidget(vendor); }, - itemCount: vendorsList.size, + itemCount: vendorsList!.length, ); } } diff --git a/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart b/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart index c5de27c4d..6131c0e50 100644 --- a/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart @@ -7,6 +7,7 @@ import 'package:cybearjinni/domain/cbj_comp/i_cbj_comp_repository.dart'; import 'package:cybearjinni/domain/manage_network/i_manage_network_repository.dart'; import 'package:cybearjinni/domain/manage_network/manage_network_entity.dart'; import 'package:cybearjinni/domain/security_bear/i_security_bear_connection_repository.dart'; +import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart'; import 'package:dartz/dartz.dart' as dartz; @@ -51,7 +52,7 @@ class _ComputerConnectionCheckWidgetState ).show(context); } - Future _checkConnectedToWiFiNetwork() async { + Future _checkConnectedToWiFiNetwork() async { if ((await WiFiScan.instance.canStartScan()) == CanStartScan.yes) { await WiFiScan.instance.startScan(); if ((await WiFiScan.instance.canGetScannedResults()) == @@ -61,7 +62,7 @@ class _ComputerConnectionCheckWidgetState } bool isConnectedToWifi = false; - icLogger.i('Waiting for user to get connected to WiFi'); + logger.i('Waiting for user to get connected to WiFi'); while (true) { isConnectedToWifi = await WiFiForIoTPlugin.isConnected(); @@ -78,7 +79,7 @@ class _ComputerConnectionCheckWidgetState _searchIfHubOnTheSameWifiNetwork(); } - Future _searchIfHubOnTheSameWifiNetwork() async { + Future _searchIfHubOnTheSameWifiNetwork() async { int connectionTimeout = 0; while (true) { @@ -124,7 +125,7 @@ class _ComputerConnectionCheckWidgetState deviceE..cbjEntityName = CbjEntityName(deviceName), ); } catch (e) { - icLogger.w("Can't add unsupported device"); + logger.w("Can't add unsupported device"); } }); final CbjCompEntity compUpdatedData = cbjCompEntity.copyWith( diff --git a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart index d892863e0..d22b8324d 100644 --- a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart @@ -8,6 +8,7 @@ import 'package:cybearjinni/domain/manage_network/i_manage_network_repository.da import 'package:cybearjinni/domain/manage_network/manage_network_entity.dart'; import 'package:cybearjinni/domain/security_bear/i_security_bear_connection_repository.dart'; import 'package:cybearjinni/domain/security_bear/security_bear_failures.dart'; +import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; @@ -47,7 +48,7 @@ class _ConfigureNewCbjCompWidgetsState _sendHotSpotInformation(widget.cbjCompEntity); } - Future _sendHotSpotInformation(CbjCompEntity cBJCompEntity) async { + Future _sendHotSpotInformation(CbjCompEntity cBJCompEntity) async { progressPercentage += 0.3; setState(() { state = ConfigureNewCbjCompState.actionInProgress; @@ -112,7 +113,7 @@ class _ConfigureNewCbjCompWidgetsState deviceE..cbjEntityName = CbjEntityName(deviceName), ); } catch (e) { - icLogger.w("Can't add unsupported device"); + logger.w("Can't add unsupported device"); } }); final CbjCompEntity compUpdatedData = cbjCompEntity.copyWith( @@ -148,8 +149,7 @@ class _ConfigureNewCbjCompWidgetsState final List widgetList = []; for (final GenericLightDE device in devicesList) { - if (device.entityTypes.getOrCrash() != - EntityTypes.smartTypeNotSupported.toString()) { + if (device.entityTypes.getOrCrash() != EntityTypes.undefined.toString()) { final TextEditingController textEditingControllerTemp = TextEditingController( text: device.cbjEntityName.value.getOrElse(() => ''), diff --git a/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart b/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart index 7e8d4cc8f..b3c168499 100644 --- a/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart @@ -25,7 +25,7 @@ class _ConnectToHomeWiFiWidgetState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final dartz.Either doesWiFiEnabled = await IManageNetworkRepository.instance.doesWiFiEnabled(); @@ -41,7 +41,7 @@ class _ConnectToHomeWiFiWidgetState extends State { }); } - Future _connectToWiFi() async { + Future _connectToWiFi() async { final ManageNetworkEntity manageWiFiEntity = ManageNetworkEntity( name: wifiName, pass: wifiPassword, diff --git a/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart b/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart index f6f293fdf..6e742a211 100644 --- a/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart @@ -29,7 +29,7 @@ class _OpenAccessPointWidgetState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { OpenAccessPointState stateTemp; if (Platform.isAndroid) { final ManageNetworkEntity manageNetworkEntity = ManageNetworkEntity( @@ -52,7 +52,7 @@ class _OpenAccessPointWidgetState extends State { }); } - Future _doesAccessPointOpen() async { + Future _doesAccessPointOpen() async { OpenAccessPointState stateTemp; if (Platform.isAndroid) { diff --git a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart index a51554c59..4af47166e 100644 --- a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart +++ b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart @@ -21,7 +21,7 @@ class CBJCompCardWithDevicesControll extends StatelessWidget { for (final GenericLightDE deviceEntity in deviceEntityList.asList()) { // if (deviceEntity.entityTypes.getOrCrash() != - EntityTypes.smartTypeNotSupported.toString()) { + EntityTypes.undefined.toString()) { typesList.add( ColoredBox( color: Colors.yellowAccent.withOpacity(0.3), diff --git a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart index 9e1bd7d87..1af978310 100644 --- a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart @@ -28,7 +28,7 @@ class _ScanForNewCBJCompsWidgetState extends State { _watchAllStarted(); } - Future _watchAllStarted() async { + Future _watchAllStarted() async { await _cbjCompStreamSubscription?.cancel(); _cbjCompStreamSubscription = ICbjCompRepository.instance .getConnectedComputersIP() @@ -45,7 +45,7 @@ class _ScanForNewCBJCompsWidgetState extends State { }); } - Future _compDevicesReceived( + Future _compDevicesReceived( dartz.Either failureOrCBJCompList, ) async { final dynamic failureOrCompListDynamic = failureOrCBJCompList.fold( @@ -71,7 +71,7 @@ class _ScanForNewCBJCompsWidgetState extends State { } @override - Future dispose() async { + Future dispose() async { await _cbjCompStreamSubscription?.cancel(); await ICbjCompRepository.instance.shutdownServer(); return super.dispose(); diff --git a/lib/presentation/pages/add_routine/add_routine_page.dart b/lib/presentation/pages/add_routine/add_routine_page.dart index 3c5a4a565..0497f292a 100644 --- a/lib/presentation/pages/add_routine/add_routine_page.dart +++ b/lib/presentation/pages/add_routine/add_routine_page.dart @@ -10,7 +10,6 @@ import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; import 'package:cybearjinni/presentation/pages/add_action_page.dart'; import 'package:cybearjinni/presentation/pages/add_routine/widgets/routine_action_widget.dart'; -import 'package:dartz/dartz.dart' as dartz; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hexcolor/hexcolor.dart'; @@ -51,21 +50,18 @@ class _AddRoutinePageState extends State { Set> allEntityActions = {}; bool showErrorMessages = false; bool isSubmitting = false; - dartz.Option> - authFailureOrSuccessOption = dartz.none(); - HashMap? entities; - Future initialzeEntities() async { + Future initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; }); } - Future _sendRoutineToHub() async { + Future _sendRoutineToHub() async { if (daysToRepeat == null || hourToRepeat == null || minutesToRepeat == null || @@ -82,11 +78,11 @@ class _AddRoutinePageState extends State { // ); } - Future _routineNameChange(String value) async { + Future _routineNameChange(String value) async { routineName = value; } - Future _addFullAction(EntityActionObject value) async { + Future _addFullAction(EntityActionObject value) async { setState(() { allDevicesWithNewAction.add(value); }); diff --git a/lib/presentation/pages/add_scene/add_scene_page.dart b/lib/presentation/pages/add_scene/add_scene_page.dart index cce9e4f85..58301d953 100644 --- a/lib/presentation/pages/add_scene/add_scene_page.dart +++ b/lib/presentation/pages/add_scene/add_scene_page.dart @@ -33,29 +33,28 @@ class _AddScenePageState extends State { /// List of devices with entities, will be treated as actions HashSet entitiesWithActions = HashSet(); - Future initialzeEntities() async { + Future initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; }); } - List entitiesWithActionsToActionsByVendor() => + List entitiesWithActionsToActionsByVendor() => entitiesWithActions .map( - (e) => ActionObjectSingle( - vendor: e.entity.cbjDeviceVendor.vendorsAndServices!, - entityId: e.entity.getCbjDeviceId, + (e) => RequestActionObject( + entityIds: HashSet.from([e.entity.getCbjDeviceId]), property: e.property, actionType: e.action, ), ) .toList(); - Future _sendSceneToHub() async { - final List actions = + Future _sendSceneToHub() async { + final List actions = entitiesWithActionsToActionsByVendor(); final SceneCbjEntity scene = SceneCbjEntity( @@ -76,16 +75,13 @@ class _AddScenePageState extends State { compUuid: SceneCbjCompUuid(''), entityStateGRPC: SceneCbjDeviceStateGRPC(EntityStateGRPC.ack.name), actions: actions, + areaPurposeType: AreaPurposesTypes.undefined, ); ConnectionsService.instance.addScene(scene); } - void _sceneNameChange(String value) { - sceneName = value; - } - - Future _addFullAction(EntityActionObject value) async { + Future _addFullAction(EntityActionObject value) async { setState(() { entitiesWithActions.add(value); }); @@ -123,7 +119,7 @@ class _AddScenePageState extends State { labelText: 'Scene Name', ), style: const TextStyle(color: Colors.black), - onChanged: _sceneNameChange, + onChanged: (value) => sceneName = value, ), SizedBox( height: 300, diff --git a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart b/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart deleted file mode 100644 index b2d2d58cd..000000000 --- a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart'; -import 'package:flutter/material.dart'; - -@RoutePage() -class AddEspHomeVendorPage extends StatelessWidget { - const AddEspHomeVendorPage(this.vendor); - - final VendorData vendor; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const TextAtom('EspHome Sign In'), - ), - body: EspHomeSignInForm(vendor), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart b/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart deleted file mode 100644 index 31d43e771..000000000 --- a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; - -class EspHomeSignInForm extends StatefulWidget { - const EspHomeSignInForm(this.vendor); - - final VendorData vendor; - - @override - State createState() => _EspHomeSignInFormState(); -} - -class _EspHomeSignInFormState extends State { - String? password; - - void _login() { - if (password == null) { - return; - } - - context.router.pop(); - - IVendorsRepository.instance.loginWithEspHome( - GenericEspHomeLoginDE( - espHomeDevicePass: GenericEspHomeDeviceLoginApiPass(password), - senderUniqueId: CoreLoginSenderId.fromUniqueString('Me'), - ), - ); - } - - @override - Widget build(BuildContext context) { - final Size screenSize = MediaQuery.of(context).size; - - return Form( - autovalidateMode: AutovalidateMode.onUserInteraction, - child: ListView( - padding: const EdgeInsets.all(8), - children: [ - Hero( - tag: 'Logo', - child: CircleAvatar( - backgroundColor: Colors.transparent, - radius: screenSize.height * 0.1, - child: Container( - width: 180, - height: 180, - decoration: BoxDecoration( - image: DecorationImage( - image: NetworkImage( - widget.vendor.image ?? '', - ), - fit: BoxFit.fitHeight, - ), - ), - ), - ), - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.key, - ), - labelText: 'ESPHome device password', - ), - autocorrect: false, - onChanged: (value) { - password = value; - }, - ), - const SizedBox( - height: 8, - ), - Row( - children: [ - Expanded( - child: TextButton( - onPressed: () { - _login(); - - SnackBarService().show( - context, - 'Sign in to ESPHome, devices will appear in the ' - 'app after getting discovered', - ); - context.router.pop(); - }, - child: const TextAtom('SIGN IN'), - ), - ), - ], - ), - ], - ), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart b/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart deleted file mode 100644 index b6f5a0486..000000000 --- a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart'; -import 'package:flutter/material.dart'; - -@RoutePage() -class AddEwelinkVendorPage extends StatelessWidget { - const AddEwelinkVendorPage(this.vendor); - - final VendorData vendor; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.blueAccent, - title: const TextAtom('eWeLink Sign In'), - ), - body: EwelinkSignInForm(vendor), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart b/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart deleted file mode 100644 index c6a003148..000000000 --- a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; - -class EwelinkSignInForm extends StatefulWidget { - const EwelinkSignInForm(this.vendor); - - final VendorData vendor; - - @override - State createState() => _EwelinkSignInFormState(); -} - -class _EwelinkSignInFormState extends State { - String? email; - String? password; - - Future _signInWithEwelink() async { - if (email == null || password == null) { - SnackBarService().show( - context, - 'Please enter Email and Password', - ); - return; - } - - SnackBarService().show( - context, - 'Sign in to eWeLink, devices will appear in the ' - 'app after getting discovered', - ); - context.router.pop(); - - final GenericEwelinkLoginDE genericEwelinkDE = GenericEwelinkLoginDE( - senderUniqueId: CoreLoginSenderId.fromUniqueString('Me'), - ewelinkAccountEmail: GenericEwelinkAccountEmail(email), - ewelinkAccountPass: GenericEwelinkAccountPass(password), - ); - IVendorsRepository.instance.loginWithEwelink(genericEwelinkDE); - } - - @override - Widget build(BuildContext context) { - final Size screenSize = MediaQuery.of(context).size; - - return Form( - autovalidateMode: AutovalidateMode.onUserInteraction, - child: ListView( - padding: const EdgeInsets.all(8), - children: [ - Hero( - tag: 'Logo', - child: CircleAvatar( - backgroundColor: Colors.transparent, - radius: screenSize.height * 0.1, - child: Container( - width: 180, - height: 180, - decoration: BoxDecoration( - image: DecorationImage( - image: NetworkImage(widget.vendor.image ?? ''), - fit: BoxFit.fitHeight, - ), - ), - ), - // ImageAtom('assets/cbj_logo.png'), - ), - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.at, - ), - labelText: 'eWeLink device email', - ), - autocorrect: false, - onChanged: (value) { - email = value; - }, - validator: (_) { - return null; - }, - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.key, - ), - labelText: 'eWeLink device password', - ), - autocorrect: false, - onChanged: (value) { - password = value; - }, - validator: (_) { - return null; - }, - ), - const SizedBox( - height: 8, - ), - Row( - children: [ - Expanded( - child: TextButton( - onPressed: () { - _signInWithEwelink(); - }, - child: const TextAtom('SIGN IN'), - ), - ), - ], - ), - ], - ), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart b/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart deleted file mode 100644 index 0eea2c536..000000000 --- a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart'; -import 'package:flutter/material.dart'; - -@RoutePage() -class AddLifxVendorPage extends StatelessWidget { - const AddLifxVendorPage(this.vendor); - - final VendorData vendor; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.deepPurple, - title: const TextAtom('Lifx Sign In'), - ), - body: LifxSignInForm(vendor), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart b/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart deleted file mode 100644 index 659d38c38..000000000 --- a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class LifxSignInForm extends StatefulWidget { - const LifxSignInForm(this.vendor); - - final VendorData vendor; - - @override - State createState() => _LifxSignInFormState(); -} - -class _LifxSignInFormState extends State { - String? api; - - Future _signInWithApiKey() async { - SnackBarService().show( - context, - 'Sign in to Lifx, devices will appear in the shortly', - ); - final GenericLifxLoginDE genericLifxDE = GenericLifxLoginDE( - senderUniqueId: CoreLoginSenderId.fromUniqueString('Me'), - lifxApiKey: GenericLifxLoginApiKey(api), - ); - IVendorsRepository.instance.loginWithLifx(genericLifxDE); - context.router.pop(); - } - - @override - Widget build(BuildContext context) { - final Size screenSize = MediaQuery.of(context).size; - - return Column( - children: [ - Expanded( - child: Form( - autovalidateMode: AutovalidateMode.onUserInteraction, - child: ListView( - padding: const EdgeInsets.all(8), - children: [ - Hero( - tag: 'Logo', - child: CircleAvatar( - backgroundColor: Colors.transparent, - radius: screenSize.height * 0.1, - child: Container( - width: 180, - height: 180, - decoration: BoxDecoration( - image: DecorationImage( - image: NetworkImage( - widget.vendor.image ?? '', - ), - fit: BoxFit.fitHeight, - ), - ), - ), - ), - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.key, - ), - labelText: 'Lifx API Key', - ), - autocorrect: false, - onChanged: (value) { - api = value; - }, - ), - const SizedBox( - height: 8, - ), - Row( - children: [ - Expanded( - child: TextButton( - onPressed: () { - _signInWithApiKey(); - }, - child: const TextAtom('SIGN IN'), - ), - ), - ], - ), - ], - ), - ), - ), - Container( - alignment: Alignment.bottomRight, - child: TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Colors.pink), - ), - onPressed: () { - launchUrl(Uri.parse('https://cloud.lifx.com/')); - }, - child: TextAtom( - 'Get Lifx API key from Lifx website', - style: TextStyle( - color: Theme.of(context).textTheme.bodyLarge!.color, - ), - ), - ), - ), - ], - ); - } -} diff --git a/lib/presentation/pages/change_area_for_devices_page.dart b/lib/presentation/pages/change_area_for_devices_page.dart index ea615a1e4..9956c1637 100644 --- a/lib/presentation/pages/change_area_for_devices_page.dart +++ b/lib/presentation/pages/change_area_for_devices_page.dart @@ -52,14 +52,14 @@ class _ChangeAreaForDevicesWidgetState _initialized(); } - Future _initialized() async { + Future _initialized() async { getAreas(); getEntities(); } Future getAreas() async { final HashMap areasTemp = - await ConnectionsService.instance.getAllAreas; + await ConnectionsService.instance.getAreas; setState(() { areas = areasTemp; }); @@ -67,7 +67,7 @@ class _ChangeAreaForDevicesWidgetState Future getEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; }); diff --git a/lib/presentation/pages/choose_automation_type_to_add_page.dart b/lib/presentation/pages/choose_automation_type_to_add_page.dart index f93c65640..9f301304e 100644 --- a/lib/presentation/pages/choose_automation_type_to_add_page.dart +++ b/lib/presentation/pages/choose_automation_type_to_add_page.dart @@ -26,19 +26,12 @@ class ChooseAutomationTypeToAddPage extends StatelessWidget { const TextAtom( 'Do several things at once or start actions' ' automatically by adding a trigger.', - style: TextStyle( - color: Colors.black, - ), ), const SizedBox( height: 13, ), const TextAtom( 'Please choose your automation trigger', - style: TextStyle( - color: Colors.black, - fontSize: 18, - ), ), const SizedBox( height: 30, diff --git a/lib/presentation/pages/comunication_method_page.dart b/lib/presentation/pages/comunication_method_page.dart new file mode 100644 index 000000000..63c8ba6c3 --- /dev/null +++ b/lib/presentation/pages/comunication_method_page.dart @@ -0,0 +1,61 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; +import 'package:cybearjinni/presentation/organisms/organisms.dart'; +import 'package:flutter/material.dart'; + +@RoutePage() +class ComunicationMethodPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return PageOrganism( + pageName: 'Comunication type', + child: Column( + children: [ + const TextAtom('Chose comunication Method'), + TextAtom( + 'Current comunication: ${ConnectionsService.getCurrentConnectionType()}', + ), + Expanded( + child: Column( + children: [ + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'App as a Hub', + onPressed: () => ConnectionsService.setCurrentConnectionType( + ConnectionType.appAsHub, + ), + ), + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'Hub', + onPressed: () { + ConnectionsService.setCurrentConnectionType( + ConnectionType.hub, + ); + ConnectionsService.instance.connect(); + }, + ), + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'Demo', + onPressed: () => ConnectionsService.setCurrentConnectionType( + ConnectionType.demo, + ), + ), + ], + ), + ), + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'Insert Remote Pipes', + onPressed: () { + context.router.push(const RemotePipesRoute()); + }, + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart b/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart index 8380df082..feed20bd3 100644 --- a/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart +++ b/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart @@ -1,5 +1,4 @@ import 'package:auto_route/auto_route.dart'; -import 'package:cybearjinni/domain/i_hub_connection_repository.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; import 'package:cybearjinni/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart'; @@ -160,7 +159,7 @@ class ConnectToHubPage extends StatelessWidget { GestureDetector( onTap: () { context.router.push(const SmartCameraContainerRoute()); - IHubConnectionRepository.instance.closeConnection(); + // IHubConnectionRepository.instance.closeConnection(); }, child: Container( margin: const EdgeInsets.symmetric(horizontal: 30), diff --git a/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart b/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart index 967edd8aa..26a4054f7 100644 --- a/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart +++ b/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart @@ -42,7 +42,7 @@ class _CbjHubInNetworkWidgetState extends State { }); final HashMap entities = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; if (entities.isNotEmpty) { if (!mounted || foundEntity) { diff --git a/lib/presentation/pages/connect_to_hub_more_page.dart b/lib/presentation/pages/connect_to_hub_more_page.dart index 7d89f66db..42e1e0fe5 100644 --- a/lib/presentation/pages/connect_to_hub_more_page.dart +++ b/lib/presentation/pages/connect_to_hub_more_page.dart @@ -1,16 +1,12 @@ import 'dart:async'; import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/domain/connections_service.dart'; -import 'package:cybearjinni/domain/device/devices_failures.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; -import 'package:dartz/dartz.dart' as dartz; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hexcolor/hexcolor.dart'; -import 'package:kt_dart/kt.dart'; @RoutePage() class ConnectToHubMorePage extends StatelessWidget { @@ -88,23 +84,13 @@ class ConnectToHubMoreWidget extends StatefulWidget { } class _ConnectToHubMoreWidgetState extends State { - StreamSubscription>>? - _deviceStreamSubscription; - bool isLoading = false; - Future _connectInDemoMode() async { + Future _connectInDemoMode() async { ConnectionsService.setCurrentConnectionType(ConnectionType.demo); context.router.replace(const HomeRoute()); } - @override - void dispose() { - _deviceStreamSubscription?.cancel(); - - super.dispose(); - } - @override Widget build(BuildContext context) { if (isLoading) { diff --git a/lib/presentation/pages/entities_in_area_page.dart b/lib/presentation/pages/entities_in_area_page.dart index 8d9208e43..731936b92 100644 --- a/lib/presentation/pages/entities_in_area_page.dart +++ b/lib/presentation/pages/entities_in_area_page.dart @@ -33,7 +33,7 @@ class _EntitiesInAreaPageState extends State { Future initialzeDevices() async { final Map entitiesMap = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; final Set entityIdsInArea = widget.areaEntity.entitiesId.getOrCrash(); final Set entityTypes = widget.entityTypes; @@ -55,8 +55,7 @@ class _EntitiesInAreaPageState extends State { } bool supportedEntityType(EntityTypes type) { - return !(type == EntityTypes.smartTypeNotSupported || - type == EntityTypes.emptyEntity); + return !(type == EntityTypes.undefined || type == EntityTypes.emptyEntity); } @override diff --git a/lib/presentation/pages/entities_in_network_page.dart b/lib/presentation/pages/entities_in_network_page.dart index 2c0e13cb7..f2c608856 100644 --- a/lib/presentation/pages/entities_in_network_page.dart +++ b/lib/presentation/pages/entities_in_network_page.dart @@ -23,7 +23,7 @@ class _EntitiesInNetworkPageState extends State { Future initializeAllEntities() async { final Map entities = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { allEntities = entities.values.toList(); }); diff --git a/lib/presentation/pages/home_page/home_page.dart b/lib/presentation/pages/home_page/home_page.dart index de48cccd1..72d130e44 100644 --- a/lib/presentation/pages/home_page/home_page.dart +++ b/lib/presentation/pages/home_page/home_page.dart @@ -45,9 +45,9 @@ class _HomePageState extends State { HashMap? areas; HashMap? entities; - Future initializedScenes() async { + Future initializedScenes() async { final HashMap scenecsTemp = - await ConnectionsService.instance.getScenes(); + await ConnectionsService.instance.getScenes; setState(() { scenes = scenecsTemp; @@ -72,7 +72,7 @@ class _HomePageState extends State { Future _initialzeAreas() async { final HashMap areasTemp = - await ConnectionsService.instance.getAllAreas; + await ConnectionsService.instance.getAreas; setState(() { areas ??= HashMap(); @@ -101,10 +101,10 @@ class _HomePageState extends State { Future _initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; entitiesTemp.removeWhere( (key, value) => - value.entityTypes.type == EntityTypes.smartTypeNotSupported || + value.entityTypes.type == EntityTypes.undefined || value.entityTypes.type == EntityTypes.emptyEntity, ); setState(() { @@ -123,8 +123,7 @@ class _HomePageState extends State { } bool unSupportedEntityType(EntityTypes type) { - return type == EntityTypes.smartTypeNotSupported || - type == EntityTypes.emptyEntity; + return type == EntityTypes.undefined || type == EntityTypes.emptyEntity; } /// Tab num, value will be the default tab to show @@ -210,7 +209,11 @@ class _HomePageState extends State { GestureDetector( onTap: () async { await context.router.push(const PlusButtonRoute()); + areas = null; + entities = null; _initialzeAreas(); + _initialzeEntities(); + initializedScenes(); }, child: CircleAvatar( diff --git a/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart b/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart index 577f77a2d..dce8ec8f4 100644 --- a/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart +++ b/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart @@ -97,7 +97,7 @@ class ScenesInFoldersTab extends StatelessWidget { leftIconFunction: (BuildContext context) {}, ), Expanded( - child: ScenesGrid( + child: ScenesGridMolecule( scenes: scenes!.values.toList(), ), ), diff --git a/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart b/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart index 964a62ac3..557509dc7 100644 --- a/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart +++ b/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart @@ -46,6 +46,7 @@ class EntitiesByAreaTab extends StatelessWidget { areas: areas, ), ), + const SeparatorAtom(), ], ), ), diff --git a/lib/presentation/pages/introduction_screen/introduction_screen_body.dart b/lib/presentation/pages/introduction_screen/introduction_screen_body.dart index d4312805c..6fe7822e8 100644 --- a/lib/presentation/pages/introduction_screen/introduction_screen_body.dart +++ b/lib/presentation/pages/introduction_screen/introduction_screen_body.dart @@ -116,7 +116,7 @@ class _IntroductionScreenBodyState extends State { ), onDone: () async { final HashMap entities = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; if (!mounted) { return; } diff --git a/lib/presentation/pages/login_vendor_page.dart b/lib/presentation/pages/login_vendor_page.dart new file mode 100644 index 000000000..beffa50da --- /dev/null +++ b/lib/presentation/pages/login_vendor_page.dart @@ -0,0 +1,140 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; +import 'package:cybearjinni/presentation/molecules/molecules.dart'; +import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; + +@RoutePage() +class LoginVendorPage extends StatefulWidget { + const LoginVendorPage(this.vendorInformation); + + final VendorEntityInformation vendorInformation; + + @override + State createState() => _LoginVendorPageState(); +} + +class _LoginVendorPageState extends State { + VendorLoginEntity? loginEntity; + + Future _signInWithApiKey() async { + if (loginEntity == null) { + return; + } + + SnackBarService().show( + context, + 'Sign in to ${widget.vendorInformation.displayName}, devices will appear in the shortly', + ); + + ConnectionsService.instance.loginVendor(loginEntity!); + context.router.pop(); + } + + Widget authTypeWidget() { + InsertloginMoleculeType type; + switch (widget.vendorInformation.loginType) { + case VendorLoginTypes.notNeeded: + return const TextAtom('Not needed'); + case VendorLoginTypes.authToken: + type = InsertloginMoleculeType.authToken; + case VendorLoginTypes.apiKey: + type = InsertloginMoleculeType.apiKey; + + case VendorLoginTypes.emailAndPassword: + type = InsertloginMoleculeType.emailAndPassword; + } + return InsertLoginMolecule( + type: type, + vendorsAndServices: widget.vendorInformation.vendorsAndServices, + onChange: (VendorLoginEntity value) { + loginEntity = value; + }, + ); + } + + @override + Widget build(BuildContext context) { + final Size screenSize = MediaQuery.of(context).size; + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.deepPurple, + title: TextAtom('${widget.vendorInformation.displayName} Sign In'), + ), + body: Column( + children: [ + Expanded( + child: Form( + autovalidateMode: AutovalidateMode.onUserInteraction, + child: ListView( + padding: const EdgeInsets.all(8), + children: [ + Hero( + tag: 'Logo', + child: CircleAvatar( + backgroundColor: Colors.transparent, + radius: screenSize.height * 0.1, + child: Container( + width: 180, + height: 180, + decoration: BoxDecoration( + image: DecorationImage( + image: + NetworkImage(widget.vendorInformation.imageUrl), + fit: BoxFit.fitHeight, + ), + ), + ), + ), + ), + const SizedBox( + height: 8, + ), + authTypeWidget(), + const SizedBox( + height: 8, + ), + Row( + children: [ + Expanded( + child: TextButton( + onPressed: _signInWithApiKey, + child: const TextAtom('SIGN IN'), + ), + ), + ], + ), + ], + ), + ), + ), + if (widget.vendorInformation.urlToLoginCredantials != null) + Container( + alignment: Alignment.bottomRight, + child: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.pink), + ), + onPressed: () { + launchUrl( + Uri.parse( + widget.vendorInformation.urlToLoginCredantials!, + ), + ); + }, + child: TextAtom( + widget.vendorInformation.loginType.name, + style: TextStyle( + color: Theme.of(context).textTheme.bodyLarge!.color, + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/pages.dart b/lib/presentation/pages/pages.dart index ceb5e18f3..5c3cb02a7 100644 --- a/lib/presentation/pages/pages.dart +++ b/lib/presentation/pages/pages.dart @@ -9,9 +9,6 @@ export 'package:cybearjinni/presentation/pages/add_new_devices_process/open_acce export 'package:cybearjinni/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/scan_for_new_cbj_comps_page.dart'; export 'package:cybearjinni/presentation/pages/add_routine/add_routine_page.dart'; export 'package:cybearjinni/presentation/pages/add_scene/add_scene_page.dart'; -export 'package:cybearjinni/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart'; -export 'package:cybearjinni/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart'; -export 'package:cybearjinni/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart'; export 'package:cybearjinni/presentation/pages/change_area_for_devices_page.dart'; export 'package:cybearjinni/presentation/pages/choose_automation_type_to_add_page.dart'; export 'package:cybearjinni/presentation/pages/connect_to_hub/connect_to_hub_page.dart'; diff --git a/lib/presentation/pages/plus_button.dart b/lib/presentation/pages/plus_button.dart index cc95ceb54..e325fcfc1 100644 --- a/lib/presentation/pages/plus_button.dart +++ b/lib/presentation/pages/plus_button.dart @@ -10,9 +10,9 @@ import 'package:iconify_flutter/icons/simple_icons.dart'; @RoutePage() class PlusButtonPage extends StatelessWidget { - Future _logout(BuildContext context) async { + Future _logout(BuildContext context) async { context.router.replace(const ConnectToHubRoute()); - ConnectionsService.setCurrentConnectionType(null); + ConnectionsService.setCurrentConnectionType(ConnectionType.none); } @override @@ -94,31 +94,6 @@ class PlusButtonPage extends StatelessWidget { }, ), ), - if (ConnectionsService.getCurrentConnectionType() == - ConnectionType.hub) ...[ - const SizedBox(height: 1), - ColoredBox( - color: Colors.blue, - child: ListTile( - leading: FaIcon( - FontAwesomeIcons.globe, - color: colorScheme.background, - ), - title: TextAtom( - 'Add Remote Control Support', - style: TextStyle( - color: Theme.of(context) - .textTheme - .bodyLarge! - .color, - ), - ), - onTap: () { - context.router.push(const RemotePipesRoute()); - }, - ), - ), - ], const SizedBox(height: 1), ColoredBox( color: Colors.purple.withOpacity(0.7), @@ -185,9 +160,28 @@ class PlusButtonPage extends StatelessWidget { color: Colors.white, child: Column( children: [ - const SizedBox( - height: 1, + const SizedBox(height: 1), + ColoredBox( + color: Colors.blue, + child: ListTile( + leading: FaIcon( + FontAwesomeIcons.globe, + color: colorScheme.background, + ), + title: TextAtom( + 'Comunication Method', + style: TextStyle( + color: + Theme.of(context).textTheme.bodyLarge!.color, + ), + ), + onTap: () { + context.router + .push(const ComunicationMethodRoute()); + }, + ), ), + const SizedBox(height: 1), ColoredBox( color: Colors.pink.withOpacity(0.9), child: ListTile( diff --git a/lib/presentation/pages/remote_pipes_page.dart b/lib/presentation/pages/remote_pipes_page.dart index 1662f52b1..00c781134 100644 --- a/lib/presentation/pages/remote_pipes_page.dart +++ b/lib/presentation/pages/remote_pipes_page.dart @@ -1,6 +1,6 @@ import 'package:adaptive_action_sheet/adaptive_action_sheet.dart'; import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; @@ -61,25 +61,19 @@ class RemotePipesWidget extends StatefulWidget { class _RemotePipesWidgetState extends State { String? remotePipesDomainName; - Future _remotePipesDomainChanged(String value) async { + Future _remotePipesDomainChanged(String value) async { setState(() { remotePipesDomainName = value; }); } - Future _addRemotePipeUrl() async { + Future _addRemotePipeUrl() async { if (remotePipesDomainName == null || remotePipesDomainName!.isEmpty) { return; } - - final RemotePipesEntity remotePipesEntity = - RemotePipesEntity.empty().copyWith( - domainName: RemotePipesDomain(remotePipesDomainName!), - ); - + ConnectionsService.setCurrentConnectionType(ConnectionType.remotePipes); + ConnectionsService.instance.connect(address: remotePipesDomainName); context.router.pop(); - await IRemotePipesRepository.instance - .setRemotePipesDomainName(remotePipesEntity); } @override @@ -91,7 +85,6 @@ class _RemotePipesWidgetState extends State { children: [ const TextAtom( 'Please insert the Remote Pipes domain', - style: TextStyle(color: Colors.black, fontSize: 25), ), const SizedBox( height: 60, diff --git a/lib/presentation/pages/scenes/scenes_page.dart b/lib/presentation/pages/scenes/scenes_page.dart index 12ab9dcf2..686f6c739 100644 --- a/lib/presentation/pages/scenes/scenes_page.dart +++ b/lib/presentation/pages/scenes/scenes_page.dart @@ -29,12 +29,12 @@ class _ScenesPageState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final HashMap scenecsTemp = - await ConnectionsService.instance.getScenes(); + await ConnectionsService.instance.getScenes; final HashMap scenesInArea = HashMap.fromEntries( - widget.area.areaScenesId.getOrCrash().map((e) { + widget.area.scenesId.getOrCrash().map((e) { final SceneCbjEntity? scene = scenecsTemp[e]; if (scene == null) { return null; @@ -107,7 +107,7 @@ class _ScenesPageState extends State { // rightSecondIcon: FontAwesomeIcons.magnifyingGlass, ), Expanded( - child: ScenesGrid( + child: ScenesGridMolecule( scenes: scenes!.values.toList(), ), ), diff --git a/lib/presentation/pages/software_info_page.dart b/lib/presentation/pages/software_info_page.dart index fb1f0bb5d..98a68610e 100644 --- a/lib/presentation/pages/software_info_page.dart +++ b/lib/presentation/pages/software_info_page.dart @@ -67,7 +67,7 @@ class _SoftwareInfoWidgetState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { SoftwareInfoEntity? appInfoEntity; (await ISoftwareInfoRepository.instance.getAppSoftwareInfo()).fold( (l) => l, diff --git a/lib/presentation/pages/splash_page.dart b/lib/presentation/pages/splash_page.dart index ea0cda862..6c528ec64 100644 --- a/lib/presentation/pages/splash_page.dart +++ b/lib/presentation/pages/splash_page.dart @@ -28,16 +28,21 @@ class _SplashPageState extends State { } Future initilizeApp() async { + // TODO: can we remove await Hive.initFlutter(); AppCommands(); + // TODO: can we remove await Future.value([ IDbRepository.instance.initializeDb(isFlutter: true), ILocalDbRepository.instance.asyncConstructor(), // ISavedDevicesRepo.instance.setUpAllFromDb(), ]); + // TODO: can we remove MqttServerRepository(); + // TODO: Same as App Command? PhoneCommandsD(); SystemCommandsManager(); + // TODO: can we remove NodeRedRepository(); ConnectionsService.instance; _navigate();