Compare commits

..

54 Commits

Author SHA1 Message Date
73d28a1800 Refactor Action class to use type annotations for actionExecutor and entityId 2025-04-17 10:41:01 +03:00
5493ca6fb0 Refactor device filtering logic to improve code readability 2025-04-17 10:38:25 +03:00
7005d8ba83 Refactor device filtering logic and improve code readability
- Extracted the logic for filtering implemented devices into a separate method `_getOnlyImplementedDevices`
- Created a set `allowedDevices` to store the allowed device types
- Updated the filtering logic to use the `allowedDevices` set for checking device types
- Removed unnecessary conditions for filtering devices

Fix nullability issues in `Action` model

- Added null checks for `actionExecutor`, `entityId`, `name`, `type`, and `productType` properties in the `fromJson` method of the `Action` model
- Set default values for `actionExecutor` and `entityId` if they are null
- Updated the type casting for `name`, `type`, and `productType` properties to avoid potential nullability issues
2025-04-17 10:16:10 +03:00
1cff69d496 change icon 2025-04-17 09:39:58 +03:00
60df77efad add OneGang product type to routine 2025-04-17 09:32:20 +03:00
ccde857c29 Merge pull request #80 from SyncrowIOT/SP-1398-FE-in-the-wizerd-the-batch-control-title-doesn-t-represent-the-the-accurate-device-name
SP-1398-FE-in-the-wizerd-the-batch-control-title-doesn-t-represent-the-the-accurate-device-name
2025-04-13 16:23:49 +03:00
b2a8086e0e Merge pull request #79 from SyncrowIOT/sp-1268-rework-v2
Sp 1268 rework v2
2025-04-13 16:20:10 +03:00
408e78962c SP-1398 2025-04-13 16:18:49 +03:00
dcdbc02ca0 Adds AppLoadingIndicator widget and replaces CircularProgressIndicator in SceneView. 2025-04-13 15:50:52 +03:00
31025e9176 Refactors SceneView constructor and improves conditional rendering for automation list 2025-04-13 15:49:13 +03:00
8219de6821 Injects SceneBloc using the new factory. 2025-04-13 15:28:44 +03:00
fbdf3817ab Created a factory helper to create a SceneBloc. 2025-04-13 15:25:48 +03:00
17422edd0d sp-1268-rework-v2. 2025-04-13 15:21:20 +03:00
9472390284 Merge pull request #76 from SyncrowIOT/bugifx/empty-subspace-routine-creation
fixed issue on empty subspace
2025-03-28 11:38:14 +04:00
731ba0f3d6 Merge pull request #77 from SyncrowIOT/SP-1268-FE-Implement-UX-Behavior-for-No-Tab-to-Run-Scene-in-Device-Screen
Sp 1268 fe implement ux behavior for no tab to run scene in device screen
2025-03-26 15:24:34 +03:00
56407c6426 indentation and trailing commas. 2025-03-26 13:49:54 +03:00
02d61ca0bb Refactor DevicesViewBody and SceneView to improve widget structure and replace CreateUnitWidget with EmptyDevicesWidget for better handling of empty states. 2025-03-26 13:44:49 +03:00
99ee4b9878 Add EmptyDevicesWidget to display message when no routines are available. 2025-03-26 13:34:07 +03:00
19edd0a275 Added /android/app/.cxx/ to .gitIgnore, because they're auto generated files that dont need to be checked into source control. 2025-03-26 13:14:23 +03:00
ef5e7c3154 fixed issue on empty subspace 2025-03-25 14:15:14 +04:00
80dd0f696f Merge pull request #75 from SyncrowIOT/SP-1245
updated endpoint for automation
2025-03-17 09:34:46 +04:00
a64a41548f updated delete endpoint for automation 2025-03-14 13:02:14 +04:00
0d50aa68fa updated endpoint for update automation 2025-03-14 12:58:12 +04:00
88aac86b10 updated endpoint for getting automation by id 2025-03-14 12:55:33 +04:00
0673548745 changed endpoint for getting automations by space 2025-03-14 12:53:29 +04:00
c2fc8fa0ae changed endpoint for create automation endpoint 2025-03-14 12:40:52 +04:00
cbf10bbf78 Merge pull request #74 from SyncrowIOT/real_time_app
Real time app
2025-03-03 17:34:34 +03:00
d95588ce84 remove unused code 2025-03-03 17:34:15 +03:00
7e2e591d71 remove unused code 2025-03-01 15:19:15 +03:00
2ec81bda9c connect the real time for all devices 2025-03-01 15:08:51 +03:00
3b0f51473c Merge pull request #73 from SyncrowIOT/SP-1190
Sp 1190
2025-02-26 12:20:06 +03:00
13757d89ee Merged with dev 2025-02-26 12:17:57 +03:00
d3068b8e14 changes in threeGang 2025-02-26 10:58:32 +03:00
7c5d7e1dda remove unused code 2025-02-25 12:45:23 +03:00
0a97a4867d disconnect real-time to some devices 2025-02-25 12:41:49 +03:00
6e55b488aa Merge pull request #72 from SyncrowIOT/feat/change-hardcode-projectid
updated project hardcoded values
2025-02-24 12:06:06 +03:00
22789234fe Sensitivity Start from 1 2025-02-23 16:30:50 +03:00
8393ec353a fetchDevices by projectUuid 2025-02-20 16:02:25 +03:00
0b45d61b25 Fixed list issue in the manage home screen 2025-02-20 10:50:47 +03:00
450b773921 set default values in the devices models instead of late, and fixed issues in the AC bloc 2025-02-20 04:13:37 +03:00
3f7f7ce49f updated project hardcoded values 2025-02-16 20:55:13 +04:00
2dc4e16a75 connect all devices to real-time and change the channel function 2025-02-16 14:54:39 +03:00
cd41720244 active the implemented device 2025-02-16 10:04:34 +03:00
67209961b4 added project model 2025-02-15 11:54:02 +04:00
9098276223 Merge pull request #71 from SyncrowIOT/fixes_bugs_sprint15
fixes bugs and add project id staging
2025-02-12 12:47:09 +03:00
36dfe2c85e change the key 2025-02-12 12:06:00 +03:00
efed5f55a7 add project id to env file and hide about 2025-02-11 11:05:13 +03:00
9897c19dad fixes bugs and add project id staging 2025-02-10 10:26:02 +03:00
48733fd65e Merge pull request #70 from SyncrowIOT/sprint_14_changes
Sprint 14 changes
2025-02-02 22:33:28 +03:00
4ca4086bd3 Merged with dev 2025-02-02 22:32:15 +03:00
4da1b16b18 Merge pull request #69 from SyncrowIOT/role_permission_restrict_user
restrict_spaceMemberUser_and_change_SignUpModel
2025-02-02 14:27:31 +03:00
457b7c2c51 Updated gradle and kotlin 2025-01-26 20:38:37 +03:00
4ae04cf2af Merged with Dev 2025-01-26 13:08:40 +03:00
f960a553ca Updated the pacakages 2025-01-13 13:02:51 +03:00
94 changed files with 3518 additions and 2221 deletions

View File

@ -1,2 +1,3 @@
ENV_NAME=development
BASE_URL=https://syncrow-dev.azurewebsites.net
BASE_URL=https://syncrow-dev.azurewebsites.net
PROJECT_ID=0e62577c-06fa-41b9-8a92-99a21fbaf51c

View File

@ -1,2 +1,3 @@
ENV_NAME=production
BASE_URL=https://syncrow-staging.azurewebsites.net
BASE_URL=https://syncrow-staging.azurewebsites.net
PROJECT_ID=bcda711e-9fc2-4168-a05e-171b4026d1ff

View File

@ -1,2 +1,3 @@
ENV_NAME=staging
BASE_URL=https://syncrow-staging.azurewebsites.net
BASE_URL=https://syncrow-staging.azurewebsites.net
PROJECT_ID=bcda711e-9fc2-4168-a05e-171b4026d1ff

1
.gitignore vendored
View File

@ -42,3 +42,4 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
/android/app/.cxx/

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.7.10'
ext.kotlin_version = '1.9.0'
repositories {
google()
mavenCentral()

View File

@ -1,3 +1,6 @@
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View File

@ -1,6 +1,6 @@
#Wed Apr 03 23:37:40 EET 2024
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -23,7 +23,7 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "com.android.application" version '8.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

View File

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'
platform :ios, '15.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -1,155 +1,153 @@
PODS:
- device_info_plus (0.0.1):
- Flutter
- Firebase/Analytics (10.25.0):
- Firebase/Analytics (11.6.0):
- Firebase/Core
- Firebase/Core (10.25.0):
- Firebase/Core (11.6.0):
- Firebase/CoreOnly
- FirebaseAnalytics (~> 10.25.0)
- Firebase/CoreOnly (10.25.0):
- FirebaseCore (= 10.25.0)
- Firebase/Crashlytics (10.25.0):
- FirebaseAnalytics (~> 11.6.0)
- Firebase/CoreOnly (11.6.0):
- FirebaseCore (~> 11.6.0)
- Firebase/Crashlytics (11.6.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 10.25.0)
- Firebase/Database (10.25.0):
- FirebaseCrashlytics (~> 11.6.0)
- Firebase/Database (11.6.0):
- Firebase/CoreOnly
- FirebaseDatabase (~> 10.25.0)
- firebase_analytics (10.8.7):
- Firebase/Analytics (= 10.25.0)
- FirebaseDatabase (~> 11.6.0)
- firebase_analytics (11.4.0):
- Firebase/Analytics (= 11.6.0)
- firebase_core
- Flutter
- firebase_core (2.32.0):
- Firebase/CoreOnly (= 10.25.0)
- firebase_core (3.10.0):
- Firebase/CoreOnly (= 11.6.0)
- Flutter
- firebase_crashlytics (3.4.16):
- Firebase/Crashlytics (= 10.25.0)
- firebase_crashlytics (4.3.0):
- Firebase/Crashlytics (= 11.6.0)
- firebase_core
- Flutter
- firebase_database (10.5.7):
- Firebase/Database (= 10.25.0)
- firebase_database (11.3.0):
- Firebase/Database (= 11.6.0)
- firebase_core
- Flutter
- FirebaseAnalytics (10.25.0):
- FirebaseAnalytics/AdIdSupport (= 10.25.0)
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
- GoogleUtilities/MethodSwizzler (~> 7.11)
- GoogleUtilities/Network (~> 7.11)
- "GoogleUtilities/NSData+zlib (~> 7.11)"
- nanopb (< 2.30911.0, >= 2.30908.0)
- FirebaseAnalytics/AdIdSupport (10.25.0):
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleAppMeasurement (= 10.25.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
- GoogleUtilities/MethodSwizzler (~> 7.11)
- GoogleUtilities/Network (~> 7.11)
- "GoogleUtilities/NSData+zlib (~> 7.11)"
- nanopb (< 2.30911.0, >= 2.30908.0)
- FirebaseAppCheckInterop (10.29.0)
- FirebaseCore (10.25.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.12)
- GoogleUtilities/Logger (~> 7.12)
- FirebaseCoreExtension (10.29.0):
- FirebaseCore (~> 10.0)
- FirebaseCoreInternal (10.29.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseCrashlytics (10.25.0):
- FirebaseCore (~> 10.5)
- FirebaseInstallations (~> 10.0)
- FirebaseRemoteConfigInterop (~> 10.23)
- FirebaseSessions (~> 10.5)
- GoogleDataTransport (~> 9.2)
- GoogleUtilities/Environment (~> 7.8)
- nanopb (< 2.30911.0, >= 2.30908.0)
- PromisesObjC (~> 2.1)
- FirebaseDatabase (10.25.0):
- FirebaseAppCheckInterop (~> 10.17)
- FirebaseCore (~> 10.0)
- FirebaseSharedSwift (~> 10.0)
- GoogleUtilities/UserDefaults (~> 7.13)
- FirebaseAnalytics (11.6.0):
- FirebaseAnalytics/AdIdSupport (= 11.6.0)
- FirebaseCore (~> 11.6.0)
- FirebaseInstallations (~> 11.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
- GoogleUtilities/MethodSwizzler (~> 8.0)
- GoogleUtilities/Network (~> 8.0)
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/AdIdSupport (11.6.0):
- FirebaseCore (~> 11.6.0)
- FirebaseInstallations (~> 11.0)
- GoogleAppMeasurement (= 11.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
- GoogleUtilities/MethodSwizzler (~> 8.0)
- GoogleUtilities/Network (~> 8.0)
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- nanopb (~> 3.30910.0)
- FirebaseAppCheckInterop (11.6.0)
- FirebaseCore (11.6.0):
- FirebaseCoreInternal (~> 11.6.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/Logger (~> 8.0)
- FirebaseCoreExtension (11.6.0):
- FirebaseCore (~> 11.6.0)
- FirebaseCoreInternal (11.6.0):
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- FirebaseCrashlytics (11.6.0):
- FirebaseCore (~> 11.6.0)
- FirebaseInstallations (~> 11.0)
- FirebaseRemoteConfigInterop (~> 11.0)
- FirebaseSessions (~> 11.0)
- GoogleDataTransport (~> 10.0)
- GoogleUtilities/Environment (~> 8.0)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseDatabase (11.6.0):
- FirebaseAppCheckInterop (~> 11.0)
- FirebaseCore (~> 11.6.0)
- FirebaseSharedSwift (~> 11.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- leveldb-library (~> 1.22)
- FirebaseInstallations (10.29.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- PromisesObjC (~> 2.1)
- FirebaseRemoteConfigInterop (10.29.0)
- FirebaseSessions (10.29.0):
- FirebaseCore (~> 10.5)
- FirebaseCoreExtension (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleDataTransport (~> 9.2)
- GoogleUtilities/Environment (~> 7.13)
- GoogleUtilities/UserDefaults (~> 7.13)
- nanopb (< 2.30911.0, >= 2.30908.0)
- FirebaseInstallations (11.6.0):
- FirebaseCore (~> 11.6.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- PromisesObjC (~> 2.4)
- FirebaseRemoteConfigInterop (11.6.0)
- FirebaseSessions (11.6.0):
- FirebaseCore (~> 11.6.0)
- FirebaseCoreExtension (~> 11.6.0)
- FirebaseInstallations (~> 11.0)
- GoogleDataTransport (~> 10.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- nanopb (~> 3.30910.0)
- PromisesSwift (~> 2.1)
- FirebaseSharedSwift (10.29.0)
- FirebaseSharedSwift (11.6.0)
- Flutter (1.0.0)
- flutter_secure_storage (6.0.0):
- Flutter
- GoogleAppMeasurement (10.25.0):
- GoogleAppMeasurement/AdIdSupport (= 10.25.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
- GoogleUtilities/MethodSwizzler (~> 7.11)
- GoogleUtilities/Network (~> 7.11)
- "GoogleUtilities/NSData+zlib (~> 7.11)"
- nanopb (< 2.30911.0, >= 2.30908.0)
- GoogleAppMeasurement/AdIdSupport (10.25.0):
- GoogleAppMeasurement/WithoutAdIdSupport (= 10.25.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
- GoogleUtilities/MethodSwizzler (~> 7.11)
- GoogleUtilities/Network (~> 7.11)
- "GoogleUtilities/NSData+zlib (~> 7.11)"
- nanopb (< 2.30911.0, >= 2.30908.0)
- GoogleAppMeasurement/WithoutAdIdSupport (10.25.0):
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
- GoogleUtilities/MethodSwizzler (~> 7.11)
- GoogleUtilities/Network (~> 7.11)
- "GoogleUtilities/NSData+zlib (~> 7.11)"
- nanopb (< 2.30911.0, >= 2.30908.0)
- GoogleDataTransport (9.4.1):
- GoogleUtilities/Environment (~> 7.7)
- nanopb (< 2.30911.0, >= 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/AppDelegateSwizzler (7.13.3):
- GoogleAppMeasurement (11.6.0):
- GoogleAppMeasurement/AdIdSupport (= 11.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
- GoogleUtilities/MethodSwizzler (~> 8.0)
- GoogleUtilities/Network (~> 8.0)
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/AdIdSupport (11.6.0):
- GoogleAppMeasurement/WithoutAdIdSupport (= 11.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
- GoogleUtilities/MethodSwizzler (~> 8.0)
- GoogleUtilities/Network (~> 8.0)
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/WithoutAdIdSupport (11.6.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
- GoogleUtilities/MethodSwizzler (~> 8.0)
- GoogleUtilities/Network (~> 8.0)
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- nanopb (~> 3.30910.0)
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- GoogleUtilities/AppDelegateSwizzler (8.0.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Privacy
- GoogleUtilities/Environment (7.13.3):
- GoogleUtilities/Environment (8.0.2):
- GoogleUtilities/Privacy
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.13.3):
- GoogleUtilities/Logger (8.0.2):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/MethodSwizzler (7.13.3):
- GoogleUtilities/MethodSwizzler (8.0.2):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/Network (7.13.3):
- GoogleUtilities/Network (8.0.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Privacy
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.13.3)":
- "GoogleUtilities/NSData+zlib (8.0.2)":
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (7.13.3)
- GoogleUtilities/Reachability (7.13.3):
- GoogleUtilities/Privacy (8.0.2)
- GoogleUtilities/Reachability (8.0.2):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/UserDefaults (7.13.3):
- GoogleUtilities/UserDefaults (8.0.2):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- image_picker_ios (0.0.1):
- Flutter
- leveldb-library (1.22.5)
- nanopb (2.30910.0):
- nanopb/decode (= 2.30910.0)
- nanopb/encode (= 2.30910.0)
- nanopb/decode (2.30910.0)
- nanopb/encode (2.30910.0)
- leveldb-library (1.22.6)
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
- nanopb/decode (3.30910.0)
- nanopb/encode (3.30910.0)
- onesignal_flutter (5.2.0):
- Flutter
- OneSignalXCFramework (= 5.2.0)
@ -291,42 +289,42 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
Firebase: 0312a2352584f782ea56f66d91606891d4607f06
firebase_analytics: 3a9263fedec72970e6bd30a7132bbdd386de2c14
firebase_core: a626d00494efa398e7c54f25f1454a64c8abf197
firebase_crashlytics: 0b7cb41f5fb3b6889d0fb408cfce3cc7a4247061
firebase_database: 2713033e426b176d4fe5e7195f3d19aa1b549a91
FirebaseAnalytics: ec00fe8b93b41dc6fe4a28784b8e51da0647a248
FirebaseAppCheckInterop: 6a1757cfd4067d8e00fccd14fcc1b8fd78cfac07
FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483
FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f
FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934
FirebaseCrashlytics: 4b96efb0ce73b38b2a85e8b8bd1bd8f63f09d015
FirebaseDatabase: faa489a42f5f868d23a55dd442d6e2099348458e
FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd
FirebaseRemoteConfigInterop: 6efda51fb5e2f15b16585197e26eaa09574e8a4d
FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc
FirebaseSharedSwift: 20530f495084b8d840f78a100d8c5ee613375f6e
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
Firebase: 374a441a91ead896215703a674d58cdb3e9d772b
firebase_analytics: 07bd7cfbac54bfcdccf2bb2530f9a65486f7ef3f
firebase_core: feb37e79f775c2bd08dd35e02d83678291317e10
firebase_crashlytics: 609a5f6f4a2f5af9e40a68182e0c1be3ca2a02f6
firebase_database: adc9efd0b70cdc8d1e6f3c9f6bb054a625c4f45d
FirebaseAnalytics: 7114c698cac995602e3b1b96663473e50d54d6e7
FirebaseAppCheckInterop: 347aa09a805219a31249b58fc956888e9fcb314b
FirebaseCore: 48b0dd707581cf9c1a1220da68223fb0a562afaa
FirebaseCoreExtension: 2d77d6430c16cf43ca2b04608302ed02b3598361
FirebaseCoreInternal: d98ab91e2d80a56d7b246856a8885443b302c0c2
FirebaseCrashlytics: b21c665fb50138766480bce73ebdb1aa30f7f300
FirebaseDatabase: ce3a83a39ab50559a85c5add54f6f285544433b8
FirebaseInstallations: efc0946fc756e4d22d8113f7c761948120322e8c
FirebaseRemoteConfigInterop: e75e348953352a000331eb77caf01e424248e176
FirebaseSessions: 9529d14180868e29a8da164b3a729c036204918b
FirebaseSharedSwift: a4e5dfca3e210633bb3a3dfb94176c019211948b
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
GoogleAppMeasurement: 9abf64b682732fed36da827aa2a68f0221fd2356
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
GoogleAppMeasurement: 6a9e6317b6a6d810ad03d4a66564ca6c4c5818a3
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28
nanopb: 438bc412db1928dac798aa6fd75726007be04262
leveldb-library: cc8b8f8e013647a295ad3f8cd2ddf49a6f19be19
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
onesignal_flutter: 5ce68a29861960168e81101cb1bd685d264361de
OneSignalXCFramework: bdf74fdc06888f9466dc21e826fe1549ed143095
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
PODFILE CHECKSUM: 4243bd7f9184f79552dd731a7c9d5cad03bd2706
PODFILE CHECKSUM: deba6d843ff3cf709e6e9051ce6601a587b24105
COCOAPODS: 1.16.2

View File

@ -547,6 +547,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -739,6 +740,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -769,6 +771,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -856,6 +859,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -959,6 +963,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -1057,6 +1062,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",

View File

@ -38,5 +38,10 @@
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>sms</string>
<string>tel</string>
</array>
</dict>
</plist>

View File

@ -10,6 +10,7 @@ import 'package:share_plus/share_plus.dart';
import 'package:syncrow_app/features/app_layout/model/permission_model.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
@ -28,6 +29,7 @@ import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/profile_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
part 'home_state.dart';
@ -67,6 +69,8 @@ class HomeCubit extends Cubit<HomeState> {
var uuid =
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
user = await ProfileApi().fetchUserInfo(uuid);
project = user?.project;
emit(HomeUserInfoLoaded(user!));
} catch (e) {
return;
@ -175,6 +179,8 @@ class HomeCubit extends Cubit<HomeState> {
SubSpaceModel? selectedRoom;
Project? project;
PageController devicesPageController = PageController();
PageController roomsPageController = PageController();
@ -324,8 +330,8 @@ class HomeCubit extends Cubit<HomeState> {
//////////////////////////////////////// API ////////////////////////////////////////
generateInvitation(SpaceModel unit) async {
try {
final invitationCode =
await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
final invitationCode = await SpacesAPI.generateInvitationCode(unit.id,
unit.community.uuid, project?.uuid ?? TempConst.projectIdDev);
if (invitationCode.isNotEmpty) {
Share.share('The invitation code is $invitationCode');
CustomSnackBar.displaySnackBar(
@ -380,8 +386,10 @@ class HomeCubit extends Cubit<HomeState> {
fetchRoomsByUnitId(SpaceModel space) async {
emitSafe(GetSpaceRoomsLoading());
try {
space.subspaces =
await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
space.subspaces = await SpacesAPI.getSubSpaceBySpaceId(
space.community.uuid,
space.id,
project?.uuid ?? TempConst.projectIdDev);
} catch (failure) {
emitSafe(GetSpaceRoomsError(failure.toString()));
return;
@ -414,7 +422,6 @@ class HomeCubit extends Cubit<HomeState> {
emitSafe(ActivationError(errMessage: errorMsg));
return false;
}
}
/////////////////////////////////////// Nav ///////////////////////////////////////

View File

@ -0,0 +1,27 @@
class Project {
final String uuid;
final String name;
final String description;
const Project({
required this.uuid,
required this.name,
required this.description,
});
factory Project.fromJson(Map<String, dynamic> json) {
return Project(
uuid: json['uuid'] as String,
name: json['name'] as String,
description: json['description'] as String,
);
}
Map<String, dynamic> toJson() {
return {
'uuid': uuid,
'name': name,
'description': description,
};
}
}

View File

@ -1,5 +1,6 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/auth/model/token.dart';
class UserModel {
@ -20,6 +21,7 @@ class UserModel {
final bool? hasAcceptedAppAgreement;
final DateTime? appAgreementAcceptedAt;
final Role? role;
final Project? project;
UserModel({
required this.uuid,
@ -38,6 +40,7 @@ class UserModel {
required this.hasAcceptedAppAgreement,
required this.appAgreementAcceptedAt,
required this.role,
required this.project,
});
factory UserModel.fromJson(Map<String, dynamic> json) {
@ -62,33 +65,35 @@ class UserModel {
? DateTime.parse(json['appAgreementAcceptedAt'])
: null,
role: json['role'] != null ? Role.fromJson(json['role']) : null,
project:
json['project'] != null ? Project.fromJson(json['project']) : null,
);
}
factory UserModel.fromToken(Token token) {
Map<String, dynamic> tempJson = Token.decodeToken(token.accessToken);
return UserModel(
uuid: tempJson['uuid'].toString(),
email: tempJson['email'],
lastName: tempJson['lastName'],
firstName: tempJson['firstName'],
profilePicture: UserModel.decodeBase64Image(tempJson['profilePicture']),
phoneNumber: null,
isEmailVerified: null,
isAgreementAccepted: null,
regionUuid: null,
regionName: tempJson['region']?['regionName'],
timeZone: tempJson['timezone']?['timeZoneOffset'],
hasAcceptedWebAgreement: tempJson['hasAcceptedWebAgreement'],
webAgreementAcceptedAt: tempJson['webAgreementAcceptedAt'] != null
? DateTime.parse(tempJson['webAgreementAcceptedAt'])
: null,
hasAcceptedAppAgreement: tempJson['hasAcceptedAppAgreement'],
appAgreementAcceptedAt: tempJson['appAgreementAcceptedAt'] != null
? DateTime.parse(tempJson['appAgreementAcceptedAt'])
: null,
role: tempJson['role'] != null ? Role.fromJson(tempJson['role']) : null,
);
uuid: tempJson['uuid'].toString(),
email: tempJson['email'],
lastName: tempJson['lastName'],
firstName: tempJson['firstName'],
profilePicture: UserModel.decodeBase64Image(tempJson['profilePicture']),
phoneNumber: null,
isEmailVerified: null,
isAgreementAccepted: null,
regionUuid: null,
regionName: tempJson['region']?['regionName'],
timeZone: tempJson['timezone']?['timeZoneOffset'],
hasAcceptedWebAgreement: tempJson['hasAcceptedWebAgreement'],
webAgreementAcceptedAt: tempJson['webAgreementAcceptedAt'] != null
? DateTime.parse(tempJson['webAgreementAcceptedAt'])
: null,
hasAcceptedAppAgreement: tempJson['hasAcceptedAppAgreement'],
appAgreementAcceptedAt: tempJson['appAgreementAcceptedAt'] != null
? DateTime.parse(tempJson['appAgreementAcceptedAt'])
: null,
role: tempJson['role'] != null ? Role.fromJson(tempJson['role']) : null,
project: null);
}
static Uint8List? decodeBase64Image(String? base64String) {
@ -137,8 +142,10 @@ class Role {
factory Role.fromJson(Map<String, dynamic> json) {
return Role(
uuid: json['uuid'],
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null,
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null,
createdAt:
json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null,
updatedAt:
json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null,
type: json['type'],
);
}

View File

@ -0,0 +1,19 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class ProjectCubit extends Cubit<String?> {
final FlutterSecureStorage storage;
static const String projectKey = "selected_project_uuid";
ProjectCubit(this.storage) : super(null);
Future<void> setProjectUUID(String newUUID) async {
await storage.write(key: projectKey, value: newUUID);
emit(newUUID);
}
Future<void> clearProjectUUID() async {
await storage.delete(key: projectKey);
emit(null);
}
}

View File

@ -7,7 +7,7 @@ import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
import 'widgets/energy_usage.dart';
// import 'widgets/energy_usage.dart';
class DashboardView extends StatelessWidget {
const DashboardView({super.key});
@ -29,7 +29,7 @@ class DashboardView extends StatelessWidget {
),
const LiveMonitorTab(),
const SizedBox(height: 10),
const EnergyUsage(),
// const EnergyUsage(),
Container(
padding: const EdgeInsets.only(top: 20),
constraints: const BoxConstraints(

View File

@ -1,178 +1,178 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/dashboard/view/widgets/energy_usage_header.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
// import 'package:fl_chart/fl_chart.dart';
// import 'package:flutter/material.dart';
// import 'package:syncrow_app/features/dashboard/view/widgets/energy_usage_header.dart';
// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
// import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class EnergyUsage extends StatelessWidget {
const EnergyUsage({
super.key,
});
// class EnergyUsage extends StatelessWidget {
// const EnergyUsage({
// super.key,
// });
@override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const EnergyUsageHeader(),
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 150,
minHeight: 150,
),
child: LineChart(
LineChartData(
gridData: FlGridData(
show: true,
drawHorizontalLine: true,
horizontalInterval: 2,
drawVerticalLine: false,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.grey.withOpacity(.5),
strokeWidth: 1,
);
},
),
titlesData: FlTitlesData(
show: true,
rightTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: 1,
getTitlesWidget: leftTitleWidgets,
reservedSize: 25,
),
),
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
interval: 12,
getTitlesWidget: (value, meta) {
switch (value.toInt()) {
case 0:
return SideTitleWidget(
axisSide: meta.axisSide,
child: const BodySmall(text: '1'),
);
// @override
// Widget build(BuildContext context) {
// return DecoratedBox(
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(15),
// ),
// child: Padding(
// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
// child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const EnergyUsageHeader(),
// ConstrainedBox(
// constraints: const BoxConstraints(
// maxHeight: 150,
// minHeight: 150,
// ),
// child: LineChart(
// LineChartData(
// gridData: FlGridData(
// show: true,
// drawHorizontalLine: true,
// horizontalInterval: 2,
// drawVerticalLine: false,
// getDrawingHorizontalLine: (value) {
// return FlLine(
// color: Colors.grey.withOpacity(.5),
// strokeWidth: 1,
// );
// },
// ),
// titlesData: FlTitlesData(
// show: true,
// rightTitles: AxisTitles(
// sideTitles: SideTitles(
// showTitles: true,
// interval: 1,
// getTitlesWidget: leftTitleWidgets,
// reservedSize: 25,
// ),
// ),
// topTitles: const AxisTitles(
// sideTitles: SideTitles(showTitles: false),
// ),
// bottomTitles: AxisTitles(
// sideTitles: SideTitles(
// showTitles: true,
// reservedSize: 30,
// interval: 12,
// getTitlesWidget: (value, meta) {
// switch (value.toInt()) {
// case 0:
// return SideTitleWidget(
// axisSide: meta.axisSide,
// child: const BodySmall(text: '1'),
// );
case 11:
return SideTitleWidget(
axisSide: meta.axisSide,
child: const BodySmall(text: '28'),
);
default:
return Container();
}
},
),
),
leftTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
),
minX: 0,
maxX: 11,
minY: 0,
maxY: 6,
lineBarsData: [
LineChartBarData(
spots: const [
FlSpot(0, 3),
FlSpot(2.6, 2),
FlSpot(4.9, 5),
FlSpot(6.8, 3.1),
FlSpot(8, 4),
FlSpot(9.5, 3),
FlSpot(11, 4),
],
isCurved: true,
gradient: LinearGradient(
colors: [
ColorsManager.primaryColor,
ColorsManager.primaryColor.withOpacity(0.3),
],
),
barWidth: 5,
isStrokeCapRound: true,
dotData: const FlDotData(
show: false,
),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: [
ColorsManager.primaryColor.withOpacity(0.5),
ColorsManager.primaryColor.withOpacity(0.1),
],
),
),
),
],
),
),
)
],
),
),
);
}
// case 11:
// return SideTitleWidget(
// axisSide: meta.axisSide,
// child: const BodySmall(text: '28'),
// );
// default:
// return Container();
// }
// },
// ),
// ),
// leftTitles: const AxisTitles(
// sideTitles: SideTitles(showTitles: false),
// ),
// ),
// minX: 0,
// maxX: 11,
// minY: 0,
// maxY: 6,
// lineBarsData: [
// LineChartBarData(
// spots: const [
// FlSpot(0, 3),
// FlSpot(2.6, 2),
// FlSpot(4.9, 5),
// FlSpot(6.8, 3.1),
// FlSpot(8, 4),
// FlSpot(9.5, 3),
// FlSpot(11, 4),
// ],
// isCurved: true,
// gradient: LinearGradient(
// colors: [
// ColorsManager.primaryColor,
// ColorsManager.primaryColor.withOpacity(0.3),
// ],
// ),
// barWidth: 5,
// isStrokeCapRound: true,
// dotData: const FlDotData(
// show: false,
// ),
// belowBarData: BarAreaData(
// show: true,
// gradient: LinearGradient(
// colors: [
// ColorsManager.primaryColor.withOpacity(0.5),
// ColorsManager.primaryColor.withOpacity(0.1),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// )
// ],
// ),
// ),
// );
// }
Widget leftTitleWidgets(double value, TitleMeta meta) {
String text;
switch (value.toInt()) {
case 1:
text = '1K';
break;
case 3:
text = '3k';
break;
case 5:
text = '5k';
break;
default:
return Container();
}
// Widget leftTitleWidgets(double value, TitleMeta meta) {
// String text;
// switch (value.toInt()) {
// case 1:
// text = '1K';
// break;
// case 3:
// text = '3k';
// break;
// case 5:
// text = '5k';
// break;
// default:
// return Container();
// }
return Center(child: BodySmall(text: text));
}
// return Center(child: BodySmall(text: text));
// }
Widget bottomTitleWidgets(double value, TitleMeta meta) {
// const style = TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 16,
// );
// Widget text;
// switch (value.toInt()) {
// case 2:
// text = const Text('MAR', style: style);
// break;
// case 5:
// text = const Text('JUN', style: style);
// break;
// case 8:
// text = const Text('SEP', style: style);
// break;
// default:
// text = const Text('', style: style);
// break;
// }
// Widget bottomTitleWidgets(double value, TitleMeta meta) {
// // const style = TextStyle(
// // fontWeight: FontWeight.bold,
// // fontSize: 16,
// // );
// // Widget text;
// // switch (value.toInt()) {
// // case 2:
// // text = const Text('MAR', style: style);
// // break;
// // case 5:
// // text = const Text('JUN', style: style);
// // break;
// // case 8:
// // text = const Text('SEP', style: style);
// // break;
// // default:
// // text = const Text('', style: style);
// // break;
// // }
return SideTitleWidget(
axisSide: meta.axisSide,
child: const BodySmall(text: 'Feb'),
);
}
}
// return SideTitleWidget(
// axisSide: meta.axisSide,
// child: const BodySmall(text: 'Feb'),
// );
// }
// }

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
@ -16,6 +17,7 @@ import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
@ -112,8 +114,9 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
FetchRoomsEvent event, Emitter<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
Project? project = HomeCubit.getInstance().project;
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
event.unit.community.uuid, event.unit.id, project?.uuid ?? TempConst.projectIdDev);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
@ -125,12 +128,14 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
try {
emit(SixSceneLoadingState());
if (_hasSelectionChanged) {
Project? project = HomeCubit.getInstance().project;
await HomeManagementAPI.assignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, sixSceneId);
event.unit.community.uuid, event.unit.id, event.roomId, sixSceneId, project?.uuid ?? TempConst.projectIdDev);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
List<String> allDevicesIds = [];
allDevices.forEach((element) {
allDevicesIds.add(element.uuid!);
@ -341,8 +346,10 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
emit(SixSceneLoadingState());
try {
Project? project = HomeCubit.getInstance().project;
allScenes = await SceneApi.getScenesByUnitId(
event.unitId, event.unit.community.uuid,
event.unitId, event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
showInDevice: event.showInDevice);
filteredScenes = allScenes;

View File

@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
@ -28,7 +27,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
bool allAcsPage = false;
bool allAcsOn = true;
bool allTempSame = true;
int globalTemp = 25;
int globalTemp = 250;
Timer? _timer;
ACsBloc({required this.acId}) : super(AcsInitialState()) {
@ -69,11 +68,10 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus =
AcStatusModel.fromJson(response['productUuid'], statusModelList);
deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList);
emit(GetAcStatusState(acStatusModel: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
_listenToChanges(acId);
}
} catch (e) {
emit(AcsFailedState(errorMessage: e.toString()));
@ -81,29 +79,38 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
}
}
_listenToChanges() {
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges(acId) {
try {
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$acId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) {
_streamSubscription = stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList
.add(StatusModel(code: element['code'], value: element['value']));
statusList.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus =
AcStatusModel.fromJson(usersMap['productUuid'], statusList);
add(AcUpdated());
});
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_onAcUpdated(AcUpdated event, Emitter<AcsState> emit) {
emit(GetAcStatusState(acStatusModel: deviceStatus));
}
@ -115,15 +122,16 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC');
for (int i = 0; i < devicesList.length; i++) {
_listenToChanges(devicesList[i].uuid);
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatusList.add(
AcStatusModel.fromJson(response['productUuid'], statusModelList));
deviceStatusList.add(AcStatusModel.fromJson(devicesList[i].uuid ?? '', statusModelList));
}
_setAllAcsTempsAndSwitches();
}
@ -132,11 +140,10 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
if (allAcsPage) {
emit(AcsLoadingState());
for (AcStatusModel ac in deviceStatusList) {
if (ac.uuid == event.productId) {
if (ac.uuid == event.deviceId) {
ac.acSwitch = acSwitchValue;
}
}
_setAllAcsTempsAndSwitches();
_emitAcsStatus(emit);
@ -146,8 +153,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
await _runDeBouncerForOneDevice(
deviceId: event.deviceId, code: 'switch', value: acSwitchValue);
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'switch', value: acSwitchValue);
}
void _changeAllAcSwitch(ChangeAllSwitch event, Emitter<AcsState> emit) async {
@ -208,8 +214,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
deviceStatus.childLock = lockValue;
emit(AcModifyingState(acStatusModel: deviceStatus));
await _runDeBouncerForOneDevice(
deviceId: acId, code: 'child_lock', value: lockValue);
await _runDeBouncerForOneDevice(deviceId: acId, code: 'child_lock', value: lockValue);
}
void _increaseCoolTo(IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
@ -225,7 +230,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
if (allAcsPage) {
emit(AcsLoadingState());
for (AcStatusModel ac in deviceStatusList) {
if (ac.uuid == event.productId) {
if (ac.uuid == event.deviceId) {
ac.tempSet = value;
}
}
@ -237,8 +242,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
await _runDeBouncerForOneDevice(
deviceId: event.deviceId, code: 'temp_set', value: value);
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value);
}
void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
@ -254,7 +258,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
if (allAcsPage) {
emit(AcsLoadingState());
for (AcStatusModel ac in deviceStatusList) {
if (ac.uuid == event.productId) {
if (ac.uuid == event.deviceId) {
ac.tempSet = value;
}
}
@ -266,8 +270,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
emit(AcModifyingState(acStatusModel: deviceStatus));
}
await _runDeBouncerForOneDevice(
deviceId: event.deviceId, code: 'temp_set', value: value);
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value);
}
void _changeAcMode(ChangeAcMode event, Emitter<AcsState> emit) async {
@ -275,7 +278,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
if (allAcsPage) {
emit(AcsLoadingState());
for (AcStatusModel ac in deviceStatusList) {
if (ac.uuid == event.productId) {
if (ac.uuid == event.deviceId) {
ac.modeString = getACModeString(tempMode);
ac.acMode = AcStatusModel.getACMode(getACModeString(tempMode));
}
@ -289,9 +292,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
}
await _runDeBouncerForOneDevice(
deviceId: event.deviceId,
code: 'mode',
value: getACModeString(tempMode));
deviceId: event.deviceId, code: 'mode', value: getACModeString(tempMode));
}
void _changeFanSpeed(ChangeFanSpeed event, Emitter<AcsState> emit) async {
@ -302,25 +303,21 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
if (allAcsPage) {
emit(AcsLoadingState());
for (AcStatusModel ac in deviceStatusList) {
if (ac.uuid == event.productId) {
if (ac.uuid == event.deviceId) {
ac.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
ac.acFanSpeed =
AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
ac.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
}
}
_emitAcsStatus(emit);
} else {
emit(AcChangeLoading(acStatusModel: deviceStatus));
deviceStatus.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
deviceStatus.acFanSpeed =
AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
emit(AcModifyingState(acStatusModel: deviceStatus));
}
await _runDeBouncerForOneDevice(
deviceId: event.deviceId,
code: 'level',
value: getNextFanSpeedKey(fanSpeed));
deviceId: event.deviceId, code: 'level', value: getNextFanSpeedKey(fanSpeed));
}
String getACModeString(TempModes value) {
@ -339,17 +336,15 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
allAcsOn = true;
allTempSame = true;
if (deviceStatusList.isNotEmpty) {
int temp = deviceStatusList[0].tempSet;
deviceStatusList.firstWhere((element) {
int temp = deviceStatusList.first.tempSet;
for (var element in deviceStatusList) {
if (!element.acSwitch) {
allAcsOn = false;
}
if (element.tempSet != temp) {
allTempSame = false;
}
return true;
});
}
if (allTempSame) {
globalTemp = temp;
}
@ -365,8 +360,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
for (int i = 0; i < deviceStatusList.length; i++) {
try {
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: devicesList[i].uuid, code: code, value: value),
DeviceControlModel(deviceId: devicesList[i].uuid, code: code, value: value),
devicesList[i].uuid ?? '');
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
@ -388,10 +382,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
_timer = Timer(const Duration(seconds: 1), () async {
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: allAcsPage ? deviceId : acId,
code: code,
value: value),
DeviceControlModel(deviceId: allAcsPage ? deviceId : acId, code: code, value: value),
allAcsPage ? deviceId : acId);
if (!response['success']) {
@ -408,8 +399,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
if (value >= 20 && value <= 30) {
return true;
} else {
emit(const AcsFailedState(
errorMessage: 'The temperature must be between 20 and 30'));
emit(const AcsFailedState(errorMessage: 'The temperature must be between 20 and 30'));
emit(GetAllAcsStatusState(
allAcsStatues: deviceStatusList,
allAcs: devicesList,
@ -435,9 +425,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
try {
seconds = event.seconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: acId, code: 'countdown_time', value: event.duration),
acId);
DeviceControlModel(deviceId: acId, code: 'countdown_time', value: event.duration), acId);
if (response['success'] ?? false) {
deviceStatus.countdown1 = seconds;
@ -458,24 +446,26 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
}
void _getCounterValue(GetCounterEvent event, Emitter<AcsState> emit) async {
try {
emit(AcsLoadingState());
var response = await DevicesAPI.getDeviceStatus(acId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus =
AcStatusModel.fromJson(response['productUuid'], statusModelList);
if (event.deviceCode == 'countdown_time') {
deviceStatus.countdown1 > 0
? _onStartTimer(deviceStatus.countdown1)
: emit(UpdateTimerState(seconds: deviceStatus.countdown1));
}
} catch (e) {
emit(AcsFailedState(errorMessage: e.toString()));
return;
emit(AcsLoadingState());
var response = await DevicesAPI.getDeviceStatus(acId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList);
deviceStatus.countdown1;
var duration;
if (deviceStatus.countdown1 == 5) {
duration = const Duration(minutes: 30);
var countNum = duration.inSeconds;
_onStartTimer(countNum);
} else if (deviceStatus.countdown1 > 5) {
duration = Duration(minutes: deviceStatus.countdown1 * 6);
var countNum = duration.inSeconds;
_onStartTimer(countNum);
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}

View File

@ -1,4 +1,4 @@
import 'dart:convert';
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
@ -35,35 +35,49 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
}
deviceStatus = CeilingSensorModel.fromJson(statusModelList);
emit(UpdateState(ceilingSensorModel: deviceStatus));
// _listenToChanges();
_listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
StreamSubscription<DatabaseEvent>? _streamSubscription;
Timer? _timer;
void _listenToChanges() {
try {
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$deviceId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) {
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = CeilingSensorModel.fromJson(statusList);
add(CeilingSensorUpdated());
if (!isClosed) {
add(CeilingSensorUpdated());
}
});
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_onCeilingSensorUpdated(
CeilingSensorUpdated event, Emitter<CeilingSensorState> emit) {
emit(UpdateState(ceilingSensorModel: deviceStatus));

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dart';
@ -30,6 +32,7 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
on<InitialWizardEvent>(_fetchWizardStatus);
on<GroupAllOffEvent>(_groupAllOff);
on<GroupAllOnEvent>(_groupAllOn);
on<UpdateCurtainEvent>(_updateCurtain);
}
Future<void> _onOpenCurtain(
@ -161,7 +164,10 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
void _fetchStatus(InitCurtain event, Emitter<CurtainState> emit) async {
try {
emit(CurtainLoadingState());
_listenToChanges(curtainId);
var response = await DevicesAPI.getDeviceStatus(curtainId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
@ -169,7 +175,6 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
openPercentage = double.tryParse(statusModelList[1].value.toString())!;
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
emit(CurtainsOpening(
curtainWidth: curtainWidth,
blindHeight: blindHeight,
@ -181,6 +186,76 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
}
}
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges(curtainId) {
try {
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$curtainId');
Stream<DatabaseEvent> stream = ref.onValue;
_streamSubscription = stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
openPercentage = double.tryParse(statusList[1].value.toString())!;
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
add(UpdateCurtainEvent());
});
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
// _listenToChanges(curtainId) {
// try {
// print('curtainId=$curtainId');
// DatabaseReference ref =
// FirebaseDatabase.instance.ref('device-status/$curtainId');
// Stream<DatabaseEvent> stream = ref.onValue;
// stream.listen((DatabaseEvent event) async {
// if (_timer != null) {
// await Future.delayed(const Duration(seconds: 2));
// }
// Map<dynamic, dynamic> usersMap =
// event.snapshot.value as Map<dynamic, dynamic>;
// List<StatusModel> statusModelList = [];
// for (var status in usersMap['status']) {
// statusModelList.add(StatusModel.fromJson(status));
// print('statusModelList==${statusModelList}');
// }
// openPercentage = double.tryParse(statusModelList[1].value.toString())!;
// curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
// blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
// add(UpdateCurtainEvent());
// });
// } catch (_) {}
// }
_updateCurtain(UpdateCurtainEvent event, Emitter<CurtainState> emit) {
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
emit(CurtainsOpening(
curtainWidth: curtainWidth,
blindHeight: blindHeight,
openPercentage: openPercentage,
));
}
List<GroupCurtainModel> groupList = [];
bool allSwitchesOn = true;
List<DeviceModel> devicesList = [];

View File

@ -33,6 +33,7 @@ class InitCurtain extends CurtainEvent {}
class PauseCurtain extends CurtainEvent {}
class useCurtainEvent extends CurtainEvent {}
class InitialWizardEvent extends CurtainEvent {}
class UpdateCurtainEvent extends CurtainEvent {}
class ChangeFirstWizardSwitchStatusEvent extends CurtainEvent {

View File

@ -2,6 +2,8 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.dart';
@ -10,6 +12,7 @@ import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
@ -27,11 +30,16 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
static List<DevicesCategoryModel>? allCategories;
Future<void> _onFetchAllDevices(FetchAllDevices event, Emitter<DeviceManagerState> emit) async {
Future<void> _onFetchAllDevices(
FetchAllDevices event, Emitter<DeviceManagerState> emit) async {
emit(state.copyWith(loading: true));
try {
final allDevices = await HomeManagementAPI.fetchDevicesByUnitId();
emit(state.copyWith(devices: _getOnlyImplementedDevices(allDevices), loading: false));
Project? project = HomeCubit.getInstance().project;
final allDevices = await HomeManagementAPI.fetchDevicesByUnitId(
project?.uuid ?? TempConst.projectIdDev);
emit(state.copyWith(
devices: _getOnlyImplementedDevices(allDevices), loading: false));
} catch (e) {
emit(state.copyWith(error: e.toString(), loading: false));
}
@ -41,26 +49,31 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
FetchDevicesByRoomId event, Emitter<DeviceManagerState> emit) async {
emit(state.copyWith(loading: true));
try {
final devices = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId,
);
Project? project = HomeCubit.getInstance().project;
emit(state.copyWith(devices: _getOnlyImplementedDevices(devices), loading: false));
final devices = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
emit(state.copyWith(
devices: _getOnlyImplementedDevices(devices), loading: false));
} catch (e) {
emit(state.copyWith(error: e.toString(), loading: false));
}
}
void _onSelectCategory(SelectCategory event, Emitter<DeviceManagerState> emit) {
void _onSelectCategory(
SelectCategory event, Emitter<DeviceManagerState> emit) {
for (var i = 0; i < allCategories!.length; i++) {
allCategories![i].isSelected = i == event.index;
}
emit(state.copyWith(categoryChanged: true));
}
void _onUnselectAllCategories(UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
void _onUnselectAllCategories(
UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
for (var category in allCategories!) {
category.isSelected = false;
}
@ -104,7 +117,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
_updateDevicesStatus(category, emit);
}
void _onTurnOnOffDevice(TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
void _onTurnOnOffDevice(
TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
var device = event.device;
device.isOnline = !device.isOnline!;
DevicesCategoryModel category = allCategories!.firstWhere((category) {
@ -127,7 +141,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
emit(state.copyWith(categoryChanged: true)); // Set category changed state
}
void _updateDevicesStatus(DevicesCategoryModel category, Emitter<DeviceManagerState> emit) {
void _updateDevicesStatus(
DevicesCategoryModel category, Emitter<DeviceManagerState> emit) {
if (category.devices != null && category.devices!.isNotEmpty) {
bool? tempStatus = category.devices![0].isOnline;
for (var device in category.devices!) {
@ -147,24 +162,26 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
try {
final deviceFunctions = await DevicesAPI.deviceFunctions(event.deviceId);
emit(state.copyWith(functionsLoading: false, deviceFunctions: deviceFunctions));
emit(state.copyWith(
functionsLoading: false, deviceFunctions: deviceFunctions));
} catch (e) {
emit(state.copyWith(functionsLoading: false, error: e.toString()));
}
}
_getOnlyImplementedDevices(List<DeviceModel> devices) {
List<DeviceModel> implementedDevices = [];
for (int i = 0; i < devices.length; i++) {
if (devices[i].productType == DeviceType.AC ||
devices[i].productType == DeviceType.DoorLock ||
devices[i].productType == DeviceType.Gateway ||
devices[i].productType == DeviceType.WallSensor ||
devices[i].productType == DeviceType.CeilingSensor ||
devices[i].productType == DeviceType.ThreeGang) {
implementedDevices.add(devices[i]);
}
}
return implementedDevices;
List<DeviceModel> _getOnlyImplementedDevices(List<DeviceModel> devices) {
const allowedDeviceTypes = {
DeviceType.AC,
DeviceType.DoorLock,
DeviceType.Gateway,
DeviceType.WallSensor,
DeviceType.CeilingSensor,
DeviceType.ThreeGang,
DeviceType.OneGang,
};
return devices
.where((device) => allowedDeviceTypes.contains(device.productType))
.toList();
}
}

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
@ -18,6 +19,7 @@ import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
@ -349,13 +351,20 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
AssignRoomEvent event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
Project? project = HomeCubit.getInstance().project;
if (_hasSelectionChanged) {
await HomeManagementAPI.assignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, deviceId);
event.unit.community.uuid,
event.unit.id,
event.roomId,
deviceId,
project?.uuid ?? TempConst.projectIdDev);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
List<String> allDevicesIds = [];
allDevices.forEach((element) {
allDevicesIds.add(element.uuid!);
@ -375,8 +384,12 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
FetchRoomsEvent event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
Project? project = HomeCubit.getInstance().project;
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
event.unit.community.uuid,
event.unit.id,
project?.uuid ?? TempConst.projectIdDev);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(

View File

@ -1,10 +1,14 @@
// ignore_for_file: constant_identifier_names, unused_import
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_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
@ -19,6 +23,7 @@ import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/network_exception.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
part 'devices_state.dart';
@ -48,7 +53,6 @@ class DevicesCubit extends Cubit<DevicesState> {
return _instance ??= DevicesCubit._();
}
@override
Future<void> close() {
_instance = null;
@ -62,6 +66,43 @@ class DevicesCubit extends Cubit<DevicesState> {
}
}
Timer? _timer;
final Map<String, StreamSubscription<DatabaseEvent>> _deviceSubscriptions =
{};
void _listenToChanges(deviceId) {
try {
if (_deviceSubscriptions.containsKey(deviceId)) {
_deviceSubscriptions[deviceId]?.cancel();
_deviceSubscriptions.remove(deviceId);
}
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$deviceId');
Stream<DatabaseEvent> stream = ref.onValue;
final subscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
// print('object-----${usersMap['status']}');
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
emitSafe(GetDevicesLoading());
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceId);
if (deviceIndex != -1) {
allDevices[deviceIndex].status = statusList;
}
emitSafe(GetDevicesSuccess(allDevices));
});
_deviceSubscriptions[deviceId] = subscription;
} catch (_) {}
}
static DevicesCubit get(context) => BlocProvider.of(context);
List<DevicesCategoryModel>? allCategories;
@ -310,11 +351,14 @@ class DevicesCubit extends Cubit<DevicesState> {
.subspaces
.indexWhere((element) => element.id == roomId);
try {
Project? project = HomeCubit.getInstance().project;
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices =
await DevicesAPI.getDevicesByRoomId(
communityUuid: unit!.community.uuid,
spaceUuid: unit.id,
roomId: roomId);
roomId: roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
} catch (e) {
emitSafe(GetDevicesError(e.toString()));
return;
@ -411,11 +455,26 @@ class DevicesCubit extends Cubit<DevicesState> {
Future<void> fetchAllDevices(SpaceModel? unit) async {
emitSafe(GetDevicesLoading());
try {
Project? project = HomeCubit.getInstance().project;
final devices = await DevicesAPI.getAllDevices(
communityUuid: unit!.community.uuid,
spaceUuid: unit.id,
);
communityUuid: unit!.community.uuid,
spaceUuid: unit.id,
projectId: project?.uuid ?? TempConst.projectIdDev);
allDevices = devices;
for (var deviceId in allDevices) {
if (deviceId.type == "3G" ||
deviceId.type == "2G" ||
deviceId.type == "1G" ||
deviceId.type == "3GT" ||
deviceId.type == "2GT" ||
deviceId.type == "1GT" ||
deviceId.type == "WH" ||
deviceId.type == "CUR" ||
deviceId.type == "AC") {
_listenToChanges(deviceId.uuid);
}
}
emitSafe(GetDevicesSuccess(allDevices));
} catch (e) {
emitSafe(GetDevicesError(e.toString()));
@ -474,26 +533,35 @@ class DevicesCubit extends Cubit<DevicesState> {
}
final device = allDevices[deviceIndex];
final switches = ['switch_1', 'switch_2', 'switch_3'];
final anySwitchOff = device.status.any(
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
);
final targetState = anySwitchOff ? true : false;
for (final switchCode in switches) {
final statusIndex =
device.status.indexWhere((s) => s.code == switchCode);
if (statusIndex != -1) {
final currentValue = device.status[statusIndex].value ?? false;
final toggledValue = !currentValue;
if (!targetState && !currentValue) {
continue;
}
final controlRequest = DeviceControlModel(
code: switchCode, value: toggledValue, deviceId: deviceUuid);
code: switchCode, value: targetState, deviceId: deviceUuid);
final response =
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
if (response['success'] != true) {
throw Exception('Failed to toggle $switchCode');
}
device.status[statusIndex].value = toggledValue;
device.status[statusIndex].value = targetState;
}
}
final anySwitchOff = device.status.any(
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
device.toggleStatus = device.status.every(
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == true),
);
device.toggleStatus = !anySwitchOff;
allDevices[deviceIndex] = device;
emit(DeviceControlSuccess(code: control.code));
} catch (failure) {
@ -518,8 +586,7 @@ class DevicesCubit extends Cubit<DevicesState> {
final statusIndex =
device.status.indexWhere((s) => s.code == switchCode);
if (statusIndex != -1) {
final currentValue = device.status[statusIndex].value ?? false;
final toggledValue = !currentValue;
final toggledValue = control.value;
final controlRequest = DeviceControlModel(
code: switchCode, value: toggledValue, deviceId: deviceUuid);
final response =
@ -556,8 +623,7 @@ class DevicesCubit extends Cubit<DevicesState> {
final statusIndex =
device.status.indexWhere((s) => s.code == switchCode);
if (statusIndex != -1) {
final currentValue = device.status[statusIndex].value ?? false;
final toggledValue = !currentValue;
final toggledValue = control.value;
final controlRequest = DeviceControlModel(
code: switchCode, value: toggledValue, deviceId: deviceUuid);
final response =
@ -589,13 +655,11 @@ class DevicesCubit extends Cubit<DevicesState> {
final statusIndex = device.status.indexWhere((s) => s.code == 'switch_1');
if (statusIndex != -1) {
final currentValue = device.status[statusIndex].value ?? false;
final toggledValue = !currentValue;
final toggledValue = control.value;
final controlRequest = DeviceControlModel(
code: 'switch_1', value: toggledValue, deviceId: deviceUuid);
final response =
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
print(response);
if (response['result'] != true) {
throw Exception('Failed to toggle switch_1');
}

View File

@ -21,13 +21,14 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
on<ToggleDoorAlarmEvent>(_toggleDoorAlarm);
}
Timer? _timer;
bool lowBattery = false;
bool closingReminder = false;
bool doorAlarm = false;
DoorSensorModel deviceStatus = DoorSensorModel(doorContactState: false, batteryPercentage: 0);
DoorSensorModel deviceStatus =
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
void _fetchStatus(DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
void _fetchStatus(
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
emit(DoorSensorLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(DSId);
@ -40,7 +41,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
);
emit(UpdateState(doorSensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
_listenToChanges();
} catch (e) {
emit(DoorSensorFailedState(errorMessage: e.toString()));
return;
@ -48,7 +49,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
// Toggle functions for each switch
void _toggleLowBattery(ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
void _toggleLowBattery(
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
lowBattery = event.isLowBatteryEnabled;
@ -89,7 +91,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
}
void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
void _toggleDoorAlarm(
ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
doorAlarm = event.isDoorAlarmEnabled;
@ -108,9 +111,11 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
}
DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []);
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
Future<void> fetchLogsForLastMonth(ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
DateTime now = DateTime.now();
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
@ -133,22 +138,27 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
}
_listenToChanges() {
// real-time database
Timer? _timer;
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$DSId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$DSId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: true));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = DoorSensorModel.fromJson(statusList);
if (!isClosed) {
add(
@ -158,4 +168,11 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
});
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
}

View File

@ -1,6 +1,8 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
@ -14,6 +16,7 @@ import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
@ -230,6 +233,7 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
deviceStatus = FourSceneModelState.fromJson(
statusModelList,
);
// _listenToChanges();
add(const FourSceneSwitchInitial());
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
@ -299,9 +303,11 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
LoadScenes event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState());
try {
Project? project = HomeCubit.getInstance().project;
if (event.unitId.isNotEmpty) {
allScenes = await SceneApi.getScenesByUnitId(
event.unitId, event.unit.community.uuid,
event.unitId, event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
showInDevice: event.showInDevice);
filteredScenes = allScenes;
@ -327,4 +333,33 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
}).toList();
emit(SearchResultsState());
}
// Real-time database
// Timer? _timer;
// _listenToChanges() {
// try {
// DatabaseReference ref =
// FirebaseDatabase.instance.ref('device-status/$fourSceneId');
// Stream<DatabaseEvent> stream = ref.onValue;
// stream.listen((DatabaseEvent event) async {
// if (_timer != null) {
// await Future.delayed(const Duration(seconds: 2));
// }
// Map<dynamic, dynamic> usersMap =
// event.snapshot.value as Map<dynamic, dynamic>;
// List<StatusModel> statusList = [];
// usersMap['status'].forEach((element) {
// statusList.add(StatusModel(code: element['code'], value: true));
// });
// deviceStatus = FourSceneModelState.fromJson(statusList);
// // if (!isClosed) {
// // add(
// // DoorSensorSwitch(switchD: deviceStatus.doorContactState),
// // );
// // }
// });
// } catch (_) {}
// }
}

View File

@ -42,7 +42,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<ToggleAlarmEvent>(_toggleAlarmEvent);
on<DeleteScheduleEvent>(deleteSchedule);
//_toggleAlarmEvent
on<UpdateStateEvent>(_updateState);
}
void _onClose(OnClose event, Emitter<GarageDoorSensorState> emit) {
_timer?.cancel();
@ -81,7 +82,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
toggleDoor = deviceStatus.switch1;
emit(UpdateState(garageSensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
_listenToChanges();
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
return;
@ -180,33 +181,59 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
}
}
_listenToChanges() {
// Real-time db
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges() {
try {
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$GDId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
await Future.delayed(const Duration(seconds: 1));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: true));
});
deviceStatus = GarageDoorModel.fromJson(statusList);
if (!isClosed) {
// add(
// DoorSensorSwitch(switchD: deviceStatus.doorContactState),
// );
if (event.snapshot.value != null) {
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(
StatusModel(code: element['code'], value: element['value']));
});
deviceStatus.tr_timecon = statusList
.firstWhere((status) => status.code == "tr_timecon",
orElse: () => StatusModel(code: "tr_timecon", value: 0))
.value as int;
deviceStatus.switch1 = statusList
.firstWhere((status) => status.code == "switch_1",
orElse: () => StatusModel(code: "switch_1", value: false))
.value as bool;
secondSelected = deviceStatus.tr_timecon;
toggleDoor = deviceStatus.switch1;
add(UpdateStateEvent());
}
});
} catch (_) {}
}
Future<void> _updateState(
UpdateStateEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(GarageDoorLoadingState());
emit(UpdateState(garageSensor: deviceStatus));
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
List<Map<String, String>> days = [
{"day": "Sun", "key": "Sun"},
{"day": "Mon", "key": "Mon"},

View File

@ -109,6 +109,8 @@ class GetScheduleEvent extends GarageDoorEvent {}
class ScheduleSaveapp extends GarageDoorEvent {}
class UpdateStateEvent extends GarageDoorEvent {}
class ToggleScheduleEvent extends GarageDoorEvent {
final String id;
final bool toggle;

View File

@ -26,7 +26,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
bool oneGangGroup = false;
List<DeviceModel> devicesList = [];
OneGangBloc({required this.oneGangId, required this.switchCode}) : super(InitialState()) {
OneGangBloc({required this.oneGangId, required this.switchCode})
: super(InitialState()) {
on<InitialEvent>(_fetchOneGangStatus);
on<OneGangUpdated>(_oneGangUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
@ -49,7 +50,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
on<GroupAllOffEvent>(_groupAllOff);
}
void _fetchOneGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
void _fetchOneGangStatus(
InitialEvent event, Emitter<OneGangState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(oneGangId);
@ -59,42 +61,51 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
deviceStatus = OneGangModel.fromJson(statusModelList);
emit(UpdateState(oneGangModel: deviceStatus));
// _listenToChanges();
_listenToChanges(oneGangId);
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
// Real-time db
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges(String id) {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneGangId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$id');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
_streamSubscription = stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = OneGangModel.fromJson(statusList);
if (!isClosed) {
add(OneGangUpdated());
}
add(OneGangUpdated());
});
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_oneGangUpdated(OneGangUpdated event, Emitter<OneGangState> emit) {
emit(LoadingInitialState());
emit(UpdateState(oneGangModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<OneGangState> emit) async {
void _changeFirstSwitch(
ChangeFirstSwitchStatusEvent event, Emitter<OneGangState> emit) async {
emit(LoadingNewSate(oneGangModel: deviceStatus));
try {
deviceStatus.firstSwitch = !event.value;
@ -119,17 +130,20 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<OneGangState> emit) async {
void _changeSliding(
ChangeSlidingSegment event, Emitter<OneGangState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<OneGangState> emit) async {
void _setCounterValue(
SetCounterValue event, Emitter<OneGangState> emit) async {
emit(LoadingNewSate(oneGangModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: oneGangId, code: event.deviceCode, value: seconds),
DeviceControlModel(
deviceId: oneGangId, code: event.deviceCode, value: seconds),
oneGangId);
if (response['success'] ?? false) {
@ -152,7 +166,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
}
void _getCounterValue(GetCounterEvent event, Emitter<OneGangState> emit) async {
void _getCounterValue(
GetCounterEvent event, Emitter<OneGangState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(oneGangId);
@ -241,7 +256,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
deviceId: oneGangId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
listSchedule =
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
@ -252,12 +268,13 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
Future toggleChange(
ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
@ -276,7 +293,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<OneGangState> emit) async {
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<OneGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
@ -296,7 +314,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<OneGangState> emit) {
void toggleCreateSchedule(
ToggleCreateScheduleEvent event, Emitter<OneGangState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
@ -325,7 +344,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
int selectedTabIndex = 0;
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<OneGangState> emit) {
void toggleSelectedIndex(
ToggleSelectedEvent event, Emitter<OneGangState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
@ -334,7 +354,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
List<GroupOneGangModel> groupOneGangList = [];
bool allSwitchesOn = true;
void _fetchOneGangWizardStatus(InitialWizardEvent event, Emitter<OneGangState> emit) async {
void _fetchOneGangWizardStatus(
InitialWizardEvent event, Emitter<OneGangState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
@ -344,7 +365,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', '1G');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
@ -365,15 +387,16 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
return true;
});
}
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesOn));
emit(UpdateGroupState(
oneGangList: groupOneGangList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<OneGangState> emit) async {
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
Emitter<OneGangState> emit) async {
emit(LoadingNewSate(oneGangModel: deviceStatus));
try {
bool allSwitchesValue = true;
@ -386,7 +409,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
});
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
oneGangList: groupOneGangList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
@ -414,7 +438,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: true));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupOneGangList.map((device) => device.deviceId).toList();
// First call for switch_1
final response = await DevicesAPI.deviceBatchController(
@ -446,7 +471,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: false));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupOneGangList.map((device) => device.deviceId).toList();
// First call for switch_1
final response = await DevicesAPI.deviceBatchController(

View File

@ -30,7 +30,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
bool oneTouchGroup = false;
List<DeviceModel> devicesList = [];
OneTouchBloc({required this.oneTouchId, required this.switchCode}) : super(InitialState()) {
OneTouchBloc({required this.oneTouchId, required this.switchCode})
: super(InitialState()) {
on<InitialEvent>(_fetchOneTouchStatus);
on<OneTouchUpdated>(_oneTouchUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
@ -53,7 +54,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
on<ChangeStatusEvent>(_changeStatus);
}
void _fetchOneTouchStatus(InitialEvent event, Emitter<OneTouchState> emit) async {
void _fetchOneTouchStatus(
InitialEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
@ -62,43 +64,59 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = OneTouchModel.fromJson(statusModelList);
_listenToChanges(oneTouchId);
emit(UpdateState(oneTouchModel: deviceStatus));
// _listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges(String id) {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneTouchId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$id');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
_streamSubscription = stream.listen((DatabaseEvent event) {
if (event.snapshot.value != null) {
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
});
usersMap['status'].forEach((element) {
statusList.add(
StatusModel(code: element['code'], value: element['value']));
});
var switchStatus = statusList.firstWhere(
(status) => status.code == "switch_1",
orElse: () => StatusModel(code: "switch_1", value: false));
deviceStatus = OneTouchModel.fromJson(statusList);
if (!isClosed) {
deviceStatus.firstSwitch = switchStatus.value as bool;
add(OneTouchUpdated());
}
});
} catch (_) {}
} catch (_) {
}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_oneTouchUpdated(OneTouchUpdated event, Emitter<OneTouchState> emit) {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
emit(UpdateState(oneTouchModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<OneTouchState> emit) async {
void _changeFirstSwitch(
ChangeFirstSwitchStatusEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
try {
deviceStatus.firstSwitch = !event.value;
@ -123,17 +141,20 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<OneTouchState> emit) async {
void _changeSliding(
ChangeSlidingSegment event, Emitter<OneTouchState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<OneTouchState> emit) async {
void _setCounterValue(
SetCounterValue event, Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: oneTouchId, code: event.deviceCode, value: seconds),
DeviceControlModel(
deviceId: oneTouchId, code: event.deviceCode, value: seconds),
oneTouchId);
if (response['success'] ?? false) {
@ -156,7 +177,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
}
}
void _getCounterValue(GetCounterEvent event, Emitter<OneTouchState> emit) async {
void _getCounterValue(
GetCounterEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
@ -245,7 +267,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
deviceId: oneTouchId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
listSchedule =
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
@ -256,12 +279,13 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<OneTouchState> emit) async {
Future toggleChange(
ToggleScheduleEvent event, Emitter<OneTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
@ -280,7 +304,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<OneTouchState> emit) async {
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<OneTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
@ -300,7 +325,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
}
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<OneTouchState> emit) {
void toggleCreateSchedule(
ToggleCreateScheduleEvent event, Emitter<OneTouchState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
@ -329,7 +355,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
int selectedTabIndex = 0;
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<OneTouchState> emit) {
void toggleSelectedIndex(
ToggleSelectedEvent event, Emitter<OneTouchState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
@ -338,7 +365,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
List<GroupOneTouchModel> groupOneTouchList = [];
bool allSwitchesOn = true;
void _fetchOneTouchWizardStatus(InitialWizardEvent event, Emitter<OneTouchState> emit) async {
void _fetchOneTouchWizardStatus(
InitialWizardEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
@ -348,7 +376,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', '1GT');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
@ -369,15 +398,16 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
return true;
});
}
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesOn));
emit(UpdateGroupState(
oneTouchList: groupOneTouchList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<OneTouchState> emit) async {
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
try {
bool allSwitchesValue = true;
@ -395,7 +425,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
value: !event.value,
);
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue));
if (response['success']) {
add(InitialEvent(groupScreen: oneTouchGroup));
}
@ -413,10 +444,12 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
}
// Emit the state with updated values
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: true));
emit(
UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: true));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneTouchList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupOneTouchList.map((device) => device.deviceId).toList();
// First call for switch_1
final response1 = await DevicesAPI.deviceBatchController(
@ -445,10 +478,12 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
}
// Emit the state with updated values
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: false));
emit(UpdateGroupState(
oneTouchList: groupOneTouchList, allSwitches: false));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneTouchList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupOneTouchList.map((device) => device.deviceId).toList();
// First call for switch_1
final response1 = await DevicesAPI.deviceBatchController(
@ -472,7 +507,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
String statusSelected = '';
String optionSelected = '';
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<OneTouchState> emit) async {
Future<void> _changeStatus(
ChangeStatusEvent event, Emitter<OneTouchState> emit) async {
try {
emit(LoadingInitialState());
@ -497,7 +533,10 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
final selectedControl = controlMap[optionSelected]?[statusSelected];
if (selectedControl != null) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: oneTouchId, code: optionSelected, value: selectedControl),
DeviceControlModel(
deviceId: oneTouchId,
code: optionSelected,
value: selectedControl),
oneTouchId,
);
} else {

View File

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:math';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
@ -37,7 +38,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
on<SelectTimeEvent>(selectTimeOfLinePassword);
on<SelectTimeOnlinePasswordEvent>(selectTimeOnlinePassword);
on<DeletePasswordEvent>(deletePassword);
on<GenerateAndSavePasswordTimeLimitEvent>(generateAndSavePasswordTimeLimited);
on<GenerateAndSavePasswordTimeLimitEvent>(
generateAndSavePasswordTimeLimited);
on<GenerateAndSavePasswordOneTimeEvent>(generateAndSavePasswordOneTime);
on<ToggleDaySelectionEvent>(toggleDaySelection);
on<RenamePasswordEvent>(_renamePassword);
@ -59,7 +61,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
List<OfflinePasswordModel>? oneTimePasswords = [];
List<OfflinePasswordModel>? timeLimitPasswords = [];
Future generate7DigitNumber(GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
Future generate7DigitNumber(
GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
emit(LoadingInitialState());
passwordController.clear();
Random random = Random();
@ -71,7 +74,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
Future generateAndSavePasswordOneTime(
GenerateAndSavePasswordOneTimeEvent event, Emitter<SmartDoorState> emit) async {
GenerateAndSavePasswordOneTimeEvent event,
Emitter<SmartDoorState> emit) async {
try {
if (isSavingPassword) return;
isSavingPassword = true;
@ -92,7 +96,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
}
void _fetchSmartDoorStatus(InitialEvent event, Emitter<SmartDoorState> emit) async {
void _fetchSmartDoorStatus(
InitialEvent event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.getDeviceStatus(deviceId);
@ -102,42 +107,63 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
deviceStatus = SmartDoorModel.fromJson(statusModelList);
emit(UpdateState(smartDoorModel: deviceStatus));
// _listenToChanges();
_listenToChanges();
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
return;
}
}
_listenToChanges() {
StreamSubscription<DatabaseEvent>? _streamSubscription;
Timer? _timer;
void _listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$deviceId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = SmartDoorModel.fromJson(statusList);
add(DoorLockUpdated());
if (!isClosed) {
add(DoorLockUpdated());
}
});
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_doorLockUpdated(DoorLockUpdated event, Emitter<SmartDoorState> emit) {
unlockRequest = deviceStatus.unlockRequest;
emit(UpdateState(smartDoorModel: deviceStatus));
}
void _renamePassword(RenamePasswordEvent event, Emitter<SmartDoorState> emit) async {
void _renamePassword(
RenamePasswordEvent event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
await DevicesAPI.renamePass(
name: passwordNameController.text, doorLockUuid: deviceId, passwordId: passwordId);
name: passwordNameController.text,
doorLockUuid: deviceId,
passwordId: passwordId);
add(InitialOneTimePassword());
add(InitialTimeLimitPassword());
emit(UpdateState(smartDoorModel: deviceStatus));
@ -147,46 +173,58 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
}
void getTemporaryPasswords(InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
void getTemporaryPasswords(
InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.getTemporaryPasswords(
deviceId,
);
if (response is List) {
temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList();
} else if (response is Map && response.containsKey('data')) {
temporaryPasswords =
(response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList();
response.map((item) => TemporaryPassword.fromJson(item)).toList();
} else if (response is Map && response.containsKey('data')) {
temporaryPasswords = (response['data'] as List)
.map((item) => TemporaryPassword.fromJson(item))
.toList();
}
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
emit(TemporaryPasswordsLoadedState(
temporaryPassword: temporaryPasswords!));
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
}
}
void getOneTimePasswords(InitialOneTimePassword event, Emitter<SmartDoorState> emit) async {
void getOneTimePasswords(
InitialOneTimePassword event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.getOneTimePasswords(deviceId);
if (response is List) {
oneTimePasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
oneTimePasswords = response
.map((item) => OfflinePasswordModel.fromJson(item))
.toList();
}
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
emit(TemporaryPasswordsLoadedState(
temporaryPassword: temporaryPasswords!));
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
}
}
void getTimeLimitPasswords(InitialTimeLimitPassword event, Emitter<SmartDoorState> emit) async {
void getTimeLimitPasswords(
InitialTimeLimitPassword event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.getTimeLimitPasswords(deviceId);
if (response is List) {
timeLimitPasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
timeLimitPasswords = response
.map((item) => OfflinePasswordModel.fromJson(item))
.toList();
}
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
emit(TemporaryPasswordsLoadedState(
temporaryPassword: temporaryPasswords!));
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
}
@ -207,7 +245,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
return repeat;
}
bool setStartEndTime(SetStartEndTimeEvent event, Emitter<SmartDoorState> emit) {
bool setStartEndTime(
SetStartEndTimeEvent event, Emitter<SmartDoorState> emit) {
emit(LoadingInitialState());
isStartEndTime = event.val;
emit(IsStartEndState(isStartEndTime: isStartEndTime));
@ -230,7 +269,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
emit(UpdateState(smartDoorModel: deviceStatus));
}
Future<void> selectTimeOfLinePassword(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
Future<void> selectTimeOfLinePassword(
SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
emit(ChangeTimeState());
final DateTime? picked = await showDatePicker(
context: event.context,
@ -260,20 +300,27 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
).millisecondsSinceEpoch ~/
1000; // Divide by 1000 to remove milliseconds
if (event.isEffective) {
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
if (expirationTimeTimeStamp != null &&
selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Effective Time cannot be later than Expiration Time.');
} else {
effectiveTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
effectiveTime = selectedDateTime
.toString()
.split('.')
.first; // Remove seconds and milliseconds
effectiveTimeTimeStamp = selectedTimestamp;
}
} else {
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
if (effectiveTimeTimeStamp != null &&
selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Expiration Time cannot be earlier than Effective Time.');
} else {
expirationTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
expirationTime = selectedDateTime
.toString()
.split('.')
.first; // Remove seconds and milliseconds
expirationTimeTimeStamp = selectedTimestamp;
}
}
@ -329,20 +376,27 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
).millisecondsSinceEpoch ~/
1000; // Divide by 1000 to remove milliseconds
if (event.isEffective) {
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
if (expirationTimeTimeStamp != null &&
selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Effective Time cannot be later than Expiration Time.');
} else {
effectiveTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
effectiveTime = selectedDateTime
.toString()
.split('.')
.first; // Remove seconds and milliseconds
effectiveTimeTimeStamp = selectedTimestamp;
}
} else {
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
if (effectiveTimeTimeStamp != null &&
selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Expiration Time cannot be earlier than Effective Time.');
} else {
expirationTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
expirationTime = selectedDateTime
.toString()
.split('.')
.first; // Remove seconds and milliseconds
expirationTimeTimeStamp = selectedTimestamp;
}
}
@ -351,7 +405,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
}
Future<void> savePassword(SavePasswordEvent event, Emitter<SmartDoorState> emit) async {
Future<void> savePassword(
SavePasswordEvent event, Emitter<SmartDoorState> emit) async {
if (_validateInputs() || isSavingPassword) return;
try {
isSavingPassword = true;
@ -381,7 +436,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
Future<void> generateAndSavePasswordTimeLimited(
GenerateAndSavePasswordTimeLimitEvent event, Emitter<SmartDoorState> emit) async {
GenerateAndSavePasswordTimeLimitEvent event,
Emitter<SmartDoorState> emit) async {
if (timeLimitValidate() || isSavingPassword) return;
try {
isSavingPassword = true;
@ -407,10 +463,12 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
}
Future<void> deletePassword(DeletePasswordEvent event, Emitter<SmartDoorState> emit) async {
Future<void> deletePassword(
DeletePasswordEvent event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId)
await DevicesAPI.deletePassword(
deviceId: deviceId, passwordId: event.passwordId)
.then((value) async {
add(InitialPasswordsPage());
});
@ -445,7 +503,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
if (repeat == true && (endTime == null || startTime == null)) {
CustomSnackBar.displaySnackBar('Start Time and End time and the days required ');
CustomSnackBar.displaySnackBar(
'Start Time and End time and the days required ');
return true;
}
return false;

View File

@ -1,10 +1,12 @@
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_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
@ -19,6 +21,7 @@ import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class SosBloc extends Bloc<SosEvent, SosState> {
@ -171,6 +174,7 @@ class SosBloc extends Bloc<SosEvent, SosState> {
);
emit(UpdateState(sensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
return;
@ -184,8 +188,12 @@ class SosBloc extends Bloc<SosEvent, SosState> {
FetchRoomsEvent event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
Project? project = HomeCubit.getInstance().project;
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
event.unit.community.uuid,
event.unit.id,
project?.uuid ?? TempConst.projectIdDev);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(const SosFailedState(errorMessage: 'Something went wrong'));
@ -223,13 +231,19 @@ class SosBloc extends Bloc<SosEvent, SosState> {
void _assignDevice(AssignRoomEvent event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
Project? project = HomeCubit.getInstance().project;
await HomeManagementAPI.assignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, sosId);
event.unit.community.uuid,
event.unit.id,
event.roomId,
sosId,
project?.uuid ?? TempConst.projectIdDev);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
List<String> allDevicesIds = [];
@ -249,13 +263,16 @@ class SosBloc extends Bloc<SosEvent, SosState> {
void _unassignDevice(UnassignRoomEvent event, Emitter<SosState> emit) async {
try {
Map<String, bool> roomDevicesId = {};
Project? project = HomeCubit.getInstance().project;
emit(SosLoadingState());
await HomeManagementAPI.unAssignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, sosId);
event.unit.community.uuid, event.unit.id, event.roomId, sosId, project?.uuid ?? TempConst.projectIdDev);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
List<String> allDevicesIds = [];
@ -419,4 +436,39 @@ class SosBloc extends Bloc<SosEvent, SosState> {
emit(SosFailedState(errorMessage: e.toString()));
}
}
//real-time db
// StreamSubscription<DatabaseEvent>? _streamSubscription;
// Timer? _timer;
// void _listenToChanges() {
// try {
// _streamSubscription?.cancel();
// DatabaseReference ref =
// FirebaseDatabase.instance.ref('device-status/$sosId');
// Stream<DatabaseEvent> stream = ref.onValue;
// _streamSubscription = stream.listen((DatabaseEvent event) async {
// if (_timer != null) {
// await Future.delayed(const Duration(seconds: 2));
// }
// Map<dynamic, dynamic> usersMap =
// event.snapshot.value as Map<dynamic, dynamic>;
// List<StatusModel> statusList = [];
// usersMap['status'].forEach((element) {
// statusList
// .add(StatusModel(code: element['code'], value: element['value']));
// });
// deviceStatus = SosModel.fromJson(statusList);
// });
// } catch (_) {}
// }
// @override
// Future<void> close() async {
// _streamSubscription?.cancel();
// _streamSubscription = null;
// return super.close();
// }
}

View File

@ -31,7 +31,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
List<GroupThreeGangModel> groupThreeGangList = [];
bool allSwitchesOn = true;
ThreeGangBloc({required this.threeGangId, required this.switchCode}) : super(InitialState()) {
ThreeGangBloc({required this.threeGangId, required this.switchCode})
: super(InitialState()) {
on<InitialEvent>(_fetchThreeGangStatus);
on<ThreeGangUpdated>(_threeGangUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
@ -57,7 +58,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
}
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
void _fetchThreeGangStatus(
InitialEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingInitialState());
try {
threeGangGroup = event.groupScreen;
@ -69,7 +71,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', '3G');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
@ -86,13 +89,16 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
if (groupThreeGangList.isNotEmpty) {
groupThreeGangList.firstWhere((element) {
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesOn));
emit(UpdateGroupState(
threeGangList: groupThreeGangList, allSwitches: allSwitchesOn));
} else {
var response = await DevicesAPI.getDeviceStatus(threeGangId);
List<StatusModel> statusModelList = [];
@ -101,7 +107,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
deviceStatus = ThreeGangModel.fromJson(statusModelList);
emit(UpdateState(threeGangModel: deviceStatus));
// _listenToChanges();
_listenToChanges();
}
} catch (e) {
emit(FailedState(error: e.toString()));
@ -109,22 +115,26 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
_listenToChanges() {
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeGangId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$threeGangId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
await Future.delayed(const Duration(seconds: 1));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = ThreeGangModel.fromJson(statusList);
if (!isClosed) {
add(ThreeGangUpdated());
@ -133,11 +143,19 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_threeGangUpdated(ThreeGangUpdated event, Emitter<ThreeGangState> emit) {
emit(UpdateState(threeGangModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
void _changeFirstSwitch(
ChangeFirstSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
if (threeGangGroup) {
@ -146,11 +164,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
} else {
deviceStatus.firstSwitch = !event.value;
emit(UpdateState(threeGangModel: deviceStatus));
@ -187,11 +208,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
if (element.deviceId == event.deviceId) {
element.secondSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
} else {
deviceStatus.secondSwitch = !event.value;
emit(UpdateState(threeGangModel: deviceStatus));
@ -217,7 +241,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
void _changeThirdSwitch(
ChangeThirdSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
if (threeGangGroup) {
@ -226,11 +251,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
if (element.deviceId == event.deviceId) {
element.thirdSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
} else {
deviceStatus.thirdSwitch = !event.value;
emit(UpdateState(threeGangModel: deviceStatus));
@ -269,15 +297,21 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
deviceId: threeGangId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
deviceId: threeGangId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch),
deviceId: threeGangId,
code: 'switch_3',
value: deviceStatus.thirdSwitch),
threeGangId),
]);
@ -303,15 +337,21 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
deviceId: threeGangId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
deviceId: threeGangId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch),
deviceId: threeGangId,
code: 'switch_3',
value: deviceStatus.thirdSwitch),
threeGangId),
]);
@ -333,9 +373,11 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
groupThreeGangList[i].secondSwitch = true;
groupThreeGangList[i].thirdSwitch = true;
}
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: true));
emit(UpdateGroupState(
threeGangList: groupThreeGangList, allSwitches: true));
List<String> allDeviceIds = groupThreeGangList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupThreeGangList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
@ -365,7 +407,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<ThreeGangState> emit) async {
void _groupAllOff(
GroupAllOffEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
for (int i = 0; i < groupThreeGangList.length; i++) {
@ -373,8 +416,10 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
groupThreeGangList[i].secondSwitch = false;
groupThreeGangList[i].thirdSwitch = false;
}
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: false));
List<String> allDeviceIds = groupThreeGangList.map((device) => device.deviceId).toList();
emit(UpdateGroupState(
threeGangList: groupThreeGangList, allSwitches: false));
List<String> allDeviceIds =
groupThreeGangList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
@ -404,17 +449,20 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<ThreeGangState> emit) async {
void _changeSliding(
ChangeSlidingSegment event, Emitter<ThreeGangState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<ThreeGangState> emit) async {
void _setCounterValue(
SetCounterValue event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: event.deviceCode, value: seconds),
DeviceControlModel(
deviceId: threeGangId, code: event.deviceCode, value: seconds),
threeGangId);
if (response['success'] ?? false) {
@ -441,7 +489,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
void _getCounterValue(GetCounterEvent event, Emitter<ThreeGangState> emit) async {
void _getCounterValue(
GetCounterEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(threeGangId);
@ -551,7 +600,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
deviceId: threeGangId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
listSchedule =
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
@ -562,12 +612,13 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
Future toggleChange(
ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
@ -586,7 +637,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<ThreeGangState> emit) async {
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<ThreeGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
@ -606,13 +658,15 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<ThreeGangState> emit) {
void toggleSelectedIndex(
ToggleSelectedEvent event, Emitter<ThreeGangState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
void toggleCreateSchedule(
ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();

View File

@ -38,7 +38,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
List<GroupThreeTouchModel> groupThreeTouchList = [];
bool allSwitchesOn = true;
ThreeTouchBloc({required this.threeTouchId, required this.switchCode}) : super(InitialState()) {
ThreeTouchBloc({required this.threeTouchId, required this.switchCode})
: super(InitialState()) {
on<InitialEvent>(_fetchThreeTouchStatus);
on<ThreeTouchUpdated>(_threeTouchUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
@ -63,7 +64,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
on<ChangeStatusEvent>(_changeStatus);
}
void _fetchThreeTouchStatus(InitialEvent event, Emitter<ThreeTouchState> emit) async {
void _fetchThreeTouchStatus(
InitialEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingInitialState());
try {
threeTouchGroup = event.groupScreen;
@ -75,7 +77,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', '3GT');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
@ -92,13 +95,16 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
if (groupThreeTouchList.isNotEmpty) {
groupThreeTouchList.firstWhere((element) {
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesOn));
emit(UpdateGroupState(
threeTouchList: groupThreeTouchList, allSwitches: allSwitchesOn));
} else {
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
List<StatusModel> statusModelList = [];
@ -107,7 +113,7 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
deviceStatus = ThreeTouchModel.fromJson(statusModelList);
emit(UpdateState(threeTouchModel: deviceStatus));
// _listenToChanges();
_listenToChanges();
}
} catch (e) {
emit(FailedState(error: e.toString()));
@ -117,18 +123,21 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
_listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeTouchId');
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$threeTouchId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = ThreeTouchModel.fromJson(statusList);
@ -143,7 +152,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
emit(UpdateState(threeTouchModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
void _changeFirstSwitch(
ChangeFirstSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
if (threeTouchGroup) {
@ -152,11 +162,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
threeTouchList: groupThreeTouchList,
allSwitches: allSwitchesValue));
} else {
deviceStatus.firstSwitch = !event.value;
emit(UpdateState(threeTouchModel: deviceStatus));
@ -183,8 +197,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
}
void _changeSecondSwitch(
ChangeSecondSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event,
Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
if (threeTouchGroup) {
@ -193,11 +207,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
if (element.deviceId == event.deviceId) {
element.secondSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
threeTouchList: groupThreeTouchList,
allSwitches: allSwitchesValue));
} else {
deviceStatus.secondSwitch = !event.value;
emit(UpdateState(threeTouchModel: deviceStatus));
@ -223,7 +241,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
}
void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
void _changeThirdSwitch(
ChangeThirdSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
if (threeTouchGroup) {
@ -232,11 +251,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
if (element.deviceId == event.deviceId) {
element.thirdSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
if (!element.firstSwitch ||
!element.secondSwitch ||
!element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
threeTouchList: groupThreeTouchList,
allSwitches: allSwitchesValue));
} else {
deviceStatus.thirdSwitch = !event.value;
emit(UpdateState(threeTouchModel: deviceStatus));
@ -275,15 +298,21 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
deviceId: threeTouchId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
deviceId: threeTouchId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_3', value: deviceStatus.thirdSwitch),
deviceId: threeTouchId,
code: 'switch_3',
value: deviceStatus.thirdSwitch),
threeTouchId),
]);
@ -309,15 +338,21 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
deviceId: threeTouchId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
deviceId: threeTouchId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_3', value: deviceStatus.thirdSwitch),
deviceId: threeTouchId,
code: 'switch_3',
value: deviceStatus.thirdSwitch),
threeTouchId),
]);
@ -339,8 +374,10 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
groupThreeTouchList[i].secondSwitch = true;
groupThreeTouchList[i].thirdSwitch = true;
}
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: true));
List<String> allDeviceIds = groupThreeTouchList.map((device) => device.deviceId).toList();
emit(UpdateGroupState(
threeTouchList: groupThreeTouchList, allSwitches: true));
List<String> allDeviceIds =
groupThreeTouchList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
@ -369,7 +406,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<ThreeTouchState> emit) async {
void _groupAllOff(
GroupAllOffEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
for (int i = 0; i < groupThreeTouchList.length; i++) {
@ -377,8 +415,10 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
groupThreeTouchList[i].secondSwitch = false;
groupThreeTouchList[i].thirdSwitch = false;
}
List<String> allDeviceIds = groupThreeTouchList.map((device) => device.deviceId).toList();
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: false));
List<String> allDeviceIds =
groupThreeTouchList.map((device) => device.deviceId).toList();
emit(UpdateGroupState(
threeTouchList: groupThreeTouchList, allSwitches: false));
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
@ -407,17 +447,20 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<ThreeTouchState> emit) async {
void _changeSliding(
ChangeSlidingSegment event, Emitter<ThreeTouchState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<ThreeTouchState> emit) async {
void _setCounterValue(
SetCounterValue event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeTouchId, code: event.deviceCode, value: seconds),
DeviceControlModel(
deviceId: threeTouchId, code: event.deviceCode, value: seconds),
threeTouchId);
if (response['success'] ?? false) {
@ -444,7 +487,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
}
void _getCounterValue(GetCounterEvent event, Emitter<ThreeTouchState> emit) async {
void _getCounterValue(
GetCounterEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
@ -554,7 +598,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
deviceId: threeTouchId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
listSchedule =
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
@ -565,12 +610,13 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<ThreeTouchState> emit) async {
Future toggleChange(
ToggleScheduleEvent event, Emitter<ThreeTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
@ -589,7 +635,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<ThreeTouchState> emit) async {
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<ThreeTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
@ -609,13 +656,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
}
}
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<ThreeTouchState> emit) {
void toggleSelectedIndex(
ToggleSelectedEvent event, Emitter<ThreeTouchState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeTouchState> emit) {
void toggleCreateSchedule(
ToggleCreateScheduleEvent event, Emitter<ThreeTouchState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
@ -633,7 +682,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
String statusSelected = '';
String optionSelected = '';
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<ThreeTouchState> emit) async {
Future<void> _changeStatus(
ChangeStatusEvent event, Emitter<ThreeTouchState> emit) async {
try {
emit(LoadingInitialState());
final Map<String, Map<String, String>> controlMap = {
@ -667,11 +717,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
final selectedControl = controlMap[optionSelected]?[statusSelected];
if (selectedControl != null) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeTouchId, code: optionSelected, value: selectedControl),
DeviceControlModel(
deviceId: threeTouchId,
code: optionSelected,
value: selectedControl),
threeTouchId,
);
} else {
emit(const FailedState(error: 'Invalid statusSelected or optionSelected'));
emit(const FailedState(
error: 'Invalid statusSelected or optionSelected'));
}
} on DioException catch (e) {
final errorData = e.response!.data;

View File

@ -35,7 +35,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
bool createSchedule = false;
List<ScheduleModel> listSchedule = [];
TwoGangBloc({required this.twoGangId, required this.switchCode}) : super(InitialState()) {
TwoGangBloc({required this.twoGangId, required this.switchCode})
: super(InitialState()) {
on<InitialEvent>(_fetchTwoGangStatus);
on<TwoGangUpdated>(_twoGangUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
@ -65,13 +66,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
int selectedTabIndex = 0;
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
void toggleSelectedIndex(
ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<TwoGangState> emit) {
void toggleCreateSchedule(
ToggleCreateScheduleEvent event, Emitter<TwoGangState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
@ -79,7 +82,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
emit(UpdateCreateScheduleState(createSchedule));
}
void _fetchTwoGangStatus(InitialEvent event, Emitter<TwoGangState> emit) async {
void _fetchTwoGangStatus(
InitialEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(twoGangId);
@ -89,42 +93,50 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
deviceStatus = TwoGangModel.fromJson(statusModelList);
emit(UpdateState(twoGangModel: deviceStatus));
// _listenToChanges();
_listenToChanges(twoGangId);
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges(String id) {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoGangId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$id');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
_streamSubscription = stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = TwoGangModel.fromJson(statusList);
if (!isClosed) {
add(TwoGangUpdated());
}
add(TwoGangUpdated());
});
} catch (_) {}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_twoGangUpdated(TwoGangUpdated event, Emitter<TwoGangState> emit) {
emit(LoadingNewSate(twoGangModel: deviceStatus));
emit(UpdateState(twoGangModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
void _changeFirstSwitch(
ChangeFirstSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
deviceStatus.firstSwitch = !event.value;
@ -135,7 +147,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: twoGangId, code: 'switch_1', value: !event.value),
DeviceControlModel(
deviceId: twoGangId, code: 'switch_1', value: !event.value),
twoGangId);
if (!response['success']) {
@ -147,7 +160,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
void _changeSecondSwitch(
ChangeSecondSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
deviceStatus.secondSwitch = !event.value;
@ -157,7 +171,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: twoGangId, code: 'switch_2', value: !event.value),
DeviceControlModel(
deviceId: twoGangId, code: 'switch_2', value: !event.value),
twoGangId);
if (!response['success']) {
@ -180,11 +195,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
deviceId: twoGangId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
twoGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
deviceId: twoGangId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
twoGangId),
]);
@ -207,11 +226,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
deviceId: twoGangId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
twoGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
deviceId: twoGangId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
twoGangId),
]);
if (response.every((element) => !element['success'])) {
@ -232,7 +255,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
groupTwoGangList[i].secondSwitch = true;
}
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: true));
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupTwoGangList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
@ -267,7 +291,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: false));
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupTwoGangList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
@ -292,17 +317,20 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<TwoGangState> emit) async {
void _changeSliding(
ChangeSlidingSegment event, Emitter<TwoGangState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<TwoGangState> emit) async {
void _setCounterValue(
SetCounterValue event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: twoGangId, code: event.deviceCode, value: seconds),
DeviceControlModel(
deviceId: twoGangId, code: event.deviceCode, value: seconds),
twoGangId);
if (response['success'] ?? false) {
@ -327,7 +355,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
void _getCounterValue(GetCounterEvent event, Emitter<TwoGangState> emit) async {
void _getCounterValue(
GetCounterEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingInitialState());
try {
add(GetScheduleEvent());
@ -435,7 +464,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
deviceId: twoGangId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
listSchedule =
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
@ -446,12 +476,13 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleRepeat(ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
Future toggleRepeat(
ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
@ -470,7 +501,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
@ -490,7 +522,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
void _fetchTwoGangWizardStatus(InitialWizardEvent event, Emitter<TwoGangState> emit) async {
void _fetchTwoGangWizardStatus(
InitialWizardEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
@ -500,7 +533,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
@ -523,15 +557,16 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
return true;
});
}
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
emit(UpdateGroupState(
twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
bool allSwitchesValue = true;
@ -544,9 +579,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
});
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupTwoGangList.map((device) => device.deviceId).toList();
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
@ -561,8 +598,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
void _changeSecondWizardSwitch(
ChangeSecondWizardSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
void _changeSecondWizardSwitch(ChangeSecondWizardSwitchStatusEvent event,
Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
bool allSwitchesValue = true;
@ -574,9 +611,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
allSwitchesValue = false;
}
});
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupTwoGangList.map((device) => device.deviceId).toList();
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_2',

View File

@ -99,41 +99,61 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
}
deviceStatus = TwoTouchModel.fromJson(statusModelList);
emit(UpdateState(twoTouchModel: deviceStatus));
// _listenToChanges();
_listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges() {
try {
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$twoTouchId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
await Future.delayed(const Duration(seconds: 1));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
if (event.snapshot.value != null) {
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
usersMap['status'].forEach((element) {
statusList.add(
StatusModel(code: element['code'], value: element['value']));
});
var switch1Status = statusList.firstWhere(
(status) => status.code == "switch_1",
orElse: () => StatusModel(code: "switch_1", value: false));
var switch2Status = statusList.firstWhere(
(status) => status.code == "switch_2",
orElse: () => StatusModel(code: "switch_2", value: false));
deviceStatus.firstSwitch = switch1Status.value as bool;
deviceStatus.secondSwitch = switch2Status.value as bool;
deviceStatus = TwoTouchModel.fromJson(statusList);
if (!isClosed) {
add(TwoTouchUpdated());
}
});
} catch (_) {}
} catch (_) {
}
}
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_twoTouchUpdated(TwoTouchUpdated event, Emitter<TwoTouchState> emit) {
emit(LoadingInitialState());
emit(UpdateState(twoTouchModel: deviceStatus));
}

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
@ -21,7 +23,8 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
on<GetDeviceReportsEvent>(_getDeviceReports);
}
void _fetchCeilingSensorStatus(InitialEvent event, Emitter<WallSensorState> emit) async {
void _fetchCeilingSensorStatus(
InitialEvent event, Emitter<WallSensorState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(deviceId);
@ -31,41 +34,62 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
}
deviceStatus = WallSensorModel.fromJson(statusModelList);
emit(UpdateState(wallSensorModel: deviceStatus));
// _listenToChanges();
_listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
Timer? _timer;
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$deviceId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = WallSensorModel.fromJson(statusList);
add(WallSensorUpdatedEvent());
if (!isClosed) {
add(WallSensorUpdatedEvent());
}
});
} catch (_) {}
}
_wallSensorUpdated(WallSensorUpdatedEvent event, Emitter<WallSensorState> emit) {
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_wallSensorUpdated(
WallSensorUpdatedEvent event, Emitter<WallSensorState> emit) {
emit(UpdateState(wallSensorModel: deviceStatus));
}
void _changeIndicator(ChangeIndicatorEvent event, Emitter<WallSensorState> emit) async {
void _changeIndicator(
ChangeIndicatorEvent event, Emitter<WallSensorState> emit) async {
emit(LoadingNewSate(wallSensorModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'indicator', value: !event.value), deviceId);
DeviceControlModel(
deviceId: deviceId, code: 'indicator', value: !event.value),
deviceId);
if (response['success'] ?? false) {
deviceStatus.indicator = !event.value;
@ -74,11 +98,14 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
emit(UpdateState(wallSensorModel: deviceStatus));
}
void _changeValue(ChangeValueEvent event, Emitter<WallSensorState> emit) async {
void _changeValue(
ChangeValueEvent event, Emitter<WallSensorState> emit) async {
emit(LoadingNewSate(wallSensorModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: event.code, value: event.value), deviceId);
DeviceControlModel(
deviceId: deviceId, code: event.code, value: event.value),
deviceId);
if (response['success'] ?? false) {
if (event.code == 'far_detection') {
@ -93,7 +120,8 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
emit(UpdateState(wallSensorModel: deviceStatus));
}
void _getDeviceReports(GetDeviceReportsEvent event, Emitter<WallSensorState> emit) async {
void _getDeviceReports(
GetDeviceReportsEvent event, Emitter<WallSensorState> emit) async {
emit(LoadingInitialState());
try {

View File

@ -35,7 +35,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
List<ScheduleModel> listSchedule = [];
DateTime? selectedTime = DateTime.now();
WaterHeaterBloc({required this.whId, required this.switchCode}) : super(WHInitialState()) {
WaterHeaterBloc({required this.whId, required this.switchCode})
: super(WHInitialState()) {
on<WaterHeaterInitial>(_fetchWaterHeaterStatus);
on<WaterHeaterSwitch>(_changeFirstSwitch);
on<SetCounterValue>(_setCounterValue);
@ -60,7 +61,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
on<WaterHeaterUpdated>(_waterHeaterUpdated);
}
void _fetchWaterHeaterStatus(WaterHeaterInitial event, Emitter<WaterHeaterState> emit) async {
void _fetchWaterHeaterStatus(
WaterHeaterInitial event, Emitter<WaterHeaterState> emit) async {
emit(WHLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(whId);
@ -72,29 +74,33 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
statusModelList,
);
emit(UpdateState(whModel: deviceStatus));
// _listenToChanges();
_listenToChanges();
} catch (e) {
emit(WHFailedState(errorMessage: e.toString()));
return;
}
}
_listenToChanges() {
//real-time db
StreamSubscription<DatabaseEvent>? _streamSubscription;
void _listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$whId');
_streamSubscription?.cancel();
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$whId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
_streamSubscription = stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
statusList
.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = WHModel.fromJson(statusList);
if (!isClosed) {
add(WaterHeaterUpdated());
@ -103,12 +109,21 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
} catch (_) {}
}
_waterHeaterUpdated(WaterHeaterUpdated event, Emitter<WaterHeaterState> emit) async {
@override
Future<void> close() async {
_streamSubscription?.cancel();
_streamSubscription = null;
return super.close();
}
_waterHeaterUpdated(
WaterHeaterUpdated event, Emitter<WaterHeaterState> emit) async {
emit(WHLoadingState());
emit(UpdateState(whModel: deviceStatus));
}
void _changeFirstSwitch(WaterHeaterSwitch event, Emitter<WaterHeaterState> emit) async {
void _changeFirstSwitch(
WaterHeaterSwitch event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
try {
deviceStatus.firstSwitch = !event.whSwitch;
@ -118,7 +133,10 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
_timer = Timer(const Duration(milliseconds: 500), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: whId, code: 'switch_1', value: deviceStatus.firstSwitch),
DeviceControlModel(
deviceId: whId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
whId);
if (!response['success']) {
@ -132,13 +150,16 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
//=====================---------- timer ----------------------------------------
void _setCounterValue(SetCounterValue event, Emitter<WaterHeaterState> emit) async {
void _setCounterValue(
SetCounterValue event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: whId, code: event.deviceCode, value: seconds), whId);
DeviceControlModel(
deviceId: whId, code: event.deviceCode, value: seconds),
whId);
if (response['success'] ?? false) {
if (event.deviceCode == 'countdown_1') {
@ -160,7 +181,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
void _getCounterValue(GetCounterEvent event, Emitter<WaterHeaterState> emit) async {
void _getCounterValue(
GetCounterEvent event, Emitter<WaterHeaterState> emit) async {
emit(WHLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(whId);
@ -250,7 +272,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
deviceId: whId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
listSchedule =
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(WHInitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
@ -261,12 +284,13 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<WaterHeaterState> emit) async {
Future toggleChange(
ToggleScheduleEvent event, Emitter<WaterHeaterState> emit) async {
try {
emit(WHLoadingState());
final response = await DevicesAPI.changeSchedule(
@ -284,7 +308,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<WaterHeaterState> emit) async {
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<WaterHeaterState> emit) async {
try {
emit(WHLoadingState());
final response = await DevicesAPI.deleteSchedule(
@ -303,7 +328,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
void _toggleCreateCirculate(ToggleCreateCirculate event, Emitter<WaterHeaterState> emit) {
void _toggleCreateCirculate(
ToggleCreateCirculate event, Emitter<WaterHeaterState> emit) {
emit(WHLoadingState());
createCirculate = !createCirculate;
selectedDays.clear();
@ -311,13 +337,15 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
emit(UpdateCreateScheduleState(createCirculate));
}
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
void toggleSelectedIndex(
ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
emit(WHLoadingState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
void toggleCreateSchedule(
ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
emit(WHLoadingState());
createSchedule = !createSchedule;
selectedDays.clear();
@ -366,8 +394,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
List<GroupWHModel> groupWaterHeaterList = [];
bool allSwitchesOn = true;
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<WaterHeaterState> emit) async {
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
try {
bool allSwitchesValue = true;
@ -379,7 +407,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue));
emit(UpdateGroupState(
twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
@ -394,7 +423,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
void _fetchWHWizardStatus(InitialWizardEvent event, Emitter<WaterHeaterState> emit) async {
void _fetchWHWizardStatus(
InitialWizardEvent event, Emitter<WaterHeaterState> emit) async {
emit(WHLoadingState());
try {
devicesList = [];
@ -404,7 +434,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', 'WH');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
@ -426,23 +457,27 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
return true;
});
}
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn));
emit(UpdateGroupState(
twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn));
} catch (e) {
// emit(FailedState(error: e.toString()));
return;
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<WaterHeaterState> emit) async {
void _groupAllOn(
GroupAllOnEvent event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
try {
for (int i = 0; i < groupWaterHeaterList.length; i++) {
groupWaterHeaterList[i].firstSwitch = true;
}
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: true));
emit(UpdateGroupState(
twoGangList: groupWaterHeaterList, allSwitches: true));
List<String> allDeviceIds = groupWaterHeaterList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupWaterHeaterList.map((device) => device.deviceId).toList();
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
@ -460,15 +495,18 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<WaterHeaterState> emit) async {
void _groupAllOff(
GroupAllOffEvent event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
try {
for (int i = 0; i < groupWaterHeaterList.length; i++) {
groupWaterHeaterList[i].firstSwitch = false;
}
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: false));
emit(UpdateGroupState(
twoGangList: groupWaterHeaterList, allSwitches: false));
List<String> allDeviceIds = groupWaterHeaterList.map((device) => device.deviceId).toList();
List<String> allDeviceIds =
groupWaterHeaterList.map((device) => device.deviceId).toList();
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',

View File

@ -1,6 +1,5 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/water_leak_bloc/water_leak_event.dart';
import 'package:syncrow_app/features/devices/bloc/water_leak_bloc/water_leak_state.dart';
@ -21,7 +20,6 @@ class WaterLeakBloc extends Bloc<WaterLeakEvent, WaterLeakState> {
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
on<ToggleWaterLeakAlarmEvent>(_toggleWaterLeakAlarm);
}
Timer? _timer;
bool lowBattery = false;
bool closingReminder = false;
bool waterAlarm = false;
@ -134,32 +132,42 @@ class WaterLeakBloc extends Bloc<WaterLeakEvent, WaterLeakState> {
emit(WaterLeakFailedState(errorMessage: errorMessage));
}
}
// Timer? _timer;
// StreamSubscription<DatabaseEvent>? _streamSubscription;
// void _listenToChanges() {
// try {
// _streamSubscription?.cancel();
// DatabaseReference ref =
// FirebaseDatabase.instance.ref('device-status/$WLId');
// Stream<DatabaseEvent> stream = ref.onValue;
_listenToChanges() {
try {
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$WLId');
Stream<DatabaseEvent> stream = ref.onValue;
// _streamSubscription = stream.listen((DatabaseEvent event) async {
// if (_timer != null) {
// await Future.delayed(const Duration(seconds: 2));
// }
// Map<dynamic, dynamic> usersMap =
// event.snapshot.value as Map<dynamic, dynamic>;
// List<StatusModel> statusList = [];
// usersMap['status'].forEach((element) {
// statusList
// .add(StatusModel(code: element['code'], value: element['value']));
// });
// deviceStatus = WaterLeakModel.fromJson(statusList);
// if (!isClosed) {
// add(
// WaterLeakSwitch(switchD: deviceStatus.waterContactState),
// );
// }
// });
// } catch (_) {}
// }
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
// @override
// Future<void> close() async {
// _streamSubscription?.cancel();
// _streamSubscription = null;
// return super.close();
// }
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: true));
});
deviceStatus = WaterLeakModel.fromJson(statusList);
if (!isClosed) {
add(
WaterLeakSwitch(switchD: deviceStatus.waterContactState),
);
}
});
} catch (_) {}
}
}

View File

@ -27,24 +27,24 @@ class AcStatusModel {
}
factory AcStatusModel.fromJson(String id, List<StatusModel> jsonList) {
late bool _acSwitch;
late String _mode;
late int _tempSet;
late int _currentTemp;
late String _fanSpeeds;
late int _countdown1;
late bool _childLock;
bool _acSwitch = false;
String _mode = '';
int _tempSet = 210;
int _currentTemp = 210;
String _fanSpeeds = '';
int _countdown1 = 0;
bool _childLock = false;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'switch') {
_acSwitch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'mode') {
_mode = jsonList[i].value ?? TempModes.cold;
_mode = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'temp_set') {
_tempSet = jsonList[i].value ?? 210;
} else if (jsonList[i].code == 'temp_current') {
_currentTemp = jsonList[i].value ?? 210;
} else if (jsonList[i].code == 'level') {
_fanSpeeds = jsonList[i].value ?? 210;
_fanSpeeds = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'child_lock') {
_childLock = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'countdown_time') {

View File

@ -23,9 +23,9 @@ class CeilingSensorModel {
required this.bodyMovement});
factory CeilingSensorModel.fromJson(List<StatusModel> jsonList) {
late String _presenceState;
late int _sensitivity;
late String _checkingResult;
String _presenceState = 'none';
int _sensitivity = 1;
String _checkingResult = '';
int _presenceRange = 1;
int _sportsPara = 1;
int _moving_max_dis = 0;

View File

@ -10,11 +10,11 @@ class CurtainModel {
});
factory CurtainModel.fromJson(List<StatusModel> jsonList) {
late String _control;
late int _percent;
String _control = '';
int _percent = 0;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'control') {
_control = jsonList[i].value ?? false;
_control = jsonList[i].value ?? '';
}
if (jsonList[i].code == 'percent_control') {
_percent = jsonList[i].value ?? 0;

View File

@ -1,5 +1,3 @@
import 'dart:convert';
class DeviceInfoModel {
final int activeTime;
final String category;

View File

@ -1,27 +1,22 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class DoorSensorModel {
bool doorContactState;
int batteryPercentage;
DoorSensorModel(
{required this.doorContactState,
required this.batteryPercentage,
});
DoorSensorModel({
required this.doorContactState,
required this.batteryPercentage,
});
factory DoorSensorModel.fromJson(List<StatusModel> jsonList) {
late bool _doorContactState;
late int _batteryPercentage;
bool _doorContactState = false;
int _batteryPercentage = 0;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'doorcontact_state') {
_doorContactState = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'battery_percentage') {
} else if (jsonList[i].code == 'battery_percentage') {
_batteryPercentage = jsonList[i].value ?? 0;
}
}

View File

@ -24,15 +24,15 @@ class GarageDoorModel {
});
factory GarageDoorModel.fromJson(List<StatusModel> jsonList) {
late bool _switch1 = false;
late bool _doorContactState = false;
late int _countdown1 = 0;
late int _countdownAlarm = 0;
late String _doorControl1 = "closed";
late bool _voiceControl1 = false;
late String _doorState1 = "closed";
late int _batteryPercentage = 0;
late int _tr_timecon = 0;
bool _switch1 = false;
bool _doorContactState = false;
int _countdown1 = 0;
int _countdownAlarm = 0;
String _doorControl1 = "closed";
bool _voiceControl1 = false;
String _doorState1 = "closed";
int _batteryPercentage = 0;
int _tr_timecon = 0;
for (var status in jsonList) {
switch (status.code) {

View File

@ -1,29 +1,27 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class OneGangModel {
bool firstSwitch;
int firstCountDown;
OneGangModel(
{required this.firstSwitch,
required this.firstCountDown,
});
OneGangModel({
required this.firstSwitch,
required this.firstCountDown,
});
factory OneGangModel.fromJson(List<StatusModel> jsonList) {
late bool _switch;
late int _count;
bool _switch = false;
int _count = 0;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'switch_1') {
_switch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'countdown_1') {
} else if (jsonList[i].code == 'countdown_1') {
_count = jsonList[i].value ?? 0;
}
}
return OneGangModel(
firstSwitch: _switch,
firstSwitch: _switch,
firstCountDown: _count,
);
}

View File

@ -1,5 +1,3 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
@ -15,15 +13,14 @@ class OneTouchModel {
required this.firstCountDown,
required this.light_mode,
required this.relay,
required this.relay_status_1
});
required this.relay_status_1});
factory OneTouchModel.fromJson(List<StatusModel> jsonList) {
late bool _switch;
late int _count;
late String _relay;
late String _light_mode;
late String relay_status_1;
bool _switch = false;
int _count = 0;
String _relay = '';
String _light_mode = '';
String relay_status_1 = '';
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'switch_1') {
@ -41,10 +38,8 @@ class OneTouchModel {
return OneTouchModel(
firstSwitch: _switch,
firstCountDown: _count,
light_mode: lightStatusExtension.fromString(_light_mode) ,
relay: StatusExtension.fromString(_relay ) ,
relay_status_1: StatusExtension.fromString(relay_status_1 )
);
light_mode: lightStatusExtension.fromString(_light_mode),
relay: StatusExtension.fromString(_relay),
relay_status_1: StatusExtension.fromString(relay_status_1));
}
}

View File

@ -22,14 +22,14 @@ class SixSceneModel {
});
factory SixSceneModel.fromJson(List<StatusModel> jsonList) {
late dynamic _scene_1;
late dynamic _scene_2;
late dynamic _scene_3;
late dynamic _scene_4;
late dynamic _scene_5;
late dynamic _scene_6;
late dynamic _scene_id_group_id;
late dynamic _switch_backlight;
dynamic _scene_1 = '';
dynamic _scene_2 = '';
dynamic _scene_3 = '';
dynamic _scene_4 = '';
dynamic _scene_5 = '';
dynamic _scene_6 = '';
dynamic _scene_id_group_id = 0;
dynamic _switch_backlight = false;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'scene_1') {

View File

@ -39,23 +39,23 @@ class SmartDoorModel {
required this.normalOpenSwitch});
factory SmartDoorModel.fromJson(List<StatusModel> jsonList) {
late int _unlockFingerprint;
late int _unlockPassword;
late int _unlockTemporary;
late int _unlockCard;
late String _unlockAlarm;
late int _unlockRequest;
late int _residualElectricity;
late bool _reverseLock;
late int _unlockApp;
late bool _hijack;
late bool _doorbell;
late String _unlockOfflinePd;
late String _unlockOfflineClear;
late String _unlockDoubleKit;
late String _remoteNoPdSetkey;
late String _remoteNoDpKey;
late bool _normalOpenSwitch;
int _unlockFingerprint = 0;
int _unlockPassword = 0;
int _unlockTemporary = 0;
int _unlockCard = 0;
String _unlockAlarm = '';
int _unlockRequest = 0;
int _residualElectricity = 0;
bool _reverseLock = false;
int _unlockApp = 0;
bool _hijack = false;
bool _doorbell = false;
String _unlockOfflinePd = '';
String _unlockOfflineClear = '';
String _unlockDoubleKit = '';
String _remoteNoPdSetkey = '';
String _remoteNoDpKey = '';
bool _normalOpenSwitch = false;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'unlock_fingerprint') {

View File

@ -10,8 +10,8 @@ class SosModel {
});
factory SosModel.fromJson(List<StatusModel> jsonList) {
late String _sosContactState;
late int _batteryPercentage;
String _sosContactState = '';
int _batteryPercentage = 0;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'sos') {

View File

@ -43,6 +43,7 @@ class AcInterfaceControls extends StatelessWidget {
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
AcTimerPage(
deviceStatus: deviceStatus,
device: deviceModel,
deviceCode: deviceModel.type!,
switchCode: '',

View File

@ -7,7 +7,7 @@ import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_st
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/custom_halfhour_timer_picker.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
@ -20,10 +20,13 @@ class AcTimerPage extends StatelessWidget {
final DeviceModel device;
final String deviceCode;
final String switchCode;
final AcStatusModel deviceStatus;
const AcTimerPage(
{required this.device,
required this.deviceCode,
required this.switchCode,
required this.deviceStatus,
super.key});
@override
@ -37,27 +40,24 @@ class AcTimerPage extends StatelessWidget {
create: (context) => ACsBloc(acId: device.uuid ?? ''),
child: BlocBuilder<ACsBloc, AcsState>(
builder: (context, state) {
final oneGangBloc = BlocProvider.of<ACsBloc>(context);
final acBloc = BlocProvider.of<ACsBloc>(context);
Duration duration = Duration.zero;
int selectedValue = 0;
int countNum = 0;
if (state is UpdateTimerState) {
if (state is AcsInitialState) {
acBloc.add(GetCounterEvent(deviceCode: deviceCode));
} else if (state is UpdateTimerState) {
countNum = state.seconds;
} else if (state is TimerRunInProgress) {
countNum = state.remainingTime;
} else if (state is TimerRunComplete) {
countNum = 0;
}
// else if (state is LoadingNewSate) {
// countNum = 0;
// }
return PopScope(
canPop: false,
onPopInvoked: (didPop) {
if (!didPop) {
oneGangBloc.add(OnClose());
acBloc.add(OnClose());
Navigator.pop(context);
}
},
@ -90,7 +90,7 @@ class AcTimerPage extends StatelessWidget {
),
),
Center(
child: Container(
child: SizedBox(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
@ -102,7 +102,7 @@ class AcTimerPage extends StatelessWidget {
.slidingBlueColor,
fontSize: 40,
)
: Container(
: SizedBox(
child: CustomHalfHourPicker(
onValueChanged: (value) {
selectedValue =
@ -120,8 +120,6 @@ class AcTimerPage extends StatelessWidget {
countNum =
duration.inSeconds;
}
print(
"Selected Value: $selectedValue, Duration: $duration");
},
),
),
@ -131,12 +129,14 @@ class AcTimerPage extends StatelessWidget {
return;
}
if (countNum > 0) {
oneGangBloc.add(SetCounterValue(
acBloc.add(SetCounterValue(
seconds: countNum,
deviceCode:'countdown_time',
deviceCode:
'countdown_time',
duration: selectedValue));
} else if (duration != Duration.zero) {
oneGangBloc.add(SetCounterValue(
} else if (duration !=
Duration.zero) {
acBloc.add(SetCounterValue(
seconds: 0,
deviceCode:
'countdown_time',

View File

@ -31,7 +31,7 @@ class ACsList extends StatelessWidget {
List<DeviceModel> devicesList = [];
bool allOn = false;
bool allTempSame = false;
int temperature = 20;
int temperature = 250;
if (state is GetAllAcsStatusState) {
devicesStatuesList = state.allAcsStatues;
devicesList = state.allAcs;

View File

@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_list.dart';
@ -23,9 +22,8 @@ class ACsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("ACsView deviceModel UUID: ${deviceModel?.uuid}");
return BlocProvider(
create: (context) => ACsBloc(acId: deviceModel?.uuid ?? '')
..add(AcsInitial(allAcs: deviceModel != null ? false : true)),
child: BlocBuilder<ACsBloc, AcsState>(
@ -41,7 +39,6 @@ class ACsView extends StatelessWidget {
extendBody: true,
appBar: deviceModel != null
? DeviceAppbar(
//BlocProvider.of<ACsBloc>(context).deviceStatus.acSwitch.toString()
value: true,
deviceName: deviceModel!.name!,
deviceUuid: deviceModel!.uuid!,

View File

@ -306,7 +306,7 @@ class CeilingSensorInterface extends StatelessWidget {
.toString()
.toLowerCase()
.replaceAll('sec', 's')
.replaceAll('1hr', '1hour'), // Replacing "sec" with "s"
.replaceAll('1hr', '1hour'),
code: 'nobody_time'));
}
} else if (title == 'Maximum Distance') {
@ -332,7 +332,7 @@ class CeilingSensorInterface extends StatelessWidget {
title: title.toString(),
sensor: ceilingSensor,
value: model.sensitivity,
min: 0,
min: 1,
max: 10,
));
if (result != null) {
@ -344,7 +344,7 @@ class CeilingSensorInterface extends StatelessWidget {
context,
MaterialPageRoute(builder: (context) => const CeilingHelpDescription()),
);
} else if (title == 'Induction History') {
} else if (title == 'Presence Record') {
Navigator.push(
context,
MaterialPageRoute(
@ -393,7 +393,7 @@ class CeilingSensorInterface extends StatelessWidget {
'val': nobodyTimeVal,
},
{
'title': 'Induction History',
'title': 'Presence Record',
'icon': Assets.assetsIconsPresenceSensorAssetsInductionRecording,
'page': null,
'withArrow': false,

View File

@ -31,12 +31,12 @@ class MaxDistanceControl extends StatefulWidget {
}
int _parseValue(String value) {
if (value.endsWith('sec')) {
return int.parse(value.replaceAll('sec', '').trim());
if (value.endsWith('s')) {
return int.parse(value.replaceAll('s', '').trim());
} else if (value.endsWith('min')) {
return int.parse(value.replaceAll('min', '').trim()) * 60;
} else if (value.endsWith('hr')) {
return int.parse(value.replaceAll('hr', '').trim()) * 3600;
} else if (value.endsWith('hour')) {
return int.parse(value.replaceAll('hour', '').trim()) * 3600;
}
return 0; // Default to 0 if the format is unrecognized
}
@ -58,7 +58,7 @@ class MaxDistanceControlState extends State<MaxDistanceControl> {
String _formatLabel(double seconds) {
if (seconds == 0) return 'None';
if (seconds < 60) return '${seconds.toInt()}sec';
if (seconds < 60) return '${seconds.toInt()}s';
if (seconds < 3600) {
final minutes = (seconds / 60).round();
return '${minutes}min';
@ -90,7 +90,6 @@ class MaxDistanceControlState extends State<MaxDistanceControl> {
@override
Widget build(BuildContext context) {
final double currentSeconds = _stepValues[_currentIndex];
return Dialog(
child: Container(
decoration: BoxDecoration(
@ -128,7 +127,9 @@ class MaxDistanceControlState extends State<MaxDistanceControl> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
TitleMedium(
text: _formatLabel(currentSeconds),
text: _formatLabel(currentSeconds)
.replaceAll('1hr', '1hour')
.replaceAllMapped(RegExp(r's$'), (match) => 'sec'),
style: context.titleMedium.copyWith(
color: Colors.black,
fontWeight: FontsManager.bold,

View File

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/view/widgets/all_devices.dart';
import 'package:syncrow_app/features/devices/view/widgets/room_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
@ -15,38 +15,34 @@ import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class DevicesViewBody extends StatelessWidget {
const DevicesViewBody({Key? key}) : super(key: key);
const DevicesViewBody({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<HomeCubit, HomeState>(
builder: (context, homeState) {
final homeCubit = HomeCubit.getInstance();
// Handle state priority: Errors first
if (homeState is ActivationError) {
return const CreateUnitWidget();
}
// Handle loading states
if (homeState is GetSpacesLoading || homeState is HomeLoading) {
return const Center(child: CircularProgressIndicator());
}
// Handle error states
if (homeState is GetSpacesError) {
return const CreateUnitWidget();
}
// Handle success states
if (homeState is GetSpacesSuccess ||
homeState is RoomUnSelected ||
homeState is RoomSelected ||
homeState is NavChangePage) {
homeState is NavChangePage ||
homeState is GetSpaceRoomsSuccess) {
// Show empty state if no spaces
if (homeCubit.spaces.isEmpty) {
return const CreateUnitWidget();
}
return BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, devicesState) {
// Devices loading states
@ -55,7 +51,6 @@ class DevicesViewBody extends StatelessWidget {
devicesState is GetDevicesLoading) {
return const Center(child: CircularProgressIndicator());
}
// Devices error state
if (devicesState is GetDevicesError) {
return Center(child: BodyLarge(text: devicesState.errorMsg));
@ -65,7 +60,6 @@ class DevicesViewBody extends StatelessWidget {
},
);
}
// Fallback for unknown states
return const Center(child: BodyLarge(text: ''));
},
@ -74,7 +68,6 @@ class DevicesViewBody extends StatelessWidget {
Widget _buildMainContent(BuildContext context, HomeCubit homeCubit) {
final devicesCubit = context.read<DevicesCubit>();
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
@ -87,10 +80,7 @@ class DevicesViewBody extends StatelessWidget {
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.1,
child: const SceneView(pageType: true),
),
const SceneView(pageType: true),
const SizedBox(height: 20),
const RoomsSlider(),
const SizedBox(height: 10),

View File

@ -8,8 +8,7 @@ import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
class GarageList extends StatelessWidget {
const GarageList(
{super.key, required this.garageList, required this.allSwitches});
const GarageList({super.key, required this.garageList, required this.allSwitches});
final List<GroupGarageModel> garageList;
final bool allSwitches;
@ -23,43 +22,42 @@ class GarageList extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 10),
const BodySmall(text: 'All Lights'),
const BodySmall(text: 'All Garages'),
const SizedBox(height: 5),
DevicesDefaultSwitch(
off: 'OFF',
on: 'ON',
off: 'Close',
on: 'Open',
switchValue: allSwitches,
action: () {
BlocProvider.of<GarageDoorBloc>(context)
.add(GroupAllOnEvent());
},
secondAction: () {
BlocProvider.of<GarageDoorBloc>(context)
.add(GroupAllOffEvent());
},
action: () => BlocProvider.of<GarageDoorBloc>(context).add(
GroupAllOnEvent(),
),
secondAction: () => BlocProvider.of<GarageDoorBloc>(context).add(
GroupAllOffEvent(),
),
),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(0),
padding: EdgeInsetsDirectional.zero,
itemCount: garageList.length,
itemBuilder: (context, index) {
final garageDoor = garageList[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
BodySmall(text: garageList[index].deviceName),
BodySmall(text: garageDoor.deviceName),
const SizedBox(height: 5),
DevicesDefaultSwitch(
off: 'OFF',
on: 'ON',
switchValue: garageList[index].firstSwitch,
action: () {
BlocProvider.of<GarageDoorBloc>(context).add(
ChangeFirstWizardSwitchStatusEvent(
value: garageList[index].firstSwitch,
deviceId: garageList[index].deviceId));
},
off: 'Close',
on: 'Open',
switchValue: garageDoor.firstSwitch,
action: () => BlocProvider.of<GarageDoorBloc>(context).add(
ChangeFirstWizardSwitchStatusEvent(
value: garageDoor.firstSwitch,
deviceId: garageDoor.deviceId,
),
),
),
],
);

View File

@ -20,8 +20,9 @@ class OneGangScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => OneGangBloc(switchCode: 'switch_1', oneGangId: device?.uuid ?? '')
..add(const InitialEvent(groupScreen: false)),
create: (context) =>
OneGangBloc(switchCode: 'switch_1', oneGangId: device?.uuid ?? '')
..add(const InitialEvent(groupScreen: false)),
child: BlocBuilder<OneGangBloc, OneGangState>(
builder: (context, state) {
OneGangModel oneGangModel = OneGangModel(
@ -36,13 +37,15 @@ class OneGangScreen extends StatelessWidget {
}
return state is LoadingInitialState
? const Center(
child:
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
BlocProvider.of<OneGangBloc>(context)
.add(InitialEvent(groupScreen: device != null ? false : true));
BlocProvider.of<OneGangBloc>(context).add(InitialEvent(
groupScreen: device != null ? false : true));
},
child: ListView(
children: [
@ -55,7 +58,8 @@ class OneGangScreen extends StatelessWidget {
const Expanded(child: SizedBox.shrink()),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
@ -64,9 +68,10 @@ class OneGangScreen extends StatelessWidget {
threeGangSwitch: device!,
value: oneGangModel.firstSwitch,
action: () {
BlocProvider.of<OneGangBloc>(context).add(
ChangeFirstSwitchStatusEvent(
value: oneGangModel.firstSwitch));
BlocProvider.of<OneGangBloc>(context)
.add(ChangeFirstSwitchStatusEvent(
value: oneGangModel
.firstSwitch));
},
),
const SizedBox(height: 20),
@ -74,7 +79,8 @@ class OneGangScreen extends StatelessWidget {
width: 70,
child: BodySmall(
text: " Entrance Light",
fontColor: ColorsManager.textPrimaryColor,
fontColor:
ColorsManager.textPrimaryColor,
textAlign: TextAlign.center,
),
),
@ -94,20 +100,24 @@ class OneGangScreen extends StatelessWidget {
Card(
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
borderRadius:
BorderRadius.circular(100),
),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder:
(context, animation1, animation2) =>
TimerScheduleScreen(
switchCode: 'switch_1',
device: device!,
deviceCode: 'countdown_1',
)));
pageBuilder: (context,
animation1,
animation2) =>
TimerScheduleScreen(
switchCode:
'switch_1',
device: device!,
deviceCode:
'countdown_1',
)));
},
child: Stack(
alignment: Alignment.center,
@ -117,7 +127,9 @@ class OneGangScreen extends StatelessWidget {
height: 60,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(100),
borderRadius:
BorderRadius.circular(
100),
),
),
Container(
@ -125,12 +137,15 @@ class OneGangScreen extends StatelessWidget {
height: 40,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
borderRadius:
BorderRadius.circular(
100),
),
child: Center(
child: Icon(
Icons.access_time,
color: ColorsManager.primaryColorWithOpacity,
color: ColorsManager
.primaryColorWithOpacity,
size: 25,
),
),

View File

@ -119,6 +119,8 @@ Future<void> showDeviceInterface(
required BuildContext context,
required isAllDevices,
List<DeviceModel>? allDevices}) async {
print('object-----${device.uuid} ${device.name}');
final devicesCubit = context.read<DevicesCubit>();
switch (device.productType) {

View File

@ -8,7 +8,11 @@ import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
class WHList extends StatelessWidget {
const WHList({super.key, required this.whList, required this.allSwitches});
const WHList({
required this.whList,
required this.allSwitches,
super.key,
});
final List<GroupWHModel> whList;
final bool allSwitches;
@ -22,43 +26,42 @@ class WHList extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 10),
const BodySmall(text: 'All Lights'),
const BodySmall(text: 'All Water Heaters'),
const SizedBox(height: 5),
DevicesDefaultSwitch(
off: 'OFF',
on: 'ON',
switchValue: allSwitches,
action: () {
BlocProvider.of<WaterHeaterBloc>(context)
.add(GroupAllOnEvent());
},
secondAction: () {
BlocProvider.of<WaterHeaterBloc>(context)
.add(GroupAllOffEvent());
},
action: () => context.read<WaterHeaterBloc>().add(
GroupAllOnEvent(),
),
secondAction: () => context.read<WaterHeaterBloc>().add(
GroupAllOffEvent(),
),
),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(0),
padding: EdgeInsetsDirectional.zero,
itemCount: whList.length,
itemBuilder: (context, index) {
final waterHeater = whList[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
BodySmall(text: whList[index].deviceName),
BodySmall(text: waterHeater.deviceName),
const SizedBox(height: 5),
DevicesDefaultSwitch(
off: 'OFF',
on: 'ON',
switchValue: whList[index].firstSwitch,
action: () {
BlocProvider.of<WaterHeaterBloc>(context).add(
switchValue: waterHeater.firstSwitch,
action: () => context.read<WaterHeaterBloc>().add(
ChangeFirstWizardSwitchStatusEvent(
value: whList[index].firstSwitch,
deviceId: whList[index].deviceId));
},
value: waterHeater.firstSwitch,
deviceId: waterHeater.deviceId,
),
),
),
],
);

View File

@ -1,10 +1,12 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_event.dart';
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_state.dart';
import 'package:syncrow_app/services/api/home_creation_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class CreateUnitBloc extends Bloc<CreateUnitEvent, CreateUnitState> {
@ -239,8 +241,13 @@ Future<String> _createNewRoom(
required String communityId}) async {
try {
Map<String, String> body = {'subspaceName': roomName};
Project? project = HomeCubit.getInstance().project;
final response = await HomeCreation.createRoom(
communityId: communityId, spaceId: unitId, body: body);
communityId: communityId,
spaceId: unitId,
body: body,
projectId: project?.uuid ?? TempConst.projectIdDev);
// if (response['data']['uuid'] != '') {
// final result = await _assignToRoom(roomId: response['data']['uuid'], userId: userId);

View File

@ -1,5 +1,6 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_event.dart';
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_state.dart';
@ -7,6 +8,7 @@ import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_creation_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
List<DeviceModel> allDevices = [];
@ -24,8 +26,12 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
FetchRoomsEvent event, Emitter<ManageUnitState> emit) async {
try {
emit(LoadingState());
Project? project = HomeCubit.getInstance().project;
final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
event.unit.community.uuid,
event.unit.id,
project?.uuid ?? TempConst.projectIdDev);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(const ErrorState(message: 'Something went wrong'));
@ -37,12 +43,16 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
FetchDevicesByRoomIdEvent event, Emitter<ManageUnitState> emit) async {
try {
Map<String, bool> roomDevicesId = {};
Project? project = HomeCubit.getInstance().project;
emit(LoadingState());
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
allDevices = await HomeManagementAPI.fetchDevices(
project?.uuid ?? TempConst.projectIdDev);
List<String> allDevicesIds = [];
@ -72,14 +82,21 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
AssignRoomEvent event, Emitter<ManageUnitState> emit) async {
try {
Map<String, bool> roomDevicesId = {};
Project? project = HomeCubit.getInstance().project;
emit(LoadingState());
await HomeManagementAPI.assignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, event.deviceId);
event.unit.community.uuid,
event.unit.id,
event.roomId,
event.deviceId,
project?.uuid ?? TempConst.projectIdDev);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
List<String> allDevicesIds = [];
@ -105,19 +122,25 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
}
}
void _unassignDevice(
UnassignRoomEvent event, Emitter<ManageUnitState> emit) async {
try {
Map<String, bool> roomDevicesId = {};
Project? project = HomeCubit.getInstance().project;
emit(LoadingState());
await HomeManagementAPI.unAssignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, event.deviceId);
event.unit.community.uuid,
event.unit.id,
event.roomId,
event.deviceId,
project?.uuid ?? TempConst.projectIdDev);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
roomId: event.roomId,
projectId: project?.uuid ?? TempConst.projectIdDev);
List<String> allDevicesIds = [];
@ -143,18 +166,22 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
}
}
_addNewRoom(AddNewRoom event, Emitter<ManageUnitState> emit) async {
Map<String, String> body = {'subspaceName': event.roomName};
try {
emit(LoadingState());
Project? project = HomeCubit.getInstance().project;
final response = await HomeCreation.createRoom(
communityId: event.unit.community.uuid,
spaceId: event.unit.id,
body: body);
body: body,
projectId: project?.uuid ?? TempConst.projectIdDev);
if (response['data']['uuid'] != '') {
final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
event.unit.community.uuid,
event.unit.id,
project?.uuid ?? TempConst.projectIdDev);
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
await HomeCubit.getInstance().fetchUnitsByUserId();

View File

@ -154,11 +154,11 @@ class MenuCubit extends Cubit<MenuState> {
'title': 'Legal Information',
'color': const Color(0xFF001B72),
'buttons': [
{
'title': 'About',
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout,
'page': null
},
// {
// 'title': 'About',
// 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout,
// 'page': null
// },
{
'title': 'Privacy Policy',
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy,
@ -176,7 +176,7 @@ class MenuCubit extends Cubit<MenuState> {
Future<void> fetchMenuSections() async {
emit(MenuLoading());
try {
emit(MenuItemsLoaded(menuSections));
emit(MenuItemsLoaded(menuSections));
} catch (e) {
emit(MenuError(e.toString()));
}

View File

@ -23,8 +23,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
String timeZoneSelected = '';
String regionSelected = '';
final TextEditingController searchController = TextEditingController();
final TextEditingController nameController =
TextEditingController(text: '${HomeCubit.user!.firstName} ${HomeCubit.user!.lastName}');
final TextEditingController nameController = TextEditingController(
text: '${HomeCubit.user!.firstName} ${HomeCubit.user!.lastName}');
List<RegionModel> allRegions = [];
List<TimeZone> allTimeZone = [];
@ -77,10 +77,13 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
emit(NameEditingState(editName: editName));
}
void _fetchUserInfo(InitialProfileEvent event, Emitter<ProfileState> emit) async {
void _fetchUserInfo(
InitialProfileEvent event, Emitter<ProfileState> emit) async {
try {
emit(LoadingInitialState());
HomeCubit.user = await ProfileApi().fetchUserInfo(HomeCubit.user!.uuid);
HomeCubit.getInstance().project = HomeCubit.user?.project;
emit(SaveState());
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
@ -88,7 +91,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
}
Future _fetchTimeZone(TimeZoneInitialEvent event, Emitter<ProfileState> emit) async {
Future _fetchTimeZone(
TimeZoneInitialEvent event, Emitter<ProfileState> emit) async {
emit(LoadingInitialState());
try {
allTimeZone = await ProfileApi.fetchTimeZone();
@ -100,7 +104,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
}
Future selectTimeZone(SelectTimeZoneEvent event, Emitter<ProfileState> emit) async {
Future selectTimeZone(
SelectTimeZoneEvent event, Emitter<ProfileState> emit) async {
try {
emit(LoadingInitialState());
timeZoneSelected = event.val;
@ -112,7 +117,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
}
Future selectRegion(SelectRegionEvent event, Emitter<ProfileState> emit) async {
Future selectRegion(
SelectRegionEvent event, Emitter<ProfileState> emit) async {
try {
emit(LoadingInitialState());
await ProfileApi.saveRegion(regionUuid: event.val);
@ -124,7 +130,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
}
Future<void> searchRegion(SearchRegionEvent event, Emitter<ProfileState> emit) async {
Future<void> searchRegion(
SearchRegionEvent event, Emitter<ProfileState> emit) async {
emit(LoadingInitialState());
final query = event.query.toLowerCase();
if (allRegions.isEmpty) {
@ -140,7 +147,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
}
Future<void> searchTimeZone(SearchTimeZoneEvent event, Emitter<ProfileState> emit) async {
Future<void> searchTimeZone(
SearchTimeZoneEvent event, Emitter<ProfileState> emit) async {
emit(LoadingInitialState());
final query = event.query.toLowerCase();
if (allTimeZone.isEmpty) {
@ -156,7 +164,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
}
void _fetchRegion(RegionInitialEvent event, Emitter<ProfileState> emit) async {
void _fetchRegion(
RegionInitialEvent event, Emitter<ProfileState> emit) async {
try {
emit(LoadingInitialState());
allRegions = await ProfileApi.fetchRegion();
@ -166,7 +175,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
}
Future<void> _selectImage(SelectImageEvent event, Emitter<ProfileState> emit) async {
Future<void> _selectImage(
SelectImageEvent event, Emitter<ProfileState> emit) async {
try {
if (await _requestPermission()) {
emit(ChangeImageState());
@ -283,7 +293,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
}
return false;
} else {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
bool firstClick = sharedPreferences.getBool('firstPermission') ?? true;
await sharedPreferences.setBool('firstPermission', false);
if (firstClick == false) {

View File

@ -28,8 +28,7 @@ class AssignDeviceView extends StatelessWidget {
listener: (context, state) {
if (state is FetchDeviceByRoomIdState) {
if (state.allDevices.isEmpty) {
CustomSnackBar.displaySnackBar(
'You do not have the permission to assign devices');
CustomSnackBar.displaySnackBar('You do not have the devices');
Navigator.of(context).pop();
}
}

View File

@ -16,85 +16,74 @@ class ManageHomeView extends StatelessWidget {
var spaces = HomeCubit.getInstance().spaces;
return DefaultScaffold(
title: 'Manage Your Home',
child: spaces == null
height: MediaQuery.sizeOf(context).height,
child: spaces.isEmpty
? const Center(
child: BodyMedium(text: 'No spaces found'),
)
: Column(
children: [
DefaultContainer(
padding: const EdgeInsets.symmetric(
horizontal: 25,
vertical: 20,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: List.generate(
spaces.length,
(index) {
if (index == spaces.length - 1) {
return InkWell(
onTap: () {
Navigator.of(context).push(CustomPageRoute(
builder: (context) => HomeSettingsView(
space: spaces[index],
)));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BodyMedium(text: StringHelpers.toTitleCase(spaces[index].name)),
const Icon(
Icons.arrow_forward_ios,
color: ColorsManager.greyColor,
size: 15,
)
],
),
);
}
return InkWell(
onTap: () {
//TODO refactor the routing to use named routes
// Navigator.of(context).pushNamed(
// '/home_settings',
// arguments: spaces[index],
// );
: DefaultContainer(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 25),
child: ListView.builder(
itemCount: spaces.length,
itemBuilder: (context, index) {
if (index == spaces.length - 1) {
return InkWell(
onTap: () {
Navigator.of(context).push(CustomPageRoute(
builder: (context) => HomeSettingsView(
space: spaces[index],
)));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BodyMedium(text: StringHelpers.toTitleCase(spaces[index].name)),
const Icon(
Icons.arrow_forward_ios,
color: ColorsManager.greyColor,
size: 15,
)
],
),
);
}
return InkWell(
onTap: () {
//TODO refactor the routing to use named routes
// Navigator.of(context).pushNamed(
// '/home_settings',
// arguments: spaces[index],
// );
Navigator.of(context).push(CustomPageRoute(
builder: (context) => HomeSettingsView(
space: spaces[index],
)));
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
Navigator.of(context).push(CustomPageRoute(
builder: (context) => HomeSettingsView(
space: spaces[index],
)));
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BodyMedium(text: HomeCubit.getInstance().spaces![index].name),
const Icon(
Icons.arrow_forward_ios,
color: ColorsManager.greyColor,
size: 15,
)
],
),
Container(
margin: const EdgeInsets.symmetric(vertical: 15),
height: 1,
BodyMedium(text: HomeCubit.getInstance().spaces[index].name),
const Icon(
Icons.arrow_forward_ios,
color: ColorsManager.greyColor,
),
size: 15,
)
],
),
);
},
),
),
),
],
Container(
margin: const EdgeInsets.symmetric(vertical: 15),
height: 1,
color: ColorsManager.greyColor,
),
],
),
);
}),
));
}
}

View File

@ -109,22 +109,19 @@ class VerificationCodePage extends StatelessWidget {
children: [
Expanded(
child: InkWell(
onTap: state is TimerState &&
!state.isButtonEnabled &&
state.remainingTime != 1
? null
: () {
_bloc.add(StartTimerEvent());
},
onTap:
state is TimerState && !state.isButtonEnabled && state.remainingTime != 1
? null
: () {
_bloc.add(StartTimerEvent());
},
child: Container(
padding: const EdgeInsets.only(
right: 20, left: 20, top: 15, bottom: 15),
padding: const EdgeInsets.only(right: 20, left: 20, top: 15, bottom: 15),
decoration: BoxDecoration(
color: state is TimerState && !state.isButtonEnabled
? ColorsManager.blueButton
: ColorsManager.blueColor,
borderRadius:
BorderRadius.all(Radius.circular(20))),
borderRadius: BorderRadius.all(Radius.circular(20))),
child: Center(
child: Center(
child: Text(
@ -132,8 +129,7 @@ class VerificationCodePage extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: state is TimerState &&
!state.isButtonEnabled
color: state is TimerState && !state.isButtonEnabled
? Colors.white
: ColorsManager.onPrimaryColor,
),
@ -146,24 +142,18 @@ class VerificationCodePage extends StatelessWidget {
Expanded(
child: InkWell(
onTap: () {
context
.read<SecurityBloc>()
.add(VerifyPassCodeEvent());
context.read<SecurityBloc>().add(VerifyPassCodeEvent());
},
child: Container(
padding: const EdgeInsets.only(
right: 20, left: 20, top: 15, bottom: 15),
padding: const EdgeInsets.only(right: 20, left: 20, top: 15, bottom: 15),
decoration: const BoxDecoration(
color: ColorsManager.blueColor,
borderRadius:
BorderRadius.all(Radius.circular(20))),
borderRadius: BorderRadius.all(Radius.circular(20))),
child: const Center(
child: Text(
"Verify",
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w700),
fontSize: 16, color: Colors.white, fontWeight: FontWeight.w700),
),
),
),

View File

@ -1,6 +1,8 @@
import 'dart:async';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart';
@ -348,15 +350,18 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
emit(CreateSceneLoading());
try {
dynamic response;
Project? project = HomeCubit.getInstance().project;
if (event.createSceneModel != null) {
response = event.updateScene
? await SceneApi.updateScene(event.createSceneModel!, event.sceneId)
: await SceneApi.createScene(event.createSceneModel!);
} else if (event.createAutomationModel != null) {
response = event.updateScene
? await SceneApi.updateAutomation(
event.createAutomationModel!, event.sceneId)
: await SceneApi.createAutomation(event.createAutomationModel!);
? await SceneApi.updateAutomation(event.createAutomationModel!,
event.sceneId, project?.uuid ?? '')
: await SceneApi.createAutomation(
event.createAutomationModel!, project?.uuid ?? '');
}
if (response['success'] == true) {
@ -421,6 +426,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
emit(CreateSceneLoading());
try {
Project? project = HomeCubit.getInstance().project;
tasksList.clear();
tempTasksList.clear();
selectedValues.clear();
@ -436,7 +443,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
conditionRule = 'or';
final response = event.isAutomation
? await SceneApi.getAutomationDetails(event.sceneId)
? await SceneApi.getAutomationDetails(
event.sceneId, project?.uuid ?? '')
: await SceneApi.getSceneDetails(event.sceneId);
if (response.id.isNotEmpty) {
if (event.isAutomation) {
@ -605,10 +613,14 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
emit(DeleteSceneLoading());
try {
Project? project = HomeCubit.getInstance().project;
final response =
sceneType.name == CreateSceneEnum.deviceStatusChanges.name
? await SceneApi.deleteAutomation(
automationId: event.sceneId, unitUuid: event.unitUuid)
automationId: event.sceneId,
unitUuid: event.unitUuid,
projectId: project?.uuid ?? '')
: await SceneApi.deleteScene(
sceneId: event.sceneId,
);

View File

@ -2,9 +2,12 @@ import 'dart:async';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
part 'scene_state.dart';
@ -23,9 +26,11 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
emit(SceneLoading());
try {
Project? project = HomeCubit.getInstance().project;
if (event.unitId.isNotEmpty) {
scenes = await SceneApi.getScenesByUnitId(
event.unitId, event.unit.community.uuid,
scenes = await SceneApi.getScenesByUnitId(event.unitId,
event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
showInDevice: event.showInDevice);
emit(SceneLoaded(scenes, automationList));
} else {
@ -41,8 +46,11 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
emit(SceneLoading());
try {
Project? project = HomeCubit.getInstance().project;
if (event.unitId.isNotEmpty) {
automationList = await SceneApi.getAutomationByUnitId(event.unitId);
automationList = await SceneApi.getAutomationByUnitId(
event.unitId, event.communityId, project?.uuid ?? '');
emit(SceneLoaded(scenes, automationList));
} else {
emit(const SceneError(message: 'Unit ID is empty'));
@ -91,11 +99,17 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
));
try {
Project? project = HomeCubit.getInstance().project;
final success = await SceneApi.updateAutomationStatus(
event.automationId, event.automationStatusUpdate);
event.automationId,
event.automationStatusUpdate,
project?.uuid ?? '');
if (success) {
automationList = await SceneApi.getAutomationByUnitId(
event.automationStatusUpdate.spaceUuid);
event.automationStatusUpdate.spaceUuid,
event.communityId,
project?.uuid ?? '');
newLoadingStates[event.automationId] = false;
emit(SceneLoaded(
currentState.scenes,

View File

@ -22,11 +22,13 @@ class LoadScenes extends SceneEvent {
class LoadAutomation extends SceneEvent {
final String unitId;
final String communityId;
const LoadAutomation(this.unitId);
const LoadAutomation(this.unitId, this.communityId);
@override
List<Object> get props => [unitId];
List<Object> get props => [unitId, communityId];
}
class SceneTrigger extends SceneEvent {
@ -43,8 +45,9 @@ class SceneTrigger extends SceneEvent {
class UpdateAutomationStatus extends SceneEvent {
final String automationId;
final AutomationStatusUpdate automationStatusUpdate;
final String communityId;
const UpdateAutomationStatus({required this.automationStatusUpdate, required this.automationId});
const UpdateAutomationStatus({required this.automationStatusUpdate, required this.automationId, required this.communityId});
@override
List<Object> get props => [automationStatusUpdate];

View File

@ -0,0 +1,78 @@
import 'package:syncrow_app/features/scene/enum/operation_dialog_type.dart';
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
import 'package:syncrow_app/generated/assets.dart';
class OneGangHelperFunctions {
static List<SceneStaticFunction> oneGangHelperFunctions(
String deviceId, String deviceName, functionValue) {
return [
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower,
operationName: 'Light Switch',
code: 'switch_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.onOff,
operationalValues: [
SceneOperationalValue(
icon: Assets.assetsAcPower, description: "ON", value: true),
SceneOperationalValue(
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
],
),
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsLightCountdown,
operationName: 'Light CountDown',
code: 'countdown_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.countdown,
operationalValues: [
SceneOperationalValue(icon: '', value: 0),
],
),
];
}
static List<SceneStaticFunction> oneGangAutomationFunctions(
String deviceId, String deviceName, functionValue) {
return [
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower,
operationName: 'Light Switch',
code: 'switch_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.onOff,
operationalValues: [
SceneOperationalValue(
icon: Assets.assetsAcPower, description: "ON", value: true),
SceneOperationalValue(
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
],
),
SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsLightCountdown,
operationName: 'Light CountDown',
code: 'countdown_1',
functionValue: functionValue,
operationDialogType: OperationDialogType.integerSteps,
operationalValues: [
SceneOperationalValue(
icon: '',
description: "sec",
value: 0.0,
minValue: 0,
maxValue: 43200,
stepValue: 1,
),
],
),
];
}
}

View File

@ -0,0 +1,48 @@
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart';
abstract final class SceneBlocFactory {
static SceneBloc create({
required bool pageType,
required HomeCubit homeCubit,
}) {
final selectedSpace = homeCubit.selectedSpace;
final defaultSpace = SpaceModel(
id: '-1',
name: '',
community: Community(
uuid: '-1',
name: '',
),
);
final spaceId = selectedSpace?.id ?? defaultSpace.id;
final space = selectedSpace ?? defaultSpace;
final communityUuid =
selectedSpace?.community.uuid ?? defaultSpace.community.uuid;
final sceneBloc = SceneBloc();
sceneBloc.add(
LoadScenes(
spaceId,
space,
showInDevice: pageType,
),
);
if (!pageType) {
sceneBloc.add(
LoadAutomation(
spaceId,
communityUuid,
),
);
}
return sceneBloc;
}
}

View File

@ -6,6 +6,7 @@ import 'package:syncrow_app/features/scene/helper/functions_per_device/ac_functi
import 'package:syncrow_app/features/scene/helper/functions_per_device/door_lock_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/gateway_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/human_presence_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/one_gang_functions.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/presence_sensor.dart';
import 'package:syncrow_app/features/scene/helper/functions_per_device/three_gang_functions.dart';
import 'package:syncrow_app/features/scene/model/scene_details_model.dart';
@ -14,8 +15,9 @@ import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
mixin SceneOperationsDataHelper {
final Map<DeviceType, Function(List<FunctionModel>, String, String, dynamic, bool)> _functionMap =
{
final Map<DeviceType,
Function(List<FunctionModel>, String, String, dynamic, bool)>
_functionMap = {
DeviceType.LightBulb: lightBulbFunctions,
DeviceType.CeilingSensor: ceilingSensorFunctions,
DeviceType.WallSensor: wallSensorFunctions,
@ -24,6 +26,7 @@ mixin SceneOperationsDataHelper {
DeviceType.Curtain: curtainFunctions,
DeviceType.ThreeGang: threeGangFunctions,
DeviceType.Gateway: gatewayFunctions,
DeviceType.OneGang: oneGangFunctions,
};
final Map<DeviceType, String> _titleMap = {
@ -35,7 +38,24 @@ mixin SceneOperationsDataHelper {
DeviceType.Curtain: 'Curtain Functions',
DeviceType.ThreeGang: '3G Light Switch Functions',
DeviceType.Gateway: 'Gateway Functions',
DeviceType.OneGang: '1G Light Switch Conditions',
};
static String _productTypeCache = '';
//one gang functions
static List<SceneStaticFunction> oneGangFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) {
return OneGangHelperFunctions.oneGangAutomationFunctions(
deviceId, deviceName, functionValue);
}
return OneGangHelperFunctions.oneGangHelperFunctions(
deviceId, deviceName, functionValue);
}
List<SceneStaticFunction> getFunctionsWithIcons({
DeviceType? type,
@ -45,16 +65,22 @@ mixin SceneOperationsDataHelper {
required bool isAutomation,
}) {
final functionValue = null;
return _functionMap[type]?.call(functions, deviceId, deviceName, functionValue, isAutomation) ??
lightBulbFunctions(functions, deviceId, deviceName, functionValue, isAutomation);
return _functionMap[type]?.call(
functions, deviceId, deviceName, functionValue, isAutomation) ??
lightBulbFunctions(
functions, deviceId, deviceName, functionValue, isAutomation);
}
String getTitle({DeviceType? type}) {
return _titleMap[type] ?? '';
}
static List<SceneStaticFunction> ceilingSensorFunctions(List<FunctionModel> functions,
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) {
static List<SceneStaticFunction> ceilingSensorFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) {
return PresenceSensorHelperFunctions.automationPresenceSensorFunctions(
deviceId, deviceName, functionValue);
@ -63,22 +89,35 @@ mixin SceneOperationsDataHelper {
deviceId, deviceName, functionValue);
}
static List<SceneStaticFunction> curtainFunctions(List<FunctionModel> functions, String deviceId,
String deviceName, dynamic functionValue, bool isAutomation) {
static List<SceneStaticFunction> curtainFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
return [];
}
static List<SceneStaticFunction> doorLockFunctions(List<FunctionModel> functions, String deviceId,
String deviceName, dynamic functionValue, bool isAutomation) {
static List<SceneStaticFunction> doorLockFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) {
return DoorLockHelperFunctions.doorLockAutomationFunctions(
deviceId, deviceName, functionValue);
}
return DoorLockHelperFunctions.doorLockTapToRunFunctions(deviceId, deviceName, functionValue);
return DoorLockHelperFunctions.doorLockTapToRunFunctions(
deviceId, deviceName, functionValue);
}
static List<SceneStaticFunction> wallSensorFunctions(List<FunctionModel> functions,
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) {
static List<SceneStaticFunction> wallSensorFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) {
return HumanPresenceHelperFunctions.automationHumanPresenceFunctions(
deviceId, deviceName, functionValue);
@ -87,31 +126,51 @@ mixin SceneOperationsDataHelper {
deviceId, deviceName, functionValue);
}
static List<SceneStaticFunction> lightBulbFunctions(List<FunctionModel> functions,
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) {
static List<SceneStaticFunction> lightBulbFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
return [];
}
static List<SceneStaticFunction> gatewayFunctions(List<FunctionModel> functions, String deviceId,
String deviceName, dynamic functionValue, bool isAutomation) {
return GatewayHelperFunctions.tabToRunGatewayFunctions(deviceId, deviceName, functionValue);
static List<SceneStaticFunction> gatewayFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
return GatewayHelperFunctions.tabToRunGatewayFunctions(
deviceId, deviceName, functionValue);
}
static List<SceneStaticFunction> threeGangFunctions(List<FunctionModel> functions,
String deviceId, String deviceName, dynamic functionValue, bool isAutomation) {
static List<SceneStaticFunction> threeGangFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) {
return ThreeGangHelperFunctions.threeGangAutomationFunctions(
deviceId, deviceName, functionValue);
}
return ThreeGangHelperFunctions.threeGangHelperFunctions(deviceId, deviceName, functionValue);
return ThreeGangHelperFunctions.threeGangHelperFunctions(
deviceId, deviceName, functionValue);
}
static List<SceneStaticFunction> acFunctions(List<FunctionModel> functions, String deviceId,
String deviceName, dynamic functionValue, bool isAutomation) {
static List<SceneStaticFunction> acFunctions(
List<FunctionModel> functions,
String deviceId,
String deviceName,
dynamic functionValue,
bool isAutomation) {
if (isAutomation) {
return ACFunctionsHelper.automationAcFunctions(deviceId, deviceName, functionValue);
return ACFunctionsHelper.automationAcFunctions(
deviceId, deviceName, functionValue);
}
return ACFunctionsHelper.tabToRunAcFunctions(deviceId, deviceName, functionValue);
return ACFunctionsHelper.tabToRunAcFunctions(
deviceId, deviceName, functionValue);
}
List<SceneStaticFunction> getTaskListFunctionsFromApi({
@ -149,8 +208,12 @@ mixin SceneOperationsDataHelper {
SceneStaticFunction(
deviceId: action.entityId,
deviceName: action.name.toString(),
deviceIcon: action.type == 'automation' ? Assets.player : Assets.handClickIcon,
icon: action.type == 'automation' ? Assets.player : Assets.handClickIcon,
deviceIcon: action.type == 'automation'
? Assets.player
: Assets.handClickIcon,
icon: action.type == 'automation'
? Assets.player
: Assets.handClickIcon,
operationName: action.type.toString(),
operationDialogType: OperationDialogType.onOff,
functionValue: action.actionExecutor,
@ -170,7 +233,8 @@ mixin SceneOperationsDataHelper {
),
);
} else {
functions.add(_mapExecutorPropertyToSceneFunction(action, isAutomation));
functions
.add(_mapExecutorPropertyToSceneFunction(action, isAutomation));
}
}
@ -206,7 +270,9 @@ mixin SceneOperationsDataHelper {
}) {
final executorProperty = action.executorProperty;
final Map<String, SceneStaticFunction Function(Action, bool, String?, String?)> functionMap = {
final Map<String,
SceneStaticFunction Function(Action, bool, String?, String?)>
functionMap = {
'sensitivity': _createSensitivityFunction,
'normal_open_switch': _createNormalOpenSwitchFunction,
'unlock_fingerprint': _createUnlockFingerprintFunction,
@ -282,14 +348,16 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createSensitivityFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createSensitivityFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Presence Sensor',
Assets.assetsIconsSensors,
'Sensitivity',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.listOfOptions,
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.listOfOptions,
isAutomation ? _createIntegerStepsOptions() : _createSensitivityOptions(),
isAutomation,
comparator,
@ -297,8 +365,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createNormalOpenSwitchFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createNormalOpenSwitchFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -351,8 +419,8 @@ mixin SceneOperationsDataHelper {
];
}
SceneStaticFunction _createUnlockFingerprintFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createUnlockFingerprintFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -366,8 +434,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createUnlockPasswordFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createUnlockPasswordFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -381,8 +449,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createUnlockCardFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createUnlockCardFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -396,8 +464,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createAlarmLockFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createAlarmLockFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -411,8 +479,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createUnlockRequestFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createUnlockRequestFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -426,8 +494,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createResidualElectricityFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createResidualElectricityFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -441,8 +509,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createReverseLockFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createReverseLockFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -456,8 +524,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createUnlockAppFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createUnlockAppFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -471,8 +539,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createHijackFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createHijackFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -486,8 +554,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createDoorbellFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createDoorbellFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -501,8 +569,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createUnlockTemporaryFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createUnlockTemporaryFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'WIFI LOCK PRO',
@ -516,8 +584,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createFarDetectionFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createFarDetectionFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -531,8 +599,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createMotionSensitivityFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createMotionSensitivityFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -546,8 +614,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createMotionlessSensitivityFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createMotionlessSensitivityFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -561,8 +629,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createIndicatorFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createIndicatorFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -576,8 +644,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createPresenceTimeFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createPresenceTimeFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -591,8 +659,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createPresenceStateFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createPresenceStateFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -606,14 +674,16 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createDisCurrentFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createDisCurrentFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
Assets.assetsIconsSensors,
'Current Distance',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown,
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.countdown,
_createCurrentDistanceOptions(),
isAutomation,
comparator,
@ -621,8 +691,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createIlluminanceValueFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createIlluminanceValueFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -636,8 +706,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createCheckingResultFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createCheckingResultFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Human Presence Sensor',
@ -651,8 +721,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createSwitchFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createSwitchFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Smart AC Thermostat - Grey - Model A',
@ -666,23 +736,27 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createTempSetFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createTempSetFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Smart AC Thermostat - Grey - Model A',
Assets.assetsIconsAC,
'Set Temperature',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.temperature,
isAutomation ? _createAutomationTemperatureOptions() : _createTemperatureOptions(),
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.temperature,
isAutomation
? _createAutomationTemperatureOptions()
: _createTemperatureOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
}
SceneStaticFunction _createTempCurrentFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createTempCurrentFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Smart AC Thermostat - Grey - Model A',
@ -696,8 +770,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createModeFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createModeFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Smart AC Thermostat - Grey - Model A',
@ -711,8 +785,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createLevelFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createLevelFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Smart AC Thermostat - Grey - Model A',
@ -726,8 +800,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createChildLockFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createChildLockFunction(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Smart AC Thermostat - Grey - Model A',
@ -741,23 +815,38 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createSwitch1Function(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch,
'Light 1 Switch',
OperationDialogType.onOff,
_createOnOffOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
SceneStaticFunction _createSwitch1Function(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
switch (action.productType) {
case "3G":
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch,
'Light 1 Switch',
OperationDialogType.onOff,
_createOnOffOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
default:
return _createSceneFunction(
action,
'1 Gang Button Switch L-L',
Assets.oneGang,
'Light Switch',
OperationDialogType.onOff,
_createOnOffOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
}
}
SceneStaticFunction _createSwitch2Function(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createSwitch2Function(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
@ -771,8 +860,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createSwitch3Function(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createSwitch3Function(Action action, bool isAutomation,
String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
@ -786,53 +875,84 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createCountdown1Function(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch,
'Light 1 CountDown',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown,
isAutomation ? _createAutomationCountDownOptions() : _createCountdownOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
SceneStaticFunction _createCountdown1Function(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
switch (action.productType) {
case "3G":
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch,
'Light 1 CountDown',
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.countdown,
isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
default:
return _createSceneFunction(
action,
'1 Gang Button Switch L-L',
Assets.oneGang,
'Light CountDown',
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.countdown,
isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
}
}
SceneStaticFunction _createCountdown2Function(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createCountdown2Function(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch,
'Light 2 CountDown',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown,
isAutomation ? _createAutomationCountDownOptions() : _createCountdownOptions(),
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.countdown,
isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
}
SceneStaticFunction _createCountdown3Function(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createCountdown3Function(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'3 Gang Button Switch L-L',
Assets.assetsIcons3GangSwitch,
'Light 3 CountDown',
isAutomation ? OperationDialogType.integerSteps : OperationDialogType.countdown,
isAutomation ? _createAutomationCountDownOptions() : _createCountdownOptions(),
isAutomation
? OperationDialogType.integerSteps
: OperationDialogType.countdown,
isAutomation
? _createAutomationCountDownOptions()
: _createCountdownOptions(),
isAutomation,
comparator,
uniqueCustomId,
);
}
SceneStaticFunction _createSwitchAlarmSoundFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createSwitchAlarmSoundFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Gateway',
@ -846,8 +966,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createMasterStateFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createMasterStateFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Gateway',
@ -861,8 +981,8 @@ mixin SceneOperationsDataHelper {
);
}
SceneStaticFunction _createFactoryResetFunction(
Action action, bool isAutomation, String? comparator, String? uniqueCustomId) {
SceneStaticFunction _createFactoryResetFunction(Action action,
bool isAutomation, String? comparator, String? uniqueCustomId) {
return _createSceneFunction(
action,
'Gateway',
@ -1180,8 +1300,12 @@ mixin SceneOperationsDataHelper {
uniqueCustomId: taskItem.uniqueCustomId,
deviceId: taskItem.deviceId,
deviceName: taskItem.deviceName.toString(),
deviceIcon: taskItem.operationName == 'automation' ? Assets.player : Assets.handClickIcon,
icon: taskItem.operationName == 'automation' ? Assets.player : Assets.handClickIcon,
deviceIcon: taskItem.operationName == 'automation'
? Assets.player
: Assets.handClickIcon,
icon: taskItem.operationName == 'automation'
? Assets.player
: Assets.handClickIcon,
operationName: taskItem.operationName,
operationDialogType: OperationDialogType.onOff,
functionValue: taskItem.functionValue == 'rule_enable' ? true : false,

View File

@ -74,6 +74,7 @@ class Action {
ExecutorProperty? executorProperty;
String? name;
String? type;
String? productType;
Action({
required this.actionExecutor,
@ -81,6 +82,7 @@ class Action {
this.executorProperty,
this.name,
this.type,
this.productType,
});
String toRawJson() => json.encode(toJson());
@ -88,10 +90,11 @@ class Action {
static Action? fromJson(Map<String, dynamic> json) {
if (json['name'] != null && json['type'] != null) {
return Action(
actionExecutor: json["actionExecutor"],
entityId: json["entityId"],
name: json['name'],
type: json['type'],
actionExecutor: json["actionExecutor"] as String,
entityId: json["entityId"] as String,
name: json['name'] as String?,
type: json['type'] as String?,
productType: json['productType'] as String?,
);
}
if (json["executorProperty"] == null) {
@ -99,9 +102,10 @@ class Action {
}
return Action(
actionExecutor: json["actionExecutor"],
entityId: json["entityId"],
actionExecutor: json["actionExecutor"] as String,
entityId: json["entityId"] as String,
executorProperty: ExecutorProperty.fromJson(json["executorProperty"]),
productType: json['productType'] as String?,
);
}

View File

@ -29,25 +29,38 @@ class _SceneRoomsTabBarDevicesViewState
@override
void initState() {
selectedSpace = HomeCubit.getInstance().selectedSpace!;
rooms = List.from(HomeCubit.getInstance().selectedSpace?.subspaces ?? []);
if (rooms != null) {
if (rooms![0].id != '-1') {
rooms?.insert(
0,
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
selectedSpace = HomeCubit.getInstance().selectedSpace!;
rooms = List.from(selectedSpace.subspaces ?? []);
if (rooms != null && rooms!.isNotEmpty) {
if (rooms![0].id != '-1') {
rooms?.insert(
0,
SubSpaceModel(
name: 'All Devices',
devices: context.read<DevicesCubit>().allDevices,
id: '-1',
),
);
}
} else {
rooms = [
SubSpaceModel(
name: 'All Devices',
devices: context.read<DevicesCubit>().allDevices,
id: '-1',
),
);
)
];
}
}
_tabController =
TabController(length: rooms!.length, vsync: this, initialIndex: 0);
_tabController.addListener(_handleTabSwitched);
super.initState();
_tabController = TabController(length: rooms!.length, vsync: this);
_tabController.addListener(_handleTabSwitched);
setState(() {});
});
}
void _handleTabSwitched() {

View File

@ -1,75 +1,45 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/scene_listview.dart';
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart';
import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart';
import 'package:syncrow_app/features/scene/helper/scene_bloc_factory.dart';
import 'package:syncrow_app/features/scene/widgets/empty_devices_widget.dart';
import 'package:syncrow_app/features/scene/widgets/scene_view_widget/scene_grid_view.dart';
import 'package:syncrow_app/features/scene/widgets/scene_view_widget/scene_header.dart';
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
import 'package:syncrow_app/features/shared_widgets/app_loading_indicator.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SceneView extends StatelessWidget {
const SceneView({
this.pageType = false,
super.key,
});
final bool pageType;
const SceneView({super.key, this.pageType = false});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (BuildContext context) {
if (pageType) {
return SceneBloc()
..add(LoadScenes(
HomeCubit.getInstance().selectedSpace?.id ?? '',
HomeCubit.getInstance().selectedSpace ??
SpaceModel(
id: '-1',
name: '',
community: Community(
uuid: '-1',
name: '',
)),
showInDevice: pageType));
} else {
return SceneBloc()
..add(LoadScenes(
HomeCubit.getInstance().selectedSpace?.id ?? '',
HomeCubit.getInstance().selectedSpace ??
SpaceModel(
id: '-1',
name: '',
community: Community(
uuid: '-1',
name: '',
)),
showInDevice: pageType))
..add(LoadAutomation(HomeCubit.getInstance().selectedSpace?.id ?? ''));
}
},
create: (context) => SceneBlocFactory.create(
pageType: pageType,
homeCubit: HomeCubit.getInstance(),
),
child: BlocBuilder<CreateSceneBloc, CreateSceneState>(
builder: (context, state) {
final selectedSpace = HomeCubit.getInstance().selectedSpace;
if (state is DeleteSceneSuccess) {
if (state.success) {
BlocProvider.of<SceneBloc>(context).add(LoadScenes(
HomeCubit.getInstance().selectedSpace!.id, HomeCubit.getInstance().selectedSpace!,
showInDevice: pageType));
BlocProvider.of<SceneBloc>(context)
.add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id));
}
if (state.success) _loadScenesAndAutomations(context, selectedSpace);
}
if (state is CreateSceneWithTasks) {
if (state.success == true) {
BlocProvider.of<SceneBloc>(context).add(LoadScenes(
HomeCubit.getInstance().selectedSpace!.id, HomeCubit.getInstance().selectedSpace!,
showInDevice: pageType));
BlocProvider.of<SceneBloc>(context)
.add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id));
if (state.success) {
_loadScenesAndAutomations(context, selectedSpace);
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
}
}
@ -77,23 +47,24 @@ class SceneView extends StatelessWidget {
listener: (context, state) {
if (state is SceneTriggerSuccess) {
context.showCustomSnackbar(
message: 'Scene ${state.sceneName} triggered successfully!');
message: 'Scene ${state.sceneName} triggered successfully!',
);
}
},
child: HomeCubit.getInstance().spaces?.isEmpty ?? true
? const CreateUnitWidget()
child: HomeCubit.getInstance().spaces.isEmpty
? const EmptyDevicesWidget()
: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (pageType == false) const SceneHeader(),
if (pageType == false) const SizedBox(height: 8),
if (!pageType) ...[
const SceneHeader(),
const SizedBox(height: 8),
],
BlocBuilder<SceneBloc, SceneState>(
builder: (context, state) {
if (state is SceneLoading) {
return const Center(
child: CircularProgressIndicator(),
);
return const AppLoadingIndicator();
}
if (state is SceneError) {
return Center(
@ -103,80 +74,83 @@ class SceneView extends StatelessWidget {
if (state is SceneLoaded) {
final scenes = state.scenes;
final automationList = state.automationList;
if (scenes.isEmpty) return const EmptyDevicesWidget();
return pageType
? Expanded(
child: SceneListview(
scenes: scenes,
loadingSceneId: state.loadingSceneId,
))
: Expanded(
child: ListView(
if (pageType) {
return SizedBox(
height: context.height * 0.1,
child: SceneListview(
scenes: scenes,
loadingSceneId: state.loadingSceneId,
),
);
}
return Theme(
data: Theme.of(context).copyWith(
dividerColor: Colors.transparent,
),
child: Expanded(
child: ListView(
children: [
ExpansionTile(
tilePadding: const EdgeInsets.symmetric(
horizontal: 6,
),
initiallyExpanded: true,
iconColor: ColorsManager.grayColor,
title: const BodyMedium(
text: 'Tap to run routines',
),
children: [
Theme(
data: ThemeData()
.copyWith(dividerColor: Colors.transparent),
child: ExpansionTile(
tilePadding: const EdgeInsets.symmetric(horizontal: 6),
initiallyExpanded: true,
iconColor: ColorsManager.grayColor,
title: const BodyMedium(text: 'Tap to run routines'),
children: [
scenes.isNotEmpty
? SceneGrid(
scenes: scenes,
loadingSceneId: state.loadingSceneId,
disablePlayButton: false,
loadingStates:
state.loadingStates, // Add this line
)
: const Center(
child: BodyMedium(
text: 'No scenes have been added yet',
),
),
const SizedBox(
height: 10,
),
],
if (scenes.isNotEmpty)
SceneGrid(
scenes: scenes,
loadingSceneId: state.loadingSceneId,
disablePlayButton: false,
loadingStates: state.loadingStates,
)
else
const Center(
child: BodyMedium(
text: 'No scenes have been added yet',
),
),
),
Theme(
data: ThemeData()
.copyWith(dividerColor: Colors.transparent),
child: ExpansionTile(
initiallyExpanded: true,
iconColor: ColorsManager.grayColor,
tilePadding: const EdgeInsets.symmetric(horizontal: 6),
title: const BodyMedium(text: 'Automation'),
children: [
automationList.isNotEmpty
? SceneGrid(
scenes: automationList,
loadingSceneId: state.loadingSceneId,
disablePlayButton: true,
loadingStates:
state.loadingStates, // Add this line
)
: const Center(
child: BodyMedium(
text: 'No automations have been added yet',
),
),
const SizedBox(
height: 10,
),
],
),
),
const SizedBox(
height: 15,
),
const SizedBox(height: 10),
],
),
);
ExpansionTile(
initiallyExpanded: true,
iconColor: ColorsManager.grayColor,
tilePadding: const EdgeInsets.symmetric(
horizontal: 6,
),
title: const BodyMedium(text: 'Automation'),
children: [
if (automationList.isNotEmpty)
SceneGrid(
scenes: automationList,
loadingSceneId: state.loadingSceneId,
disablePlayButton: true,
loadingStates: state.loadingStates,
)
else
const Center(
child: BodyMedium(
text:
'No automations have been added yet',
),
),
const SizedBox(height: 10),
],
),
const SizedBox(height: 15),
],
),
),
);
}
return const SizedBox();
return const SizedBox.shrink();
},
),
],
@ -186,4 +160,21 @@ class SceneView extends StatelessWidget {
),
);
}
void _loadScenesAndAutomations(BuildContext context, SpaceModel? selectedSpace) {
BlocProvider.of<SceneBloc>(context)
..add(
LoadScenes(
selectedSpace!.id,
selectedSpace,
showInDevice: pageType,
),
)
..add(
LoadAutomation(
selectedSpace.id,
selectedSpace.community.uuid,
),
);
}
}

View File

@ -25,7 +25,7 @@ class DeleteRoutineButton extends StatelessWidget {
BlocProvider.of<SceneBloc>(context).add(LoadScenes(
HomeCubit.getInstance().selectedSpace!.id, HomeCubit.getInstance().selectedSpace!));
BlocProvider.of<SceneBloc>(context)
.add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id));
.add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id,HomeCubit.getInstance().selectedSpace!.community.uuid));
}
}
},

View File

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class EmptyDevicesWidget extends StatelessWidget {
const EmptyDevicesWidget({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 48),
child: Text(
"No routines.\nEnable 'Show on Home Screen' to add routines",
textAlign: TextAlign.center,
style: TextStyle(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400,
fontSize: 12,
),
),
);
}
}

View File

@ -132,6 +132,10 @@ class SceneItem extends StatelessWidget {
spaceUuid: HomeCubit.getInstance()
.selectedSpace!
.id),
communityId: HomeCubit.getInstance()
.selectedSpace!
.community
.uuid,
automationId: scene.id));
},
),

View File

@ -22,7 +22,7 @@ class SmartEnableAutomation extends StatelessWidget {
child: BlocBuilder<SceneBloc, SceneState>(
bloc: context.read<SceneBloc>()
..add(
LoadAutomation(HomeCubit.getInstance().selectedSpace?.id ?? '')),
LoadAutomation(HomeCubit.getInstance().selectedSpace?.id ?? '',HomeCubit.getInstance().selectedSpace?.community.uuid ?? '')),
builder: (context, state) {
if (state is SceneLoading) {
return const Align(

View File

@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
class AppLoadingIndicator extends StatelessWidget {
const AppLoadingIndicator({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: CircularProgressIndicator.adaptive(),
);
}
}

View File

@ -88,6 +88,8 @@ abstract class ApiEndpoints {
//SPACE Module
//GET
static const String userSpaces = '/user/{userUuid}/spaces';
static const String devices = '/projects/{projectUuid}/devices';
static const String spaceDevices =
'/projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
@ -142,7 +144,7 @@ abstract class ApiEndpoints {
/// POST
static const String createScene = '/scene/tap-to-run';
static const String triggerScene = '/scene/tap-to-run/{sceneId}/trigger';
static const String createAutomation = '/automation';
static const String createAutomation = '/projects/{projectId}/automations';
/// GET
static const String getUnitScenes =
@ -151,23 +153,23 @@ abstract class ApiEndpoints {
static const String getScene = '/scene/tap-to-run/{sceneId}';
static const String getIconScene = '/scene/icon';
static const String getUnitAutomation = '/automation/{unitUuid}';
static const String getUnitAutomation = '/projects/{projectId}/communities/{communityId}/spaces/{unitUuid}/automations';
static const String getAutomationDetails =
'/automation/details/{automationId}';
'/projects/{projectId}/automations/{automationId}';
/// PUT
static const String updateScene = '/scene/tap-to-run/{sceneId}';
static const String updateAutomation = '/automation/{automationId}';
static const String updateAutomation = '/projects/{projectId}/automations/{automationId}';
static const String updateAutomationStatus =
'/automation/status/{automationId}';
'/projects/{projectId}/automations/{automationId}';
/// DELETE
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
static const String deleteAutomation = '/automation/{automationId}';
static const String deleteAutomation = '/projects/{projectId}/automations/{automationId}';
//////////////////////Door Lock //////////////////////
//online

View File

@ -51,14 +51,11 @@ class DevicesAPI {
static Future<Map<String, dynamic>> controlDevice(
DeviceControlModel controlModel, String deviceId) async {
try {
print('object-*/-*/-*/${controlModel.toJson()}');
final response = await _httpService.post(
path: ApiEndpoints.controlDevice.replaceAll('{deviceUuid}', deviceId),
body: controlModel.toJson(),
showServerMessage: true,
expectedResponseModel: (json) {
print('object-*/-*/-*/${json}');
return json;
},
);
@ -191,7 +188,6 @@ class DevicesAPI {
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
print('object-*-*-*${json}');
return json;
});
return response;
@ -223,13 +219,14 @@ class DevicesAPI {
required String communityUuid,
required String spaceUuid,
required String roomId,
required String projectId,
}) async {
try {
final String path = ApiEndpoints.deviceByRoom
.replaceAll('{communityUuid}', communityUuid)
.replaceAll('{spaceUuid}', spaceUuid)
.replaceAll('{subSpaceUuid}', roomId)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{projectUuid}', projectId);
final response = await _httpService.get(
path: path,
@ -568,22 +565,18 @@ class DevicesAPI {
static Future<List<DeviceModel>> getAllDevices({
required String communityUuid,
required String spaceUuid,
required String projectId,
}) async {
print('communityUuid=$communityUuid');
print('spaceUuid=$spaceUuid');
print('projectUuid=${TempConst.projectId}');
try {
final String path = ApiEndpoints.getAllDevices
.replaceAll('{communityUuid}', communityUuid)
.replaceAll('{spaceUuid}', spaceUuid)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{projectUuid}', projectId);
final response = await _httpService.get(
path: path,
showServerMessage: false,
expectedResponseModel: (json) {
print('response-*/-*/$json');
final data = json['data'];
if (data == null || data.isEmpty) {

View File

@ -145,12 +145,13 @@ class HomeCreation {
required String communityId,
required String spaceId,
required Map<String, String> body,
required String projectId
}) async {
try {
final fullPath = ApiEndpoints.addSubSpace
.replaceAll('{communityUuid}', communityId)
.replaceAll('{spaceUuid}', spaceId)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{projectUuid}', projectId);
final response = await _httpService.post(
path: fullPath,
body: body,

View File

@ -27,7 +27,23 @@ class HomeManagementAPI {
return list;
}
static Future<List<DeviceModel>> fetchDevicesByUnitId() async {
static Future<List<DeviceModel>> fetchDevices(projectUuid) async {
List<DeviceModel> list = [];
await _httpService.get(
path: ApiEndpoints.devices.replaceAll("{projectUuid}", projectUuid),
showServerMessage: false,
expectedResponseModel: (json) {
json.forEach((value) {
list.add(DeviceModel.fromJson(value));
});
});
return list;
}
static Future<List<DeviceModel>> fetchDevicesByUnitId(
String projectUuid) async {
List<DeviceModel> list = [];
try {
@ -40,7 +56,7 @@ class HomeManagementAPI {
final path = ApiEndpoints.spaceDevices
.replaceAll('{communityUuid}', communityUuid)
.replaceAll('{spaceUuid}', spaceUuid)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{projectUuid}', projectUuid);
await _httpService.get(
path: path,
@ -62,11 +78,16 @@ class HomeManagementAPI {
return list;
}
static Future<Map<String, dynamic>> assignDeviceToRoom(String communityId,
String spaceId, String subSpaceId, String deviceId) async {
static Future<Map<String, dynamic>> assignDeviceToRoom(
String communityId,
String spaceId,
String subSpaceId,
String deviceId,
String projectId) async {
try {
final response = await _httpService.post(
path: ApiEndpoints.assignDeviceToRoom
.replaceAll('{projectUuid}', projectId)
.replaceAll('{communityUuid}', communityId)
.replaceAll('{spaceUuid}', spaceId)
.replaceAll('{subSpaceUuid}', subSpaceId)
@ -81,8 +102,12 @@ class HomeManagementAPI {
}
}
static Future<Map<String, dynamic>> unAssignDeviceToRoom(String communityId,
String spaceId, String subSpaceId, String deviceId) async {
static Future<Map<String, dynamic>> unAssignDeviceToRoom(
String communityId,
String spaceId,
String subSpaceId,
String deviceId,
String projectId) async {
try {
final response = await _httpService.delete(
path: ApiEndpoints.assignDeviceToRoom
@ -90,7 +115,7 @@ class HomeManagementAPI {
.replaceAll('{spaceUuid}', spaceId)
.replaceAll('{subSpaceUuid}', subSpaceId)
.replaceAll('{deviceUuid}', deviceId)
.replaceAll('{projectUuid}', TempConst.projectId),
.replaceAll('{projectUuid}', projectId),
expectedResponseModel: (json) {
return json;
},

View File

@ -6,7 +6,6 @@ import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/features/scene/model/update_automation.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
class SceneApi {
static final HTTPService _httpService = HTTPService();
@ -31,10 +30,11 @@ class SceneApi {
// create automation
static Future<Map<String, dynamic>> createAutomation(
CreateAutomationModel createAutomationModel) async {
CreateAutomationModel createAutomationModel, String projectId) async {
try {
final response = await _httpService.post(
path: ApiEndpoints.createAutomation,
path:
ApiEndpoints.createAutomation.replaceAll('{projectId}', projectId),
body: createAutomationModel.toMap(),
showServerMessage: false,
expectedResponseModel: (json) {
@ -50,14 +50,14 @@ class SceneApi {
//get scene by unit id
static Future<List<ScenesModel>> getScenesByUnitId(
String unitId, String communityId,
String unitId, String communityId, String projectId,
{showInDevice = false}) async {
try {
final response = await _httpService.get(
path: ApiEndpoints.getUnitScenes
.replaceAll('{spaceUuid}', unitId)
.replaceAll('{communityUuid}', communityId)
.replaceAll('{projectUuid}', TempConst.projectId),
.replaceAll('{projectUuid}', projectId),
queryParameters: {'showInHomePage': showInDevice},
showServerMessage: false,
expectedResponseModel: (json) {
@ -78,10 +78,17 @@ class SceneApi {
//getAutomation
static Future<List<ScenesModel>> getAutomationByUnitId(String unitId) async {
static Future<List<ScenesModel>> getAutomationByUnitId(
String unitId,
String communityId,
String projectId,
) async {
try {
final response = await _httpService.get(
path: ApiEndpoints.getUnitAutomation.replaceAll('{unitUuid}', unitId),
path: ApiEndpoints.getUnitAutomation
.replaceAll('{unitUuid}', unitId)
.replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', projectId),
showServerMessage: false,
expectedResponseModel: (json) {
List<ScenesModel> scenes = [];
@ -112,11 +119,12 @@ class SceneApi {
//automation details
static Future<SceneDetailsModel> getAutomationDetails(
String automationId) async {
String automationId, String projectId) async {
try {
final response = await _httpService.get(
path: ApiEndpoints.getAutomationDetails
.replaceAll('{automationId}', automationId),
.replaceAll('{automationId}', automationId)
.replaceAll('{projectId}', projectId),
showServerMessage: false,
expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
);
@ -128,11 +136,12 @@ class SceneApi {
//updateAutomationStatus
static Future<bool> updateAutomationStatus(String automationId,
AutomationStatusUpdate createAutomationEnable) async {
AutomationStatusUpdate createAutomationEnable, String projectId) async {
try {
final response = await _httpService.put(
final response = await _httpService.patch(
path: ApiEndpoints.updateAutomationStatus
.replaceAll('{automationId}', automationId),
.replaceAll('{automationId}', automationId)
.replaceAll('{projectId}', projectId),
body: createAutomationEnable.toMap(),
expectedResponseModel: (json) => json['success'],
);
@ -194,12 +203,13 @@ class SceneApi {
}
//update automation
static updateAutomation(
CreateAutomationModel createAutomationModel, String automationId) async {
static updateAutomation(CreateAutomationModel createAutomationModel,
String automationId, String projectId) async {
try {
final response = await _httpService.put(
path: ApiEndpoints.updateAutomation
.replaceAll('{automationId}', automationId),
.replaceAll('{automationId}', automationId)
.replaceAll('{projectId}', projectId),
body: createAutomationModel
.toJson(automationId.isNotEmpty == true ? automationId : null),
expectedResponseModel: (json) {
@ -229,11 +239,14 @@ class SceneApi {
// delete automation
static Future<bool> deleteAutomation(
{required String unitUuid, required String automationId}) async {
{required String unitUuid,
required String automationId,
required String projectId}) async {
try {
final response = await _httpService.delete(
path: ApiEndpoints.deleteAutomation
.replaceAll('{automationId}', automationId),
.replaceAll('{automationId}', automationId)
.replaceAll('{projectId}', projectId),
showServerMessage: false,
expectedResponseModel: (json) => json['statusCode'] == 200,
);

View File

@ -32,13 +32,13 @@ class SpacesAPI {
}
static Future<List<SubSpaceModel>> getSubSpaceBySpaceId(
String communityId, String spaceId) async {
String communityId, String spaceId, String projectId) async {
try {
// Construct the API path
final path = ApiEndpoints.listSubspace
.replaceFirst('{communityUuid}', communityId)
.replaceFirst('{spaceUuid}', spaceId)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{projectUuid}', projectId);
final response = await _httpService.get(
path: path,
@ -66,12 +66,12 @@ class SpacesAPI {
//factory/reset/{deviceUuid}
static Future<String> generateInvitationCode(
String unitId, String communityId) async {
String unitId, String communityId, String projectId) async {
final response = await _httpService.post(
path: ApiEndpoints.invitationCode
.replaceAll('{unitUuid}', unitId)
.replaceAll('{communityUuid}', communityId)
.replaceAll('{projectUuid}', TempConst.projectId),
.replaceAll('{projectUuid}', projectId),
showServerMessage: false,
expectedResponseModel: (json) {
if (json != null && json['data'] != null) {

View File

@ -1,3 +1,5 @@
import 'package:flutter_dotenv/flutter_dotenv.dart';
class TempConst {
static const projectId = '0e62577c-06fa-41b9-8a92-99a21fbaf51c';
static String projectIdDev = dotenv.env['PROJECT_ID'] ?? '';
}

View File

@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "37a42d06068e2fe3deddb2da079a8c4d105f241225ba27b7122b37e9865fd8f7"
sha256: "27899c95f9e7ec06c8310e6e0eac967707714b9f1450c4a58fa00ca011a4a8ae"
url: "https://pub.dev"
source: hosted
version: "1.3.35"
version: "1.3.49"
args:
dependency: transitive
description:
@ -25,14 +25,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
audio_session:
dependency: transitive
description:
name: audio_session
sha256: b2a26ba8b7efa1790d6460e82971fde3e398cfbe2295df9dea22f3499d2c12a7
url: "https://pub.dev"
source: hosted
version: "0.1.23"
bloc:
dependency: transitive
description:
@ -81,14 +73,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
chewie:
dependency: transitive
description:
name: chewie
sha256: "8bc4ac4cf3f316e50a25958c0f5eb9bb12cf7e8308bb1d74a43b230da2cfc144"
url: "https://pub.dev"
source: hosted
version: "1.7.5"
clock:
dependency: transitive
description:
@ -101,18 +85,18 @@ packages:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.19.0"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
url: "https://pub.dev"
source: hosted
version: "0.3.4+1"
version: "0.3.4+2"
crypto:
dependency: transitive
description:
@ -125,10 +109,10 @@ packages:
dependency: transitive
description:
name: csslib
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "0.17.3"
cupertino_icons:
dependency: "direct main"
description:
@ -141,34 +125,26 @@ packages:
dependency: "direct main"
description:
name: day_picker
sha256: a0f73716d688b3643769db39e7626cae54026bec24c33a8ebf5a6f8c618a05f2
sha256: "0f7b7e0078f8c7882d009bebabf3b9825acfe5ac0dbcc6ad0fd520bef3fc1047"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
dbus:
dependency: transitive
description:
name: dbus
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
version: "2.3.0"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus
sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91
sha256: "4fa68e53e26ab17b70ca39f072c285562cfc1589df5bb1e9295db90f6645f431"
url: "https://pub.dev"
source: hosted
version: "10.1.0"
version: "11.2.0"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
version: "7.0.2"
dio:
dependency: "direct main"
description:
@ -181,10 +157,10 @@ packages:
dependency: "direct main"
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
url: "https://pub.dev"
source: hosted
version: "2.0.5"
version: "2.0.7"
fake_async:
dependency: transitive
description:
@ -197,10 +173,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.3"
file:
dependency: transitive
description:
@ -245,90 +221,90 @@ packages:
dependency: "direct main"
description:
name: firebase_analytics
sha256: c6220b23397f9302a42617227ee8fb1c5d718097a5351fcce53561d73fc10339
sha256: "498c6cb8468e348a556709c745d92a52173ab3a9b906aa0593393f0787f201ea"
url: "https://pub.dev"
source: hosted
version: "10.8.7"
version: "11.4.0"
firebase_analytics_platform_interface:
dependency: transitive
description:
name: firebase_analytics_platform_interface
sha256: "7f1c02cdd93a5e0a561af2f551465ffb6abdd541dbd0c8a9b8628d9ae0a5d024"
sha256: ccbb350554e98afdb4b59852689292d194d31232a2647b5012a66622b3711df9
url: "https://pub.dev"
source: hosted
version: "3.9.7"
version: "4.3.0"
firebase_analytics_web:
dependency: transitive
description:
name: firebase_analytics_web
sha256: ebb857c23f35fed52220b6c3271c12eeb6137de3930845223e3d0590b6fd0649
sha256: "68e1f18fc16482c211c658e739c25f015b202a260d9ad8249c6d3d7963b8105f"
url: "https://pub.dev"
source: hosted
version: "0.5.5+19"
version: "0.5.10+6"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "26de145bb9688a90962faec6f838247377b0b0d32cc0abecd9a4e43525fc856c"
sha256: "0307c1fde82e2b8b97e0be2dab93612aff9a72f31ebe9bfac66ed8b37ef7c568"
url: "https://pub.dev"
source: hosted
version: "2.32.0"
version: "3.10.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63
sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
url: "https://pub.dev"
source: hosted
version: "5.0.0"
version: "5.4.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: "22fcb352744908224fc7be3caae254836099786acfe5df6e9fe901e9c2575a41"
sha256: fbc008cf390d909b823763064b63afefe9f02d8afdb13eb3f485b871afee956b
url: "https://pub.dev"
source: hosted
version: "2.17.1"
version: "2.19.0"
firebase_crashlytics:
dependency: "direct main"
description:
name: firebase_crashlytics
sha256: "0126fa101b74fb981796b3e6f47ccf7fc40237ec918327aaec7c0a06fd1bb4c1"
sha256: f6adb65fa3d6391a79f0e60833bb4cdc468ce0c318831c90057ee11e0909cd29
url: "https://pub.dev"
source: hosted
version: "3.4.16"
version: "4.3.0"
firebase_crashlytics_platform_interface:
dependency: transitive
description:
name: firebase_crashlytics_platform_interface
sha256: cdfa0a20d66e1b32de542883c0ddf651ee9b66b12cebf73067e4d2cdc0865d17
sha256: "6635166c22c6f75f634b8e77b70fcc43b24af4cfee28f975249dbdbd9769a702"
url: "https://pub.dev"
source: hosted
version: "3.6.23"
version: "3.8.0"
firebase_database:
dependency: "direct main"
description:
name: firebase_database
sha256: "3b9ca306d26ad243ccbc4c717ff6e8563a080ebe11ee77fa7349b419c894b42d"
sha256: af9e0b2e8a117d2324027a5632d64b003e710283a20c692e12ebcc439d22be5c
url: "https://pub.dev"
source: hosted
version: "10.5.7"
version: "11.3.0"
firebase_database_platform_interface:
dependency: transitive
description:
name: firebase_database_platform_interface
sha256: "5864cc362275465e9bd682b243f19419c9d78b861c2db820241eea596ae3b320"
sha256: "6f92dfdd773c40d7b04113ad9e9de66826cd8a9f6c939a3693943eba4adce234"
url: "https://pub.dev"
source: hosted
version: "0.2.5+35"
version: "0.2.6"
firebase_database_web:
dependency: transitive
description:
name: firebase_database_web
sha256: a6008395dd20e8b8dde0691b441c181a1216c3866f89f48dcb6889d34fd35905
sha256: "6b863cc62cbd5d006d8e36d5407336115d3737cfe1d8574c6d8a3d035d0ed259"
url: "https://pub.dev"
source: hosted
version: "0.2.5+7"
version: "0.2.6+6"
fixnum:
dependency: transitive
description:
@ -341,10 +317,10 @@ packages:
dependency: "direct main"
description:
name: fl_chart
sha256: "94307bef3a324a0d329d3ab77b2f0c6e5ed739185ffc029ed28c0f9b019ea7ef"
sha256: "10ddaf334fe84d59333a12d153043e366f243e0bdfff2df0313e1e249f5bf926"
url: "https://pub.dev"
source: hosted
version: "0.69.0"
version: "0.70.1"
flutter:
dependency: "direct main"
description: flutter
@ -382,14 +358,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.1.0"
flutter_html:
dependency: "direct main"
description:
name: flutter_html
sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee"
url: "https://pub.dev"
source: hosted
version: "3.0.0-beta.2"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "5.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
@ -464,78 +448,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_widget_from_html:
dependency: "direct main"
description:
name: flutter_widget_from_html
sha256: f3967a5b42896662efdd420b5adaf8a7d3692b0f44462a07c80e3b4c173b1a02
url: "https://pub.dev"
source: hosted
version: "0.15.3"
flutter_widget_from_html_core:
dependency: transitive
description:
name: flutter_widget_from_html_core
sha256: b1048fd119a14762e2361bd057da608148a895477846d6149109b2151d2f7abf
url: "https://pub.dev"
source: hosted
version: "0.15.2"
fwfh_cached_network_image:
dependency: transitive
description:
name: fwfh_cached_network_image
sha256: "8e44226801bfba27930673953afce8af44da7e92573be93f60385d9865a089dd"
url: "https://pub.dev"
source: hosted
version: "0.14.3"
fwfh_chewie:
dependency: transitive
description:
name: fwfh_chewie
sha256: "37bde9cedfb6dc5546176f7f0c56af1e814966cb33ec58f16c9565ed93ccb704"
url: "https://pub.dev"
source: hosted
version: "0.14.8"
fwfh_just_audio:
dependency: transitive
description:
name: fwfh_just_audio
sha256: "38dc2c55803bd3cef33042c473e0c40b891ad4548078424641a32032f6a1245f"
url: "https://pub.dev"
source: hosted
version: "0.15.2"
fwfh_svg:
dependency: transitive
description:
name: fwfh_svg
sha256: "550b1014d12b5528d8bdb6e3b44b58721f3fb1f65d7a852d1623a817008bdfc4"
url: "https://pub.dev"
source: hosted
version: "0.8.3"
fwfh_url_launcher:
dependency: transitive
description:
name: fwfh_url_launcher
sha256: b9f5d55a5ae2c2c07243ba33f7ba49ac9544bdb2f4c16d8139df9ccbebe3449c
url: "https://pub.dev"
source: hosted
version: "0.9.1"
fwfh_webview:
dependency: transitive
description:
name: fwfh_webview
sha256: c0a8b664b642f40f4c252a0ab4e72c22dcd97c7fb3a7e50a6b4bdb6f63afca19
url: "https://pub.dev"
source: hosted
version: "0.15.3"
get_it:
dependency: "direct main"
description:
name: get_it
sha256: e6017ce7fdeaf218dc51a100344d8cb70134b80e28b760f8bb23c242437bafd7
sha256: f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103
url: "https://pub.dev"
source: hosted
version: "7.6.7"
version: "8.0.3"
html:
dependency: "direct main"
description:
@ -548,10 +468,10 @@ packages:
dependency: transitive
description:
name: http
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
http_parser:
dependency: transitive
description:
@ -580,10 +500,10 @@ packages:
dependency: transitive
description:
name: image_picker_for_web
sha256: "5d6eb13048cd47b60dbf1a5495424dea226c5faf3950e20bf8120a58efb5b5f3"
sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83"
url: "https://pub.dev"
source: hosted
version: "3.0.4"
version: "3.0.6"
image_picker_ios:
dependency: transitive
description:
@ -628,10 +548,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
sha256: "00f33b908655e606b86d2ade4710a231b802eec6f11e87e4ea3783fd72077a50"
url: "https://pub.dev"
source: hosted
version: "0.19.0"
version: "0.20.1"
js:
dependency: transitive
description:
@ -640,46 +560,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.7"
just_audio:
dependency: transitive
description:
name: just_audio
sha256: "1a1eb86e7d81e69a1d36943f2b3efd62dece3dad2cafd9ec2e62e6db7c04d9b7"
url: "https://pub.dev"
source: hosted
version: "0.9.43"
just_audio_platform_interface:
dependency: transitive
description:
name: just_audio_platform_interface
sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790"
url: "https://pub.dev"
source: hosted
version: "4.3.0"
just_audio_web:
dependency: transitive
description:
name: just_audio_web
sha256: "9a98035b8b24b40749507687520ec5ab404e291d2b0937823ff45d92cb18d448"
url: "https://pub.dev"
source: hosted
version: "0.4.13"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
url: "https://pub.dev"
source: hosted
version: "10.0.4"
version: "10.0.7"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
version: "3.0.8"
leak_tracker_testing:
dependency: transitive
description:
@ -692,18 +588,18 @@ packages:
dependency: transitive
description:
name: lints
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
url: "https://pub.dev"
source: hosted
version: "3.0.0"
logging:
version: "5.1.1"
list_counter:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
name: list_counter
sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.0.2"
matcher:
dependency: transitive
description:
@ -716,18 +612,18 @@ packages:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.15.0"
mime:
dependency: transitive
description:
@ -760,22 +656,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.2.0"
package_info_plus:
dependency: transitive
description:
name: package_info_plus
sha256: cb44f49b6e690fa766f023d5b22cac6b9affe741dd792b6ac7ad4fabe0d7b097
url: "https://pub.dev"
source: hosted
version: "6.0.0"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
path:
dependency: transitive
description:
@ -948,18 +828,18 @@ packages:
dependency: "direct main"
description:
name: share_plus
sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
sha256: "6327c3f233729374d0abaafd61f6846115b2a481b4feddd8534211dc10659400"
url: "https://pub.dev"
source: hosted
version: "9.0.0"
version: "10.1.3"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
url: "https://pub.dev"
source: hosted
version: "4.0.0"
version: "5.0.2"
shared_preferences:
dependency: "direct main"
description:
@ -1004,10 +884,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_web
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
url: "https://pub.dev"
source: hosted
version: "2.3.0"
version: "2.2.1"
shared_preferences_windows:
dependency: transitive
description:
@ -1020,7 +900,7 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
version: "0.0.0"
sleek_circular_slider:
dependency: "direct main"
description:
@ -1073,10 +953,10 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.12.0"
stream_channel:
dependency: transitive
description:
@ -1089,10 +969,10 @@ packages:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.3.0"
synchronized:
dependency: transitive
description:
@ -1113,10 +993,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
version: "0.7.3"
time_picker_spinner:
dependency: "direct main"
description:
@ -1137,26 +1017,26 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.2.5"
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.3.14"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
url: "https://pub.dev"
source: hosted
version: "6.2.4"
version: "6.3.2"
url_launcher_linux:
dependency: transitive
description:
@ -1169,34 +1049,34 @@ packages:
dependency: transitive
description:
name: url_launcher_macos
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.2.2"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.4.0"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.1.4"
uuid:
dependency: "direct main"
description:
@ -1237,118 +1117,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
video_player:
dependency: transitive
description:
name: video_player
sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17"
url: "https://pub.dev"
source: hosted
version: "2.9.2"
video_player_android:
dependency: transitive
description:
name: video_player_android
sha256: e343701aa890b74a863fa460f5c0e628127ed06a975d7d9af6b697133fb25bdf
url: "https://pub.dev"
source: hosted
version: "2.7.1"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
sha256: "8a4e73a3faf2b13512978a43cf1cdda66feeeb900a0527f1fbfd7b19cf3458d3"
url: "https://pub.dev"
source: hosted
version: "2.6.7"
video_player_platform_interface:
dependency: transitive
description:
name: video_player_platform_interface
sha256: "229d7642ccd9f3dc4aba169609dd6b5f3f443bb4cc15b82f7785fcada5af9bbb"
url: "https://pub.dev"
source: hosted
version: "6.2.3"
video_player_web:
dependency: transitive
description:
name: video_player_web
sha256: "881b375a934d8ebf868c7fb1423b2bfaa393a0a265fa3f733079a86536064a10"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
url: "https://pub.dev"
source: hosted
version: "14.2.1"
wakelock_plus:
dependency: transitive
description:
name: wakelock_plus
sha256: "104d94837bb28c735894dcd592877e990149c380e6358b00c04398ca1426eed4"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
wakelock_plus_platform_interface:
dependency: transitive
description:
name: wakelock_plus_platform_interface
sha256: "70e780bc99796e1db82fe764b1e7dcb89a86f1e5b3afb1db354de50f2e41eb7a"
url: "https://pub.dev"
source: hosted
version: "1.2.2"
version: "14.3.0"
web:
dependency: transitive
description:
name: web
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
url: "https://pub.dev"
source: hosted
version: "0.5.1"
webview_flutter:
dependency: transitive
description:
name: webview_flutter
sha256: "6869c8786d179f929144b4a1f86e09ac0eddfe475984951ea6c634774c16b522"
url: "https://pub.dev"
source: hosted
version: "4.8.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: ed021f27ae621bc97a6019fb601ab16331a3db4bf8afa305e9f6689bdb3edced
url: "https://pub.dev"
source: hosted
version: "3.16.8"
webview_flutter_platform_interface:
dependency: transitive
description:
name: webview_flutter_platform_interface
sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
url: "https://pub.dev"
source: hosted
version: "2.10.0"
webview_flutter_wkwebview:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: "9c62cc46fa4f2d41e10ab81014c1de470a6c6f26051a2de32111b2ee55287feb"
url: "https://pub.dev"
source: hosted
version: "3.14.0"
version: "1.1.0"
win32:
dependency: transitive
description:
name: win32
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
sha256: "154360849a56b7b67331c21f09a386562d88903f90a1099c5987afc1912e1f29"
url: "https://pub.dev"
source: hosted
version: "5.2.0"
version: "5.10.0"
win32_registry:
dependency: transitive
description:
@ -1374,5 +1166,5 @@ packages:
source: hosted
version: "6.5.0"
sdks:
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.22.0"
dart: ">=3.6.0 <4.0.0"
flutter: ">=3.27.0"

View File

@ -5,7 +5,7 @@ description: This is the mobile application project, developed with Flutter for
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.18+55
version: 1.0.30+1
environment:
sdk: ">=3.0.6 <4.0.0"
@ -15,43 +15,43 @@ dependencies:
cupertino_icons: ^1.0.6
dio: ^5.4.1
equatable: ^2.0.5
firebase_analytics: ^10.8.7
firebase_core: ^2.25.5
firebase_crashlytics: ^3.4.16
firebase_analytics: ^11.4.0
firebase_core: ^3.10.0
firebase_crashlytics: ^4.3.0
flutter:
sdk: flutter
flutter_animated_dialog: ^2.0.1
flutter_svg: ^2.0.10+1
sleek_circular_slider: ^2.0.1
day_picker: 2.2.0
day_picker: ^2.3.0
# Utility Packages
flutter_secure_storage: ^9.0.0
flutter_dotenv: ^5.1.0
# noinspection YAMLSchemaValidation
intl: ^0.19.0
get_it: ^7.6.7
url_launcher: ^6.2.5
intl: ^0.20.1
get_it: ^8.0.3
url_launcher: ^6.3.1
# flutter_localization: ^0.2.0
flutter_bloc: ^8.1.4
html: ^0.15.4
onesignal_flutter: ^5.2.0
permission_handler: ^11.3.1
pin_code_fields: ^8.0.1
share_plus: ^9.0.0
share_plus: ^10.1.3
shared_preferences: ^2.2.2
smooth_page_indicator: ^1.1.0
uuid: ^4.4.0
time_picker_spinner: ^1.0.0
image_picker: ^1.1.2
device_info_plus: ^10.1.0
fl_chart: ^0.69.0
firebase_database: ^10.5.7
device_info_plus: ^11.2.0
fl_chart: ^0.70.1
firebase_database: ^11.3.0
percent_indicator: ^4.2.3
flutter_html: ^3.0.0-beta.2
dev_dependencies:
flutter_lints: ^3.0.1
flutter_lints: ^5.0.0
flutter_test:
sdk: flutter