diff --git a/android/app/build.gradle b/android/app/build.gradle index 75ed15fd..8981dae5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,5 +1,9 @@ plugins { id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' + // END: FlutterFire Configuration id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" } diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 00000000..3cc77ccd --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,68 @@ +{ + "project_info": { + "project_number": "427332280600", + "firebase_url": "https://test2-8a3d2-default-rtdb.firebaseio.com", + "project_id": "test2-8a3d2", + "storage_bucket": "test2-8a3d2.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:427332280600:android:550f67441246cb1a0c7e6d", + "android_client_info": { + "package_name": "com.example.syncrow.app" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:427332280600:android:bb6047adeeb80fb00c7e6d", + "android_client_info": { + "package_name": "com.example.syncrow_application" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:427332280600:android:2bc36fbe82994a3e0c7e6d", + "android_client_info": { + "package_name": "com.example.syncrow_web" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/settings.gradle b/android/settings.gradle index 1d6d19b7..85edcfc9 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -20,6 +20,10 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "7.3.0" apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.15" apply false + id "com.google.firebase.crashlytics" version "2.8.1" apply false + // END: FlutterFire Configuration id "org.jetbrains.kotlin.android" version "1.7.10" apply false } diff --git a/firebase.json b/firebase.json new file mode 100644 index 00000000..fa1105a3 --- /dev/null +++ b/firebase.json @@ -0,0 +1 @@ +{"flutter":{"platforms":{"android":{"default":{"projectId":"test2-8a3d2","appId":"1:427332280600:android:2bc36fbe82994a3e0c7e6d","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"test2-8a3d2","appId":"1:427332280600:ios:14346b200780dc760c7e6d","uploadDebugSymbols":true,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"macos":{"default":{"projectId":"test2-8a3d2","appId":"1:427332280600:ios:14346b200780dc760c7e6d","uploadDebugSymbols":true,"fileOutput":"macos/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"test2-8a3d2","configurations":{"android":"1:427332280600:android:2bc36fbe82994a3e0c7e6d","ios":"1:427332280600:ios:14346b200780dc760c7e6d","macos":"1:427332280600:ios:14346b200780dc760c7e6d","web":"1:427332280600:web:ad50516a87a35a1a0c7e6d","windows":"1:427332280600:web:f7a25537ccd5a7bd0c7e6d"}}}}}} \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index dffe452f..4f245401 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; E44A9405B1EB1B638DD05A58 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */; }; + F2A3345EC3021060731668D3 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B14AB50E8716720E10D074BD /* GoogleService-Info.plist */; }; FF49F60EC38658783D8D66DA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ @@ -64,6 +65,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B14AB50E8716720E10D074BD /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; D3AD250AADBF93406007C9EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -138,6 +140,7 @@ 331C8082294A63A400263BE5 /* RunnerTests */, 1454C118FFCECEEDF59152D2 /* Pods */, 20A3C64D2B1CFED5A81C3251 /* Frameworks */, + B14AB50E8716720E10D074BD /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -199,6 +202,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */, + 7A77858F6F15CB76D2D3A872 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */, ); buildRules = ( ); @@ -264,6 +268,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + F2A3345EC3021060731668D3 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -303,6 +308,24 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 7A77858F6F15CB76D2D3A872 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\""; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\"\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --platform=ios --apple-project-path=\"${SRCROOT}\" --env-platform-name=\"${PLATFORM_NAME}\" --env-configuration=\"${CONFIGURATION}\" --env-project-dir=\"${PROJECT_DIR}\" --env-built-products-dir=\"${BUILT_PRODUCTS_DIR}\" --env-dwarf-dsym-folder-path=\"${DWARF_DSYM_FOLDER_PATH}\" --env-dwarf-dsym-file-name=\"${DWARF_DSYM_FILE_NAME}\" --env-infoplist-path=\"${INFOPLIST_PATH}\" --default-config=default\n"; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist new file mode 100644 index 00000000..9cdebed0 --- /dev/null +++ b/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,32 @@ + + + + + API_KEY + AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw + GCM_SENDER_ID + 427332280600 + PLIST_VERSION + 1 + BUNDLE_ID + com.example.syncrowWeb + PROJECT_ID + test2-8a3d2 + STORAGE_BUCKET + test2-8a3d2.firebasestorage.app + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:427332280600:ios:14346b200780dc760c7e6d + DATABASE_URL + https://test2-8a3d2-default-rtdb.firebaseio.com + + \ No newline at end of file diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 00000000..703411a9 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,93 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + return macos; + case TargetPlatform.windows: + return windows; + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyCVEvKsJYzhWDFM-9Od68FE0nPpP933st0', + appId: '1:427332280600:web:ad50516a87a35a1a0c7e6d', + messagingSenderId: '427332280600', + projectId: 'test2-8a3d2', + authDomain: 'test2-8a3d2.firebaseapp.com', + databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com', + storageBucket: 'test2-8a3d2.firebasestorage.app', + measurementId: 'G-Z1RTTTV5H9', + ); + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0', + appId: '1:427332280600:android:2bc36fbe82994a3e0c7e6d', + messagingSenderId: '427332280600', + projectId: 'test2-8a3d2', + databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com', + storageBucket: 'test2-8a3d2.firebasestorage.app', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw', + appId: '1:427332280600:ios:14346b200780dc760c7e6d', + messagingSenderId: '427332280600', + projectId: 'test2-8a3d2', + databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com', + storageBucket: 'test2-8a3d2.firebasestorage.app', + iosBundleId: 'com.example.syncrowWeb', + ); + + static const FirebaseOptions macos = FirebaseOptions( + apiKey: 'AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw', + appId: '1:427332280600:ios:14346b200780dc760c7e6d', + messagingSenderId: '427332280600', + projectId: 'test2-8a3d2', + databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com', + storageBucket: 'test2-8a3d2.firebasestorage.app', + iosBundleId: 'com.example.syncrowWeb', + ); + + static const FirebaseOptions windows = FirebaseOptions( + apiKey: 'AIzaSyDizKjPC5rdkEjDxwXjM-RU5unB0Ziq3iw', + appId: '1:427332280600:web:f7a25537ccd5a7bd0c7e6d', + messagingSenderId: '427332280600', + projectId: 'test2-8a3d2', + authDomain: 'test2-8a3d2.firebaseapp.com', + databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com', + storageBucket: 'test2-8a3d2.firebasestorage.app', + measurementId: 'G-4LFVXEXWKY', + ); +} diff --git a/lib/main.dart b/lib/main.dart index 0bf0b9d3..67880868 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,10 @@ +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:go_router/go_router.dart'; +import 'package:syncrow_web/firebase_options.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart'; import 'package:syncrow_web/pages/home/bloc/home_bloc.dart'; import 'package:syncrow_web/pages/home/bloc/home_event.dart'; @@ -17,9 +19,13 @@ import 'package:syncrow_web/utils/theme/theme.dart'; Future main() async { try { - const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development'); + const environment = + String.fromEnvironment('FLAVOR', defaultValue: 'development'); await dotenv.load(fileName: '.env.$environment'); WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); initialSetup(); } catch (_) {} runApp(MyApp()); @@ -49,7 +55,8 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())), + BlocProvider( + create: (context) => HomeBloc()..add(const FetchUserInfo())), BlocProvider( create: (context) => VisitorPasswordBloc(), ), diff --git a/lib/pages/device_managment/ac/bloc/ac_bloc.dart b/lib/pages/device_managment/ac/bloc/ac_bloc.dart index 7c6ee628..7c35034e 100644 --- a/lib/pages/device_managment/ac/bloc/ac_bloc.dart +++ b/lib/pages/device_managment/ac/bloc/ac_bloc.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'package:dio/dio.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; @@ -19,6 +20,7 @@ class AcBloc extends Bloc { on(_onAcControl); on(_onAcBatchControl); on(_onFactoryReset); + on(_onAcStatusUpdated); } FutureOr _onFetchAcStatus( @@ -28,12 +30,64 @@ class AcBloc extends Bloc { final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status); + _listenToChanges(event.deviceId); emit(ACStatusLoaded(deviceStatus)); } catch (e) { emit(AcsFailedState(error: e.toString())); } } + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) async { + if (event.snapshot.value == null) return; + + if (_timer != null) { + await Future.delayed(const Duration(seconds: 1)); + } + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + AcStatusModel.fromJson(usersMap['productUuid'], statusList); + if (!isClosed) { + add(AcStatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } + + void _onAcStatusUpdated(AcStatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(ACStatusLoaded(deviceStatus)); + } + + // Future testFirebaseConnection() async { + // // Reference to a test node in your database + // final testRef = FirebaseDatabase.instance.ref("test"); + + // // Write a test value + // await testRef.set("Hello, Firebase!"); + + // // Listen for changes on the test node + // testRef.onValue.listen((DatabaseEvent event) { + // final data = event.snapshot.value; + // print("Data from Firebase: $data"); + // // If you see "Hello, Firebase!" printed in your console, it means the connection works. + // }); + // } + FutureOr _onAcControl( AcControlEvent event, Emitter emit) async { final oldValue = _getValueByCode(event.code); diff --git a/lib/pages/device_managment/ac/bloc/ac_event.dart b/lib/pages/device_managment/ac/bloc/ac_event.dart index 8d49df96..5492e198 100644 --- a/lib/pages/device_managment/ac/bloc/ac_event.dart +++ b/lib/pages/device_managment/ac/bloc/ac_event.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; sealed class AcsEvent extends Equatable { @@ -7,6 +8,7 @@ sealed class AcsEvent extends Equatable { @override List get props => []; } +class AcUpdated extends AcsEvent {} class AcFetchDeviceStatusEvent extends AcsEvent { final String deviceId; @@ -16,7 +18,10 @@ class AcFetchDeviceStatusEvent extends AcsEvent { @override List get props => [deviceId]; } - +class AcStatusUpdated extends AcsEvent { + final AcStatusModel deviceStatus; + AcStatusUpdated(this.deviceStatus); +} class AcFetchBatchStatusEvent extends AcsEvent { final List devicesIds; diff --git a/lib/pages/device_managment/ac/view/ac_device_control.dart b/lib/pages/device_managment/ac/view/ac_device_control.dart index 5197d722..071344d7 100644 --- a/lib/pages/device_managment/ac/view/ac_device_control.dart +++ b/lib/pages/device_managment/ac/view/ac_device_control.dart @@ -24,7 +24,8 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout { final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => AcBloc(deviceId: device.uuid!)..add(AcFetchDeviceStatusEvent(device.uuid!)), + create: (context) => AcBloc(deviceId: device.uuid!) + ..add(AcFetchDeviceStatusEvent(device.uuid!)), child: BlocBuilder( builder: (context, state) { if (state is ACStatusLoaded) { @@ -98,7 +99,8 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout { ), Text( 'h', - style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor), + style: context.textTheme.bodySmall! + .copyWith(color: ColorsManager.blackColor), ), Text( '30', @@ -107,7 +109,9 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout { fontWeight: FontWeight.bold, ), ), - Text('m', style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor)), + Text('m', + style: context.textTheme.bodySmall! + .copyWith(color: ColorsManager.blackColor)), IconButton( padding: const EdgeInsets.all(0), onPressed: () {}, diff --git a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart index 4e13bfd6..4e8d5a8b 100644 --- a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart +++ b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart'; @@ -22,42 +23,55 @@ class CeilingSensorBloc extends Bloc { on(_showDescription); on(_backToGridView); on(_onFactoryReset); + on(_onStatusUpdated); } void _fetchCeilingSensorStatus( CeilingInitialEvent event, Emitter emit) async { emit(CeilingLoadingInitialState()); try { - var response = await DevicesManagementApi().getDeviceStatus(event.deviceId); + var response = + await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); - // _listenToChanges(); + _listenToChanges(event.deviceId); } catch (e) { emit(CeilingFailedState(error: e.toString())); return; } } - // _listenToChanges() { - // try { - // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - // Stream stream = ref.onValue; + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; - // stream.listen((DatabaseEvent event) { - // Map usersMap = event.snapshot.value as Map; - // List statusList = []; + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; - // usersMap['status'].forEach((element) { - // statusList.add(StatusModel(code: element['code'], value: element['value'])); - // }); + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); - // deviceStatus = WallSensorModel.fromJson(statusList); - // add(WallSensorUpdatedEvent()); - // }); - // } catch (_) {} - // } + deviceStatus = CeilingSensorModel.fromJson(statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } - void _changeValue(CeilingChangeValueEvent event, Emitter emit) async { + void _onStatusUpdated(StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); + } + + void _changeValue( + CeilingChangeValueEvent event, Emitter emit) async { emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus)); if (event.code == 'sensitivity') { deviceStatus.sensitivity = event.value; @@ -122,7 +136,8 @@ class CeilingSensorBloc extends Bloc { try { late bool response; if (isBatch) { - response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value); + response = await DevicesManagementApi() + .deviceBatchControl(deviceId, code, value); } else { response = await DevicesManagementApi() .deviceControl(deviceId, Status(code: code, value: value)); @@ -143,8 +158,8 @@ class CeilingSensorBloc extends Bloc { }); } - FutureOr _getDeviceReports( - GetCeilingDeviceReportsEvent event, Emitter emit) async { + FutureOr _getDeviceReports(GetCeilingDeviceReportsEvent event, + Emitter emit) async { if (event.code.isEmpty) { emit(ShowCeilingDescriptionState(description: reportString)); return; @@ -155,7 +170,8 @@ class CeilingSensorBloc extends Bloc { try { // await DevicesManagementApi.getDeviceReportsByDate(deviceId, event.code, from.toString(), to.toString()) - await DevicesManagementApi.getDeviceReports(deviceId, event.code).then((value) { + await DevicesManagementApi.getDeviceReports(deviceId, event.code) + .then((value) { emit(CeilingReportsState(deviceReport: value)); }); } catch (e) { @@ -165,19 +181,23 @@ class CeilingSensorBloc extends Bloc { } } - void _showDescription(ShowCeilingDescriptionEvent event, Emitter emit) { + void _showDescription( + ShowCeilingDescriptionEvent event, Emitter emit) { emit(ShowCeilingDescriptionState(description: event.description)); } - void _backToGridView(BackToCeilingGridViewEvent event, Emitter emit) { + void _backToGridView( + BackToCeilingGridViewEvent event, Emitter emit) { emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); } FutureOr _fetchCeilingSensorBatchControl( - CeilingFetchDeviceStatusEvent event, Emitter emit) async { + CeilingFetchDeviceStatusEvent event, + Emitter emit) async { emit(CeilingLoadingInitialState()); try { - var response = await DevicesManagementApi().getBatchStatus(event.devicesIds); + var response = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); } catch (e) { diff --git a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart index 582c9836..1dc7d8d7 100644 --- a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart +++ b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart @@ -1,5 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; +import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart'; abstract class CeilingSensorEvent extends Equatable { const CeilingSensorEvent(); @@ -83,3 +84,12 @@ class CeilingFactoryResetEvent extends CeilingSensorEvent { @override List get props => [devicesId, factoryResetModel]; } + + + +class StatusUpdated extends CeilingSensorEvent { + final CeilingSensorModel deviceStatus; + const StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} diff --git a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart index 4599f360..f4bedd1c 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart'; @@ -32,6 +33,36 @@ class CurtainBloc extends Bloc { emit(CurtainError(e.toString())); } } + // _listenToChanges(deviceId) { + // try { + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$deviceId'); + // Stream stream = ref.onValue; + + // stream.listen((DatabaseEvent event) { + // Map usersMap = + // event.snapshot.value as Map; + + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(Status(code: element['code'], value: element['value'])); + // }); + + // deviceStatus = + // GarageDoorStatusModel.fromJson(usersMap['productUuid'], statusList); + // if (!isClosed) { + // add(StatusUpdated(deviceStatus)); + // } + // }); + // } catch (_) {} + // } + + // void _onStatusUpdated(StatusUpdated event, Emitter emit) { + // deviceStatus = event.deviceStatus; + // emit(GarageDoorLoadedState(status: deviceStatus)); + // } + FutureOr _onCurtainControl( CurtainControl event, Emitter emit) async { diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart index 7060c668..025de303 100644 --- a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart +++ b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart'; @@ -39,31 +40,68 @@ class GarageDoorBloc extends Bloc { on(_onFetchBatchStatus); on(_onFactoryReset); on(_onEditSchedule); + on(_onStatusUpdated); + } + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + GarageDoorStatusModel.fromJson(usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} } - void _fetchGarageDoorStatus(GarageDoorInitialEvent event, Emitter emit) async { + void _onStatusUpdated(StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(GarageDoorLoadedState(status: deviceStatus)); + } + + void _fetchGarageDoorStatus( + GarageDoorInitialEvent event, Emitter emit) async { emit(GarageDoorLoadingState()); try { - var response = await DevicesManagementApi().getDeviceStatus(event.deviceId); + var response = + await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status); + _listenToChanges(deviceId); emit(GarageDoorLoadedState(status: deviceStatus)); } catch (e) { emit(GarageDoorErrorState(message: e.toString())); } } - Future _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, Emitter emit) async { + Future _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, + Emitter emit) async { emit(GarageDoorLoadingState()); try { - final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status); + final status = + await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = + GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status); emit(GarageDoorBatchStatusLoaded(deviceStatus)); } catch (e) { emit(GarageDoorBatchControlError(e.toString())); } } - Future _addSchedule(AddGarageDoorScheduleEvent event, Emitter emit) async { + Future _addSchedule( + AddGarageDoorScheduleEvent event, Emitter emit) async { try { ScheduleEntry newSchedule = ScheduleEntry( category: event.category, @@ -71,9 +109,11 @@ class GarageDoorBloc extends Bloc { function: Status(code: 'switch_1', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId); + bool success = + await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId); if (success) { - add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1')); + add(FetchGarageDoorSchedulesEvent( + deviceId: deviceId, category: 'switch_1')); } else { emit(GarageDoorLoadedState(status: deviceStatus)); } @@ -82,16 +122,19 @@ class GarageDoorBloc extends Bloc { } } - void _onUpdateCountdownAlarm(UpdateCountdownAlarmEvent event, Emitter emit) { + void _onUpdateCountdownAlarm( + UpdateCountdownAlarmEvent event, Emitter emit) { final currentState = state; if (currentState is GarageDoorLoadedState) { emit(currentState.copyWith( - status: currentState.status.copyWith(countdownAlarm: event.countdownAlarm), + status: + currentState.status.copyWith(countdownAlarm: event.countdownAlarm), )); } } - void _onUpdateTrTimeCon(UpdateTrTimeConEvent event, Emitter emit) { + void _onUpdateTrTimeCon( + UpdateTrTimeConEvent event, Emitter emit) { final currentState = state; if (currentState is GarageDoorLoadedState) { emit(currentState.copyWith( @@ -100,7 +143,8 @@ class GarageDoorBloc extends Bloc { } } - Future _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter emit) async { + Future _updateSchedule(UpdateGarageDoorScheduleEvent event, + Emitter emit) async { try { final updatedSchedules = deviceStatus.schedules?.map((schedule) { if (schedule.scheduleId == event.scheduleId) { @@ -127,12 +171,15 @@ class GarageDoorBloc extends Bloc { } } - Future _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter emit) async { + Future _deleteSchedule(DeleteGarageDoorScheduleEvent event, + Emitter emit) async { try { - bool success = await DevicesManagementApi().deleteScheduleRecord(deviceStatus.uuid, event.scheduleId); + bool success = await DevicesManagementApi() + .deleteScheduleRecord(deviceStatus.uuid, event.scheduleId); if (success) { - final updatedSchedules = - deviceStatus.schedules?.where((schedule) => schedule.scheduleId != event.scheduleId).toList(); + final updatedSchedules = deviceStatus.schedules + ?.where((schedule) => schedule.scheduleId != event.scheduleId) + .toList(); deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules); emit(GarageDoorLoadedState(status: deviceStatus)); } else { @@ -143,11 +190,12 @@ class GarageDoorBloc extends Bloc { } } - Future _fetchSchedules(FetchGarageDoorSchedulesEvent event, Emitter emit) async { + Future _fetchSchedules(FetchGarageDoorSchedulesEvent event, + Emitter emit) async { emit(ScheduleGarageLoadingState()); try { - List schedules = - await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category); + List schedules = await DevicesManagementApi() + .getDeviceSchedules(deviceStatus.uuid, event.category); deviceStatus = deviceStatus.copyWith(schedules: schedules); emit( GarageDoorLoadedState( @@ -165,30 +213,37 @@ class GarageDoorBloc extends Bloc { } } - Future _updateSelectedTime(UpdateSelectedTimeEvent event, Emitter emit) async { + Future _updateSelectedTime( + UpdateSelectedTimeEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { emit(currentState.copyWith(selectedTime: event.selectedTime)); } } - Future _updateSelectedDay(UpdateSelectedDayEvent event, Emitter emit) async { + Future _updateSelectedDay( + UpdateSelectedDayEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { List updatedDays = List.from(currentState.selectedDays); updatedDays[event.dayIndex] = event.isSelected; - emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime)); + emit(currentState.copyWith( + selectedDays: updatedDays, selectedTime: currentState.selectedTime)); } } - Future _updateFunctionOn(UpdateFunctionOnEvent event, Emitter emit) async { + Future _updateFunctionOn( + UpdateFunctionOnEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { - emit(currentState.copyWith(functionOn: event.functionOn, selectedTime: currentState.selectedTime)); + emit(currentState.copyWith( + functionOn: event.functionOn, + selectedTime: currentState.selectedTime)); } } - Future _initializeAddSchedule(InitializeAddScheduleEvent event, Emitter emit) async { + Future _initializeAddSchedule( + InitializeAddScheduleEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { emit(currentState.copyWith( @@ -200,20 +255,25 @@ class GarageDoorBloc extends Bloc { } } - Future _fetchRecords(FetchGarageDoorRecordsEvent event, Emitter emit) async { + Future _fetchRecords( + FetchGarageDoorRecordsEvent event, Emitter emit) async { emit(GarageDoorReportsLoadingState()); try { - final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; + final from = DateTime.now() + .subtract(const Duration(days: 30)) + .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; final DeviceReport records = - await DevicesManagementApi.getDeviceReportsByDate(event.deviceId, 'switch_1', from.toString(), to.toString()); + await DevicesManagementApi.getDeviceReportsByDate( + event.deviceId, 'switch_1', from.toString(), to.toString()); emit(GarageDoorReportsState(deviceReport: records)); } catch (e) { emit(GarageDoorReportsFailedState(error: e.toString())); } } - Future _onBatchControl(GarageDoorBatchControlEvent event, Emitter emit) async { + Future _onBatchControl( + GarageDoorBatchControlEvent event, Emitter emit) async { final oldValue = event.code == 'switch_1' ? deviceStatus.switch1 : false; _updateLocalValue(event.code, event.value); @@ -233,11 +293,13 @@ class GarageDoorBloc extends Bloc { } } - void _backToGridView(BackToGarageDoorGridViewEvent event, Emitter emit) { + void _backToGridView( + BackToGarageDoorGridViewEvent event, Emitter emit) { emit(GarageDoorLoadedState(status: deviceStatus)); } - void _handleUpdate(GarageDoorUpdatedEvent event, Emitter emit) { + void _handleUpdate( + GarageDoorUpdatedEvent event, Emitter emit) { emit(GarageDoorLoadedState(status: deviceStatus)); } @@ -253,9 +315,11 @@ class GarageDoorBloc extends Bloc { late bool status; await Future.delayed(const Duration(milliseconds: 500)); if (isBatch) { - status = await DevicesManagementApi().deviceBatchControl(deviceId, code, value); + status = await DevicesManagementApi() + .deviceBatchControl(deviceId, code, value); } else { - status = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value)); + status = await DevicesManagementApi() + .deviceControl(deviceId, Status(code: code, value: value)); } if (!status) { @@ -270,10 +334,12 @@ class GarageDoorBloc extends Bloc { } } - Future _onFactoryReset(GarageDoorFactoryResetEvent event, Emitter emit) async { + Future _onFactoryReset( + GarageDoorFactoryResetEvent event, Emitter emit) async { emit(GarageDoorLoadingState()); try { - final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId); + final response = await DevicesManagementApi() + .factoryReset(event.factoryReset, event.deviceId); if (!response) { emit(const GarageDoorErrorState(message: 'Failed to reset device')); } else { @@ -284,34 +350,47 @@ class GarageDoorBloc extends Bloc { } } - void _increaseDelay(IncreaseGarageDoorDelayEvent event, Emitter emit) async { + void _increaseDelay( + IncreaseGarageDoorDelayEvent event, Emitter emit) async { // if (deviceStatus.countdown1 != 0) { try { - deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay + Duration(minutes: 10)); + deviceStatus = deviceStatus.copyWith( + delay: deviceStatus.delay + Duration(minutes: 10)); emit(GarageDoorLoadedState(status: deviceStatus)); - add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1')); + add(GarageDoorControlEvent( + deviceId: event.deviceId, + value: deviceStatus.delay.inSeconds, + code: 'countdown_1')); } catch (e) { emit(GarageDoorErrorState(message: e.toString())); } // } } - void _decreaseDelay(DecreaseGarageDoorDelayEvent event, Emitter emit) async { + void _decreaseDelay( + DecreaseGarageDoorDelayEvent event, Emitter emit) async { // if (deviceStatus.countdown1 != 0) { try { if (deviceStatus.delay.inMinutes > 10) { - deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay - Duration(minutes: 10)); + deviceStatus = deviceStatus.copyWith( + delay: deviceStatus.delay - Duration(minutes: 10)); } emit(GarageDoorLoadedState(status: deviceStatus)); - add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1')); + add(GarageDoorControlEvent( + deviceId: event.deviceId, + value: deviceStatus.delay.inSeconds, + code: 'countdown_1')); } catch (e) { emit(GarageDoorErrorState(message: e.toString())); } //} } - void _garageDoorControlEvent(GarageDoorControlEvent event, Emitter emit) async { - final oldValue = event.code == 'countdown_1' ? deviceStatus.countdown1 : deviceStatus.switch1; + void _garageDoorControlEvent( + GarageDoorControlEvent event, Emitter emit) async { + final oldValue = event.code == 'countdown_1' + ? deviceStatus.countdown1 + : deviceStatus.switch1; _updateLocalValue(event.code, event.value); emit(GarageDoorLoadedState(status: deviceStatus)); final success = await _runDeBouncer( @@ -327,7 +406,8 @@ class GarageDoorBloc extends Bloc { } } - void _revertValue(String code, dynamic oldValue, Emitter emit) { + void _revertValue( + String code, dynamic oldValue, Emitter emit) { switch (code) { case 'switch_1': if (oldValue is bool) { @@ -336,7 +416,8 @@ class GarageDoorBloc extends Bloc { break; case 'countdown_1': if (oldValue is int) { - deviceStatus = deviceStatus.copyWith(countdown1: oldValue, delay: Duration(seconds: oldValue)); + deviceStatus = deviceStatus.copyWith( + countdown1: oldValue, delay: Duration(seconds: oldValue)); } break; // Add other cases if needed @@ -358,7 +439,8 @@ class GarageDoorBloc extends Bloc { break; case 'countdown_1': if (value is int) { - deviceStatus = deviceStatus.copyWith(countdown1: value, delay: Duration(seconds: value)); + deviceStatus = deviceStatus.copyWith( + countdown1: value, delay: Duration(seconds: value)); } break; case 'countdown_alarm': @@ -401,7 +483,8 @@ class GarageDoorBloc extends Bloc { return super.close(); } - FutureOr _onEditSchedule(EditGarageDoorScheduleEvent event, Emitter emit) async { + FutureOr _onEditSchedule( + EditGarageDoorScheduleEvent event, Emitter emit) async { try { ScheduleEntry newSchedule = ScheduleEntry( scheduleId: event.scheduleId, @@ -410,9 +493,11 @@ class GarageDoorBloc extends Bloc { function: Status(code: 'switch_1', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - bool success = await DevicesManagementApi().editScheduleRecord(deviceId, newSchedule); + bool success = await DevicesManagementApi() + .editScheduleRecord(deviceId, newSchedule); if (success) { - add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1')); + add(FetchGarageDoorSchedulesEvent( + deviceId: deviceId, category: 'switch_1')); } else { emit(GarageDoorLoadedState(status: deviceStatus)); } diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart index d1fb15bb..fc625e32 100644 --- a/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart +++ b/lib/pages/device_managment/garage_door/bloc/garage_door_event.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; +import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart'; abstract class GarageDoorEvent extends Equatable { const GarageDoorEvent(); @@ -25,7 +26,8 @@ class GarageDoorControlEvent extends GarageDoorEvent { final dynamic value; final String code; - const GarageDoorControlEvent({required this.deviceId, required this.value, required this.code}); + const GarageDoorControlEvent( + {required this.deviceId, required this.value, required this.code}); @override List get props => [deviceId, value]; @@ -121,7 +123,8 @@ class FetchGarageDoorRecordsEvent extends GarageDoorEvent { final String deviceId; final String code; - const FetchGarageDoorRecordsEvent({required this.deviceId, required this.code}); + const FetchGarageDoorRecordsEvent( + {required this.deviceId, required this.code}); @override List get props => [deviceId, code]; @@ -232,3 +235,10 @@ class GarageDoorFactoryResetEvent extends GarageDoorEvent { @override List get props => [factoryReset, deviceId]; } + +class StatusUpdated extends GarageDoorEvent { + final GarageDoorStatusModel deviceStatus; + const StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} diff --git a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart index 595e7e06..db5ceddb 100644 --- a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart +++ b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/one_gang_switch/bloc/wall_light_switch_event.dart'; @@ -31,12 +32,44 @@ class WallLightSwitchBloc deviceStatus = WallLightStatusModel.fromJson(event.deviceId, status.status); + _listenToChanges(event.deviceId); emit(WallLightSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(WallLightSwitchError(e.toString())); } } + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + WallLightStatusModel.fromJson(usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } + + void _onStatusUpdated( + StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(WallLightSwitchStatusLoaded(deviceStatus)); + } + FutureOr _onControl( WallLightSwitchControl event, Emitter emit) async { final oldValue = _getValueByCode(event.code); diff --git a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_event.dart b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_event.dart index 5c601484..45b6e4d1 100644 --- a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_event.dart +++ b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_event.dart @@ -1,5 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; +import 'package:syncrow_web/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart'; class WallLightSwitchEvent extends Equatable { @override @@ -57,3 +58,10 @@ class WallLightFactoryReset extends WallLightSwitchEvent { @override List get props => [deviceId, factoryReset]; } + +class StatusUpdated extends WallLightSwitchEvent { + final WallLightStatusModel deviceStatus; + StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} diff --git a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart index 8e3c109e..174cd167 100644 --- a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:meta/meta.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; @@ -10,7 +11,8 @@ import 'package:syncrow_web/services/devices_mang_api.dart'; part 'three_gang_glass_switch_event.dart'; part 'three_gang_glass_switch_state.dart'; -class ThreeGangGlassSwitchBloc extends Bloc { +class ThreeGangGlassSwitchBloc + extends Bloc { ThreeGangGlassStatusModel deviceStatus; Timer? _timer; @@ -29,21 +31,57 @@ class ThreeGangGlassSwitchBloc extends Bloc(_onBatchControl); on(_onFetchBatchStatus); on(_onFactoryReset); + on(_onStatusUpdated); } - Future _onFetchDeviceStatus( - ThreeGangGlassSwitchFetchDeviceEvent event, Emitter emit) async { + Future _onFetchDeviceStatus(ThreeGangGlassSwitchFetchDeviceEvent event, + Emitter emit) async { emit(ThreeGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = + ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status); + _listenToChanges(event.deviceId); emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(ThreeGangGlassSwitchError(e.toString())); } } - Future _onControl(ThreeGangGlassSwitchControl event, Emitter emit) async { + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = ThreeGangGlassStatusModel.fromJson( + usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } + + void _onStatusUpdated( + StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus)); + } + + Future _onControl(ThreeGangGlassSwitchControl event, + Emitter emit) async { final oldValue = _getValueByCode(event.code); _updateLocalValue(event.code, event.value); @@ -59,7 +97,8 @@ class ThreeGangGlassSwitchBloc extends Bloc _onBatchControl(ThreeGangGlassSwitchBatchControl event, Emitter emit) async { + Future _onBatchControl(ThreeGangGlassSwitchBatchControl event, + Emitter emit) async { final oldValue = _getValueByCode(event.code); _updateLocalValue(event.code, event.value); @@ -76,21 +115,26 @@ class ThreeGangGlassSwitchBloc extends Bloc _onFetchBatchStatus( - ThreeGangGlassSwitchFetchBatchStatusEvent event, Emitter emit) async { + ThreeGangGlassSwitchFetchBatchStatusEvent event, + Emitter emit) async { emit(ThreeGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceIds.first, status.status); + final status = + await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = ThreeGangGlassStatusModel.fromJson( + event.deviceIds.first, status.status); emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus)); } catch (e) { emit(ThreeGangGlassSwitchError(e.toString())); } } - Future _onFactoryReset(ThreeGangGlassFactoryReset event, Emitter emit) async { + Future _onFactoryReset(ThreeGangGlassFactoryReset event, + Emitter emit) async { emit(ThreeGangGlassSwitchLoading()); try { - final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId); + final response = await DevicesManagementApi() + .factoryReset(event.factoryReset, event.deviceId); if (!response) { emit(ThreeGangGlassSwitchError('Failed')); } else { @@ -124,9 +168,11 @@ class ThreeGangGlassSwitchBloc extends Bloc emit) { + void _revertValueAndEmit(String deviceId, String code, bool oldValue, + Emitter emit) { _updateLocalValue(code, oldValue); emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus)); } diff --git a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_event.dart b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_event.dart index 558b9824..82b93fba 100644 --- a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_event.dart +++ b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_event.dart @@ -49,3 +49,10 @@ class ThreeGangGlassFactoryReset extends ThreeGangGlassSwitchEvent { required this.factoryReset, }); } + +class StatusUpdated extends ThreeGangGlassSwitchEvent { + final ThreeGangGlassStatusModel deviceStatus; + StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} diff --git a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart index ca264c13..f64ef314 100644 --- a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart +++ b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; @@ -22,6 +23,7 @@ class LivingRoomBloc extends Bloc { on(_livingRoomBatchControl); on(_livingRoomFetchBatchControl); on(_livingRoomFactoryReset); + on(_onStatusUpdated); } FutureOr _onFetchDeviceStatus(LivingRoomFetchDeviceStatusEvent event, @@ -32,6 +34,7 @@ class LivingRoomBloc extends Bloc { await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = LivingRoomStatusModel.fromJson(event.deviceId, status.status); + _listenToChanges(deviceId); emit(LivingRoomDeviceStatusLoaded(deviceStatus)); } catch (e) { emit(LivingRoomDeviceManagementError(e.toString())); @@ -185,4 +188,34 @@ class LivingRoomBloc extends Bloc { emit(LivingRoomDeviceManagementError(e.toString())); } } + + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + LivingRoomStatusModel.fromJson(usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } + + void _onStatusUpdated(StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(LivingRoomDeviceStatusLoaded(deviceStatus)); + } } diff --git a/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart b/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart index c0ada0f6..d1776d52 100644 --- a/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart +++ b/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart @@ -58,3 +58,10 @@ class LivingRoomFactoryResetEvent extends LivingRoomEvent { @override List get props => [uuid, factoryReset]; } + +class StatusUpdated extends LivingRoomEvent { + final LivingRoomStatusModel deviceStatus; + const StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} diff --git a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart index 5169b0e4..eece65a1 100644 --- a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:meta/meta.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; @@ -38,6 +39,7 @@ class TwoGangGlassSwitchBloc await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceId, status.status); + _listenToChanges(event.deviceId); emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(TwoGangGlassSwitchError(e.toString())); @@ -178,4 +180,57 @@ class TwoGangGlassSwitchBloc _timer?.cancel(); return super.close(); } + + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + TwoGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } + + void _onStatusUpdated(StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); + } + + + // _listenToChanges(deviceId, Emitter emit) { + // try { + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$deviceId'); + // Stream stream = ref.onValue; + + // stream.listen((DatabaseEvent event) { + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + + // usersMap['status'].forEach((element) { + // statusList + // .add(Status(code: element['code'], value: element['value'])); + // }); + + // deviceStatus = TwoGangGlassStatusModel.fromJson(deviceId, statusList); + // emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); + // }); + // } catch (_) {} + // } } diff --git a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_event.dart b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_event.dart index f88d61fe..02b61bd0 100644 --- a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_event.dart +++ b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_event.dart @@ -48,3 +48,11 @@ class TwoGangGlassFactoryReset extends TwoGangGlassSwitchEvent { required this.factoryReset, }); } + +class StatusUpdated extends TwoGangGlassSwitchEvent { + final TwoGangGlassStatusModel deviceStatus; + StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} + diff --git a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart index 0d35d8e8..788d8676 100644 --- a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart +++ b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart'; @@ -14,6 +15,7 @@ class TwoGangSwitchBloc extends Bloc { on(_onFetchBatchStatus); on(_onBatchControl); on(_onFactoryReset); + on(_onStatusUpdated); } late TwoGangStatusModel deviceStatus; @@ -26,8 +28,8 @@ class TwoGangSwitchBloc extends Bloc { try { final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = TwoGangStatusModel.fromJson(event.deviceId, status.status); + _listenToChanges(emit); emit(TwoGangSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(TwoGangSwitchError(e.toString())); @@ -174,4 +176,34 @@ class TwoGangSwitchBloc extends Bloc { emit(TwoGangSwitchError(e.toString())); } } + + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + TwoGangStatusModel.fromJson(usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } + + void _onStatusUpdated(StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(TwoGangSwitchStatusLoaded(deviceStatus)); + } } diff --git a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart index 16973b3a..b45fd11f 100644 --- a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart +++ b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart @@ -1,5 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; +import 'package:syncrow_web/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart'; class TwoGangSwitchEvent extends Equatable { @override @@ -57,3 +58,10 @@ class TwoGangFactoryReset extends TwoGangSwitchEvent { @override List get props => [deviceId, factoryReset]; } + +class StatusUpdated extends TwoGangSwitchEvent { + final TwoGangStatusModel deviceStatus; + StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} diff --git a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart index 41598439..a8a52fff 100644 --- a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart +++ b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_event.dart'; @@ -29,7 +30,7 @@ class WallSensorBloc extends Bloc { var response = await DevicesManagementApi().getDeviceStatus(deviceId); deviceStatus = WallSensorModel.fromJson(response.status); emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); - // _listenToChanges(); + _listenToChanges(emit); } catch (e) { emit(WallSensorFailedState(error: e.toString())); return; @@ -38,10 +39,12 @@ class WallSensorBloc extends Bloc { // Fetch batch status FutureOr _fetchWallSensorBatchControl( - WallSensorFetchBatchStatusEvent event, Emitter emit) async { + WallSensorFetchBatchStatusEvent event, + Emitter emit) async { emit(WallSensorLoadingInitialState()); try { - var response = await DevicesManagementApi().getBatchStatus(event.devicesIds); + var response = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = WallSensorModel.fromJson(response.status); emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); } catch (e) { @@ -49,26 +52,30 @@ class WallSensorBloc extends Bloc { } } - // _listenToChanges() { - // try { - // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - // Stream stream = ref.onValue; + _listenToChanges(Emitter emit) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; - // stream.listen((DatabaseEvent event) { - // Map usersMap = event.snapshot.value as Map; - // List statusList = []; + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + List statusList = []; - // usersMap['status'].forEach((element) { - // statusList.add(StatusModel(code: element['code'], value: element['value'])); - // }); + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); - // deviceStatus = WallSensorModel.fromJson(statusList); - // add(WallSensorUpdatedEvent()); - // }); - // } catch (_) {} - // } + deviceStatus = WallSensorModel.fromJson(statusList); + emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus)); + }); + } catch (_) {} + } - void _changeValue(WallSensorChangeValueEvent event, Emitter emit) async { + void _changeValue( + WallSensorChangeValueEvent event, Emitter emit) async { emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus)); if (event.code == 'far_detection') { deviceStatus.farDetection = event.value; @@ -125,7 +132,8 @@ class WallSensorBloc extends Bloc { try { late bool response; if (isBatch) { - response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value); + response = await DevicesManagementApi() + .deviceBatchControl(deviceId, code, value); } else { response = await DevicesManagementApi() .deviceControl(deviceId, Status(code: code, value: value)); @@ -150,7 +158,8 @@ class WallSensorBloc extends Bloc { try { // await DevicesManagementApi.getDeviceReportsByDate( // deviceId, event.code, from.toString(), to.toString()) - await DevicesManagementApi.getDeviceReports(deviceId, event.code).then((value) { + await DevicesManagementApi.getDeviceReports(deviceId, event.code) + .then((value) { emit(DeviceReportsState(deviceReport: value, code: event.code)); }); } catch (e) { @@ -159,11 +168,13 @@ class WallSensorBloc extends Bloc { } } - void _showDescription(ShowDescriptionEvent event, Emitter emit) { + void _showDescription( + ShowDescriptionEvent event, Emitter emit) { emit(WallSensorShowDescriptionState(description: event.description)); } - void _backToGridView(BackToGridViewEvent event, Emitter emit) { + void _backToGridView( + BackToGridViewEvent event, Emitter emit) { emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); } diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart index 498c55fb..18a0787f 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart'; @@ -34,6 +35,7 @@ class WaterHeaterBloc extends Bloc { on(_onEditSchedule); on(_onDeleteSchedule); on(_onUpdateSchedule); + on(_onStatusUpdated); } late WaterHeaterStatusModel deviceStatus; @@ -78,7 +80,8 @@ class WaterHeaterBloc extends Bloc { final currentState = state as WaterHeaterDeviceStatusLoaded; final updatedDays = List.from(currentState.selectedDays); updatedDays[event.index] = event.value; - emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime)); + emit(currentState.copyWith( + selectedDays: updatedDays, selectedTime: currentState.selectedTime)); } FutureOr _updateFunctionOn( @@ -86,7 +89,8 @@ class WaterHeaterBloc extends Bloc { Emitter emit, ) { final currentState = state as WaterHeaterDeviceStatusLoaded; - emit(currentState.copyWith(functionOn: event.isOn, selectedTime: currentState.selectedTime)); + emit(currentState.copyWith( + functionOn: event.isOn, selectedTime: currentState.selectedTime)); } FutureOr _updateScheduleEvent( @@ -101,7 +105,8 @@ class WaterHeaterBloc extends Bloc { )); } if (event.scheduleMode == ScheduleModes.countdown) { - final countdownRemaining = Duration(hours: event.hours, minutes: event.minutes); + final countdownRemaining = + Duration(hours: event.hours, minutes: event.minutes); emit(currentState.copyWith( scheduleMode: ScheduleModes.countdown, @@ -111,11 +116,13 @@ class WaterHeaterBloc extends Bloc { countdownRemaining: countdownRemaining, )); - if (!currentState.isCountdownActive! && countdownRemaining > Duration.zero) { + if (!currentState.isCountdownActive! && + countdownRemaining > Duration.zero) { _startCountdownTimer(emit, countdownRemaining); } } else if (event.scheduleMode == ScheduleModes.inching) { - final inchingDuration = Duration(hours: event.hours, minutes: event.minutes); + final inchingDuration = + Duration(hours: event.hours, minutes: event.minutes); emit(currentState.copyWith( scheduleMode: ScheduleModes.inching, @@ -217,7 +224,8 @@ class WaterHeaterBloc extends Bloc { try { final status = await DevicesManagementApi().deviceControl( event.deviceId, - Status(code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), + Status( + code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), ); if (!status) { emit(const WaterHeaterFailedState(error: 'Failed to stop schedule.')); @@ -235,8 +243,10 @@ class WaterHeaterBloc extends Bloc { emit(WaterHeaterLoadingState()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = WaterHeaterStatusModel.fromJson(event.deviceId, status.status); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = + WaterHeaterStatusModel.fromJson(event.deviceId, status.status); if (deviceStatus.scheduleMode == ScheduleModes.countdown) { final countdownRemaining = Duration( @@ -300,11 +310,42 @@ class WaterHeaterBloc extends Bloc { isInchingActive: false, )); } + _listenToChanges(event.deviceId); } catch (e) { emit(WaterHeaterFailedState(error: e.toString())); } } + _listenToChanges(deviceId) { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = WaterHeaterStatusModel.fromJson( + usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus)); + } + }); + } catch (_) {} + } + + void _onStatusUpdated(StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(WaterHeaterDeviceStatusLoaded(deviceStatus)); + } + void _startCountdownTimer( Emitter emit, Duration countdownRemaining, @@ -334,8 +375,10 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - if (currentState.countdownRemaining != null && currentState.countdownRemaining! > Duration.zero) { - final newRemaining = currentState.countdownRemaining! - const Duration(minutes: 1); + if (currentState.countdownRemaining != null && + currentState.countdownRemaining! > Duration.zero) { + final newRemaining = + currentState.countdownRemaining! - const Duration(minutes: 1); if (newRemaining <= Duration.zero) { _countdownTimer?.cancel(); @@ -430,7 +473,8 @@ class WaterHeaterBloc extends Bloc { } } - void _revertValue(String code, dynamic oldValue, void Function(WaterHeaterState state) emit) { + void _revertValue(String code, dynamic oldValue, + void Function(WaterHeaterState state) emit) { _updateLocalValue(code, oldValue); if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; @@ -477,12 +521,13 @@ class WaterHeaterBloc extends Bloc { return super.close(); } - FutureOr _getSchedule(GetSchedulesEvent event, Emitter emit) async { + FutureOr _getSchedule( + GetSchedulesEvent event, Emitter emit) async { emit(ScheduleLoadingState()); try { - List schedules = - await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category); + List schedules = await DevicesManagementApi() + .getDeviceSchedules(deviceStatus.uuid, event.category); emit(WaterHeaterDeviceStatusLoaded( deviceStatus, @@ -514,7 +559,8 @@ class WaterHeaterBloc extends Bloc { // emit(ScheduleLoadingState()); - bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, currentState.status.uuid); + bool success = await DevicesManagementApi() + .addScheduleRecord(newSchedule, currentState.status.uuid); if (success) { add(GetSchedulesEvent(category: 'switch_1', uuid: deviceStatus.uuid)); @@ -525,7 +571,8 @@ class WaterHeaterBloc extends Bloc { } } - FutureOr _onEditSchedule(EditWaterHeaterScheduleEvent event, Emitter emit) async { + FutureOr _onEditSchedule(EditWaterHeaterScheduleEvent event, + Emitter emit) async { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; @@ -594,11 +641,13 @@ class WaterHeaterBloc extends Bloc { // emit(ScheduleLoadingState()); - bool success = await DevicesManagementApi().deleteScheduleRecord(currentState.status.uuid, event.scheduleId); + bool success = await DevicesManagementApi() + .deleteScheduleRecord(currentState.status.uuid, event.scheduleId); if (success) { - final updatedSchedules = - currentState.schedules.where((schedule) => schedule.scheduleId != event.scheduleId).toList(); + final updatedSchedules = currentState.schedules + .where((schedule) => schedule.scheduleId != event.scheduleId) + .toList(); emit(currentState.copyWith(schedules: updatedSchedules)); } else { @@ -608,12 +657,15 @@ class WaterHeaterBloc extends Bloc { } } - FutureOr _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, Emitter emit) async { + FutureOr _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, + Emitter emit) async { emit(WaterHeaterLoadingState()); try { - final status = await DevicesManagementApi().getBatchStatus(event.devicesUuid); - deviceStatus = WaterHeaterStatusModel.fromJson(event.devicesUuid.first, status.status); + final status = + await DevicesManagementApi().getBatchStatus(event.devicesUuid); + deviceStatus = WaterHeaterStatusModel.fromJson( + event.devicesUuid.first, status.status); emit(WaterHeaterDeviceStatusLoaded(deviceStatus)); } catch (e) { @@ -621,7 +673,8 @@ class WaterHeaterBloc extends Bloc { } } - FutureOr _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, Emitter emit) async { + FutureOr _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, + Emitter emit) async { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart index ff5de32c..e4cc8474 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart @@ -54,6 +54,15 @@ final class WaterHeaterFetchStatusEvent extends WaterHeaterEvent { final class DecrementCountdownEvent extends WaterHeaterEvent {} + +class StatusUpdated extends WaterHeaterEvent { + final WaterHeaterStatusModel deviceStatus; + const StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} + + final class AddScheduleEvent extends WaterHeaterEvent { final List selectedDays; final TimeOfDay time; diff --git a/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart b/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart index f1063dc9..6d3ca9a6 100644 --- a/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart +++ b/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart @@ -1,4 +1,5 @@ import 'package:bloc/bloc.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart'; @@ -21,6 +22,7 @@ class WaterLeakBloc extends Bloc { on(_onFetchBatchStatus); on(_onFetchWaterLeakReports); on(_onFactoryReset); + on(_onStatusUpdated); } Future _onFetchWaterLeakStatus( @@ -30,12 +32,43 @@ class WaterLeakBloc extends Bloc { final response = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = WaterLeakStatusModel.fromJson(deviceId, response.status); + _listenToChanges(); emit(WaterLeakLoadedState(deviceStatus!)); } catch (e) { emit(WaterLeakErrorState(e.toString())); } } + _listenToChanges() { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + WaterLeakStatusModel.fromJson(usersMap['productUuid'], statusList); + if (!isClosed) { + add(StatusUpdated(deviceStatus!)); + } + }); + } catch (_) {} + } + + void _onStatusUpdated(StatusUpdated event, Emitter emit) { + deviceStatus = event.deviceStatus; + emit(WaterLeakLoadedState(deviceStatus!)); + } + Future _onControl( WaterLeakControlEvent event, Emitter emit) async { final oldValue = deviceStatus!.watersensorState; diff --git a/lib/pages/device_managment/water_leak/bloc/water_leak_event.dart b/lib/pages/device_managment/water_leak/bloc/water_leak_event.dart index 9c048280..39864462 100644 --- a/lib/pages/device_managment/water_leak/bloc/water_leak_event.dart +++ b/lib/pages/device_managment/water_leak/bloc/water_leak_event.dart @@ -1,5 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; +import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart'; abstract class WaterLeakEvent extends Equatable { const WaterLeakEvent(); @@ -17,6 +18,13 @@ class FetchWaterLeakStatusEvent extends WaterLeakEvent { List get props => [deviceId]; } +class StatusUpdated extends WaterLeakEvent { + final WaterLeakStatusModel deviceStatus; + const StatusUpdated(this.deviceStatus); + @override + List get props => [deviceStatus]; +} + class WaterLeakControlEvent extends WaterLeakEvent { final String deviceId; final String code; diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index fda76728..042a91d1 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -65,8 +65,6 @@ class HomeBloc extends Bloc { emit(LoadingHome()); terms = await HomeApi().fetchTerms(); emit(HomeInitial()); - - // emit(PolicyAgreement()); } catch (e) { return; } @@ -76,8 +74,6 @@ class HomeBloc extends Bloc { try { emit(LoadingHome()); policy = await HomeApi().fetchPolicy(); - debugPrint("Fetched policy: $policy"); - // Emit a state to trigger the UI update emit(HomeInitial()); } catch (e) { debugPrint("Error fetching policy: $e"); diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 51aae316..e6f3527d 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,12 +5,20 @@ import FlutterMacOS import Foundation +import firebase_analytics +import firebase_core +import firebase_crashlytics +import firebase_database import flutter_secure_storage_macos import path_provider_foundation import shared_preferences_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin")) + FLTFirebaseDatabasePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseDatabasePlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index eec16af6..7bfb45ff 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ /* Begin PBXBuildFile section */ 108157F896CD9F637B06D7C0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DAF1C60594A51D692304366 /* Pods_Runner.framework */; }; + 2901225E5FAB0C696EE79F77 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */; }; 2D0F1F294F673EF0DB5E4CA1 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */; }; 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; @@ -84,6 +85,7 @@ 81F2F315AC5109F6F5D27BE6 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 96C46007EE0A4E9E1D6D74CE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + 996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; A604E311B663FBF4B7C54DC5 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; AB949539E0D0A8E2BDAB9ADF /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -138,6 +140,7 @@ 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, 75DCDFECC7757C5159E8F0C5 /* Pods */, + 996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -241,6 +244,7 @@ 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, 92D754792F50A5D35F6D5AEE /* [CP] Embed Pods Frameworks */, + 7E188D2155D07A3E9E027C0F /* FlutterFire: "flutterfire upload-crashlytics-symbols" */, ); buildRules = ( ); @@ -317,6 +321,7 @@ files = ( 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + 2901225E5FAB0C696EE79F77 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -361,6 +366,24 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + 7E188D2155D07A3E9E027C0F /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\""; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\"\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --platform=macos --apple-project-path=\"${SRCROOT}\" --env-platform-name=\"${PLATFORM_NAME}\" --env-configuration=\"${CONFIGURATION}\" --env-project-dir=\"${PROJECT_DIR}\" --env-built-products-dir=\"${BUILT_PRODUCTS_DIR}\" --env-dwarf-dsym-folder-path=\"${DWARF_DSYM_FOLDER_PATH}\" --env-dwarf-dsym-file-name=\"${DWARF_DSYM_FILE_NAME}\" --env-infoplist-path=\"${INFOPLIST_PATH}\" --default-config=default\n"; + }; 8ECFD939A4D371A145DBA191 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/macos/Runner/GoogleService-Info.plist b/macos/Runner/GoogleService-Info.plist new file mode 100644 index 00000000..9cdebed0 --- /dev/null +++ b/macos/Runner/GoogleService-Info.plist @@ -0,0 +1,32 @@ + + + + + API_KEY + AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw + GCM_SENDER_ID + 427332280600 + PLIST_VERSION + 1 + BUNDLE_ID + com.example.syncrowWeb + PROJECT_ID + test2-8a3d2 + STORAGE_BUCKET + test2-8a3d2.firebasestorage.app + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:427332280600:ios:14346b200780dc760c7e6d + DATABASE_URL + https://test2-8a3d2-default-rtdb.firebaseio.com + + \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 7833f1ec..a0cbfaad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: e051259913915ea5bc8fe18664596bea08592fd123930605d562969cd7315fcd + url: "https://pub.dev" + source: hosted + version: "1.3.51" args: dependency: transitive description: @@ -153,6 +161,94 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + firebase_analytics: + dependency: "direct main" + description: + name: firebase_analytics + sha256: "47428047a0778f72af53a3c7cb5d556e1cb25e2327cc8aa40d544971dc6245b2" + url: "https://pub.dev" + source: hosted + version: "11.4.2" + firebase_analytics_platform_interface: + dependency: transitive + description: + name: firebase_analytics_platform_interface + sha256: "1076f4b041f76143e14878c70f0758f17fe5910c0cd992db9e93bd3c3584512b" + url: "https://pub.dev" + source: hosted + version: "4.3.2" + firebase_analytics_web: + dependency: transitive + description: + name: firebase_analytics_web + sha256: "8f6dd64ea6d28b7f5b9e739d183a9e1c7f17027794a3e9aba1879621d42426ef" + url: "https://pub.dev" + source: hosted + version: "0.5.10+8" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "93dc4dd12f9b02c5767f235307f609e61ed9211047132d07f9e02c668f0bfc33" + url: "https://pub.dev" + source: hosted + version: "3.11.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf + url: "https://pub.dev" + source: hosted + version: "5.4.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "0e13c80f0de8acaa5d0519cbe23c8b4cc138a2d5d508b5755c861bdfc9762678" + url: "https://pub.dev" + source: hosted + version: "2.20.0" + firebase_crashlytics: + dependency: "direct main" + description: + name: firebase_crashlytics + sha256: "6273ed71bcd8a6fb4d0ca13d3abddbb3301796807efaad8782b5f90156f26f03" + url: "https://pub.dev" + source: hosted + version: "4.3.2" + firebase_crashlytics_platform_interface: + dependency: transitive + description: + name: firebase_crashlytics_platform_interface + sha256: "94f3986e1a10e5a883f2ad5e3d719aef98a8a0f9a49357f6e45b7d3696ea6a97" + url: "https://pub.dev" + source: hosted + version: "3.8.2" + firebase_database: + dependency: "direct main" + description: + name: firebase_database + sha256: cd2354dfef68e52c0713b5efbb7f4e10dfc2aff2f945c7bc8db34d1934170627 + url: "https://pub.dev" + source: hosted + version: "11.3.2" + firebase_database_platform_interface: + dependency: transitive + description: + name: firebase_database_platform_interface + sha256: d430983f4d877c9f72f88b3d715cca9a50021dd7ccd8e3ae6fb79603853317de + url: "https://pub.dev" + source: hosted + version: "0.2.6+2" + firebase_database_web: + dependency: transitive + description: + name: firebase_database_web + sha256: f64edae62c5beaa08e9e611a0736d64ab11a812983a0aa132695d2d191311ea7 + url: "https://pub.dev" + source: hosted + version: "0.2.6+8" fixnum: dependency: transitive description: @@ -572,10 +668,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "3a293170d4d9403c3254ee05b84e62e8a9b3c5808ebd17de6a33fe9ea6457936" + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: @@ -777,10 +873,10 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.1.0" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f4108d5c..fd7ed797 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,6 +56,11 @@ dependencies: number_pagination: ^1.1.6 url_launcher: ^6.2.5 flutter_html: ^3.0.0-beta.2 + firebase_analytics: ^11.4.0 + firebase_core: ^3.11.0 + firebase_crashlytics: ^4.3.2 + firebase_database: ^11.3.2 + dev_dependencies: flutter_test: diff --git a/web/index.html b/web/index.html index a8b2aa25..d099103c 100644 --- a/web/index.html +++ b/web/index.html @@ -40,6 +40,8 @@ + + diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 2048c455..0e0afee0 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,10 +6,13 @@ #include "generated_plugin_registrant.h" +#include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index de626cc8..9efea82a 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + firebase_core flutter_secure_storage_windows url_launcher_windows )