diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 4f6986bd..f3bf9a07 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 c00f4767..0c4a1e42 100644 --- a/lib/domain/connections_service.dart +++ b/lib/domain/connections_service.dart @@ -73,4 +73,8 @@ abstract interface class ConnectionsService { Future activateScene(String id); Future addScene(SceneCbjEntity scene); + + Future loginVendor(VendorLoginEntity value); + + Future> getVendors(); } diff --git a/lib/infrastructure/connection_service/app_connection_service.dart b/lib/infrastructure/connection_service/app_connection_service.dart index a1b7a82f..620e997a 100644 --- a/lib/infrastructure/connection_service/app_connection_service.dart +++ b/lib/infrastructure/connection_service/app_connection_service.dart @@ -53,4 +53,12 @@ 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(); } diff --git a/lib/infrastructure/connection_service/demo_connection_service.dart b/lib/infrastructure/connection_service/demo_connection_service.dart index 555dfcb0..eb4c8165 100644 --- a/lib/infrastructure/connection_service/demo_connection_service.dart +++ b/lib/infrastructure/connection_service/demo_connection_service.dart @@ -52,4 +52,10 @@ class _DemoConnectionService implements ConnectionsService { @override Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => []; } diff --git a/lib/infrastructure/connection_service/none_connection_service.dart b/lib/infrastructure/connection_service/none_connection_service.dart index dabda1bd..d3a8f8d1 100644 --- a/lib/infrastructure/connection_service/none_connection_service.dart +++ b/lib/infrastructure/connection_service/none_connection_service.dart @@ -52,4 +52,10 @@ class _NoneConnectionService implements ConnectionsService { @override Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => []; } diff --git a/lib/presentation/atoms/switch_atom.dart b/lib/presentation/atoms/switch_atom.dart index 95b9d296..f75cd69e 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/core/entities_utils.dart b/lib/presentation/core/entities_utils.dart index 9ecb5a5b..912d3b0a 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.smartTypeNotSupported: + 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 cda391ab..903ba0d9 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,7 @@ class AppRouter extends $AppRouter { AutoRoute(page: ComputerConnectionCheckRoute.page), AutoRoute(page: EntitiesInNetworkRoute.page), AutoRoute(page: EntitiesInAreaRoute.page), + AutoRoute(page: LoginVendorRoute.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 a9560ecb..de7fec35 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.smartTypeNotSupported: + case EntityTypes.emptyEntity: + case EntityTypes.pingEntity: + case null: + return const SizedBox(); } } } diff --git a/lib/presentation/molecules/devices/ac_molecule.dart b/lib/presentation/molecules/devices/ac_molecule.dart new file mode 100644 index 00000000..fdef8ed9 --- /dev/null +++ b/lib/presentation/molecules/devices/ac_molecule.dart @@ -0,0 +1,87 @@ +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 VendorsAndServices? vendor = + widget.entity.cbjDeviceVendor.vendorsAndServices; + if (vendor == null) { + return; + } + final HashMap> uniqueIdByVendor = + HashMap(); + uniqueIdByVendor.addEntries( + [ + MapEntry( + vendor, + HashSet() + ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), + ), + ], + ); + + ConnectionsService.instance.setEntityState( + ActionObject( + uniqueIdByVendor: uniqueIdByVendor, + 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 DeviceNameRow( + 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/molecules.dart b/lib/presentation/molecules/molecules.dart index 7343aac4..f90f49b3 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 'devices/ac_molecule.dart'; export 'devices/blind_molecule.dart'; export 'devices/blinds_card_molecule.dart'; export 'devices/boiler_molecule.dart'; @@ -17,5 +18,5 @@ export 'devices/switch_molecule.dart'; export 'list_tile_molecule.dart'; export 'list_view_molecule.dart'; export 'loading_page_molecule.dart'; -export 'top_bar_molecule.dart'; export 'scenes_grid.dart'; +export 'top_bar_molecule.dart'; diff --git a/lib/presentation/organisms/devices_list_view.dart b/lib/presentation/organisms/devices_list_view.dart index 98811f2c..600f4891 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_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 e14224e2..cc5ce96b 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 f14efa69..000a7f61 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() { @@ -18,10 +19,12 @@ class _VendorsListState extends State { } Future initializeVendors() async { - final KtList temp = - (await IVendorsRepository.instance.getVendors()).fold( - (f) => [].toImmutableList(), - (vendorsListSuccess) => vendorsListSuccess, + final List temp = + await ConnectionsService.instance.getVendors(); + temp.removeWhere( + (element) => + element.vendorsAndServices == + VendorsAndServices.vendorsAndServicesNotSupported, ); setState(() { vendorsList = temp; @@ -30,6 +33,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 +44,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_routine/add_routine_page.dart b/lib/presentation/pages/add_routine/add_routine_page.dart index 3c5a4a56..36aba05f 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,9 +50,6 @@ class _AddRoutinePageState extends State { Set> allEntityActions = {}; bool showErrorMessages = false; bool isSubmitting = false; - dartz.Option> - authFailureOrSuccessOption = dartz.none(); - HashMap? entities; Future initialzeEntities() async { 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 b2d2d58c..00000000 --- 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 31d43e77..00000000 --- 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 b6f5a048..00000000 --- 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 c6a00314..00000000 --- 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 0eea2c53..00000000 --- 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 659d38c3..00000000 --- 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/choose_automation_type_to_add_page.dart b/lib/presentation/pages/choose_automation_type_to_add_page.dart index f93c6564..9f301304 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/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 964a62ac..557509dc 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/login_vendor_page.dart b/lib/presentation/pages/login_vendor_page.dart new file mode 100644 index 00000000..6d89125a --- /dev/null +++ b/lib/presentation/pages/login_vendor_page.dart @@ -0,0 +1,125 @@ +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:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.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 { + String? apiKey; + + Future _signInWithApiKey() async { + SnackBarService().show( + context, + 'Sign in to ${widget.vendorInformation.displayName}, devices will appear in the shortly', + ); + + ConnectionsService.instance.loginVendor( + VendorLoginEntity( + widget.vendorInformation.vendorsAndServices, + apiKey: apiKey, + ), + ); + context.router.pop(); + } + + @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, + ), + TextFormField( + decoration: const InputDecoration( + prefixIcon: FaIcon(FontAwesomeIcons.key), + labelText: 'value', + ), + autocorrect: false, + onChanged: (value) { + apiKey = value; + }, + ), + 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 ceb5e18f..5c3cb02a 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';