mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-03-11 13:31:44 +00:00
Compare commits
94 Commits
Implement_
...
Fix-Save-D
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f49a18130 | |||
| a51c4d9679 | |||
| caeed8e73f | |||
| dc5ac9be5b | |||
| 5c9b30895f | |||
| 06b14a3964 | |||
| 3c92ea3047 | |||
| 73d28a1800 | |||
| 5493ca6fb0 | |||
| 7005d8ba83 | |||
| cb79627038 | |||
| 1cff69d496 | |||
| 60df77efad | |||
| 9e84048f81 | |||
| 99adb1c286 | |||
| f2412aa867 | |||
| e4768c95aa | |||
| f25b4dbf6d | |||
| 9eff9ab371 | |||
| a2e68d6194 | |||
| 94c94b170f | |||
| 253cf15559 | |||
| 443eea9421 | |||
| 87a2c08f64 | |||
| dd66e7c747 | |||
| 7af61d2f65 | |||
| f37eacb0ee | |||
| c7dcc297aa | |||
| aefe5ad081 | |||
| 8d9af8519d | |||
| b1d52937c9 | |||
| 5fedf37421 | |||
| ccde857c29 | |||
| b2a8086e0e | |||
| 408e78962c | |||
| dcdbc02ca0 | |||
| 31025e9176 | |||
| 8219de6821 | |||
| fbdf3817ab | |||
| 17422edd0d | |||
| 4c8f2c72df | |||
| fb867e5df3 | |||
| 9472390284 | |||
| 731ba0f3d6 | |||
| 56407c6426 | |||
| 02d61ca0bb | |||
| 99ee4b9878 | |||
| 19edd0a275 | |||
| ef5e7c3154 | |||
| 80dd0f696f | |||
| a64a41548f | |||
| 0d50aa68fa | |||
| 88aac86b10 | |||
| 0673548745 | |||
| c2fc8fa0ae | |||
| cbf10bbf78 | |||
| d95588ce84 | |||
| 7e2e591d71 | |||
| 2ec81bda9c | |||
| 3b0f51473c | |||
| 13757d89ee | |||
| d3068b8e14 | |||
| 7c5d7e1dda | |||
| 0a97a4867d | |||
| 6e55b488aa | |||
| 22789234fe | |||
| 8393ec353a | |||
| 0b45d61b25 | |||
| 450b773921 | |||
| 3f7f7ce49f | |||
| 2dc4e16a75 | |||
| cd41720244 | |||
| 67209961b4 | |||
| 9098276223 | |||
| 36dfe2c85e | |||
| efed5f55a7 | |||
| 9897c19dad | |||
| 48733fd65e | |||
| 4ca4086bd3 | |||
| 4da1b16b18 | |||
| 1189b52c57 | |||
| c578d63134 | |||
| 457b7c2c51 | |||
| 4ae04cf2af | |||
| d72253e3de | |||
| 790479effb | |||
| 827585815b | |||
| de024994c9 | |||
| bcc4ba98ff | |||
| df0f1c6c94 | |||
| 1f62cadcec | |||
| f960a553ca | |||
| 90812f78e8 | |||
| b1368bf4d7 |
5
.env.dev
5
.env.dev
@ -1,2 +1,5 @@
|
|||||||
ENV_NAME=development
|
ENV_NAME=development
|
||||||
BASE_URL=https://syncrow-dev.azurewebsites.net
|
BASE_URL=https://syncrow-dev.azurewebsites.net
|
||||||
|
PROJECT_ID=0e62577c-06fa-41b9-8a92-99a21fbaf51c
|
||||||
|
CLIENT_ID=c024573d191a327ce74db7d4502fdc29
|
||||||
|
CLIENT_SECRET=fec6ccbc33664f94a3b84a45c7cceef3f3ebd1613ef4307db8946ede530cd1ed
|
||||||
@ -1,2 +1,3 @@
|
|||||||
ENV_NAME=production
|
ENV_NAME=production
|
||||||
BASE_URL=https://syncrow-staging.azurewebsites.net
|
BASE_URL=https://syncrow-staging.azurewebsites.net
|
||||||
|
PROJECT_ID=bcda711e-9fc2-4168-a05e-171b4026d1ff
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
ENV_NAME=staging
|
ENV_NAME=staging
|
||||||
BASE_URL=https://syncrow-staging.azurewebsites.net
|
BASE_URL=https://syncrow-staging.azurewebsites.net
|
||||||
|
PROJECT_ID=bcda711e-9fc2-4168-a05e-171b4026d1ff
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,9 +5,11 @@
|
|||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.atom/
|
.atom/
|
||||||
|
.build/
|
||||||
.buildlog/
|
.buildlog/
|
||||||
.history
|
.history
|
||||||
.svn/
|
.svn/
|
||||||
|
.swiftpm/
|
||||||
migrate_working_dir/
|
migrate_working_dir/
|
||||||
|
|
||||||
# IntelliJ related
|
# IntelliJ related
|
||||||
@ -40,3 +42,4 @@ app.*.map.json
|
|||||||
/android/app/debug
|
/android/app/debug
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
/android/app/.cxx/
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.7.10'
|
ext.kotlin_version = '1.9.0'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
org.gradle.jvmargs=-Xmx4G
|
org.gradle.jvmargs=-Xmx4G
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
android.defaults.buildfeatures.buildconfig=true
|
||||||
|
android.nonTransitiveRClass=false
|
||||||
|
android.nonFinalResIds=false
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#Wed Apr 03 23:37:40 EET 2024
|
#Wed Apr 03 23:37:40 EET 2024
|
||||||
distributionBase=GRADLE_USER_HOME
|
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
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@ -23,7 +23,7 @@ pluginManagement {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
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
|
// START: FlutterFire Configuration
|
||||||
id "com.google.gms.google-services" version "4.3.15" apply false
|
id "com.google.gms.google-services" version "4.3.15" apply false
|
||||||
id "com.google.firebase.crashlytics" version "2.8.1" apply false
|
id "com.google.firebase.crashlytics" version "2.8.1" apply false
|
||||||
|
|||||||
10
assets/icons/cancel_icon.svg
Normal file
10
assets/icons/cancel_icon.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_7302_4118)">
|
||||||
|
<path d="M11.1049 10.0001L19.7712 1.33381C20.0763 1.02869 20.0763 0.534007 19.7712 0.228929C19.4661 -0.0761485 18.9714 -0.0761876 18.6663 0.228929L9.99999 8.89524L1.33372 0.228929C1.0286 -0.0761876 0.533915 -0.0761876 0.228837 0.228929C-0.0762401 0.534046 -0.0762792 1.02873 0.228837 1.33381L8.89511 10.0001L0.228837 18.6664C-0.0762792 18.9715 -0.0762792 19.4662 0.228837 19.7713C0.381376 19.9238 0.581337 20.0001 0.781297 20.0001C0.981258 20.0001 1.18118 19.9238 1.33376 19.7713L9.99999 11.105L18.6663 19.7713C18.8188 19.9238 19.0188 20.0001 19.2187 20.0001C19.4187 20.0001 19.6186 19.9238 19.7712 19.7713C20.0763 19.4662 20.0763 18.9715 19.7712 18.6664L11.1049 10.0001Z" fill="#999999"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_7302_4118">
|
||||||
|
<rect width="20" height="20" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 939 B |
18
assets/icons/offToggleSwitchSmall.svg
Normal file
18
assets/icons/offToggleSwitchSmall.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<svg width="47" height="37" viewBox="0 0 47 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="6" y="1" width="41" height="25" rx="12.5" fill="#E9E9E9"/>
|
||||||
|
<g filter="url(#filter0_d_6419_4507)">
|
||||||
|
<circle cx="18.5" cy="13.5" r="10.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_6419_4507" x="0" y="0" width="37" height="37" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="5"/>
|
||||||
|
<feGaussianBlur stdDeviation="4"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_6419_4507"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_6419_4507" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 965 B |
10
assets/icons/save_routines_icon.svg
Normal file
10
assets/icons/save_routines_icon.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_7302_4149)">
|
||||||
|
<path d="M19.9969 4.94279C19.986 4.83232 19.943 4.72146 19.8674 4.62924C19.8382 4.59358 20.1367 4.89431 15.4141 0.17176C15.3015 0.0591838 15.1487 8.30277e-05 14.9996 0.00012209C14.6443 0.00012209 2.11177 0.00012209 1.75779 0.00012209C0.788544 0.00012209 0 0.788666 0 1.75791V18.2421C0 19.2113 0.788544 19.9998 1.75779 19.9998H18.2419C19.2112 19.9998 19.9997 19.2113 19.9997 18.2421C19.9998 4.01624 20.0013 4.98771 19.9969 4.94279ZM13.4764 1.17198V5.00005C13.4764 5.32314 13.2136 5.58598 12.8905 5.58598H12.1483V1.17198H13.4764ZM10.9765 1.17198V5.58598H5.54684C5.22376 5.58598 4.96091 5.32314 4.96091 5.00005V1.17198H10.9765ZM13.4764 12.539H4.96091V11.7968C4.96091 11.4738 5.22376 11.2109 5.54684 11.2109H12.8905C13.2136 11.2109 13.4764 11.4738 13.4764 11.7968V12.539ZM4.96091 18.828V13.7109H13.4764V18.828H4.96091ZM18.8279 18.2421C18.8279 18.5651 18.5651 18.828 18.242 18.828H14.6483C14.6483 18.0641 14.6483 12.6676 14.6483 11.7968C14.6483 10.8276 13.8597 10.039 12.8905 10.039H5.54684C4.57759 10.039 3.78905 10.8276 3.78905 11.7968V18.828H1.75783C1.43475 18.828 1.1719 18.5651 1.1719 18.2421V1.75791C1.1719 1.43483 1.43475 1.17198 1.75783 1.17198H3.78905V5.00005C3.78905 5.9693 4.57759 6.75784 5.54684 6.75784H12.8905C13.8597 6.75784 14.6483 5.9693 14.6483 5.00005V1.17198H14.7571L18.8279 5.24278V18.2421Z" fill="#023DFE" fill-opacity="0.6"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_7302_4149">
|
||||||
|
<rect width="20" height="20" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
18
assets/icons/toggleSwitchSmall.svg
Normal file
18
assets/icons/toggleSwitchSmall.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<svg width="47" height="37" viewBox="0 0 47 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect y="1" width="41" height="25" rx="12.5" fill="#023DFE" fill-opacity="0.7"/>
|
||||||
|
<g filter="url(#filter0_d_6689_981)">
|
||||||
|
<circle cx="28.5" cy="13.5" r="10.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_6689_981" x="10" y="0" width="37" height="37" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="5"/>
|
||||||
|
<feGaussianBlur stdDeviation="4"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_6689_981"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_6689_981" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 975 B |
@ -1,5 +1,5 @@
|
|||||||
# Uncomment this line to define a global platform for your project
|
# 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.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|||||||
276
ios/Podfile.lock
276
ios/Podfile.lock
@ -1,155 +1,153 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Firebase/Analytics (10.25.0):
|
- Firebase/Analytics (11.6.0):
|
||||||
- Firebase/Core
|
- Firebase/Core
|
||||||
- Firebase/Core (10.25.0):
|
- Firebase/Core (11.6.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseAnalytics (~> 10.25.0)
|
- FirebaseAnalytics (~> 11.6.0)
|
||||||
- Firebase/CoreOnly (10.25.0):
|
- Firebase/CoreOnly (11.6.0):
|
||||||
- FirebaseCore (= 10.25.0)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- Firebase/Crashlytics (10.25.0):
|
- Firebase/Crashlytics (11.6.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseCrashlytics (~> 10.25.0)
|
- FirebaseCrashlytics (~> 11.6.0)
|
||||||
- Firebase/Database (10.25.0):
|
- Firebase/Database (11.6.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseDatabase (~> 10.25.0)
|
- FirebaseDatabase (~> 11.6.0)
|
||||||
- firebase_analytics (10.8.7):
|
- firebase_analytics (11.4.0):
|
||||||
- Firebase/Analytics (= 10.25.0)
|
- Firebase/Analytics (= 11.6.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_core (2.32.0):
|
- firebase_core (3.10.0):
|
||||||
- Firebase/CoreOnly (= 10.25.0)
|
- Firebase/CoreOnly (= 11.6.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_crashlytics (3.4.16):
|
- firebase_crashlytics (4.3.0):
|
||||||
- Firebase/Crashlytics (= 10.25.0)
|
- Firebase/Crashlytics (= 11.6.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_database (10.5.7):
|
- firebase_database (11.3.0):
|
||||||
- Firebase/Database (= 10.25.0)
|
- Firebase/Database (= 11.6.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- FirebaseAnalytics (10.25.0):
|
- FirebaseAnalytics (11.6.0):
|
||||||
- FirebaseAnalytics/AdIdSupport (= 10.25.0)
|
- FirebaseAnalytics/AdIdSupport (= 11.6.0)
|
||||||
- FirebaseCore (~> 10.0)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- FirebaseInstallations (~> 10.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 7.11)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseAnalytics/AdIdSupport (10.25.0):
|
- FirebaseAnalytics/AdIdSupport (11.6.0):
|
||||||
- FirebaseCore (~> 10.0)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- FirebaseInstallations (~> 10.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleAppMeasurement (= 10.25.0)
|
- GoogleAppMeasurement (= 11.6.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 7.11)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseAppCheckInterop (10.29.0)
|
- FirebaseAppCheckInterop (11.6.0)
|
||||||
- FirebaseCore (10.25.0):
|
- FirebaseCore (11.6.0):
|
||||||
- FirebaseCoreInternal (~> 10.0)
|
- FirebaseCoreInternal (~> 11.6.0)
|
||||||
- GoogleUtilities/Environment (~> 7.12)
|
- GoogleUtilities/Environment (~> 8.0)
|
||||||
- GoogleUtilities/Logger (~> 7.12)
|
- GoogleUtilities/Logger (~> 8.0)
|
||||||
- FirebaseCoreExtension (10.29.0):
|
- FirebaseCoreExtension (11.6.0):
|
||||||
- FirebaseCore (~> 10.0)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- FirebaseCoreInternal (10.29.0):
|
- FirebaseCoreInternal (11.6.0):
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- FirebaseCrashlytics (10.25.0):
|
- FirebaseCrashlytics (11.6.0):
|
||||||
- FirebaseCore (~> 10.5)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- FirebaseInstallations (~> 10.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- FirebaseRemoteConfigInterop (~> 10.23)
|
- FirebaseRemoteConfigInterop (~> 11.0)
|
||||||
- FirebaseSessions (~> 10.5)
|
- FirebaseSessions (~> 11.0)
|
||||||
- GoogleDataTransport (~> 9.2)
|
- GoogleDataTransport (~> 10.0)
|
||||||
- GoogleUtilities/Environment (~> 7.8)
|
- GoogleUtilities/Environment (~> 8.0)
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- PromisesObjC (~> 2.1)
|
- PromisesObjC (~> 2.4)
|
||||||
- FirebaseDatabase (10.25.0):
|
- FirebaseDatabase (11.6.0):
|
||||||
- FirebaseAppCheckInterop (~> 10.17)
|
- FirebaseAppCheckInterop (~> 11.0)
|
||||||
- FirebaseCore (~> 10.0)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- FirebaseSharedSwift (~> 10.0)
|
- FirebaseSharedSwift (~> 11.0)
|
||||||
- GoogleUtilities/UserDefaults (~> 7.13)
|
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||||
- leveldb-library (~> 1.22)
|
- leveldb-library (~> 1.22)
|
||||||
- FirebaseInstallations (10.29.0):
|
- FirebaseInstallations (11.6.0):
|
||||||
- FirebaseCore (~> 10.0)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- GoogleUtilities/Environment (~> 7.8)
|
- GoogleUtilities/Environment (~> 8.0)
|
||||||
- GoogleUtilities/UserDefaults (~> 7.8)
|
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||||
- PromisesObjC (~> 2.1)
|
- PromisesObjC (~> 2.4)
|
||||||
- FirebaseRemoteConfigInterop (10.29.0)
|
- FirebaseRemoteConfigInterop (11.6.0)
|
||||||
- FirebaseSessions (10.29.0):
|
- FirebaseSessions (11.6.0):
|
||||||
- FirebaseCore (~> 10.5)
|
- FirebaseCore (~> 11.6.0)
|
||||||
- FirebaseCoreExtension (~> 10.0)
|
- FirebaseCoreExtension (~> 11.6.0)
|
||||||
- FirebaseInstallations (~> 10.0)
|
- FirebaseInstallations (~> 11.0)
|
||||||
- GoogleDataTransport (~> 9.2)
|
- GoogleDataTransport (~> 10.0)
|
||||||
- GoogleUtilities/Environment (~> 7.13)
|
- GoogleUtilities/Environment (~> 8.0)
|
||||||
- GoogleUtilities/UserDefaults (~> 7.13)
|
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- PromisesSwift (~> 2.1)
|
- PromisesSwift (~> 2.1)
|
||||||
- FirebaseSharedSwift (10.29.0)
|
- FirebaseSharedSwift (11.6.0)
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
- flutter_secure_storage (6.0.0):
|
- flutter_secure_storage (6.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- GoogleAppMeasurement (10.25.0):
|
- GoogleAppMeasurement (11.6.0):
|
||||||
- GoogleAppMeasurement/AdIdSupport (= 10.25.0)
|
- GoogleAppMeasurement/AdIdSupport (= 11.6.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 7.11)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAppMeasurement/AdIdSupport (10.25.0):
|
- GoogleAppMeasurement/AdIdSupport (11.6.0):
|
||||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 10.25.0)
|
- GoogleAppMeasurement/WithoutAdIdSupport (= 11.6.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 7.11)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAppMeasurement/WithoutAdIdSupport (10.25.0):
|
- GoogleAppMeasurement/WithoutAdIdSupport (11.6.0):
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
- GoogleUtilities/MethodSwizzler (~> 8.0)
|
||||||
- GoogleUtilities/Network (~> 7.11)
|
- GoogleUtilities/Network (~> 8.0)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleDataTransport (9.4.1):
|
- GoogleDataTransport (10.1.0):
|
||||||
- GoogleUtilities/Environment (~> 7.7)
|
- nanopb (~> 3.30910.0)
|
||||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
- PromisesObjC (~> 2.4)
|
||||||
- PromisesObjC (< 3.0, >= 1.2)
|
- GoogleUtilities/AppDelegateSwizzler (8.0.2):
|
||||||
- GoogleUtilities/AppDelegateSwizzler (7.13.3):
|
|
||||||
- GoogleUtilities/Environment
|
- GoogleUtilities/Environment
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Network
|
- GoogleUtilities/Network
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/Environment (7.13.3):
|
- GoogleUtilities/Environment (8.0.2):
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- PromisesObjC (< 3.0, >= 1.2)
|
- GoogleUtilities/Logger (8.0.2):
|
||||||
- GoogleUtilities/Logger (7.13.3):
|
|
||||||
- GoogleUtilities/Environment
|
- GoogleUtilities/Environment
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/MethodSwizzler (7.13.3):
|
- GoogleUtilities/MethodSwizzler (8.0.2):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/Network (7.13.3):
|
- GoogleUtilities/Network (8.0.2):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- "GoogleUtilities/NSData+zlib"
|
- "GoogleUtilities/NSData+zlib"
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/Reachability
|
- GoogleUtilities/Reachability
|
||||||
- "GoogleUtilities/NSData+zlib (7.13.3)":
|
- "GoogleUtilities/NSData+zlib (8.0.2)":
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/Privacy (7.13.3)
|
- GoogleUtilities/Privacy (8.0.2)
|
||||||
- GoogleUtilities/Reachability (7.13.3):
|
- GoogleUtilities/Reachability (8.0.2):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/UserDefaults (7.13.3):
|
- GoogleUtilities/UserDefaults (8.0.2):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- image_picker_ios (0.0.1):
|
- image_picker_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- leveldb-library (1.22.5)
|
- leveldb-library (1.22.6)
|
||||||
- nanopb (2.30910.0):
|
- nanopb (3.30910.0):
|
||||||
- nanopb/decode (= 2.30910.0)
|
- nanopb/decode (= 3.30910.0)
|
||||||
- nanopb/encode (= 2.30910.0)
|
- nanopb/encode (= 3.30910.0)
|
||||||
- nanopb/decode (2.30910.0)
|
- nanopb/decode (3.30910.0)
|
||||||
- nanopb/encode (2.30910.0)
|
- nanopb/encode (3.30910.0)
|
||||||
- onesignal_flutter (5.2.0):
|
- onesignal_flutter (5.2.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- OneSignalXCFramework (= 5.2.0)
|
- OneSignalXCFramework (= 5.2.0)
|
||||||
@ -291,42 +289,42 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
|
||||||
Firebase: 0312a2352584f782ea56f66d91606891d4607f06
|
Firebase: 374a441a91ead896215703a674d58cdb3e9d772b
|
||||||
firebase_analytics: 3a9263fedec72970e6bd30a7132bbdd386de2c14
|
firebase_analytics: 07bd7cfbac54bfcdccf2bb2530f9a65486f7ef3f
|
||||||
firebase_core: a626d00494efa398e7c54f25f1454a64c8abf197
|
firebase_core: feb37e79f775c2bd08dd35e02d83678291317e10
|
||||||
firebase_crashlytics: 0b7cb41f5fb3b6889d0fb408cfce3cc7a4247061
|
firebase_crashlytics: 609a5f6f4a2f5af9e40a68182e0c1be3ca2a02f6
|
||||||
firebase_database: 2713033e426b176d4fe5e7195f3d19aa1b549a91
|
firebase_database: adc9efd0b70cdc8d1e6f3c9f6bb054a625c4f45d
|
||||||
FirebaseAnalytics: ec00fe8b93b41dc6fe4a28784b8e51da0647a248
|
FirebaseAnalytics: 7114c698cac995602e3b1b96663473e50d54d6e7
|
||||||
FirebaseAppCheckInterop: 6a1757cfd4067d8e00fccd14fcc1b8fd78cfac07
|
FirebaseAppCheckInterop: 347aa09a805219a31249b58fc956888e9fcb314b
|
||||||
FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483
|
FirebaseCore: 48b0dd707581cf9c1a1220da68223fb0a562afaa
|
||||||
FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f
|
FirebaseCoreExtension: 2d77d6430c16cf43ca2b04608302ed02b3598361
|
||||||
FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934
|
FirebaseCoreInternal: d98ab91e2d80a56d7b246856a8885443b302c0c2
|
||||||
FirebaseCrashlytics: 4b96efb0ce73b38b2a85e8b8bd1bd8f63f09d015
|
FirebaseCrashlytics: b21c665fb50138766480bce73ebdb1aa30f7f300
|
||||||
FirebaseDatabase: faa489a42f5f868d23a55dd442d6e2099348458e
|
FirebaseDatabase: ce3a83a39ab50559a85c5add54f6f285544433b8
|
||||||
FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd
|
FirebaseInstallations: efc0946fc756e4d22d8113f7c761948120322e8c
|
||||||
FirebaseRemoteConfigInterop: 6efda51fb5e2f15b16585197e26eaa09574e8a4d
|
FirebaseRemoteConfigInterop: e75e348953352a000331eb77caf01e424248e176
|
||||||
FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc
|
FirebaseSessions: 9529d14180868e29a8da164b3a729c036204918b
|
||||||
FirebaseSharedSwift: 20530f495084b8d840f78a100d8c5ee613375f6e
|
FirebaseSharedSwift: a4e5dfca3e210633bb3a3dfb94176c019211948b
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
||||||
GoogleAppMeasurement: 9abf64b682732fed36da827aa2a68f0221fd2356
|
GoogleAppMeasurement: 6a9e6317b6a6d810ad03d4a66564ca6c4c5818a3
|
||||||
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
|
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||||
leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28
|
leveldb-library: cc8b8f8e013647a295ad3f8cd2ddf49a6f19be19
|
||||||
nanopb: 438bc412db1928dac798aa6fd75726007be04262
|
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||||
onesignal_flutter: 5ce68a29861960168e81101cb1bd685d264361de
|
onesignal_flutter: 5ce68a29861960168e81101cb1bd685d264361de
|
||||||
OneSignalXCFramework: bdf74fdc06888f9466dc21e826fe1549ed143095
|
OneSignalXCFramework: bdf74fdc06888f9466dc21e826fe1549ed143095
|
||||||
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
|
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
|
||||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
|
||||||
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
|
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
|
||||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||||
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
|
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||||
|
|
||||||
PODFILE CHECKSUM: 4243bd7f9184f79552dd731a7c9d5cad03bd2706
|
PODFILE CHECKSUM: deba6d843ff3cf709e6e9051ce6601a587b24105
|
||||||
|
|
||||||
COCOAPODS: 1.15.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
@ -547,6 +547,7 @@
|
|||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -739,6 +740,7 @@
|
|||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -769,6 +771,7 @@
|
|||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -856,6 +859,7 @@
|
|||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -959,6 +963,7 @@
|
|||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -1057,6 +1062,7 @@
|
|||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Flutter
|
import Flutter
|
||||||
|
|
||||||
@UIApplicationMain
|
@main
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
override func application(
|
override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
|
|||||||
@ -38,5 +38,10 @@
|
|||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>sms</string>
|
||||||
|
<string>tel</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -7,10 +7,11 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:onesignal_flutter/onesignal_flutter.dart';
|
import 'package:onesignal_flutter/onesignal_flutter.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
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/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.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/auth/model/user_model.dart';
|
||||||
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
||||||
@ -28,25 +29,33 @@ import 'package:syncrow_app/navigation/routing_constants.dart';
|
|||||||
import 'package:syncrow_app/services/api/devices_api.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/profile_api.dart';
|
||||||
import 'package:syncrow_app/services/api/spaces_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/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
part 'home_state.dart';
|
part 'home_state.dart';
|
||||||
|
|
||||||
class HomeCubit extends Cubit<HomeState> {
|
class HomeCubit extends Cubit<HomeState> {
|
||||||
HomeCubit._() : super(HomeInitial()) {
|
HomeCubit._() : super(HomeInitial()) {
|
||||||
// checkIfNotificationPermissionGranted();
|
// checkIfNotificationPermissionGranted();
|
||||||
fetchUserInfo();
|
fetchUserInfo().then(
|
||||||
if (selectedSpace == null) {
|
(value) {
|
||||||
fetchUnitsByUserId();
|
if (selectedSpace == null) {
|
||||||
// .then((value) {
|
fetchUnitsByUserId();
|
||||||
// if (selectedSpace != null) {
|
fetchPermissions();
|
||||||
// fetchRoomsByUnitId(selectedSpace!);
|
|
||||||
// }
|
// .then((value) {
|
||||||
// });
|
// if (selectedSpace != null) {
|
||||||
}
|
// fetchRoomsByUnitId(selectedSpace!);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
static UserModel? user;
|
static UserModel? user;
|
||||||
|
|
||||||
|
List<PermissionModel>? permissionModel = [];
|
||||||
|
|
||||||
static HomeCubit? _instance;
|
static HomeCubit? _instance;
|
||||||
static HomeCubit getInstance() {
|
static HomeCubit getInstance() {
|
||||||
// If an instance already exists, return it
|
// If an instance already exists, return it
|
||||||
@ -56,15 +65,90 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
Future fetchUserInfo() async {
|
Future fetchUserInfo() async {
|
||||||
try {
|
try {
|
||||||
|
emit(HomeLoading());
|
||||||
var uuid =
|
var uuid =
|
||||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
user = await ProfileApi().fetchUserInfo(uuid);
|
user = await ProfileApi().fetchUserInfo(uuid);
|
||||||
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
|
project = user?.project;
|
||||||
|
|
||||||
|
emit(HomeUserInfoLoaded(user!));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool manageSupSpace = false;
|
||||||
|
static bool manageScene = false;
|
||||||
|
static bool manageDeviceLocation = false;
|
||||||
|
static bool visitorPasswordManagement = false;
|
||||||
|
String errorMsg = '';
|
||||||
|
|
||||||
|
Future<void> fetchPermissions() async {
|
||||||
|
try {
|
||||||
|
emit(HomeLoading());
|
||||||
|
final response = await ProfileApi().fetchPermissions(user!.role!.uuid);
|
||||||
|
permissionModel = PermissionModel.fromJsonList(response);
|
||||||
|
hasViewPermission();
|
||||||
|
emit(PermissionsRoleLoaded(permissionModel!));
|
||||||
|
} catch (e) {
|
||||||
|
emit(HomeError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hasViewPermission() {
|
||||||
|
emit(HomeLoading());
|
||||||
|
|
||||||
|
manageSupSpace = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'SPACE_MANAGEMENT',
|
||||||
|
'MANAGE_SPACE',
|
||||||
|
'ASSIGN_USER_TO_SPACE',
|
||||||
|
);
|
||||||
|
manageScene = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'AUTOMATION_MANAGEMENT',
|
||||||
|
'MANAGE_SCENES',
|
||||||
|
'UPDATE',
|
||||||
|
);
|
||||||
|
manageDeviceLocation = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'DEVICE_MANAGEMENT',
|
||||||
|
'MANAGE_DEVICE',
|
||||||
|
'LOCATION_UPDATE',
|
||||||
|
);
|
||||||
|
visitorPasswordManagement = hasPermission(
|
||||||
|
permissionModel!,
|
||||||
|
'VISITOR_PASSWORD_MANAGEMENT',
|
||||||
|
'MANAGE_VISITOR_PASSWORD',
|
||||||
|
'VIEW',
|
||||||
|
);
|
||||||
|
emit(HomePermissionUpdated());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasPermission(List<PermissionModel> permissions, String mainTitle,
|
||||||
|
String subTitle, String finalTitle) {
|
||||||
|
try {
|
||||||
|
final mainOption = permissions.firstWhere(
|
||||||
|
(perm) => perm.title == mainTitle,
|
||||||
|
);
|
||||||
|
|
||||||
|
final subOption = mainOption.subOptions.firstWhere(
|
||||||
|
(sub) => sub.title == subTitle,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (subOption.subOptions == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final finalOption = subOption.subOptions!.firstWhere(
|
||||||
|
(finalSub) => finalSub.title == finalTitle,
|
||||||
|
);
|
||||||
|
return finalOption.isChecked == true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void emitSafe(HomeState newState) {
|
void emitSafe(HomeState newState) {
|
||||||
final cubit = this;
|
final cubit = this;
|
||||||
if (!cubit.isClosed) {
|
if (!cubit.isClosed) {
|
||||||
@ -89,12 +173,14 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
static HomeCubit get(context) => BlocProvider.of(context);
|
static HomeCubit get(context) => BlocProvider.of(context);
|
||||||
|
|
||||||
List<SpaceModel>? spaces;
|
List<SpaceModel> spaces = [];
|
||||||
|
|
||||||
SpaceModel? selectedSpace;
|
SpaceModel? selectedSpace;
|
||||||
|
|
||||||
SubSpaceModel? selectedRoom;
|
SubSpaceModel? selectedRoom;
|
||||||
|
|
||||||
|
Project? project;
|
||||||
|
|
||||||
PageController devicesPageController = PageController();
|
PageController devicesPageController = PageController();
|
||||||
|
|
||||||
PageController roomsPageController = PageController();
|
PageController roomsPageController = PageController();
|
||||||
@ -182,8 +268,10 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
unselectRoom();
|
unselectRoom();
|
||||||
|
} else if (index == 1) {
|
||||||
|
unselectRoom1();
|
||||||
} else {
|
} else {
|
||||||
selectedRoom = selectedSpace!.subspaces[index - 1];
|
selectedRoom = selectedSpace!.subspaces[index - 2];
|
||||||
emitSafe(RoomSelected(selectedRoom!));
|
emitSafe(RoomSelected(selectedRoom!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,8 +285,10 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
if (index <= 0) {
|
if (index <= 0) {
|
||||||
unselectRoom();
|
unselectRoom();
|
||||||
|
} else if (index == 1) {
|
||||||
|
unselectRoom1();
|
||||||
} else {
|
} else {
|
||||||
selectedRoom = selectedSpace!.subspaces[index - 1];
|
selectedRoom = selectedSpace!.subspaces[index - 2];
|
||||||
emitSafe(RoomSelected(selectedRoom!));
|
emitSafe(RoomSelected(selectedRoom!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,11 +310,28 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
emitSafe(RoomUnSelected());
|
emitSafe(RoomUnSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unselectRoom1() {
|
||||||
|
// selectedRoom = null;
|
||||||
|
devicesPageController.animateToPage(
|
||||||
|
1,
|
||||||
|
duration: duration,
|
||||||
|
curve: Curves.linear,
|
||||||
|
);
|
||||||
|
|
||||||
|
roomsPageController.animateToPage(
|
||||||
|
1,
|
||||||
|
duration: duration,
|
||||||
|
curve: Curves.linear,
|
||||||
|
);
|
||||||
|
|
||||||
|
emitSafe(RoomUnSelected());
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////// API ////////////////////////////////////////
|
//////////////////////////////////////// API ////////////////////////////////////////
|
||||||
generateInvitation(SpaceModel unit) async {
|
generateInvitation(SpaceModel unit) async {
|
||||||
try {
|
try {
|
||||||
final invitationCode =
|
final invitationCode = await SpacesAPI.generateInvitationCode(unit.id,
|
||||||
await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
|
unit.community.uuid, project?.uuid ?? TempConst.projectIdDev);
|
||||||
if (invitationCode.isNotEmpty) {
|
if (invitationCode.isNotEmpty) {
|
||||||
Share.share('The invitation code is $invitationCode');
|
Share.share('The invitation code is $invitationCode');
|
||||||
CustomSnackBar.displaySnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
@ -261,15 +368,16 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
emitSafe(GetSpacesLoading());
|
emitSafe(GetSpacesLoading());
|
||||||
try {
|
try {
|
||||||
spaces = await SpacesAPI.getSpacesByUserId();
|
spaces = await SpacesAPI.getSpacesByUserId();
|
||||||
|
emitSafe(GetSpacesSuccess(spaces));
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emitSafe(GetSpacesError("No units found"));
|
emitSafe(GetSpacesError("No units found"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spaces != null && spaces!.isNotEmpty) {
|
if (spaces.isNotEmpty) {
|
||||||
selectedSpace = spaces!.first;
|
selectedSpace = spaces.first;
|
||||||
await fetchRoomsByUnitId(selectedSpace!);
|
await fetchRoomsByUnitId(selectedSpace!);
|
||||||
emitSafe(GetSpacesSuccess(spaces!));
|
emitSafe(GetSpacesSuccess(spaces));
|
||||||
} else {
|
} else {
|
||||||
emitSafe(GetSpacesError("No spaces found"));
|
emitSafe(GetSpacesError("No spaces found"));
|
||||||
}
|
}
|
||||||
@ -278,8 +386,10 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
fetchRoomsByUnitId(SpaceModel space) async {
|
fetchRoomsByUnitId(SpaceModel space) async {
|
||||||
emitSafe(GetSpaceRoomsLoading());
|
emitSafe(GetSpaceRoomsLoading());
|
||||||
try {
|
try {
|
||||||
space.subspaces =
|
space.subspaces = await SpacesAPI.getSubSpaceBySpaceId(
|
||||||
await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
|
space.community.uuid,
|
||||||
|
space.id,
|
||||||
|
project?.uuid ?? TempConst.projectIdDev);
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emitSafe(GetSpaceRoomsError(failure.toString()));
|
emitSafe(GetSpaceRoomsError(failure.toString()));
|
||||||
return;
|
return;
|
||||||
@ -298,18 +408,18 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
var res = await SpacesAPI.activationCodeSpace(
|
var res = await SpacesAPI.activationCodeSpace(
|
||||||
activationCode: activationCode, userUuid: uuid);
|
activationCode: activationCode, userUuid: uuid);
|
||||||
|
|
||||||
if (res['success'] == true) {
|
if (res['success'] == true) {
|
||||||
fetchUserInfo();
|
fetchUserInfo();
|
||||||
fetchUnitsByUserId();
|
fetchUnitsByUserId();
|
||||||
}
|
}
|
||||||
emitSafe(GetSpacesSuccess(spaces!));
|
emitSafe(GetSpacesSuccess(spaces!));
|
||||||
|
|
||||||
return res['success'];
|
return res['success'];
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorMessage = e.response?.data['error']['message'];
|
final errorMessage = e.response?.data['error']['message'];
|
||||||
emitSafe(ActivationError(errMessage: errorMessage));
|
errorMsg = e.response?.data['error']['message'];
|
||||||
return false;
|
emitSafe(ActivationError(errMessage: errorMsg));
|
||||||
} catch (e) {
|
|
||||||
emitSafe(ActivationError(errMessage: e.toString()));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,42 +488,44 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
// ),
|
// ),
|
||||||
// onPressed: () {},
|
// onPressed: () {},
|
||||||
// ),
|
// ),
|
||||||
IconButton(
|
manageScene
|
||||||
icon: const Icon(
|
? IconButton(
|
||||||
Icons.add,
|
icon: const Icon(
|
||||||
size: 32,
|
Icons.add,
|
||||||
),
|
size: 32,
|
||||||
style: ButtonStyle(
|
),
|
||||||
foregroundColor:
|
style: ButtonStyle(
|
||||||
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
foregroundColor:
|
||||||
),
|
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||||
onPressed: () {
|
),
|
||||||
Navigator.pushNamed(
|
onPressed: () {
|
||||||
NavigationService.navigatorKey.currentContext!,
|
Navigator.pushNamed(
|
||||||
Routes.sceneTasksRoute,
|
NavigationService.navigatorKey.currentContext!,
|
||||||
arguments: SceneSettingsRouteArguments(
|
Routes.sceneTasksRoute,
|
||||||
sceneType: '',
|
arguments: SceneSettingsRouteArguments(
|
||||||
sceneId: '',
|
sceneType: '',
|
||||||
sceneName: '',
|
sceneId: '',
|
||||||
),
|
sceneName: '',
|
||||||
);
|
),
|
||||||
NavigationService.navigatorKey.currentContext!
|
);
|
||||||
.read<CreateSceneBloc>()
|
NavigationService.navigatorKey.currentContext!
|
||||||
.add(const ClearTaskListEvent());
|
.read<CreateSceneBloc>()
|
||||||
NavigationService.navigatorKey.currentContext!
|
.add(const ClearTaskListEvent());
|
||||||
.read<CreateSceneBloc>()
|
NavigationService.navigatorKey.currentContext!
|
||||||
.add(const SceneTypeEvent(CreateSceneEnum.none));
|
.read<CreateSceneBloc>()
|
||||||
NavigationService.navigatorKey.currentContext!
|
.add(const SceneTypeEvent(CreateSceneEnum.none));
|
||||||
.read<SmartSceneSelectBloc>()
|
NavigationService.navigatorKey.currentContext!
|
||||||
.add(const SmartSceneClearEvent());
|
.read<SmartSceneSelectBloc>()
|
||||||
BlocProvider.of<EffectPeriodBloc>(
|
.add(const SmartSceneClearEvent());
|
||||||
NavigationService.navigatorKey.currentState!.context)
|
BlocProvider.of<EffectPeriodBloc>(
|
||||||
.add(ResetEffectivePeriod());
|
NavigationService.navigatorKey.currentState!.context)
|
||||||
NavigationService.navigatorKey.currentContext!
|
.add(ResetEffectivePeriod());
|
||||||
.read<CreateSceneBloc>()
|
NavigationService.navigatorKey.currentContext!
|
||||||
.add(const ClearTabToRunSetting());
|
.read<CreateSceneBloc>()
|
||||||
},
|
.add(const ClearTabToRunSetting());
|
||||||
),
|
},
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
// IconButton(
|
// IconButton(
|
||||||
// icon: const Icon(
|
// icon: const Icon(
|
||||||
// Icons.more_vert,
|
// Icons.more_vert,
|
||||||
@ -503,3 +615,28 @@ BottomNavigationBarItem defaultBottomNavBarItem(
|
|||||||
label: label,
|
label: label,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// class PermissionUtils {
|
||||||
|
// // Check if the "VIEW" permission exists in "MANAGE_SUBSPACE"
|
||||||
|
// static bool hasViewPermission(List<dynamic> permissions) {
|
||||||
|
// return _hasPermission(permissions, 'MANAGE_SUBSPACE', 'VIEW');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Generalized permission checker
|
||||||
|
// static bool _hasPermission(
|
||||||
|
// List<dynamic> permissions, String mainTitle, String subTitle) {
|
||||||
|
// final mainOption = permissions.firstWhere(
|
||||||
|
// (perm) => perm['title'] == mainTitle,
|
||||||
|
// orElse: () => null,
|
||||||
|
// );
|
||||||
|
// if (mainOption != null) {
|
||||||
|
// final subOption = mainOption['subOptions'].firstWhere(
|
||||||
|
// (sub) => sub['title'] == subTitle,
|
||||||
|
// orElse: () => null,
|
||||||
|
// );
|
||||||
|
// return subOption != null && subOption['isChecked'] == true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|||||||
@ -15,8 +15,8 @@ class HomeError extends HomeState {
|
|||||||
|
|
||||||
class HomeSuccess extends HomeState {}
|
class HomeSuccess extends HomeState {}
|
||||||
|
|
||||||
///specific states
|
class ActivationSuccess extends HomeState {}
|
||||||
//get spaces
|
|
||||||
class GetSpacesLoading extends HomeLoading {}
|
class GetSpacesLoading extends HomeLoading {}
|
||||||
|
|
||||||
class GetSpacesSuccess extends HomeSuccess {
|
class GetSpacesSuccess extends HomeSuccess {
|
||||||
@ -65,9 +65,15 @@ class RoomUnSelected extends HomeState {}
|
|||||||
|
|
||||||
class NavChangePage extends HomeState {}
|
class NavChangePage extends HomeState {}
|
||||||
|
|
||||||
// Define new state classes
|
class HomePermissionUpdated extends HomeState {}
|
||||||
|
|
||||||
class HomeUserInfoLoaded extends HomeState {
|
class HomeUserInfoLoaded extends HomeState {
|
||||||
final UserModel user;
|
final UserModel user;
|
||||||
|
|
||||||
HomeUserInfoLoaded(this.user);
|
HomeUserInfoLoaded(this.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PermissionsRoleLoaded extends HomeState {
|
||||||
|
final List<PermissionModel> permissionModel;
|
||||||
|
PermissionsRoleLoaded(this.permissionModel);
|
||||||
|
}
|
||||||
|
|||||||
39
lib/features/app_layout/model/permission_model.dart
Normal file
39
lib/features/app_layout/model/permission_model.dart
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
class PermissionModel {
|
||||||
|
final String title;
|
||||||
|
final List<PermissionAttributes> subOptions;
|
||||||
|
|
||||||
|
PermissionModel({required this.title, required this.subOptions});
|
||||||
|
|
||||||
|
factory PermissionModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return PermissionModel(
|
||||||
|
title: json['title'],
|
||||||
|
subOptions: (json['subOptions'] as List)
|
||||||
|
.map((e) => PermissionAttributes.fromJson(e))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<PermissionModel> fromJsonList(List<dynamic> jsonList) {
|
||||||
|
return jsonList.map((json) => PermissionModel.fromJson(json)).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PermissionAttributes {
|
||||||
|
final String title;
|
||||||
|
final List<PermissionAttributes>? subOptions;
|
||||||
|
final bool? isChecked;
|
||||||
|
|
||||||
|
PermissionAttributes({required this.title, this.subOptions, this.isChecked});
|
||||||
|
|
||||||
|
factory PermissionAttributes.fromJson(Map<String, dynamic> json) {
|
||||||
|
return PermissionAttributes(
|
||||||
|
title: json['title'],
|
||||||
|
isChecked: json['isChecked'],
|
||||||
|
subOptions: json['subOptions'] != null
|
||||||
|
? (json['subOptions'] as List)
|
||||||
|
.map((e) => PermissionAttributes.fromJson(e))
|
||||||
|
.toList()
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,7 +17,10 @@ class AppLayout extends StatelessWidget {
|
|||||||
child: BlocBuilder<HomeCubit, HomeState>(
|
child: BlocBuilder<HomeCubit, HomeState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
appBar: HomeCubit.getInstance().spaces != null ? const DefaultAppBar() : null,
|
appBar: HomeCubit.getInstance().spaces != null &&
|
||||||
|
HomeCubit.getInstance().spaces!.isNotEmpty
|
||||||
|
? const DefaultAppBar()
|
||||||
|
: null,
|
||||||
bottomNavBar: const DefaultNavBar(),
|
bottomNavBar: const DefaultNavBar(),
|
||||||
child: const AppBody(),
|
child: const AppBody(),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.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/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
|
|
||||||
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
@ -19,10 +22,23 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
leadingWidth: 200,
|
leadingWidth: 200,
|
||||||
toolbarHeight: Constants.appBarHeight,
|
toolbarHeight: Constants.appBarHeight,
|
||||||
leading: HomeCubit.getInstance().spaces!.isNotEmpty
|
leading: InkWell(
|
||||||
? HomeCubit.appBarLeading[HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]!
|
onTap: () {
|
||||||
|
final spaces = HomeCubit.getInstance().spaces!;
|
||||||
|
showSpaceBottomSheet(context, spaces);
|
||||||
|
},
|
||||||
|
child: HomeCubit.getInstance().spaces!.isNotEmpty
|
||||||
|
? AbsorbPointer(
|
||||||
|
absorbing: true,
|
||||||
|
child: HomeCubit.appBarLeading[HomeCubit
|
||||||
|
.bottomNavItems[HomeCubit.pageIndex].label]!,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
actions: HomeCubit.manageScene
|
||||||
|
? HomeCubit.appBarActions[
|
||||||
|
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]
|
||||||
: null,
|
: null,
|
||||||
actions: HomeCubit.appBarActions[HomeCubit.bottomNavItems[HomeCubit.pageIndex].label],
|
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -31,3 +47,83 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
@override
|
@override
|
||||||
Size get preferredSize => Size.fromHeight(Constants.appBarHeight);
|
Size get preferredSize => Size.fromHeight(Constants.appBarHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showSpaceBottomSheet(BuildContext context, List<SpaceModel> spaces) {
|
||||||
|
showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return StatefulBuilder(
|
||||||
|
builder: (BuildContext context, StateSetter setModalState) {
|
||||||
|
String? selectedSpaceId = HomeCubit.getInstance().selectedSpace?.id;
|
||||||
|
final bool shouldLimitHeight = spaces.length > 5;
|
||||||
|
return Container(
|
||||||
|
constraints: shouldLimitHeight
|
||||||
|
? BoxConstraints(
|
||||||
|
maxHeight: MediaQuery.of(context).size.height * 0.5,
|
||||||
|
)
|
||||||
|
: const BoxConstraints(),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Container(
|
||||||
|
decoration: const BoxDecoration(color: Colors.black12),
|
||||||
|
height: 5,
|
||||||
|
width: 50,
|
||||||
|
),
|
||||||
|
ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
itemCount: spaces.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
final space = spaces[index];
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 30, right: 30),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(space.name),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Radio<String>(
|
||||||
|
value: space.id,
|
||||||
|
groupValue: selectedSpaceId,
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
if (newValue != null) {
|
||||||
|
setModalState(() {
|
||||||
|
selectedSpaceId = newValue;
|
||||||
|
});
|
||||||
|
HomeCubit.getInstance().changeSelectedSpace(
|
||||||
|
spaces.firstWhere((s) => s.id == newValue),
|
||||||
|
);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
child: const Divider(
|
||||||
|
color: Colors.grey,
|
||||||
|
thickness: 0.5,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/login_with_email_model.dart';
|
import 'package:syncrow_app/features/auth/model/login_with_email_model.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/signup_model.dart';
|
import 'package:syncrow_app/features/auth/model/signup_model.dart';
|
||||||
@ -217,10 +218,24 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
signUp() async {
|
signUp() async {
|
||||||
emit(AuthLoginLoading());
|
emit(AuthLoginLoading());
|
||||||
final response;
|
final response;
|
||||||
|
|
||||||
|
final clientId = dotenv.env['CLIENT_ID'] ?? '';
|
||||||
|
final clientSecret = dotenv.env['CLIENT_SECRET'] ?? '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> userFullName = fullName.split(' ');
|
List<String> userFullName = fullName.split(' ');
|
||||||
|
|
||||||
|
final clientToken = await AuthenticationAPI.fetchClientToken(
|
||||||
|
clientId: clientId,
|
||||||
|
clientSecret: clientSecret,
|
||||||
|
);
|
||||||
|
|
||||||
|
final accessToken = clientToken['accessToken'];
|
||||||
|
|
||||||
response = await AuthenticationAPI.signUp(
|
response = await AuthenticationAPI.signUp(
|
||||||
|
accessToken: accessToken,
|
||||||
model: SignUpModel(
|
model: SignUpModel(
|
||||||
|
hasAcceptedAppAgreement: true,
|
||||||
email: email.toLowerCase(),
|
email: email.toLowerCase(),
|
||||||
password: signUpPassword,
|
password: signUpPassword,
|
||||||
firstName: userFullName[0],
|
firstName: userFullName[0],
|
||||||
|
|||||||
27
lib/features/auth/model/project_model.dart
Normal file
27
lib/features/auth/model/project_model.dart
Normal 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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,10 +3,12 @@ class SignUpModel {
|
|||||||
final String password;
|
final String password;
|
||||||
final String firstName;
|
final String firstName;
|
||||||
final String lastName;
|
final String lastName;
|
||||||
|
final bool hasAcceptedAppAgreement;
|
||||||
|
|
||||||
SignUpModel(
|
SignUpModel(
|
||||||
{required this.email,
|
{required this.email,
|
||||||
required this.password,
|
required this.password,
|
||||||
|
required this.hasAcceptedAppAgreement,
|
||||||
required this.firstName,
|
required this.firstName,
|
||||||
required this.lastName});
|
required this.lastName});
|
||||||
|
|
||||||
@ -15,7 +17,8 @@ class SignUpModel {
|
|||||||
email: json['email'],
|
email: json['email'],
|
||||||
password: json['password'],
|
password: json['password'],
|
||||||
firstName: json['firstName'],
|
firstName: json['firstName'],
|
||||||
lastName: json['lastName']);
|
lastName: json['lastName'],
|
||||||
|
hasAcceptedAppAgreement: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
@ -24,6 +27,7 @@ class SignUpModel {
|
|||||||
'password': password,
|
'password': password,
|
||||||
'firstName': firstName,
|
'firstName': firstName,
|
||||||
'lastName': lastName,
|
'lastName': lastName,
|
||||||
|
"hasAcceptedAppAgreement": hasAcceptedAppAgreement
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:syncrow_app/features/auth/model/project_model.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/token.dart';
|
import 'package:syncrow_app/features/auth/model/token.dart';
|
||||||
|
|
||||||
class UserModel {
|
class UserModel {
|
||||||
@ -15,6 +16,12 @@ class UserModel {
|
|||||||
final String? timeZone;
|
final String? timeZone;
|
||||||
final String? regionUuid;
|
final String? regionUuid;
|
||||||
final bool? isAgreementAccepted;
|
final bool? isAgreementAccepted;
|
||||||
|
final bool? hasAcceptedWebAgreement;
|
||||||
|
final DateTime? webAgreementAcceptedAt;
|
||||||
|
final bool? hasAcceptedAppAgreement;
|
||||||
|
final DateTime? appAgreementAcceptedAt;
|
||||||
|
final Role? role;
|
||||||
|
final Project? project;
|
||||||
|
|
||||||
UserModel({
|
UserModel({
|
||||||
required this.uuid,
|
required this.uuid,
|
||||||
@ -28,7 +35,12 @@ class UserModel {
|
|||||||
required this.isAgreementAccepted,
|
required this.isAgreementAccepted,
|
||||||
required this.regionName,
|
required this.regionName,
|
||||||
required this.timeZone,
|
required this.timeZone,
|
||||||
// required this.role,
|
required this.hasAcceptedWebAgreement,
|
||||||
|
required this.webAgreementAcceptedAt,
|
||||||
|
required this.hasAcceptedAppAgreement,
|
||||||
|
required this.appAgreementAcceptedAt,
|
||||||
|
required this.role,
|
||||||
|
required this.project,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory UserModel.fromJson(Map<String, dynamic> json) {
|
factory UserModel.fromJson(Map<String, dynamic> json) {
|
||||||
@ -44,24 +56,44 @@ class UserModel {
|
|||||||
regionName: json['region']?['regionName'],
|
regionName: json['region']?['regionName'],
|
||||||
timeZone: json['timeZone']?['timeZoneOffset'],
|
timeZone: json['timeZone']?['timeZoneOffset'],
|
||||||
regionUuid: json['region']?['uuid'],
|
regionUuid: json['region']?['uuid'],
|
||||||
|
hasAcceptedWebAgreement: json['hasAcceptedWebAgreement'],
|
||||||
|
webAgreementAcceptedAt: json['webAgreementAcceptedAt'] != null
|
||||||
|
? DateTime.parse(json['webAgreementAcceptedAt'])
|
||||||
|
: null,
|
||||||
|
hasAcceptedAppAgreement: json['hasAcceptedAppAgreement'],
|
||||||
|
appAgreementAcceptedAt: json['appAgreementAcceptedAt'] != null
|
||||||
|
? 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) {
|
factory UserModel.fromToken(Token token) {
|
||||||
Map<String, dynamic> tempJson = Token.decodeToken(token.accessToken);
|
Map<String, dynamic> tempJson = Token.decodeToken(token.accessToken);
|
||||||
return UserModel(
|
return UserModel(
|
||||||
uuid: tempJson['uuid'].toString(),
|
uuid: tempJson['uuid'].toString(),
|
||||||
email: tempJson['email'],
|
email: tempJson['email'],
|
||||||
lastName: tempJson['lastName'],
|
lastName: tempJson['lastName'],
|
||||||
firstName: tempJson['firstName'],
|
firstName: tempJson['firstName'],
|
||||||
profilePicture: UserModel.decodeBase64Image(tempJson['profilePicture']),
|
profilePicture: UserModel.decodeBase64Image(tempJson['profilePicture']),
|
||||||
phoneNumber: null,
|
phoneNumber: null,
|
||||||
isEmailVerified: null,
|
isEmailVerified: null,
|
||||||
isAgreementAccepted: null,
|
isAgreementAccepted: null,
|
||||||
regionUuid: null,
|
regionUuid: null,
|
||||||
regionName: tempJson['region']?['regionName'],
|
regionName: tempJson['region']?['regionName'],
|
||||||
timeZone: tempJson['timezone']?['timeZoneOffset'],
|
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) {
|
static Uint8List? decodeBase64Image(String? base64String) {
|
||||||
@ -85,6 +117,45 @@ class UserModel {
|
|||||||
'isAgreementAccepted': isAgreementAccepted,
|
'isAgreementAccepted': isAgreementAccepted,
|
||||||
'regionName': regionName,
|
'regionName': regionName,
|
||||||
'timeZone': timeZone,
|
'timeZone': timeZone,
|
||||||
|
'hasAcceptedWebAgreement': hasAcceptedWebAgreement,
|
||||||
|
'webAgreementAcceptedAt': webAgreementAcceptedAt?.toIso8601String(),
|
||||||
|
'hasAcceptedAppAgreement': hasAcceptedAppAgreement,
|
||||||
|
'appAgreementAcceptedAt': appAgreementAcceptedAt?.toIso8601String(),
|
||||||
|
'role': role?.toJson(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Role {
|
||||||
|
final String? uuid;
|
||||||
|
final DateTime? createdAt;
|
||||||
|
final DateTime? updatedAt;
|
||||||
|
final String? type;
|
||||||
|
|
||||||
|
Role({
|
||||||
|
required this.uuid,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
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,
|
||||||
|
type: json['type'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'uuid': uuid,
|
||||||
|
'createdAt': createdAt?.toIso8601String(),
|
||||||
|
'updatedAt': updatedAt?.toIso8601String(),
|
||||||
|
'type': type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,12 +3,15 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/bloc/privacy_policy.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/bloc/user_agreement.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/styles_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/styles_manager.dart';
|
||||||
@ -202,6 +205,93 @@ class SignUpView extends StatelessWidget {
|
|||||||
hint: "At least 8 characters"),
|
hint: "At least 8 characters"),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 40),
|
const SizedBox(height: 40),
|
||||||
|
Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0),
|
||||||
|
child: Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
text:
|
||||||
|
'By signing up you agree to our ',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(
|
||||||
|
fontSize: 16,
|
||||||
|
color: ColorsManager
|
||||||
|
.onPrimaryColor,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
WidgetSpan(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.push(MaterialPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
const UserAgreement(),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
child: BodyMedium(
|
||||||
|
text: 'Terms & Conditions',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium
|
||||||
|
?.copyWith(
|
||||||
|
decoration:
|
||||||
|
TextDecoration
|
||||||
|
.underline,
|
||||||
|
decorationColor:
|
||||||
|
ColorsManager
|
||||||
|
.onPrimaryColor,
|
||||||
|
color: ColorsManager
|
||||||
|
.onPrimaryColor,
|
||||||
|
fontSize: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: ' and ',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(
|
||||||
|
fontSize: 16,
|
||||||
|
color: ColorsManager
|
||||||
|
.onPrimaryColor,
|
||||||
|
)),
|
||||||
|
WidgetSpan(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.push(MaterialPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
const PrivacyPolicy(),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
child: BodyMedium(
|
||||||
|
text: 'Privacy Policy',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(
|
||||||
|
decoration:
|
||||||
|
TextDecoration
|
||||||
|
.underline,
|
||||||
|
decorationColor:
|
||||||
|
Colors.white,
|
||||||
|
color: ColorsManager
|
||||||
|
.onPrimaryColor,
|
||||||
|
fontSize: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 40),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
19
lib/features/common/bloc/project_cubit.dart
Normal file
19
lib/features/common/bloc/project_cubit.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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/features/shared_widgets/text_widgets/title_medium.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.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 {
|
class DashboardView extends StatelessWidget {
|
||||||
const DashboardView({super.key});
|
const DashboardView({super.key});
|
||||||
@ -29,7 +29,7 @@ class DashboardView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const LiveMonitorTab(),
|
const LiveMonitorTab(),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
const EnergyUsage(),
|
// const EnergyUsage(),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(top: 20),
|
padding: const EdgeInsets.only(top: 20),
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
|
|||||||
@ -1,178 +1,178 @@
|
|||||||
import 'package:fl_chart/fl_chart.dart';
|
// import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:flutter/material.dart';
|
// import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_app/features/dashboard/view/widgets/energy_usage_header.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/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
// import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class EnergyUsage extends StatelessWidget {
|
// class EnergyUsage extends StatelessWidget {
|
||||||
const EnergyUsage({
|
// const EnergyUsage({
|
||||||
super.key,
|
// super.key,
|
||||||
});
|
// });
|
||||||
|
|
||||||
@override
|
// @override
|
||||||
Widget build(BuildContext context) {
|
// Widget build(BuildContext context) {
|
||||||
return DecoratedBox(
|
// return DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
// color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(15),
|
// borderRadius: BorderRadius.circular(15),
|
||||||
),
|
// ),
|
||||||
child: Padding(
|
// child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||||
child: Column(
|
// child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
// mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
// children: [
|
||||||
const EnergyUsageHeader(),
|
// const EnergyUsageHeader(),
|
||||||
ConstrainedBox(
|
// ConstrainedBox(
|
||||||
constraints: const BoxConstraints(
|
// constraints: const BoxConstraints(
|
||||||
maxHeight: 150,
|
// maxHeight: 150,
|
||||||
minHeight: 150,
|
// minHeight: 150,
|
||||||
),
|
// ),
|
||||||
child: LineChart(
|
// child: LineChart(
|
||||||
LineChartData(
|
// LineChartData(
|
||||||
gridData: FlGridData(
|
// gridData: FlGridData(
|
||||||
show: true,
|
// show: true,
|
||||||
drawHorizontalLine: true,
|
// drawHorizontalLine: true,
|
||||||
horizontalInterval: 2,
|
// horizontalInterval: 2,
|
||||||
drawVerticalLine: false,
|
// drawVerticalLine: false,
|
||||||
getDrawingHorizontalLine: (value) {
|
// getDrawingHorizontalLine: (value) {
|
||||||
return FlLine(
|
// return FlLine(
|
||||||
color: Colors.grey.withOpacity(.5),
|
// color: Colors.grey.withOpacity(.5),
|
||||||
strokeWidth: 1,
|
// strokeWidth: 1,
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
titlesData: FlTitlesData(
|
// titlesData: FlTitlesData(
|
||||||
show: true,
|
// show: true,
|
||||||
rightTitles: AxisTitles(
|
// rightTitles: AxisTitles(
|
||||||
sideTitles: SideTitles(
|
// sideTitles: SideTitles(
|
||||||
showTitles: true,
|
// showTitles: true,
|
||||||
interval: 1,
|
// interval: 1,
|
||||||
getTitlesWidget: leftTitleWidgets,
|
// getTitlesWidget: leftTitleWidgets,
|
||||||
reservedSize: 25,
|
// reservedSize: 25,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
topTitles: const AxisTitles(
|
// topTitles: const AxisTitles(
|
||||||
sideTitles: SideTitles(showTitles: false),
|
// sideTitles: SideTitles(showTitles: false),
|
||||||
),
|
// ),
|
||||||
bottomTitles: AxisTitles(
|
// bottomTitles: AxisTitles(
|
||||||
sideTitles: SideTitles(
|
// sideTitles: SideTitles(
|
||||||
showTitles: true,
|
// showTitles: true,
|
||||||
reservedSize: 30,
|
// reservedSize: 30,
|
||||||
interval: 12,
|
// interval: 12,
|
||||||
getTitlesWidget: (value, meta) {
|
// getTitlesWidget: (value, meta) {
|
||||||
switch (value.toInt()) {
|
// switch (value.toInt()) {
|
||||||
case 0:
|
// case 0:
|
||||||
return SideTitleWidget(
|
// return SideTitleWidget(
|
||||||
axisSide: meta.axisSide,
|
// axisSide: meta.axisSide,
|
||||||
child: const BodySmall(text: '1'),
|
// child: const BodySmall(text: '1'),
|
||||||
);
|
// );
|
||||||
|
|
||||||
case 11:
|
// case 11:
|
||||||
return SideTitleWidget(
|
// return SideTitleWidget(
|
||||||
axisSide: meta.axisSide,
|
// axisSide: meta.axisSide,
|
||||||
child: const BodySmall(text: '28'),
|
// child: const BodySmall(text: '28'),
|
||||||
);
|
// );
|
||||||
default:
|
// default:
|
||||||
return Container();
|
// return Container();
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
leftTitles: const AxisTitles(
|
// leftTitles: const AxisTitles(
|
||||||
sideTitles: SideTitles(showTitles: false),
|
// sideTitles: SideTitles(showTitles: false),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
minX: 0,
|
// minX: 0,
|
||||||
maxX: 11,
|
// maxX: 11,
|
||||||
minY: 0,
|
// minY: 0,
|
||||||
maxY: 6,
|
// maxY: 6,
|
||||||
lineBarsData: [
|
// lineBarsData: [
|
||||||
LineChartBarData(
|
// LineChartBarData(
|
||||||
spots: const [
|
// spots: const [
|
||||||
FlSpot(0, 3),
|
// FlSpot(0, 3),
|
||||||
FlSpot(2.6, 2),
|
// FlSpot(2.6, 2),
|
||||||
FlSpot(4.9, 5),
|
// FlSpot(4.9, 5),
|
||||||
FlSpot(6.8, 3.1),
|
// FlSpot(6.8, 3.1),
|
||||||
FlSpot(8, 4),
|
// FlSpot(8, 4),
|
||||||
FlSpot(9.5, 3),
|
// FlSpot(9.5, 3),
|
||||||
FlSpot(11, 4),
|
// FlSpot(11, 4),
|
||||||
],
|
// ],
|
||||||
isCurved: true,
|
// isCurved: true,
|
||||||
gradient: LinearGradient(
|
// gradient: LinearGradient(
|
||||||
colors: [
|
// colors: [
|
||||||
ColorsManager.primaryColor,
|
// ColorsManager.primaryColor,
|
||||||
ColorsManager.primaryColor.withOpacity(0.3),
|
// ColorsManager.primaryColor.withOpacity(0.3),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
barWidth: 5,
|
// barWidth: 5,
|
||||||
isStrokeCapRound: true,
|
// isStrokeCapRound: true,
|
||||||
dotData: const FlDotData(
|
// dotData: const FlDotData(
|
||||||
show: false,
|
// show: false,
|
||||||
),
|
// ),
|
||||||
belowBarData: BarAreaData(
|
// belowBarData: BarAreaData(
|
||||||
show: true,
|
// show: true,
|
||||||
gradient: LinearGradient(
|
// gradient: LinearGradient(
|
||||||
colors: [
|
// colors: [
|
||||||
ColorsManager.primaryColor.withOpacity(0.5),
|
// ColorsManager.primaryColor.withOpacity(0.5),
|
||||||
ColorsManager.primaryColor.withOpacity(0.1),
|
// ColorsManager.primaryColor.withOpacity(0.1),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
Widget leftTitleWidgets(double value, TitleMeta meta) {
|
// Widget leftTitleWidgets(double value, TitleMeta meta) {
|
||||||
String text;
|
// String text;
|
||||||
switch (value.toInt()) {
|
// switch (value.toInt()) {
|
||||||
case 1:
|
// case 1:
|
||||||
text = '1K';
|
// text = '1K';
|
||||||
break;
|
// break;
|
||||||
case 3:
|
// case 3:
|
||||||
text = '3k';
|
// text = '3k';
|
||||||
break;
|
// break;
|
||||||
case 5:
|
// case 5:
|
||||||
text = '5k';
|
// text = '5k';
|
||||||
break;
|
// break;
|
||||||
default:
|
// default:
|
||||||
return Container();
|
// return Container();
|
||||||
}
|
// }
|
||||||
|
|
||||||
return Center(child: BodySmall(text: text));
|
// return Center(child: BodySmall(text: text));
|
||||||
}
|
// }
|
||||||
|
|
||||||
Widget bottomTitleWidgets(double value, TitleMeta meta) {
|
// Widget bottomTitleWidgets(double value, TitleMeta meta) {
|
||||||
// const style = TextStyle(
|
// // const style = TextStyle(
|
||||||
// fontWeight: FontWeight.bold,
|
// // fontWeight: FontWeight.bold,
|
||||||
// fontSize: 16,
|
// // fontSize: 16,
|
||||||
// );
|
// // );
|
||||||
// Widget text;
|
// // Widget text;
|
||||||
// switch (value.toInt()) {
|
// // switch (value.toInt()) {
|
||||||
// case 2:
|
// // case 2:
|
||||||
// text = const Text('MAR', style: style);
|
// // text = const Text('MAR', style: style);
|
||||||
// break;
|
// // break;
|
||||||
// case 5:
|
// // case 5:
|
||||||
// text = const Text('JUN', style: style);
|
// // text = const Text('JUN', style: style);
|
||||||
// break;
|
// // break;
|
||||||
// case 8:
|
// // case 8:
|
||||||
// text = const Text('SEP', style: style);
|
// // text = const Text('SEP', style: style);
|
||||||
// break;
|
// // break;
|
||||||
// default:
|
// // default:
|
||||||
// text = const Text('', style: style);
|
// // text = const Text('', style: style);
|
||||||
// break;
|
// // break;
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
return SideTitleWidget(
|
// return SideTitleWidget(
|
||||||
axisSide: meta.axisSide,
|
// axisSide: meta.axisSide,
|
||||||
child: const BodySmall(text: 'Feb'),
|
// child: const BodySmall(text: 'Feb'),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/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_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.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';
|
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/home_management_api.dart';
|
||||||
import 'package:syncrow_app/services/api/scene_api.dart';
|
import 'package:syncrow_app/services/api/scene_api.dart';
|
||||||
import 'package:syncrow_app/services/api/spaces_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/helpers/snack_bar.dart';
|
||||||
|
|
||||||
class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
|
class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
|
||||||
@ -112,8 +114,9 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
|
|||||||
FetchRoomsEvent event, Emitter<SixSceneState> emit) async {
|
FetchRoomsEvent event, Emitter<SixSceneState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(SixSceneLoadingState());
|
emit(SixSceneLoadingState());
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
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));
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SixSceneFailedState(errorMessage: e.toString()));
|
emit(SixSceneFailedState(errorMessage: e.toString()));
|
||||||
@ -125,12 +128,14 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
|
|||||||
try {
|
try {
|
||||||
emit(SixSceneLoadingState());
|
emit(SixSceneLoadingState());
|
||||||
if (_hasSelectionChanged) {
|
if (_hasSelectionChanged) {
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
await HomeManagementAPI.assignDeviceToRoom(
|
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(
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: event.unit.community.uuid,
|
communityUuid: event.unit.community.uuid,
|
||||||
spaceUuid: event.unit.id,
|
spaceUuid: event.unit.id,
|
||||||
roomId: event.roomId);
|
roomId: event.roomId,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
allDevices.forEach((element) {
|
allDevices.forEach((element) {
|
||||||
allDevicesIds.add(element.uuid!);
|
allDevicesIds.add(element.uuid!);
|
||||||
@ -341,8 +346,10 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
|
|||||||
emit(SixSceneLoadingState());
|
emit(SixSceneLoadingState());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
allScenes = await SceneApi.getScenesByUnitId(
|
allScenes = await SceneApi.getScenesByUnitId(
|
||||||
event.unitId, event.unit.community.uuid,
|
event.unitId, event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
|
||||||
showInDevice: event.showInDevice);
|
showInDevice: event.showInDevice);
|
||||||
|
|
||||||
filteredScenes = allScenes;
|
filteredScenes = allScenes;
|
||||||
|
|||||||
@ -27,7 +27,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
bool allAcsPage = false;
|
bool allAcsPage = false;
|
||||||
bool allAcsOn = true;
|
bool allAcsOn = true;
|
||||||
bool allTempSame = true;
|
bool allTempSame = true;
|
||||||
int globalTemp = 25;
|
int globalTemp = 250;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
ACsBloc({required this.acId}) : super(AcsInitialState()) {
|
ACsBloc({required this.acId}) : super(AcsInitialState()) {
|
||||||
@ -68,11 +68,10 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
}
|
}
|
||||||
deviceStatus =
|
deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
||||||
AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
|
||||||
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
Future.delayed(const Duration(milliseconds: 500));
|
||||||
// _listenToChanges();
|
_listenToChanges(acId);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(AcsFailedState(errorMessage: e.toString()));
|
emit(AcsFailedState(errorMessage: e.toString()));
|
||||||
@ -80,29 +79,38 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
|
||||||
|
void _listenToChanges(acId) {
|
||||||
try {
|
try {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
DatabaseReference ref =
|
DatabaseReference ref =
|
||||||
FirebaseDatabase.instance.ref('device-status/$acId');
|
FirebaseDatabase.instance.ref('device-status/$acId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) {
|
_streamSubscription = stream.listen((DatabaseEvent event) {
|
||||||
Map<dynamic, dynamic> usersMap =
|
Map<dynamic, dynamic> usersMap =
|
||||||
event.snapshot.value as Map<dynamic, dynamic>;
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList
|
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
||||||
.add(StatusModel(code: element['code'], value: element['value']));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
AcStatusModel.fromJson(usersMap['productUuid'], statusList);
|
AcStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
|
||||||
add(AcUpdated());
|
add(AcUpdated());
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
_onAcUpdated(AcUpdated event, Emitter<AcsState> emit) {
|
_onAcUpdated(AcUpdated event, Emitter<AcsState> emit) {
|
||||||
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
@ -114,15 +122,16 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
for (int i = 0; i < devicesList.length; i++) {
|
||||||
|
_listenToChanges(devicesList[i].uuid);
|
||||||
var response =
|
var response =
|
||||||
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
}
|
}
|
||||||
deviceStatusList.add(
|
deviceStatusList.add(AcStatusModel.fromJson(devicesList[i].uuid ?? '', statusModelList));
|
||||||
AcStatusModel.fromJson(response['productUuid'], statusModelList));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setAllAcsTempsAndSwitches();
|
_setAllAcsTempsAndSwitches();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,10 +140,11 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (allAcsPage) {
|
if (allAcsPage) {
|
||||||
emit(AcsLoadingState());
|
emit(AcsLoadingState());
|
||||||
for (AcStatusModel ac in deviceStatusList) {
|
for (AcStatusModel ac in deviceStatusList) {
|
||||||
if (ac.uuid == event.productId) {
|
if (ac.uuid == event.deviceId) {
|
||||||
ac.acSwitch = acSwitchValue;
|
ac.acSwitch = acSwitchValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_setAllAcsTempsAndSwitches();
|
_setAllAcsTempsAndSwitches();
|
||||||
_emitAcsStatus(emit);
|
_emitAcsStatus(emit);
|
||||||
} else {
|
} else {
|
||||||
@ -143,8 +153,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'switch', value: acSwitchValue);
|
||||||
deviceId: event.deviceId, code: 'switch', value: acSwitchValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeAllAcSwitch(ChangeAllSwitch event, Emitter<AcsState> emit) async {
|
void _changeAllAcSwitch(ChangeAllSwitch event, Emitter<AcsState> emit) async {
|
||||||
@ -205,8 +214,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
deviceStatus.childLock = lockValue;
|
deviceStatus.childLock = lockValue;
|
||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(deviceId: acId, code: 'child_lock', value: lockValue);
|
||||||
deviceId: acId, code: 'child_lock', value: lockValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _increaseCoolTo(IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
void _increaseCoolTo(IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
||||||
@ -222,7 +230,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (allAcsPage) {
|
if (allAcsPage) {
|
||||||
emit(AcsLoadingState());
|
emit(AcsLoadingState());
|
||||||
for (AcStatusModel ac in deviceStatusList) {
|
for (AcStatusModel ac in deviceStatusList) {
|
||||||
if (ac.uuid == event.productId) {
|
if (ac.uuid == event.deviceId) {
|
||||||
ac.tempSet = value;
|
ac.tempSet = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,8 +242,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value);
|
||||||
deviceId: event.deviceId, code: 'temp_set', value: value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
void _decreaseCoolTo(DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
||||||
@ -251,7 +258,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (allAcsPage) {
|
if (allAcsPage) {
|
||||||
emit(AcsLoadingState());
|
emit(AcsLoadingState());
|
||||||
for (AcStatusModel ac in deviceStatusList) {
|
for (AcStatusModel ac in deviceStatusList) {
|
||||||
if (ac.uuid == event.productId) {
|
if (ac.uuid == event.deviceId) {
|
||||||
ac.tempSet = value;
|
ac.tempSet = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,8 +270,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(deviceId: event.deviceId, code: 'temp_set', value: value);
|
||||||
deviceId: event.deviceId, code: 'temp_set', value: value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeAcMode(ChangeAcMode event, Emitter<AcsState> emit) async {
|
void _changeAcMode(ChangeAcMode event, Emitter<AcsState> emit) async {
|
||||||
@ -272,7 +278,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (allAcsPage) {
|
if (allAcsPage) {
|
||||||
emit(AcsLoadingState());
|
emit(AcsLoadingState());
|
||||||
for (AcStatusModel ac in deviceStatusList) {
|
for (AcStatusModel ac in deviceStatusList) {
|
||||||
if (ac.uuid == event.productId) {
|
if (ac.uuid == event.deviceId) {
|
||||||
ac.modeString = getACModeString(tempMode);
|
ac.modeString = getACModeString(tempMode);
|
||||||
ac.acMode = AcStatusModel.getACMode(getACModeString(tempMode));
|
ac.acMode = AcStatusModel.getACMode(getACModeString(tempMode));
|
||||||
}
|
}
|
||||||
@ -286,9 +292,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(
|
||||||
deviceId: event.deviceId,
|
deviceId: event.deviceId, code: 'mode', value: getACModeString(tempMode));
|
||||||
code: 'mode',
|
|
||||||
value: getACModeString(tempMode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFanSpeed(ChangeFanSpeed event, Emitter<AcsState> emit) async {
|
void _changeFanSpeed(ChangeFanSpeed event, Emitter<AcsState> emit) async {
|
||||||
@ -299,25 +303,21 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (allAcsPage) {
|
if (allAcsPage) {
|
||||||
emit(AcsLoadingState());
|
emit(AcsLoadingState());
|
||||||
for (AcStatusModel ac in deviceStatusList) {
|
for (AcStatusModel ac in deviceStatusList) {
|
||||||
if (ac.uuid == event.productId) {
|
if (ac.uuid == event.deviceId) {
|
||||||
ac.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
ac.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
||||||
ac.acFanSpeed =
|
ac.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
||||||
AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_emitAcsStatus(emit);
|
_emitAcsStatus(emit);
|
||||||
} else {
|
} else {
|
||||||
emit(AcChangeLoading(acStatusModel: deviceStatus));
|
emit(AcChangeLoading(acStatusModel: deviceStatus));
|
||||||
deviceStatus.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
deviceStatus.fanSpeedsString = getNextFanSpeedKey(fanSpeed);
|
||||||
deviceStatus.acFanSpeed =
|
deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
||||||
AcStatusModel.getFanSpeed(getNextFanSpeedKey(fanSpeed));
|
|
||||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runDeBouncerForOneDevice(
|
await _runDeBouncerForOneDevice(
|
||||||
deviceId: event.deviceId,
|
deviceId: event.deviceId, code: 'level', value: getNextFanSpeedKey(fanSpeed));
|
||||||
code: 'level',
|
|
||||||
value: getNextFanSpeedKey(fanSpeed));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getACModeString(TempModes value) {
|
String getACModeString(TempModes value) {
|
||||||
@ -336,17 +336,15 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
allAcsOn = true;
|
allAcsOn = true;
|
||||||
allTempSame = true;
|
allTempSame = true;
|
||||||
if (deviceStatusList.isNotEmpty) {
|
if (deviceStatusList.isNotEmpty) {
|
||||||
int temp = deviceStatusList[0].tempSet;
|
int temp = deviceStatusList.first.tempSet;
|
||||||
deviceStatusList.firstWhere((element) {
|
for (var element in deviceStatusList) {
|
||||||
if (!element.acSwitch) {
|
if (!element.acSwitch) {
|
||||||
allAcsOn = false;
|
allAcsOn = false;
|
||||||
}
|
}
|
||||||
if (element.tempSet != temp) {
|
if (element.tempSet != temp) {
|
||||||
allTempSame = false;
|
allTempSame = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
|
||||||
});
|
|
||||||
if (allTempSame) {
|
if (allTempSame) {
|
||||||
globalTemp = temp;
|
globalTemp = temp;
|
||||||
}
|
}
|
||||||
@ -362,8 +360,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
for (int i = 0; i < deviceStatusList.length; i++) {
|
for (int i = 0; i < deviceStatusList.length; i++) {
|
||||||
try {
|
try {
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(deviceId: devicesList[i].uuid, code: code, value: value),
|
||||||
deviceId: devicesList[i].uuid, code: code, value: value),
|
|
||||||
devicesList[i].uuid ?? '');
|
devicesList[i].uuid ?? '');
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
@ -385,10 +382,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
_timer = Timer(const Duration(seconds: 1), () async {
|
_timer = Timer(const Duration(seconds: 1), () async {
|
||||||
try {
|
try {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(deviceId: allAcsPage ? deviceId : acId, code: code, value: value),
|
||||||
deviceId: allAcsPage ? deviceId : acId,
|
|
||||||
code: code,
|
|
||||||
value: value),
|
|
||||||
allAcsPage ? deviceId : acId);
|
allAcsPage ? deviceId : acId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -405,8 +399,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (value >= 20 && value <= 30) {
|
if (value >= 20 && value <= 30) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
emit(const AcsFailedState(
|
emit(const AcsFailedState(errorMessage: 'The temperature must be between 20 and 30'));
|
||||||
errorMessage: 'The temperature must be between 20 and 30'));
|
|
||||||
emit(GetAllAcsStatusState(
|
emit(GetAllAcsStatusState(
|
||||||
allAcsStatues: deviceStatusList,
|
allAcsStatues: deviceStatusList,
|
||||||
allAcs: devicesList,
|
allAcs: devicesList,
|
||||||
@ -432,9 +425,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
try {
|
try {
|
||||||
seconds = event.seconds;
|
seconds = event.seconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(deviceId: acId, code: 'countdown_time', value: event.duration), acId);
|
||||||
deviceId: acId, code: 'countdown_time', value: event.duration),
|
|
||||||
acId);
|
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
deviceStatus.countdown1 = seconds;
|
deviceStatus.countdown1 = seconds;
|
||||||
@ -455,24 +446,26 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _getCounterValue(GetCounterEvent event, Emitter<AcsState> emit) async {
|
void _getCounterValue(GetCounterEvent event, Emitter<AcsState> emit) async {
|
||||||
try {
|
emit(AcsLoadingState());
|
||||||
emit(AcsLoadingState());
|
var response = await DevicesAPI.getDeviceStatus(acId);
|
||||||
var response = await DevicesAPI.getDeviceStatus(acId);
|
List<StatusModel> statusModelList = [];
|
||||||
List<StatusModel> statusModelList = [];
|
for (var status in response['status']) {
|
||||||
for (var status in response['status']) {
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
}
|
||||||
}
|
deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
||||||
deviceStatus =
|
deviceStatus.countdown1;
|
||||||
AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
var duration;
|
||||||
|
if (deviceStatus.countdown1 == 5) {
|
||||||
if (event.deviceCode == 'countdown_time') {
|
duration = const Duration(minutes: 30);
|
||||||
deviceStatus.countdown1 > 0
|
var countNum = duration.inSeconds;
|
||||||
? _onStartTimer(deviceStatus.countdown1)
|
_onStartTimer(countNum);
|
||||||
: emit(UpdateTimerState(seconds: deviceStatus.countdown1));
|
} else if (deviceStatus.countdown1 > 5) {
|
||||||
}
|
duration = Duration(minutes: deviceStatus.countdown1 * 6);
|
||||||
} catch (e) {
|
var countNum = duration.inSeconds;
|
||||||
emit(AcsFailedState(errorMessage: e.toString()));
|
_onStartTimer(countNum);
|
||||||
return;
|
} else {
|
||||||
|
_timer?.cancel();
|
||||||
|
emit(TimerRunComplete());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -33,35 +35,49 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = CeilingSensorModel.fromJson(statusModelList);
|
deviceStatus = CeilingSensorModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(ceilingSensorModel: deviceStatus));
|
emit(UpdateState(ceilingSensorModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
void _listenToChanges() {
|
||||||
try {
|
try {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
DatabaseReference ref =
|
DatabaseReference ref =
|
||||||
FirebaseDatabase.instance.ref('device-status/$deviceId');
|
FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
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 =
|
Map<dynamic, dynamic> usersMap =
|
||||||
event.snapshot.value as Map<dynamic, dynamic>;
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList
|
statusList
|
||||||
.add(StatusModel(code: element['code'], value: element['value']));
|
.add(StatusModel(code: element['code'], value: element['value']));
|
||||||
});
|
});
|
||||||
|
|
||||||
deviceStatus = CeilingSensorModel.fromJson(statusList);
|
deviceStatus = CeilingSensorModel.fromJson(statusList);
|
||||||
add(CeilingSensorUpdated());
|
if (!isClosed) {
|
||||||
|
add(CeilingSensorUpdated());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
_onCeilingSensorUpdated(
|
_onCeilingSensorUpdated(
|
||||||
CeilingSensorUpdated event, Emitter<CeilingSensorState> emit) {
|
CeilingSensorUpdated event, Emitter<CeilingSensorState> emit) {
|
||||||
emit(UpdateState(ceilingSensorModel: deviceStatus));
|
emit(UpdateState(ceilingSensorModel: deviceStatus));
|
||||||
@ -112,7 +128,7 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
code: 'presence_state',
|
code: 'presence_state',
|
||||||
);
|
);
|
||||||
recordGroups = response;
|
recordGroups = response;
|
||||||
// print('---${recordGroups.data!.first.eventTime}');
|
// print('---${jsonEncode(recordGroups.data.first.)}');
|
||||||
emit(FitchData());
|
emit(FitchData());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.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<InitialWizardEvent>(_fetchWizardStatus);
|
||||||
on<GroupAllOffEvent>(_groupAllOff);
|
on<GroupAllOffEvent>(_groupAllOff);
|
||||||
on<GroupAllOnEvent>(_groupAllOn);
|
on<GroupAllOnEvent>(_groupAllOn);
|
||||||
|
on<UpdateCurtainEvent>(_updateCurtain);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onOpenCurtain(
|
Future<void> _onOpenCurtain(
|
||||||
@ -161,7 +164,10 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
|
|||||||
void _fetchStatus(InitCurtain event, Emitter<CurtainState> emit) async {
|
void _fetchStatus(InitCurtain event, Emitter<CurtainState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(CurtainLoadingState());
|
emit(CurtainLoadingState());
|
||||||
|
_listenToChanges(curtainId);
|
||||||
|
|
||||||
var response = await DevicesAPI.getDeviceStatus(curtainId);
|
var response = await DevicesAPI.getDeviceStatus(curtainId);
|
||||||
|
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -169,7 +175,6 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
|
|||||||
openPercentage = double.tryParse(statusModelList[1].value.toString())!;
|
openPercentage = double.tryParse(statusModelList[1].value.toString())!;
|
||||||
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
|
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
|
||||||
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
|
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
|
||||||
|
|
||||||
emit(CurtainsOpening(
|
emit(CurtainsOpening(
|
||||||
curtainWidth: curtainWidth,
|
curtainWidth: curtainWidth,
|
||||||
blindHeight: blindHeight,
|
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 = [];
|
List<GroupCurtainModel> groupList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
List<DeviceModel> devicesList = [];
|
List<DeviceModel> devicesList = [];
|
||||||
|
|||||||
@ -33,6 +33,7 @@ class InitCurtain extends CurtainEvent {}
|
|||||||
class PauseCurtain extends CurtainEvent {}
|
class PauseCurtain extends CurtainEvent {}
|
||||||
class useCurtainEvent extends CurtainEvent {}
|
class useCurtainEvent extends CurtainEvent {}
|
||||||
class InitialWizardEvent extends CurtainEvent {}
|
class InitialWizardEvent extends CurtainEvent {}
|
||||||
|
class UpdateCurtainEvent extends CurtainEvent {}
|
||||||
|
|
||||||
|
|
||||||
class ChangeFirstWizardSwitchStatusEvent extends CurtainEvent {
|
class ChangeFirstWizardSwitchStatusEvent extends CurtainEvent {
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:flutter/material.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_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.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/devices_api.dart';
|
||||||
import 'package:syncrow_app/services/api/home_management_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';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
|
|
||||||
class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
||||||
@ -27,11 +30,16 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
|
|
||||||
static List<DevicesCategoryModel>? allCategories;
|
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));
|
emit(state.copyWith(loading: true));
|
||||||
try {
|
try {
|
||||||
final allDevices = await HomeManagementAPI.fetchDevicesByUnitId();
|
Project? project = HomeCubit.getInstance().project;
|
||||||
emit(state.copyWith(devices: _getOnlyImplementedDevices(allDevices), loading: false));
|
|
||||||
|
final allDevices = await HomeManagementAPI.fetchDevicesByUnitId(
|
||||||
|
project?.uuid ?? TempConst.projectIdDev);
|
||||||
|
emit(state.copyWith(
|
||||||
|
devices: _getOnlyImplementedDevices(allDevices), loading: false));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(error: e.toString(), loading: false));
|
emit(state.copyWith(error: e.toString(), loading: false));
|
||||||
}
|
}
|
||||||
@ -41,26 +49,31 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
FetchDevicesByRoomId event, Emitter<DeviceManagerState> emit) async {
|
FetchDevicesByRoomId event, Emitter<DeviceManagerState> emit) async {
|
||||||
emit(state.copyWith(loading: true));
|
emit(state.copyWith(loading: true));
|
||||||
try {
|
try {
|
||||||
final devices = await DevicesAPI.getDevicesByRoomId(
|
Project? project = HomeCubit.getInstance().project;
|
||||||
communityUuid: event.unit.community.uuid,
|
|
||||||
spaceUuid: event.unit.id,
|
|
||||||
roomId: event.roomId,
|
|
||||||
);
|
|
||||||
|
|
||||||
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) {
|
} catch (e) {
|
||||||
emit(state.copyWith(error: e.toString(), loading: false));
|
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++) {
|
for (var i = 0; i < allCategories!.length; i++) {
|
||||||
allCategories![i].isSelected = i == event.index;
|
allCategories![i].isSelected = i == event.index;
|
||||||
}
|
}
|
||||||
emit(state.copyWith(categoryChanged: true));
|
emit(state.copyWith(categoryChanged: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onUnselectAllCategories(UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
|
void _onUnselectAllCategories(
|
||||||
|
UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
|
||||||
for (var category in allCategories!) {
|
for (var category in allCategories!) {
|
||||||
category.isSelected = false;
|
category.isSelected = false;
|
||||||
}
|
}
|
||||||
@ -104,7 +117,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
_updateDevicesStatus(category, emit);
|
_updateDevicesStatus(category, emit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onTurnOnOffDevice(TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
|
void _onTurnOnOffDevice(
|
||||||
|
TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
|
||||||
var device = event.device;
|
var device = event.device;
|
||||||
device.isOnline = !device.isOnline!;
|
device.isOnline = !device.isOnline!;
|
||||||
DevicesCategoryModel category = allCategories!.firstWhere((category) {
|
DevicesCategoryModel category = allCategories!.firstWhere((category) {
|
||||||
@ -127,7 +141,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
emit(state.copyWith(categoryChanged: true)); // Set category changed state
|
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) {
|
if (category.devices != null && category.devices!.isNotEmpty) {
|
||||||
bool? tempStatus = category.devices![0].isOnline;
|
bool? tempStatus = category.devices![0].isOnline;
|
||||||
for (var device in category.devices!) {
|
for (var device in category.devices!) {
|
||||||
@ -147,24 +162,27 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
try {
|
try {
|
||||||
final deviceFunctions = await DevicesAPI.deviceFunctions(event.deviceId);
|
final deviceFunctions = await DevicesAPI.deviceFunctions(event.deviceId);
|
||||||
|
|
||||||
emit(state.copyWith(functionsLoading: false, deviceFunctions: deviceFunctions));
|
emit(state.copyWith(
|
||||||
|
functionsLoading: false, deviceFunctions: deviceFunctions));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(functionsLoading: false, error: e.toString()));
|
emit(state.copyWith(functionsLoading: false, error: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getOnlyImplementedDevices(List<DeviceModel> devices) {
|
List<DeviceModel> _getOnlyImplementedDevices(List<DeviceModel> devices) {
|
||||||
List<DeviceModel> implementedDevices = [];
|
const allowedDeviceTypes = {
|
||||||
for (int i = 0; i < devices.length; i++) {
|
DeviceType.AC,
|
||||||
if (devices[i].productType == DeviceType.AC ||
|
DeviceType.DoorLock,
|
||||||
devices[i].productType == DeviceType.DoorLock ||
|
DeviceType.Gateway,
|
||||||
devices[i].productType == DeviceType.Gateway ||
|
DeviceType.WallSensor,
|
||||||
devices[i].productType == DeviceType.WallSensor ||
|
DeviceType.CeilingSensor,
|
||||||
devices[i].productType == DeviceType.CeilingSensor ||
|
DeviceType.ThreeGang,
|
||||||
devices[i].productType == DeviceType.ThreeGang) {
|
DeviceType.OneGang,
|
||||||
implementedDevices.add(devices[i]);
|
DeviceType.TwoGang
|
||||||
}
|
};
|
||||||
}
|
|
||||||
return implementedDevices;
|
return devices
|
||||||
|
.where((device) => allowedDeviceTypes.contains(device.productType))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/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_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.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';
|
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/devices_api.dart';
|
||||||
import 'package:syncrow_app/services/api/home_management_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/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/helpers/snack_bar.dart';
|
||||||
|
|
||||||
class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
|
class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
|
||||||
@ -349,13 +351,20 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
|
|||||||
AssignRoomEvent event, Emitter<DeviceSettingState> emit) async {
|
AssignRoomEvent event, Emitter<DeviceSettingState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(DeviceSettingLoadingState());
|
emit(DeviceSettingLoadingState());
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
if (_hasSelectionChanged) {
|
if (_hasSelectionChanged) {
|
||||||
await HomeManagementAPI.assignDeviceToRoom(
|
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(
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: event.unit.community.uuid,
|
communityUuid: event.unit.community.uuid,
|
||||||
spaceUuid: event.unit.id,
|
spaceUuid: event.unit.id,
|
||||||
roomId: event.roomId);
|
roomId: event.roomId,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
allDevices.forEach((element) {
|
allDevices.forEach((element) {
|
||||||
allDevicesIds.add(element.uuid!);
|
allDevicesIds.add(element.uuid!);
|
||||||
@ -375,8 +384,12 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
|
|||||||
FetchRoomsEvent event, Emitter<DeviceSettingState> emit) async {
|
FetchRoomsEvent event, Emitter<DeviceSettingState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(DeviceSettingLoadingState());
|
emit(DeviceSettingLoadingState());
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
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));
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(
|
emit(
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
// ignore_for_file: constant_identifier_names, unused_import
|
// ignore_for_file: constant_identifier_names, unused_import
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/model/space_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/model/device_category_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_control_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_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/home_management_api.dart';
|
||||||
import 'package:syncrow_app/services/api/network_exception.dart';
|
import 'package:syncrow_app/services/api/network_exception.dart';
|
||||||
import 'package:syncrow_app/services/api/spaces_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/resource_manager/constants.dart';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
part 'devices_state.dart';
|
part 'devices_state.dart';
|
||||||
|
|
||||||
@ -31,6 +36,7 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
|
|
||||||
// Fetch groups based on the selected space ID
|
// Fetch groups based on the selected space ID
|
||||||
await fetchGroups(selectedSpace.id);
|
await fetchGroups(selectedSpace.id);
|
||||||
|
await fetchAllDevices(selectedSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
DevicesCubit._() : super(DevicesInitial()) {
|
DevicesCubit._() : super(DevicesInitial()) {
|
||||||
@ -60,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);
|
static DevicesCubit get(context) => BlocProvider.of(context);
|
||||||
|
|
||||||
List<DevicesCategoryModel>? allCategories;
|
List<DevicesCategoryModel>? allCategories;
|
||||||
@ -109,17 +152,6 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getter to retrieve all devices from HomeCubit
|
// Getter to retrieve all devices from HomeCubit
|
||||||
List<DeviceModel> get allDevices {
|
|
||||||
List<DeviceModel> devices = [];
|
|
||||||
if (HomeCubit.getInstance().selectedSpace != null) {
|
|
||||||
for (var room in HomeCubit.getInstance().selectedSpace!.subspaces) {
|
|
||||||
if (room.devices != null) {
|
|
||||||
devices.addAll(room.devices!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DevicesCategoryModel? get chosenCategory {
|
// DevicesCategoryModel? get chosenCategory {
|
||||||
// for (var category in allCategories!) {
|
// for (var category in allCategories!) {
|
||||||
@ -267,36 +299,36 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////// API CALLS //////////////////////////
|
///////////////////////// API CALLS //////////////////////////
|
||||||
deviceControl(DeviceControlModel control, String deviceId) async {
|
// deviceControl(DeviceControlModel control, String deviceId) async {
|
||||||
emitSafe(DeviceControlLoading(
|
// emitSafe(DeviceControlLoading(
|
||||||
code: control.code,
|
// code: control.code,
|
||||||
));
|
// ));
|
||||||
try {
|
// try {
|
||||||
var response = await DevicesAPI.controlDevice(control, deviceId);
|
// var response = await DevicesAPI.controlDevice(control, deviceId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
// if (response['success'] ?? false) {
|
||||||
emitSafe(DeviceControlSuccess(code: control.code));
|
// emitSafe(DeviceControlSuccess(code: control.code));
|
||||||
//this delay is to give tuya server time to update the status
|
// //this delay is to give tuya server time to update the status
|
||||||
// Future.delayed(const Duration(milliseconds: 400), () {
|
// // Future.delayed(const Duration(milliseconds: 400), () {
|
||||||
fetchDevicesStatues(
|
// fetchDevicesStatues(
|
||||||
deviceId,
|
// deviceId,
|
||||||
HomeCubit.getInstance()
|
// HomeCubit.getInstance()
|
||||||
.selectedSpace!
|
// .selectedSpace!
|
||||||
.subspaces
|
// .subspaces
|
||||||
.indexOf(HomeCubit.getInstance().selectedRoom!),
|
// .indexOf(HomeCubit.getInstance().selectedRoom!),
|
||||||
code: control.code);
|
// code: control.code);
|
||||||
// });
|
// // });
|
||||||
} else {
|
// } else {
|
||||||
emitSafe(DeviceControlError('Failed to control the device'));
|
// emitSafe(DeviceControlError('Failed to control the device'));
|
||||||
}
|
// }
|
||||||
} catch (failure) {
|
// } catch (failure) {
|
||||||
emitSafe(DeviceControlError(failure.toString()));
|
// emitSafe(DeviceControlError(failure.toString()));
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fetchGroups(String spaceId) async {
|
fetchGroups(String spaceId) async {
|
||||||
emitSafe(DevicesCategoriesLoading());
|
emitSafe(GetDevicesLoading());
|
||||||
try {
|
try {
|
||||||
allCategories = await DevicesAPI.fetchGroups(spaceId);
|
allCategories = await DevicesAPI.fetchGroups(spaceId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -319,14 +351,20 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
.subspaces
|
.subspaces
|
||||||
.indexWhere((element) => element.id == roomId);
|
.indexWhere((element) => element.id == roomId);
|
||||||
try {
|
try {
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices =
|
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices =
|
||||||
await DevicesAPI.getDevicesByRoomId(
|
await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: unit!.community.uuid, spaceUuid: unit.id, roomId: roomId);
|
communityUuid: unit!.community.uuid,
|
||||||
|
spaceUuid: unit.id,
|
||||||
|
roomId: roomId,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emitSafe(GetDevicesError(e.toString()));
|
emitSafe(GetDevicesError(e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final devices = HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices;
|
final devices =
|
||||||
|
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices;
|
||||||
emitSafe(GetDevicesSuccess(devices));
|
emitSafe(GetDevicesSuccess(devices));
|
||||||
|
|
||||||
//get status for each device
|
//get status for each device
|
||||||
@ -356,8 +394,11 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
emitSafe(GetDeviceStatusError(e.toString()));
|
emitSafe(GetDeviceStatusError(e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices![deviceIndex].status =
|
HomeCubit.getInstance()
|
||||||
statuses;
|
.selectedSpace!
|
||||||
|
.subspaces[roomIndex]
|
||||||
|
.devices![deviceIndex]
|
||||||
|
.status = statuses;
|
||||||
emitSafe(GetDeviceStatusSuccess(code: code));
|
emitSafe(GetDeviceStatusSuccess(code: code));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +447,365 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
// emitSafe(LightBrightnessChanged(value));
|
// emitSafe(LightBrightnessChanged(value));
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
// List<DeviceModel> _fetchedDevices = [];
|
||||||
|
|
||||||
|
// List<DeviceModel> get allDevices => _fetchedDevices;
|
||||||
|
List<DeviceModel> allDevices = [];
|
||||||
|
|
||||||
|
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,
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDeviceOn(DeviceModel device) {
|
||||||
|
final switchStatuses = device.status.where(
|
||||||
|
(s) => (s.code?.startsWith('switch') ?? false),
|
||||||
|
);
|
||||||
|
final anySwitchFalse = switchStatuses.any((s) => s.value == false);
|
||||||
|
return !anySwitchFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateDeviceStatus(String deviceId, bool newToggleStatus) {
|
||||||
|
emitSafe(GetDevicesLoading());
|
||||||
|
|
||||||
|
// Create a fresh copy of the device list.
|
||||||
|
final updatedDevices = List<DeviceModel>.from(allDevices);
|
||||||
|
|
||||||
|
for (int i = 0; i < updatedDevices.length; i++) {
|
||||||
|
final device = updatedDevices[i];
|
||||||
|
if (device.uuid == deviceId) {
|
||||||
|
updatedDevices[i] = DeviceModel(
|
||||||
|
activeTime: device.activeTime,
|
||||||
|
localKey: device.localKey,
|
||||||
|
model: device.model,
|
||||||
|
name: device.name,
|
||||||
|
icon: device.icon,
|
||||||
|
categoryName: device.categoryName,
|
||||||
|
type: device.type,
|
||||||
|
isOnline: device.isOnline,
|
||||||
|
status: device.status, // Make sure to keep the same status list
|
||||||
|
productName: device.productName,
|
||||||
|
timeZone: device.timeZone,
|
||||||
|
updateTime: device.updateTime,
|
||||||
|
uuid: device.uuid,
|
||||||
|
productUuid: device.productUuid,
|
||||||
|
productType: device.productType,
|
||||||
|
subspace: device.subspace,
|
||||||
|
toggleStatus: newToggleStatus,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(GetDevicesSuccess(updatedDevices));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> threeGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!targetState && !currentValue) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
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 = targetState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
device.toggleStatus = device.status.every(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == true),
|
||||||
|
);
|
||||||
|
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> towGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final switches = [
|
||||||
|
'switch_1',
|
||||||
|
'switch_2',
|
||||||
|
];
|
||||||
|
for (final switchCode in switches) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == switchCode);
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final toggledValue = control.value;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> towGTGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final switches = [
|
||||||
|
'switch_1',
|
||||||
|
'switch_2',
|
||||||
|
];
|
||||||
|
for (final switchCode in switches) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == switchCode);
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final toggledValue = control.value;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> oneGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
|
||||||
|
final statusIndex = device.status.indexWhere((s) => s.code == 'switch_1');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final toggledValue = control.value;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: 'switch_1', value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
if (response['result'] != true) {
|
||||||
|
throw Exception('Failed to toggle switch_1');
|
||||||
|
}
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> oneGTGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
|
||||||
|
final statusIndex = device.status.indexWhere((s) => s.code == 'switch_1');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final currentValue = device.status[statusIndex].value ?? false;
|
||||||
|
final toggledValue = !currentValue;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: 'switch_1', value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
if (response['result'] != true) {
|
||||||
|
throw Exception('Failed to toggle switch_1');
|
||||||
|
}
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deviceControl(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final response = await DevicesAPI.controlDevice(control, deviceUuid);
|
||||||
|
if (response['success'] == true) {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex != -1) {
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == control.code);
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
device.status[statusIndex].value = control.value;
|
||||||
|
}
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) =>
|
||||||
|
(s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
}
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} else {
|
||||||
|
emit(DeviceControlError('Failed to control the device'));
|
||||||
|
}
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> changeCurtainSwitch(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final isOpen = control.value == "open";
|
||||||
|
final newValue = isOpen ? 0 : 100;
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'percent_control',
|
||||||
|
devicesUuid: [deviceUuid],
|
||||||
|
value: newValue,
|
||||||
|
);
|
||||||
|
if (response['success'] == true) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == 'percent_control');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
device.status[statusIndex].value = newValue;
|
||||||
|
}
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} else {
|
||||||
|
emit(DeviceControlError('Failed to toggle curtain.'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
emit(DeviceControlError(error.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> changeGarageSwitch(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final isOpen = control.value == "open";
|
||||||
|
final newValue = isOpen ? 0 : 100;
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'percent_control',
|
||||||
|
devicesUuid: [deviceUuid],
|
||||||
|
value: newValue,
|
||||||
|
);
|
||||||
|
if (response['success'] == true) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == 'percent_control');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
device.status[statusIndex].value = newValue;
|
||||||
|
}
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} else {
|
||||||
|
emit(DeviceControlError('Failed to toggle curtain.'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
emit(DeviceControlError(error.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LightMode {
|
enum LightMode {
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class GetDeviceStatusError extends DevicesState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GetDevicesLoading extends DevicesState {}
|
class GetDevicesLoading extends DevicesState {}
|
||||||
|
class RoomLoading extends DevicesState {}
|
||||||
|
|
||||||
class GetDevicesSuccess extends DevicesState {
|
class GetDevicesSuccess extends DevicesState {
|
||||||
GetDevicesSuccess(this.devices);
|
GetDevicesSuccess(this.devices);
|
||||||
@ -55,10 +56,16 @@ class DeviceSwitchChanged extends DevicesState {}
|
|||||||
class DeviceSelected extends DevicesState {}
|
class DeviceSelected extends DevicesState {}
|
||||||
|
|
||||||
// Device Control
|
// Device Control
|
||||||
class DeviceControlLoading extends DevicesState {
|
// class DeviceControlLoading extends DevicesState {
|
||||||
final String? code;
|
// final String? code;
|
||||||
|
|
||||||
DeviceControlLoading({this.code});
|
// DeviceControlLoading({this.code});
|
||||||
|
// }
|
||||||
|
class SwitchControlLoading extends DevicesState {
|
||||||
|
final String? code;
|
||||||
|
final String? deviceId;
|
||||||
|
|
||||||
|
SwitchControlLoading({this.deviceId, this.code});
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeviceControlSuccess extends DevicesState {
|
class DeviceControlSuccess extends DevicesState {
|
||||||
|
|||||||
@ -21,13 +21,14 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
||||||
on<ToggleDoorAlarmEvent>(_toggleDoorAlarm);
|
on<ToggleDoorAlarmEvent>(_toggleDoorAlarm);
|
||||||
}
|
}
|
||||||
Timer? _timer;
|
|
||||||
bool lowBattery = false;
|
bool lowBattery = false;
|
||||||
bool closingReminder = false;
|
bool closingReminder = false;
|
||||||
bool doorAlarm = 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());
|
emit(DoorSensorLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(DSId);
|
var response = await DevicesAPI.getDeviceStatus(DSId);
|
||||||
@ -40,7 +41,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
);
|
);
|
||||||
emit(UpdateState(doorSensor: deviceStatus));
|
emit(UpdateState(doorSensor: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
Future.delayed(const Duration(milliseconds: 500));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(DoorSensorFailedState(errorMessage: e.toString()));
|
emit(DoorSensorFailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
@ -48,7 +49,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Toggle functions for each switch
|
// 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));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
lowBattery = event.isLowBatteryEnabled;
|
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));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
doorAlarm = event.isDoorAlarmEnabled;
|
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 now = DateTime.now();
|
||||||
|
|
||||||
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
|
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 {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
_streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
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 = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = DoorSensorModel.fromJson(statusList);
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
add(
|
add(
|
||||||
@ -158,4 +168,11 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.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';
|
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/features/scene/model/scenes_model.dart';
|
||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||||
import 'package:syncrow_app/services/api/scene_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';
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
|
|
||||||
class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
|
class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
|
||||||
@ -230,6 +233,7 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
|
|||||||
deviceStatus = FourSceneModelState.fromJson(
|
deviceStatus = FourSceneModelState.fromJson(
|
||||||
statusModelList,
|
statusModelList,
|
||||||
);
|
);
|
||||||
|
// _listenToChanges();
|
||||||
add(const FourSceneSwitchInitial());
|
add(const FourSceneSwitchInitial());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FourSceneFailedState(errorMessage: e.toString()));
|
emit(FourSceneFailedState(errorMessage: e.toString()));
|
||||||
@ -299,9 +303,11 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
|
|||||||
LoadScenes event, Emitter<FourSceneState> emit) async {
|
LoadScenes event, Emitter<FourSceneState> emit) async {
|
||||||
emit(FourSceneLoadingState());
|
emit(FourSceneLoadingState());
|
||||||
try {
|
try {
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
if (event.unitId.isNotEmpty) {
|
if (event.unitId.isNotEmpty) {
|
||||||
allScenes = await SceneApi.getScenesByUnitId(
|
allScenes = await SceneApi.getScenesByUnitId(
|
||||||
event.unitId, event.unit.community.uuid,
|
event.unitId, event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
|
||||||
showInDevice: event.showInDevice);
|
showInDevice: event.showInDevice);
|
||||||
|
|
||||||
filteredScenes = allScenes;
|
filteredScenes = allScenes;
|
||||||
@ -327,4 +333,33 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
|
|||||||
}).toList();
|
}).toList();
|
||||||
emit(SearchResultsState());
|
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 (_) {}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
|
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
|
||||||
on<ToggleAlarmEvent>(_toggleAlarmEvent);
|
on<ToggleAlarmEvent>(_toggleAlarmEvent);
|
||||||
on<DeleteScheduleEvent>(deleteSchedule);
|
on<DeleteScheduleEvent>(deleteSchedule);
|
||||||
//_toggleAlarmEvent
|
|
||||||
|
on<UpdateStateEvent>(_updateState);
|
||||||
}
|
}
|
||||||
void _onClose(OnClose event, Emitter<GarageDoorSensorState> emit) {
|
void _onClose(OnClose event, Emitter<GarageDoorSensorState> emit) {
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
@ -81,7 +82,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
toggleDoor = deviceStatus.switch1;
|
toggleDoor = deviceStatus.switch1;
|
||||||
emit(UpdateState(garageSensor: deviceStatus));
|
emit(UpdateState(garageSensor: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
Future.delayed(const Duration(milliseconds: 500));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(GarageDoorFailedState(errorMessage: e.toString()));
|
emit(GarageDoorFailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
@ -180,33 +181,59 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
// Real-time db
|
||||||
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
void _listenToChanges() {
|
||||||
try {
|
try {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
DatabaseReference ref =
|
DatabaseReference ref =
|
||||||
FirebaseDatabase.instance.ref('device-status/$GDId');
|
FirebaseDatabase.instance.ref('device-status/$GDId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
_streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
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 (event.snapshot.value != null) {
|
||||||
if (!isClosed) {
|
Map<dynamic, dynamic> usersMap =
|
||||||
// add(
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
// DoorSensorSwitch(switchD: deviceStatus.doorContactState),
|
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 (_) {}
|
} 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 = [
|
List<Map<String, String>> days = [
|
||||||
{"day": "Sun", "key": "Sun"},
|
{"day": "Sun", "key": "Sun"},
|
||||||
{"day": "Mon", "key": "Mon"},
|
{"day": "Mon", "key": "Mon"},
|
||||||
|
|||||||
@ -109,6 +109,8 @@ class GetScheduleEvent extends GarageDoorEvent {}
|
|||||||
|
|
||||||
class ScheduleSaveapp extends GarageDoorEvent {}
|
class ScheduleSaveapp extends GarageDoorEvent {}
|
||||||
|
|
||||||
|
class UpdateStateEvent extends GarageDoorEvent {}
|
||||||
|
|
||||||
class ToggleScheduleEvent extends GarageDoorEvent {
|
class ToggleScheduleEvent extends GarageDoorEvent {
|
||||||
final String id;
|
final String id;
|
||||||
final bool toggle;
|
final bool toggle;
|
||||||
|
|||||||
@ -26,7 +26,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
bool oneGangGroup = false;
|
bool oneGangGroup = false;
|
||||||
List<DeviceModel> devicesList = [];
|
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<InitialEvent>(_fetchOneGangStatus);
|
||||||
on<OneGangUpdated>(_oneGangUpdated);
|
on<OneGangUpdated>(_oneGangUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -49,7 +50,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
on<GroupAllOffEvent>(_groupAllOff);
|
on<GroupAllOffEvent>(_groupAllOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchOneGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
|
void _fetchOneGangStatus(
|
||||||
|
InitialEvent event, Emitter<OneGangState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(oneGangId);
|
var response = await DevicesAPI.getDeviceStatus(oneGangId);
|
||||||
@ -59,42 +61,51 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = OneGangModel.fromJson(statusModelList);
|
deviceStatus = OneGangModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(oneGangModel: deviceStatus));
|
emit(UpdateState(oneGangModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges(oneGangId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
// Real-time db
|
||||||
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
void _listenToChanges(String id) {
|
||||||
try {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
_streamSubscription = stream.listen((DatabaseEvent event) {
|
||||||
if (_timer != null) {
|
Map<dynamic, dynamic> usersMap =
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
}
|
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = OneGangModel.fromJson(statusList);
|
||||||
if (!isClosed) {
|
add(OneGangUpdated());
|
||||||
add(OneGangUpdated());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
_oneGangUpdated(OneGangUpdated event, Emitter<OneGangState> emit) {
|
_oneGangUpdated(OneGangUpdated event, Emitter<OneGangState> emit) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
emit(UpdateState(oneGangModel: deviceStatus));
|
emit(UpdateState(oneGangModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<OneGangState> emit) async {
|
void _changeFirstSwitch(
|
||||||
|
ChangeFirstSwitchStatusEvent event, Emitter<OneGangState> emit) async {
|
||||||
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.firstSwitch = !event.value;
|
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));
|
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));
|
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: oneGangId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: oneGangId, code: event.deviceCode, value: seconds),
|
||||||
oneGangId);
|
oneGangId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
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());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(oneGangId);
|
var response = await DevicesAPI.getDeviceStatus(oneGangId);
|
||||||
@ -241,7 +256,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
deviceId: oneGangId,
|
deviceId: oneGangId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(InitialState());
|
emit(InitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -252,12 +268,13 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleChange(ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
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());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -325,7 +344,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<OneGangState> emit) {
|
void toggleSelectedIndex(
|
||||||
|
ToggleSelectedEvent event, Emitter<OneGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
@ -334,7 +354,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
List<GroupOneGangModel> groupOneGangList = [];
|
List<GroupOneGangModel> groupOneGangList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
void _fetchOneGangWizardStatus(InitialWizardEvent event, Emitter<OneGangState> emit) async {
|
void _fetchOneGangWizardStatus(
|
||||||
|
InitialWizardEvent event, Emitter<OneGangState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
devicesList = [];
|
devicesList = [];
|
||||||
@ -344,7 +365,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '1G');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '1G');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
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 = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -365,15 +387,16 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
oneGangList: groupOneGangList, allSwitches: allSwitchesOn));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstWizardSwitch(
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
ChangeFirstWizardSwitchStatusEvent event, Emitter<OneGangState> emit) async {
|
Emitter<OneGangState> emit) async {
|
||||||
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
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(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
@ -414,7 +438,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: true));
|
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: true));
|
||||||
|
|
||||||
// Get a list of all device IDs
|
// 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
|
// First call for switch_1
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
@ -446,7 +471,8 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: false));
|
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: false));
|
||||||
|
|
||||||
// Get a list of all device IDs
|
// 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
|
// First call for switch_1
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
|||||||
@ -30,7 +30,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
bool oneTouchGroup = false;
|
bool oneTouchGroup = false;
|
||||||
List<DeviceModel> devicesList = [];
|
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<InitialEvent>(_fetchOneTouchStatus);
|
||||||
on<OneTouchUpdated>(_oneTouchUpdated);
|
on<OneTouchUpdated>(_oneTouchUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -53,7 +54,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
on<ChangeStatusEvent>(_changeStatus);
|
on<ChangeStatusEvent>(_changeStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchOneTouchStatus(InitialEvent event, Emitter<OneTouchState> emit) async {
|
void _fetchOneTouchStatus(
|
||||||
|
InitialEvent event, Emitter<OneTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
|
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
|
||||||
@ -62,43 +64,59 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
}
|
}
|
||||||
deviceStatus = OneTouchModel.fromJson(statusModelList);
|
deviceStatus = OneTouchModel.fromJson(statusModelList);
|
||||||
|
_listenToChanges(oneTouchId);
|
||||||
|
|
||||||
emit(UpdateState(oneTouchModel: deviceStatus));
|
emit(UpdateState(oneTouchModel: deviceStatus));
|
||||||
// _listenToChanges();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
void _listenToChanges(String id) {
|
||||||
try {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
_streamSubscription = stream.listen((DatabaseEvent event) {
|
||||||
if (_timer != null) {
|
if (event.snapshot.value != 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 = [];
|
||||||
List<StatusModel> statusList = [];
|
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
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);
|
deviceStatus.firstSwitch = switchStatus.value as bool;
|
||||||
if (!isClosed) {
|
|
||||||
add(OneTouchUpdated());
|
add(OneTouchUpdated());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
_oneTouchUpdated(OneTouchUpdated event, Emitter<OneTouchState> emit) {
|
_oneTouchUpdated(OneTouchUpdated event, Emitter<OneTouchState> emit) {
|
||||||
|
emit(LoadingNewSate(oneTouchModel: deviceStatus));
|
||||||
emit(UpdateState(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));
|
emit(LoadingNewSate(oneTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.firstSwitch = !event.value;
|
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));
|
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));
|
emit(LoadingNewSate(oneTouchModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: oneTouchId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: oneTouchId, code: event.deviceCode, value: seconds),
|
||||||
oneTouchId);
|
oneTouchId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
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());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
|
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
|
||||||
@ -245,7 +267,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
deviceId: oneTouchId,
|
deviceId: oneTouchId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(InitialState());
|
emit(InitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -256,12 +279,13 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleChange(ToggleScheduleEvent event, Emitter<OneTouchState> emit) async {
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<OneTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
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());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -329,7 +355,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<OneTouchState> emit) {
|
void toggleSelectedIndex(
|
||||||
|
ToggleSelectedEvent event, Emitter<OneTouchState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
@ -338,7 +365,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
List<GroupOneTouchModel> groupOneTouchList = [];
|
List<GroupOneTouchModel> groupOneTouchList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
void _fetchOneTouchWizardStatus(InitialWizardEvent event, Emitter<OneTouchState> emit) async {
|
void _fetchOneTouchWizardStatus(
|
||||||
|
InitialWizardEvent event, Emitter<OneTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
devicesList = [];
|
devicesList = [];
|
||||||
@ -348,7 +376,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '1GT');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '1GT');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
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 = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -369,15 +398,16 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
oneTouchList: groupOneTouchList, allSwitches: allSwitchesOn));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstWizardSwitch(
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
ChangeFirstWizardSwitchStatusEvent event, Emitter<OneTouchState> emit) async {
|
Emitter<OneTouchState> emit) async {
|
||||||
emit(LoadingNewSate(oneTouchModel: deviceStatus));
|
emit(LoadingNewSate(oneTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -395,7 +425,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
value: !event.value,
|
value: !event.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue));
|
||||||
if (response['success']) {
|
if (response['success']) {
|
||||||
add(InitialEvent(groupScreen: oneTouchGroup));
|
add(InitialEvent(groupScreen: oneTouchGroup));
|
||||||
}
|
}
|
||||||
@ -413,10 +444,12 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit the state with updated values
|
// 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
|
// 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
|
// First call for switch_1
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
@ -445,10 +478,12 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit the state with updated values
|
// 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
|
// 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
|
// First call for switch_1
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
@ -472,7 +507,8 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
String statusSelected = '';
|
String statusSelected = '';
|
||||||
String optionSelected = '';
|
String optionSelected = '';
|
||||||
|
|
||||||
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<OneTouchState> emit) async {
|
Future<void> _changeStatus(
|
||||||
|
ChangeStatusEvent event, Emitter<OneTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
|
|
||||||
@ -497,7 +533,10 @@ class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
|
|||||||
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
||||||
if (selectedControl != null) {
|
if (selectedControl != null) {
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: oneTouchId, code: optionSelected, value: selectedControl),
|
DeviceControlModel(
|
||||||
|
deviceId: oneTouchId,
|
||||||
|
code: optionSelected,
|
||||||
|
value: selectedControl),
|
||||||
oneTouchId,
|
oneTouchId,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -37,7 +38,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
on<SelectTimeEvent>(selectTimeOfLinePassword);
|
on<SelectTimeEvent>(selectTimeOfLinePassword);
|
||||||
on<SelectTimeOnlinePasswordEvent>(selectTimeOnlinePassword);
|
on<SelectTimeOnlinePasswordEvent>(selectTimeOnlinePassword);
|
||||||
on<DeletePasswordEvent>(deletePassword);
|
on<DeletePasswordEvent>(deletePassword);
|
||||||
on<GenerateAndSavePasswordTimeLimitEvent>(generateAndSavePasswordTimeLimited);
|
on<GenerateAndSavePasswordTimeLimitEvent>(
|
||||||
|
generateAndSavePasswordTimeLimited);
|
||||||
on<GenerateAndSavePasswordOneTimeEvent>(generateAndSavePasswordOneTime);
|
on<GenerateAndSavePasswordOneTimeEvent>(generateAndSavePasswordOneTime);
|
||||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||||
on<RenamePasswordEvent>(_renamePassword);
|
on<RenamePasswordEvent>(_renamePassword);
|
||||||
@ -59,7 +61,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
List<OfflinePasswordModel>? oneTimePasswords = [];
|
List<OfflinePasswordModel>? oneTimePasswords = [];
|
||||||
List<OfflinePasswordModel>? timeLimitPasswords = [];
|
List<OfflinePasswordModel>? timeLimitPasswords = [];
|
||||||
|
|
||||||
Future generate7DigitNumber(GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
Future generate7DigitNumber(
|
||||||
|
GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
passwordController.clear();
|
passwordController.clear();
|
||||||
Random random = Random();
|
Random random = Random();
|
||||||
@ -71,7 +74,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future generateAndSavePasswordOneTime(
|
Future generateAndSavePasswordOneTime(
|
||||||
GenerateAndSavePasswordOneTimeEvent event, Emitter<SmartDoorState> emit) async {
|
GenerateAndSavePasswordOneTimeEvent event,
|
||||||
|
Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
if (isSavingPassword) return;
|
if (isSavingPassword) return;
|
||||||
isSavingPassword = true;
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
||||||
@ -102,42 +107,63 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = SmartDoorModel.fromJson(statusModelList);
|
deviceStatus = SmartDoorModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
void _listenToChanges() {
|
||||||
try {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) {
|
_streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
if (_timer != null) {
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
}
|
||||||
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = SmartDoorModel.fromJson(statusList);
|
||||||
add(DoorLockUpdated());
|
if (!isClosed) {
|
||||||
|
add(DoorLockUpdated());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_doorLockUpdated(DoorLockUpdated event, Emitter<SmartDoorState> emit) {
|
_doorLockUpdated(DoorLockUpdated event, Emitter<SmartDoorState> emit) {
|
||||||
unlockRequest = deviceStatus.unlockRequest;
|
unlockRequest = deviceStatus.unlockRequest;
|
||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _renamePassword(RenamePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
void _renamePassword(
|
||||||
|
RenamePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
await DevicesAPI.renamePass(
|
await DevicesAPI.renamePass(
|
||||||
name: passwordNameController.text, doorLockUuid: deviceId, passwordId: passwordId);
|
name: passwordNameController.text,
|
||||||
|
doorLockUuid: deviceId,
|
||||||
|
passwordId: passwordId);
|
||||||
add(InitialOneTimePassword());
|
add(InitialOneTimePassword());
|
||||||
add(InitialTimeLimitPassword());
|
add(InitialTimeLimitPassword());
|
||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
var response = await DevicesAPI.getTemporaryPasswords(
|
var response = await DevicesAPI.getTemporaryPasswords(
|
||||||
deviceId,
|
deviceId,
|
||||||
);
|
);
|
||||||
if (response is List) {
|
if (response is List) {
|
||||||
temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList();
|
|
||||||
} else if (response is Map && response.containsKey('data')) {
|
|
||||||
temporaryPasswords =
|
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) {
|
} catch (e) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getOneTimePasswords(InitialOneTimePassword event, Emitter<SmartDoorState> emit) async {
|
void getOneTimePasswords(
|
||||||
|
InitialOneTimePassword event, Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
var response = await DevicesAPI.getOneTimePasswords(deviceId);
|
var response = await DevicesAPI.getOneTimePasswords(deviceId);
|
||||||
if (response is List) {
|
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) {
|
} catch (e) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getTimeLimitPasswords(InitialTimeLimitPassword event, Emitter<SmartDoorState> emit) async {
|
void getTimeLimitPasswords(
|
||||||
|
InitialTimeLimitPassword event, Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
var response = await DevicesAPI.getTimeLimitPasswords(deviceId);
|
var response = await DevicesAPI.getTimeLimitPasswords(deviceId);
|
||||||
if (response is List) {
|
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) {
|
} catch (e) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
}
|
}
|
||||||
@ -207,7 +245,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
return repeat;
|
return repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setStartEndTime(SetStartEndTimeEvent event, Emitter<SmartDoorState> emit) {
|
bool setStartEndTime(
|
||||||
|
SetStartEndTimeEvent event, Emitter<SmartDoorState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
isStartEndTime = event.val;
|
isStartEndTime = event.val;
|
||||||
emit(IsStartEndState(isStartEndTime: isStartEndTime));
|
emit(IsStartEndState(isStartEndTime: isStartEndTime));
|
||||||
@ -230,7 +269,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> selectTimeOfLinePassword(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
Future<void> selectTimeOfLinePassword(
|
||||||
|
SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
emit(ChangeTimeState());
|
emit(ChangeTimeState());
|
||||||
final DateTime? picked = await showDatePicker(
|
final DateTime? picked = await showDatePicker(
|
||||||
context: event.context,
|
context: event.context,
|
||||||
@ -260,20 +300,27 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
).millisecondsSinceEpoch ~/
|
).millisecondsSinceEpoch ~/
|
||||||
1000; // Divide by 1000 to remove milliseconds
|
1000; // Divide by 1000 to remove milliseconds
|
||||||
if (event.isEffective) {
|
if (event.isEffective) {
|
||||||
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
|
if (expirationTimeTimeStamp != null &&
|
||||||
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
|
selectedTimestamp > expirationTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Effective Time cannot be later than Expiration Time.');
|
||||||
} else {
|
} else {
|
||||||
effectiveTime =
|
effectiveTime = selectedDateTime
|
||||||
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
.toString()
|
||||||
|
.split('.')
|
||||||
|
.first; // Remove seconds and milliseconds
|
||||||
effectiveTimeTimeStamp = selectedTimestamp;
|
effectiveTimeTimeStamp = selectedTimestamp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
if (effectiveTimeTimeStamp != null &&
|
||||||
|
selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||||
CustomSnackBar.displaySnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
'Expiration Time cannot be earlier than Effective Time.');
|
'Expiration Time cannot be earlier than Effective Time.');
|
||||||
} else {
|
} else {
|
||||||
expirationTime =
|
expirationTime = selectedDateTime
|
||||||
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
.toString()
|
||||||
|
.split('.')
|
||||||
|
.first; // Remove seconds and milliseconds
|
||||||
expirationTimeTimeStamp = selectedTimestamp;
|
expirationTimeTimeStamp = selectedTimestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,20 +376,27 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
).millisecondsSinceEpoch ~/
|
).millisecondsSinceEpoch ~/
|
||||||
1000; // Divide by 1000 to remove milliseconds
|
1000; // Divide by 1000 to remove milliseconds
|
||||||
if (event.isEffective) {
|
if (event.isEffective) {
|
||||||
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
|
if (expirationTimeTimeStamp != null &&
|
||||||
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
|
selectedTimestamp > expirationTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Effective Time cannot be later than Expiration Time.');
|
||||||
} else {
|
} else {
|
||||||
effectiveTime =
|
effectiveTime = selectedDateTime
|
||||||
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
.toString()
|
||||||
|
.split('.')
|
||||||
|
.first; // Remove seconds and milliseconds
|
||||||
effectiveTimeTimeStamp = selectedTimestamp;
|
effectiveTimeTimeStamp = selectedTimestamp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
if (effectiveTimeTimeStamp != null &&
|
||||||
|
selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||||
CustomSnackBar.displaySnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
'Expiration Time cannot be earlier than Effective Time.');
|
'Expiration Time cannot be earlier than Effective Time.');
|
||||||
} else {
|
} else {
|
||||||
expirationTime =
|
expirationTime = selectedDateTime
|
||||||
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
.toString()
|
||||||
|
.split('.')
|
||||||
|
.first; // Remove seconds and milliseconds
|
||||||
expirationTimeTimeStamp = selectedTimestamp;
|
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;
|
if (_validateInputs() || isSavingPassword) return;
|
||||||
try {
|
try {
|
||||||
isSavingPassword = true;
|
isSavingPassword = true;
|
||||||
@ -381,7 +436,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> generateAndSavePasswordTimeLimited(
|
Future<void> generateAndSavePasswordTimeLimited(
|
||||||
GenerateAndSavePasswordTimeLimitEvent event, Emitter<SmartDoorState> emit) async {
|
GenerateAndSavePasswordTimeLimitEvent event,
|
||||||
|
Emitter<SmartDoorState> emit) async {
|
||||||
if (timeLimitValidate() || isSavingPassword) return;
|
if (timeLimitValidate() || isSavingPassword) return;
|
||||||
try {
|
try {
|
||||||
isSavingPassword = true;
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId)
|
await DevicesAPI.deletePassword(
|
||||||
|
deviceId: deviceId, passwordId: event.passwordId)
|
||||||
.then((value) async {
|
.then((value) async {
|
||||||
add(InitialPasswordsPage());
|
add(InitialPasswordsPage());
|
||||||
});
|
});
|
||||||
@ -445,7 +503,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (repeat == true && (endTime == null || startTime == null)) {
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/model/community_model.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/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_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_control_model.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/devices_api.dart';
|
||||||
import 'package:syncrow_app/services/api/home_management_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/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/helpers/snack_bar.dart';
|
||||||
|
|
||||||
class SosBloc extends Bloc<SosEvent, SosState> {
|
class SosBloc extends Bloc<SosEvent, SosState> {
|
||||||
@ -171,6 +174,7 @@ class SosBloc extends Bloc<SosEvent, SosState> {
|
|||||||
);
|
);
|
||||||
emit(UpdateState(sensor: deviceStatus));
|
emit(UpdateState(sensor: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
// _listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SosFailedState(errorMessage: e.toString()));
|
emit(SosFailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
@ -184,8 +188,12 @@ class SosBloc extends Bloc<SosEvent, SosState> {
|
|||||||
FetchRoomsEvent event, Emitter<SosState> emit) async {
|
FetchRoomsEvent event, Emitter<SosState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(SosLoadingState());
|
emit(SosLoadingState());
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
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));
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(const SosFailedState(errorMessage: 'Something went wrong'));
|
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 {
|
void _assignDevice(AssignRoomEvent event, Emitter<SosState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(SosLoadingState());
|
emit(SosLoadingState());
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
await HomeManagementAPI.assignDeviceToRoom(
|
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(
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: event.unit.community.uuid,
|
communityUuid: event.unit.community.uuid,
|
||||||
spaceUuid: event.unit.id,
|
spaceUuid: event.unit.id,
|
||||||
roomId: event.roomId);
|
roomId: event.roomId,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
|
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
|
|
||||||
@ -249,13 +263,16 @@ class SosBloc extends Bloc<SosEvent, SosState> {
|
|||||||
void _unassignDevice(UnassignRoomEvent event, Emitter<SosState> emit) async {
|
void _unassignDevice(UnassignRoomEvent event, Emitter<SosState> emit) async {
|
||||||
try {
|
try {
|
||||||
Map<String, bool> roomDevicesId = {};
|
Map<String, bool> roomDevicesId = {};
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
emit(SosLoadingState());
|
emit(SosLoadingState());
|
||||||
await HomeManagementAPI.unAssignDeviceToRoom(
|
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(
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: event.unit.community.uuid,
|
communityUuid: event.unit.community.uuid,
|
||||||
spaceUuid: event.unit.id,
|
spaceUuid: event.unit.id,
|
||||||
roomId: event.roomId);
|
roomId: event.roomId,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
|
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
|
|
||||||
@ -419,4 +436,39 @@ class SosBloc extends Bloc<SosEvent, SosState> {
|
|||||||
emit(SosFailedState(errorMessage: e.toString()));
|
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();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
List<GroupThreeGangModel> groupThreeGangList = [];
|
List<GroupThreeGangModel> groupThreeGangList = [];
|
||||||
bool allSwitchesOn = true;
|
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<InitialEvent>(_fetchThreeGangStatus);
|
||||||
on<ThreeGangUpdated>(_threeGangUpdated);
|
on<ThreeGangUpdated>(_threeGangUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -57,7 +58,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
|
void _fetchThreeGangStatus(
|
||||||
|
InitialEvent event, Emitter<ThreeGangState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
threeGangGroup = event.groupScreen;
|
threeGangGroup = event.groupScreen;
|
||||||
@ -69,7 +71,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '3G');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '3G');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
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 = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -86,13 +89,16 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
|
|
||||||
if (groupThreeGangList.isNotEmpty) {
|
if (groupThreeGangList.isNotEmpty) {
|
||||||
groupThreeGangList.firstWhere((element) {
|
groupThreeGangList.firstWhere((element) {
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesOn = false;
|
allSwitchesOn = false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
threeGangList: groupThreeGangList, allSwitches: allSwitchesOn));
|
||||||
} else {
|
} else {
|
||||||
var response = await DevicesAPI.getDeviceStatus(threeGangId);
|
var response = await DevicesAPI.getDeviceStatus(threeGangId);
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
@ -101,7 +107,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = ThreeGangModel.fromJson(statusModelList);
|
deviceStatus = ThreeGangModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(threeGangModel: deviceStatus));
|
emit(UpdateState(threeGangModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
@ -109,22 +115,26 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
|
||||||
|
void _listenToChanges() {
|
||||||
try {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
_streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
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 = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = ThreeGangModel.fromJson(statusList);
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
add(ThreeGangUpdated());
|
add(ThreeGangUpdated());
|
||||||
@ -133,11 +143,19 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
_threeGangUpdated(ThreeGangUpdated event, Emitter<ThreeGangState> emit) {
|
_threeGangUpdated(ThreeGangUpdated event, Emitter<ThreeGangState> emit) {
|
||||||
emit(UpdateState(threeGangModel: deviceStatus));
|
emit(UpdateState(threeGangModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
|
void _changeFirstSwitch(
|
||||||
|
ChangeFirstSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
|
||||||
emit(LoadingNewSate(threeGangModel: deviceStatus));
|
emit(LoadingNewSate(threeGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
if (threeGangGroup) {
|
if (threeGangGroup) {
|
||||||
@ -146,11 +164,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
if (element.deviceId == event.deviceId) {
|
if (element.deviceId == event.deviceId) {
|
||||||
element.firstSwitch = !event.value;
|
element.firstSwitch = !event.value;
|
||||||
}
|
}
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesValue = false;
|
allSwitchesValue = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
|
||||||
} else {
|
} else {
|
||||||
deviceStatus.firstSwitch = !event.value;
|
deviceStatus.firstSwitch = !event.value;
|
||||||
emit(UpdateState(threeGangModel: deviceStatus));
|
emit(UpdateState(threeGangModel: deviceStatus));
|
||||||
@ -187,11 +208,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
if (element.deviceId == event.deviceId) {
|
if (element.deviceId == event.deviceId) {
|
||||||
element.secondSwitch = !event.value;
|
element.secondSwitch = !event.value;
|
||||||
}
|
}
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesValue = false;
|
allSwitchesValue = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
|
||||||
} else {
|
} else {
|
||||||
deviceStatus.secondSwitch = !event.value;
|
deviceStatus.secondSwitch = !event.value;
|
||||||
emit(UpdateState(threeGangModel: deviceStatus));
|
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));
|
emit(LoadingNewSate(threeGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
if (threeGangGroup) {
|
if (threeGangGroup) {
|
||||||
@ -226,11 +251,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
if (element.deviceId == event.deviceId) {
|
if (element.deviceId == event.deviceId) {
|
||||||
element.thirdSwitch = !event.value;
|
element.thirdSwitch = !event.value;
|
||||||
}
|
}
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesValue = false;
|
allSwitchesValue = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
threeGangList: groupThreeGangList, allSwitches: allSwitchesValue));
|
||||||
} else {
|
} else {
|
||||||
deviceStatus.thirdSwitch = !event.value;
|
deviceStatus.thirdSwitch = !event.value;
|
||||||
emit(UpdateState(threeGangModel: deviceStatus));
|
emit(UpdateState(threeGangModel: deviceStatus));
|
||||||
@ -269,15 +297,21 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: threeGangId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
threeGangId),
|
threeGangId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: threeGangId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
threeGangId),
|
threeGangId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch),
|
deviceId: threeGangId,
|
||||||
|
code: 'switch_3',
|
||||||
|
value: deviceStatus.thirdSwitch),
|
||||||
threeGangId),
|
threeGangId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -303,15 +337,21 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: threeGangId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
threeGangId),
|
threeGangId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: threeGangId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
threeGangId),
|
threeGangId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch),
|
deviceId: threeGangId,
|
||||||
|
code: 'switch_3',
|
||||||
|
value: deviceStatus.thirdSwitch),
|
||||||
threeGangId),
|
threeGangId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -333,9 +373,11 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
groupThreeGangList[i].secondSwitch = true;
|
groupThreeGangList[i].secondSwitch = true;
|
||||||
groupThreeGangList[i].thirdSwitch = 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(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
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));
|
emit(LoadingNewSate(threeGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < groupThreeGangList.length; i++) {
|
for (int i = 0; i < groupThreeGangList.length; i++) {
|
||||||
@ -373,8 +416,10 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
groupThreeGangList[i].secondSwitch = false;
|
groupThreeGangList[i].secondSwitch = false;
|
||||||
groupThreeGangList[i].thirdSwitch = false;
|
groupThreeGangList[i].thirdSwitch = false;
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: false));
|
emit(UpdateGroupState(
|
||||||
List<String> allDeviceIds = groupThreeGangList.map((device) => device.deviceId).toList();
|
threeGangList: groupThreeGangList, allSwitches: false));
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupThreeGangList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
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));
|
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));
|
emit(LoadingNewSate(threeGangModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: threeGangId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: threeGangId, code: event.deviceCode, value: seconds),
|
||||||
threeGangId);
|
threeGangId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
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());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(threeGangId);
|
var response = await DevicesAPI.getDeviceStatus(threeGangId);
|
||||||
@ -551,7 +600,8 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
deviceId: threeGangId,
|
deviceId: threeGangId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(InitialState());
|
emit(InitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -562,12 +612,13 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleChange(ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
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());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
|
void toggleCreateSchedule(
|
||||||
|
ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
|
|||||||
@ -38,7 +38,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
List<GroupThreeTouchModel> groupThreeTouchList = [];
|
List<GroupThreeTouchModel> groupThreeTouchList = [];
|
||||||
bool allSwitchesOn = true;
|
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<InitialEvent>(_fetchThreeTouchStatus);
|
||||||
on<ThreeTouchUpdated>(_threeTouchUpdated);
|
on<ThreeTouchUpdated>(_threeTouchUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -63,7 +64,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
on<ChangeStatusEvent>(_changeStatus);
|
on<ChangeStatusEvent>(_changeStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchThreeTouchStatus(InitialEvent event, Emitter<ThreeTouchState> emit) async {
|
void _fetchThreeTouchStatus(
|
||||||
|
InitialEvent event, Emitter<ThreeTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
threeTouchGroup = event.groupScreen;
|
threeTouchGroup = event.groupScreen;
|
||||||
@ -75,7 +77,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '3GT');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '3GT');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
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 = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -92,13 +95,16 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
|
|
||||||
if (groupThreeTouchList.isNotEmpty) {
|
if (groupThreeTouchList.isNotEmpty) {
|
||||||
groupThreeTouchList.firstWhere((element) {
|
groupThreeTouchList.firstWhere((element) {
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesOn = false;
|
allSwitchesOn = false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
threeTouchList: groupThreeTouchList, allSwitches: allSwitchesOn));
|
||||||
} else {
|
} else {
|
||||||
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
|
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
@ -107,7 +113,7 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = ThreeTouchModel.fromJson(statusModelList);
|
deviceStatus = ThreeTouchModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(threeTouchModel: deviceStatus));
|
emit(UpdateState(threeTouchModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
@ -117,18 +123,21 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
|
|
||||||
_listenToChanges() {
|
_listenToChanges() {
|
||||||
try {
|
try {
|
||||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeTouchId');
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$threeTouchId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
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 = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = ThreeTouchModel.fromJson(statusList);
|
||||||
@ -143,7 +152,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
emit(UpdateState(threeTouchModel: deviceStatus));
|
emit(UpdateState(threeTouchModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
|
void _changeFirstSwitch(
|
||||||
|
ChangeFirstSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
|
||||||
emit(LoadingNewSate(threeTouchModel: deviceStatus));
|
emit(LoadingNewSate(threeTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
if (threeTouchGroup) {
|
if (threeTouchGroup) {
|
||||||
@ -152,11 +162,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
if (element.deviceId == event.deviceId) {
|
if (element.deviceId == event.deviceId) {
|
||||||
element.firstSwitch = !event.value;
|
element.firstSwitch = !event.value;
|
||||||
}
|
}
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesValue = false;
|
allSwitchesValue = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
threeTouchList: groupThreeTouchList,
|
||||||
|
allSwitches: allSwitchesValue));
|
||||||
} else {
|
} else {
|
||||||
deviceStatus.firstSwitch = !event.value;
|
deviceStatus.firstSwitch = !event.value;
|
||||||
emit(UpdateState(threeTouchModel: deviceStatus));
|
emit(UpdateState(threeTouchModel: deviceStatus));
|
||||||
@ -183,8 +197,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSecondSwitch(
|
void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event,
|
||||||
ChangeSecondSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
|
Emitter<ThreeTouchState> emit) async {
|
||||||
emit(LoadingNewSate(threeTouchModel: deviceStatus));
|
emit(LoadingNewSate(threeTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
if (threeTouchGroup) {
|
if (threeTouchGroup) {
|
||||||
@ -193,11 +207,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
if (element.deviceId == event.deviceId) {
|
if (element.deviceId == event.deviceId) {
|
||||||
element.secondSwitch = !event.value;
|
element.secondSwitch = !event.value;
|
||||||
}
|
}
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesValue = false;
|
allSwitchesValue = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
threeTouchList: groupThreeTouchList,
|
||||||
|
allSwitches: allSwitchesValue));
|
||||||
} else {
|
} else {
|
||||||
deviceStatus.secondSwitch = !event.value;
|
deviceStatus.secondSwitch = !event.value;
|
||||||
emit(UpdateState(threeTouchModel: deviceStatus));
|
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));
|
emit(LoadingNewSate(threeTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
if (threeTouchGroup) {
|
if (threeTouchGroup) {
|
||||||
@ -232,11 +251,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
if (element.deviceId == event.deviceId) {
|
if (element.deviceId == event.deviceId) {
|
||||||
element.thirdSwitch = !event.value;
|
element.thirdSwitch = !event.value;
|
||||||
}
|
}
|
||||||
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
|
if (!element.firstSwitch ||
|
||||||
|
!element.secondSwitch ||
|
||||||
|
!element.thirdSwitch) {
|
||||||
allSwitchesValue = false;
|
allSwitchesValue = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
threeTouchList: groupThreeTouchList,
|
||||||
|
allSwitches: allSwitchesValue));
|
||||||
} else {
|
} else {
|
||||||
deviceStatus.thirdSwitch = !event.value;
|
deviceStatus.thirdSwitch = !event.value;
|
||||||
emit(UpdateState(threeTouchModel: deviceStatus));
|
emit(UpdateState(threeTouchModel: deviceStatus));
|
||||||
@ -275,15 +298,21 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: threeTouchId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
threeTouchId),
|
threeTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: threeTouchId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
threeTouchId),
|
threeTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeTouchId, code: 'switch_3', value: deviceStatus.thirdSwitch),
|
deviceId: threeTouchId,
|
||||||
|
code: 'switch_3',
|
||||||
|
value: deviceStatus.thirdSwitch),
|
||||||
threeTouchId),
|
threeTouchId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -309,15 +338,21 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: threeTouchId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
threeTouchId),
|
threeTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: threeTouchId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
threeTouchId),
|
threeTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: threeTouchId, code: 'switch_3', value: deviceStatus.thirdSwitch),
|
deviceId: threeTouchId,
|
||||||
|
code: 'switch_3',
|
||||||
|
value: deviceStatus.thirdSwitch),
|
||||||
threeTouchId),
|
threeTouchId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -339,8 +374,10 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
groupThreeTouchList[i].secondSwitch = true;
|
groupThreeTouchList[i].secondSwitch = true;
|
||||||
groupThreeTouchList[i].thirdSwitch = true;
|
groupThreeTouchList[i].thirdSwitch = true;
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: true));
|
emit(UpdateGroupState(
|
||||||
List<String> allDeviceIds = groupThreeTouchList.map((device) => device.deviceId).toList();
|
threeTouchList: groupThreeTouchList, allSwitches: true));
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupThreeTouchList.map((device) => device.deviceId).toList();
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
devicesUuid: allDeviceIds,
|
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));
|
emit(LoadingNewSate(threeTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < groupThreeTouchList.length; i++) {
|
for (int i = 0; i < groupThreeTouchList.length; i++) {
|
||||||
@ -377,8 +415,10 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
groupThreeTouchList[i].secondSwitch = false;
|
groupThreeTouchList[i].secondSwitch = false;
|
||||||
groupThreeTouchList[i].thirdSwitch = false;
|
groupThreeTouchList[i].thirdSwitch = false;
|
||||||
}
|
}
|
||||||
List<String> allDeviceIds = groupThreeTouchList.map((device) => device.deviceId).toList();
|
List<String> allDeviceIds =
|
||||||
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: false));
|
groupThreeTouchList.map((device) => device.deviceId).toList();
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
threeTouchList: groupThreeTouchList, allSwitches: false));
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
devicesUuid: allDeviceIds,
|
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));
|
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));
|
emit(LoadingNewSate(threeTouchModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: threeTouchId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: threeTouchId, code: event.deviceCode, value: seconds),
|
||||||
threeTouchId);
|
threeTouchId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
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());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
|
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
|
||||||
@ -554,7 +598,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
deviceId: threeTouchId,
|
deviceId: threeTouchId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(InitialState());
|
emit(InitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -565,12 +610,13 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleChange(ToggleScheduleEvent event, Emitter<ThreeTouchState> emit) async {
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<ThreeTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
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());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeTouchState> emit) {
|
void toggleCreateSchedule(
|
||||||
|
ToggleCreateScheduleEvent event, Emitter<ThreeTouchState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -633,7 +682,8 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
String statusSelected = '';
|
String statusSelected = '';
|
||||||
String optionSelected = '';
|
String optionSelected = '';
|
||||||
|
|
||||||
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<ThreeTouchState> emit) async {
|
Future<void> _changeStatus(
|
||||||
|
ChangeStatusEvent event, Emitter<ThreeTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final Map<String, Map<String, String>> controlMap = {
|
final Map<String, Map<String, String>> controlMap = {
|
||||||
@ -667,11 +717,15 @@ class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
|
|||||||
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
||||||
if (selectedControl != null) {
|
if (selectedControl != null) {
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: threeTouchId, code: optionSelected, value: selectedControl),
|
DeviceControlModel(
|
||||||
|
deviceId: threeTouchId,
|
||||||
|
code: optionSelected,
|
||||||
|
value: selectedControl),
|
||||||
threeTouchId,
|
threeTouchId,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
emit(const FailedState(error: 'Invalid statusSelected or optionSelected'));
|
emit(const FailedState(
|
||||||
|
error: 'Invalid statusSelected or optionSelected'));
|
||||||
}
|
}
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
|
|||||||
@ -35,7 +35,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
bool createSchedule = false;
|
bool createSchedule = false;
|
||||||
List<ScheduleModel> listSchedule = [];
|
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<InitialEvent>(_fetchTwoGangStatus);
|
||||||
on<TwoGangUpdated>(_twoGangUpdated);
|
on<TwoGangUpdated>(_twoGangUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -65,13 +66,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
|
void toggleSelectedIndex(
|
||||||
|
ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<TwoGangState> emit) {
|
void toggleCreateSchedule(
|
||||||
|
ToggleCreateScheduleEvent event, Emitter<TwoGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -79,7 +82,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
emit(UpdateCreateScheduleState(createSchedule));
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchTwoGangStatus(InitialEvent event, Emitter<TwoGangState> emit) async {
|
void _fetchTwoGangStatus(
|
||||||
|
InitialEvent event, Emitter<TwoGangState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
||||||
@ -89,42 +93,50 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(twoGangModel: deviceStatus));
|
emit(UpdateState(twoGangModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges(twoGangId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
void _listenToChanges(String id) {
|
||||||
try {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
_streamSubscription = stream.listen((DatabaseEvent event) {
|
||||||
stream.listen((DatabaseEvent event) async {
|
Map<dynamic, dynamic> usersMap =
|
||||||
if (_timer != null) {
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
|
||||||
}
|
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = TwoGangModel.fromJson(statusList);
|
||||||
if (!isClosed) {
|
add(TwoGangUpdated());
|
||||||
add(TwoGangUpdated());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
_twoGangUpdated(TwoGangUpdated event, Emitter<TwoGangState> emit) {
|
_twoGangUpdated(TwoGangUpdated event, Emitter<TwoGangState> emit) {
|
||||||
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
|
|
||||||
emit(UpdateState(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));
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.firstSwitch = !event.value;
|
deviceStatus.firstSwitch = !event.value;
|
||||||
@ -135,7 +147,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
|
|
||||||
_timer = Timer(const Duration(milliseconds: 100), () async {
|
_timer = Timer(const Duration(milliseconds: 100), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoGangId, code: 'switch_1', value: !event.value),
|
DeviceControlModel(
|
||||||
|
deviceId: twoGangId, code: 'switch_1', value: !event.value),
|
||||||
twoGangId);
|
twoGangId);
|
||||||
|
|
||||||
if (!response['success']) {
|
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));
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.secondSwitch = !event.value;
|
deviceStatus.secondSwitch = !event.value;
|
||||||
@ -157,7 +171,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
}
|
}
|
||||||
_timer = Timer(const Duration(milliseconds: 100), () async {
|
_timer = Timer(const Duration(milliseconds: 100), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoGangId, code: 'switch_2', value: !event.value),
|
DeviceControlModel(
|
||||||
|
deviceId: twoGangId, code: 'switch_2', value: !event.value),
|
||||||
twoGangId);
|
twoGangId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -180,11 +195,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: twoGangId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
twoGangId),
|
twoGangId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: twoGangId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
twoGangId),
|
twoGangId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -207,11 +226,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: twoGangId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
twoGangId),
|
twoGangId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: twoGangId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
twoGangId),
|
twoGangId),
|
||||||
]);
|
]);
|
||||||
if (response.every((element) => !element['success'])) {
|
if (response.every((element) => !element['success'])) {
|
||||||
@ -232,7 +255,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
groupTwoGangList[i].secondSwitch = true;
|
groupTwoGangList[i].secondSwitch = true;
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: 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(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
@ -267,7 +291,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
|
|
||||||
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: false));
|
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(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
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));
|
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));
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoGangId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: twoGangId, code: event.deviceCode, value: seconds),
|
||||||
twoGangId);
|
twoGangId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
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());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
add(GetScheduleEvent());
|
add(GetScheduleEvent());
|
||||||
@ -435,7 +464,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
deviceId: twoGangId,
|
deviceId: twoGangId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(InitialState());
|
emit(InitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -446,12 +476,13 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleRepeat(ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
|
Future toggleRepeat(
|
||||||
|
ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
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 {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
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());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
devicesList = [];
|
devicesList = [];
|
||||||
@ -500,7 +533,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
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 = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -523,15 +557,16 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstWizardSwitch(
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
ChangeFirstWizardSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
|
Emitter<TwoGangState> emit) async {
|
||||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
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(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
devicesUuid: allDeviceIds,
|
devicesUuid: allDeviceIds,
|
||||||
@ -561,8 +598,8 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSecondWizardSwitch(
|
void _changeSecondWizardSwitch(ChangeSecondWizardSwitchStatusEvent event,
|
||||||
ChangeSecondWizardSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
|
Emitter<TwoGangState> emit) async {
|
||||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -574,9 +611,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
allSwitchesValue = false;
|
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(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_2',
|
code: 'switch_2',
|
||||||
|
|||||||
@ -40,7 +40,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
bool createSchedule = false;
|
bool createSchedule = false;
|
||||||
List<ScheduleModel> listSchedule = [];
|
List<ScheduleModel> listSchedule = [];
|
||||||
|
|
||||||
TwoTouchBloc({required this.twoTouchId, required this.switchCode}) : super(InitialState()) {
|
TwoTouchBloc({required this.twoTouchId, required this.switchCode})
|
||||||
|
: super(InitialState()) {
|
||||||
on<InitialEvent>(_fetchTwoTouchStatus);
|
on<InitialEvent>(_fetchTwoTouchStatus);
|
||||||
on<TwoTouchUpdated>(_twoTouchUpdated);
|
on<TwoTouchUpdated>(_twoTouchUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -71,13 +72,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<TwoTouchState> emit) {
|
void toggleSelectedIndex(
|
||||||
|
ToggleSelectedEvent event, Emitter<TwoTouchState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<TwoTouchState> emit) {
|
void toggleCreateSchedule(
|
||||||
|
ToggleCreateScheduleEvent event, Emitter<TwoTouchState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -85,7 +88,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
emit(UpdateCreateScheduleState(createSchedule));
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchTwoTouchStatus(InitialEvent event, Emitter<TwoTouchState> emit) async {
|
void _fetchTwoTouchStatus(
|
||||||
|
InitialEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(twoTouchId);
|
var response = await DevicesAPI.getDeviceStatus(twoTouchId);
|
||||||
@ -95,42 +99,66 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = TwoTouchModel.fromJson(statusModelList);
|
deviceStatus = TwoTouchModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(twoTouchModel: deviceStatus));
|
emit(UpdateState(twoTouchModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
|
||||||
|
void _listenToChanges() {
|
||||||
try {
|
try {
|
||||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoTouchId');
|
_streamSubscription?.cancel();
|
||||||
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$twoTouchId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
_streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
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>;
|
if (event.snapshot.value != null) {
|
||||||
List<StatusModel> statusList = [];
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
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());
|
add(TwoTouchUpdated());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
_streamSubscription?.cancel();
|
||||||
|
_streamSubscription = null;
|
||||||
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
_twoTouchUpdated(TwoTouchUpdated event, Emitter<TwoTouchState> emit) {
|
_twoTouchUpdated(TwoTouchUpdated event, Emitter<TwoTouchState> emit) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
emit(UpdateState(twoTouchModel: deviceStatus));
|
emit(UpdateState(twoTouchModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
void _changeFirstSwitch(
|
||||||
|
ChangeFirstSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.firstSwitch = !event.value;
|
deviceStatus.firstSwitch = !event.value;
|
||||||
@ -141,7 +169,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
|
|
||||||
_timer = Timer(const Duration(milliseconds: 100), () async {
|
_timer = Timer(const Duration(milliseconds: 100), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: 'switch_1', value: !event.value),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId, code: 'switch_1', value: !event.value),
|
||||||
twoTouchId);
|
twoTouchId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -153,7 +182,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
void _changeSecondSwitch(
|
||||||
|
ChangeSecondSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.secondSwitch = !event.value;
|
deviceStatus.secondSwitch = !event.value;
|
||||||
@ -163,7 +193,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
_timer = Timer(const Duration(milliseconds: 100), () async {
|
_timer = Timer(const Duration(milliseconds: 100), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: 'switch_2', value: !event.value),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId, code: 'switch_2', value: !event.value),
|
||||||
twoTouchId);
|
twoTouchId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -186,11 +217,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -213,11 +248,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
]);
|
]);
|
||||||
if (response.every((element) => !element['success'])) {
|
if (response.every((element) => !element['success'])) {
|
||||||
@ -237,8 +276,10 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
groupTwoTouchList[i].firstSwitch = true;
|
groupTwoTouchList[i].firstSwitch = true;
|
||||||
groupTwoTouchList[i].secondSwitch = true;
|
groupTwoTouchList[i].secondSwitch = true;
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: true));
|
emit(
|
||||||
List<String> allDeviceIds = groupTwoTouchList.map((device) => device.deviceId).toList();
|
UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: true));
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupTwoTouchList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
@ -271,9 +312,11 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
groupTwoTouchList[i].secondSwitch = false;
|
groupTwoTouchList[i].secondSwitch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: false));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: false));
|
||||||
|
|
||||||
List<String> allDeviceIds = groupTwoTouchList.map((device) => device.deviceId).toList();
|
List<String> allDeviceIds =
|
||||||
|
groupTwoTouchList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
@ -298,17 +341,20 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSliding(ChangeSlidingSegment event, Emitter<TwoTouchState> emit) async {
|
void _changeSliding(
|
||||||
|
ChangeSlidingSegment event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(ChangeSlidingSegmentState(value: event.value));
|
emit(ChangeSlidingSegmentState(value: event.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCounterValue(SetCounterValue event, Emitter<TwoTouchState> emit) async {
|
void _setCounterValue(
|
||||||
|
SetCounterValue event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId, code: event.deviceCode, value: seconds),
|
||||||
twoTouchId);
|
twoTouchId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
@ -333,7 +379,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getCounterValue(GetCounterEvent event, Emitter<TwoTouchState> emit) async {
|
void _getCounterValue(
|
||||||
|
GetCounterEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
add(GetScheduleEvent());
|
add(GetScheduleEvent());
|
||||||
@ -441,7 +488,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
deviceId: twoTouchId,
|
deviceId: twoTouchId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(InitialState());
|
emit(InitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -452,12 +500,13 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleRepeat(ToggleScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
Future toggleRepeat(
|
||||||
|
ToggleScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
final response = await DevicesAPI.changeSchedule(
|
||||||
@ -476,7 +525,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future deleteSchedule(DeleteScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
Future deleteSchedule(
|
||||||
|
DeleteScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
final response = await DevicesAPI.deleteSchedule(
|
||||||
@ -496,7 +546,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchTwoTouchWizardStatus(InitialWizardEvent event, Emitter<TwoTouchState> emit) async {
|
void _fetchTwoTouchWizardStatus(
|
||||||
|
InitialWizardEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
devicesList = [];
|
devicesList = [];
|
||||||
@ -506,7 +557,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '2GT');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '2GT');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
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 = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -529,15 +581,16 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: allSwitchesOn));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstWizardSwitch(
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
ChangeFirstWizardSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -550,7 +603,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
devicesUuid: [event.deviceId],
|
devicesUuid: [event.deviceId],
|
||||||
@ -565,8 +619,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSecondWizardSwitch(
|
void _changeSecondWizardSwitch(ChangeSecondWizardSwitchStatusEvent event,
|
||||||
ChangeSecondWizardSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -579,7 +633,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_2',
|
code: 'switch_2',
|
||||||
@ -598,7 +653,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
String statusSelected = '';
|
String statusSelected = '';
|
||||||
String optionSelected = '';
|
String optionSelected = '';
|
||||||
|
|
||||||
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<TwoTouchState> emit) async {
|
Future<void> _changeStatus(
|
||||||
|
ChangeStatusEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final Map<String, Map<String, String>> controlMap = {
|
final Map<String, Map<String, String>> controlMap = {
|
||||||
@ -627,11 +683,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
||||||
if (selectedControl != null) {
|
if (selectedControl != null) {
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: optionSelected, value: selectedControl),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId,
|
||||||
|
code: optionSelected,
|
||||||
|
value: selectedControl),
|
||||||
twoTouchId,
|
twoTouchId,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
emit(const FailedState(error: 'Invalid statusSelected or optionSelected'));
|
emit(const FailedState(
|
||||||
|
error: 'Invalid statusSelected or optionSelected'));
|
||||||
}
|
}
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
|
||||||
@ -18,9 +20,11 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
on<ChangeIndicatorEvent>(_changeIndicator);
|
on<ChangeIndicatorEvent>(_changeIndicator);
|
||||||
on<ChangeValueEvent>(_changeValue);
|
on<ChangeValueEvent>(_changeValue);
|
||||||
on<WallSensorUpdatedEvent>(_wallSensorUpdated);
|
on<WallSensorUpdatedEvent>(_wallSensorUpdated);
|
||||||
|
on<GetDeviceReportsEvent>(_getDeviceReports);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchCeilingSensorStatus(InitialEvent event, Emitter<WallSensorState> emit) async {
|
void _fetchCeilingSensorStatus(
|
||||||
|
InitialEvent event, Emitter<WallSensorState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
||||||
@ -30,41 +34,62 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
}
|
}
|
||||||
deviceStatus = WallSensorModel.fromJson(statusModelList);
|
deviceStatus = WallSensorModel.fromJson(statusModelList);
|
||||||
emit(UpdateState(wallSensorModel: deviceStatus));
|
emit(UpdateState(wallSensorModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
Timer? _timer;
|
||||||
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
|
||||||
|
void _listenToChanges() {
|
||||||
try {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) {
|
_streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
if (_timer != null) {
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
}
|
||||||
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = WallSensorModel.fromJson(statusList);
|
||||||
add(WallSensorUpdatedEvent());
|
if (!isClosed) {
|
||||||
|
add(WallSensorUpdatedEvent());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} 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));
|
emit(UpdateState(wallSensorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeIndicator(ChangeIndicatorEvent event, Emitter<WallSensorState> emit) async {
|
void _changeIndicator(
|
||||||
|
ChangeIndicatorEvent event, Emitter<WallSensorState> emit) async {
|
||||||
emit(LoadingNewSate(wallSensorModel: deviceStatus));
|
emit(LoadingNewSate(wallSensorModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
final response = await DevicesAPI.controlDevice(
|
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) {
|
if (response['success'] ?? false) {
|
||||||
deviceStatus.indicator = !event.value;
|
deviceStatus.indicator = !event.value;
|
||||||
@ -73,11 +98,14 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
emit(UpdateState(wallSensorModel: deviceStatus));
|
emit(UpdateState(wallSensorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeValue(ChangeValueEvent event, Emitter<WallSensorState> emit) async {
|
void _changeValue(
|
||||||
|
ChangeValueEvent event, Emitter<WallSensorState> emit) async {
|
||||||
emit(LoadingNewSate(wallSensorModel: deviceStatus));
|
emit(LoadingNewSate(wallSensorModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
final response = await DevicesAPI.controlDevice(
|
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 (response['success'] ?? false) {
|
||||||
if (event.code == 'far_detection') {
|
if (event.code == 'far_detection') {
|
||||||
@ -91,4 +119,18 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
emit(UpdateState(wallSensorModel: deviceStatus));
|
emit(UpdateState(wallSensorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _getDeviceReports(
|
||||||
|
GetDeviceReportsEvent event, Emitter<WallSensorState> emit) async {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
|
||||||
|
try {
|
||||||
|
await DevicesAPI.getDeviceReports(deviceId, event.code).then((value) {
|
||||||
|
emit(DeviceReportsState(deviceReport: value, code: event.code));
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(error: e.toString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,3 +29,15 @@ class ChangeValueEvent extends WallSensorEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [value, code];
|
List<Object> get props => [value, code];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GetDeviceReportsEvent extends WallSensorEvent {
|
||||||
|
final String deviceUuid;
|
||||||
|
final String code;
|
||||||
|
const GetDeviceReportsEvent({
|
||||||
|
required this.deviceUuid,
|
||||||
|
required this.code,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceUuid, code];
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart';
|
import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart';
|
||||||
|
|
||||||
class WallSensorState extends Equatable {
|
class WallSensorState extends Equatable {
|
||||||
@ -36,3 +37,9 @@ class FailedState extends WallSensorState {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [error];
|
List<Object> get props => [error];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeviceReportsState extends WallSensorState {
|
||||||
|
final DeviceReport deviceReport;
|
||||||
|
final String code;
|
||||||
|
const DeviceReportsState({required this.deviceReport, required this.code});
|
||||||
|
}
|
||||||
|
|||||||
@ -35,7 +35,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
List<ScheduleModel> listSchedule = [];
|
List<ScheduleModel> listSchedule = [];
|
||||||
DateTime? selectedTime = DateTime.now();
|
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<WaterHeaterInitial>(_fetchWaterHeaterStatus);
|
||||||
on<WaterHeaterSwitch>(_changeFirstSwitch);
|
on<WaterHeaterSwitch>(_changeFirstSwitch);
|
||||||
on<SetCounterValue>(_setCounterValue);
|
on<SetCounterValue>(_setCounterValue);
|
||||||
@ -60,7 +61,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
on<WaterHeaterUpdated>(_waterHeaterUpdated);
|
on<WaterHeaterUpdated>(_waterHeaterUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchWaterHeaterStatus(WaterHeaterInitial event, Emitter<WaterHeaterState> emit) async {
|
void _fetchWaterHeaterStatus(
|
||||||
|
WaterHeaterInitial event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(whId);
|
var response = await DevicesAPI.getDeviceStatus(whId);
|
||||||
@ -72,29 +74,33 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
statusModelList,
|
statusModelList,
|
||||||
);
|
);
|
||||||
emit(UpdateState(whModel: deviceStatus));
|
emit(UpdateState(whModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(WHFailedState(errorMessage: e.toString()));
|
emit(WHFailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenToChanges() {
|
//real-time db
|
||||||
|
StreamSubscription<DatabaseEvent>? _streamSubscription;
|
||||||
|
void _listenToChanges() {
|
||||||
try {
|
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<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
_streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
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 = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
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);
|
deviceStatus = WHModel.fromJson(statusList);
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
add(WaterHeaterUpdated());
|
add(WaterHeaterUpdated());
|
||||||
@ -103,12 +109,21 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
} catch (_) {}
|
} 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(WHLoadingState());
|
||||||
emit(UpdateState(whModel: deviceStatus));
|
emit(UpdateState(whModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstSwitch(WaterHeaterSwitch event, Emitter<WaterHeaterState> emit) async {
|
void _changeFirstSwitch(
|
||||||
|
WaterHeaterSwitch event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(LoadingNewSate(whModel: deviceStatus));
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.firstSwitch = !event.whSwitch;
|
deviceStatus.firstSwitch = !event.whSwitch;
|
||||||
@ -118,7 +133,10 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: whId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
DeviceControlModel(
|
||||||
|
deviceId: whId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
whId);
|
whId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -132,13 +150,16 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
|
|
||||||
//=====================---------- timer ----------------------------------------
|
//=====================---------- timer ----------------------------------------
|
||||||
|
|
||||||
void _setCounterValue(SetCounterValue event, Emitter<WaterHeaterState> emit) async {
|
void _setCounterValue(
|
||||||
|
SetCounterValue event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(LoadingNewSate(whModel: deviceStatus));
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
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 (response['success'] ?? false) {
|
||||||
if (event.deviceCode == 'countdown_1') {
|
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());
|
emit(WHLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(whId);
|
var response = await DevicesAPI.getDeviceStatus(whId);
|
||||||
@ -250,7 +272,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
deviceId: whId,
|
deviceId: whId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(WHInitialState());
|
emit(WHInitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -261,12 +284,13 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleChange(ToggleScheduleEvent event, Emitter<WaterHeaterState> emit) async {
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
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 {
|
try {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
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());
|
emit(WHLoadingState());
|
||||||
createCirculate = !createCirculate;
|
createCirculate = !createCirculate;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -311,13 +337,15 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
emit(UpdateCreateScheduleState(createCirculate));
|
emit(UpdateCreateScheduleState(createCirculate));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
|
void toggleSelectedIndex(
|
||||||
|
ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
|
void toggleCreateSchedule(
|
||||||
|
ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -366,8 +394,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
List<GroupWHModel> groupWaterHeaterList = [];
|
List<GroupWHModel> groupWaterHeaterList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
void _changeFirstWizardSwitch(
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
ChangeFirstWizardSwitchStatusEvent event, Emitter<WaterHeaterState> emit) async {
|
Emitter<WaterHeaterState> emit) async {
|
||||||
emit(LoadingNewSate(whModel: deviceStatus));
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -379,7 +407,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
allSwitchesValue = false;
|
allSwitchesValue = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
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());
|
emit(WHLoadingState());
|
||||||
try {
|
try {
|
||||||
devicesList = [];
|
devicesList = [];
|
||||||
@ -404,7 +434,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', 'WH');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', 'WH');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
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 = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -426,23 +457,27 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// emit(FailedState(error: e.toString()));
|
// emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _groupAllOn(GroupAllOnEvent event, Emitter<WaterHeaterState> emit) async {
|
void _groupAllOn(
|
||||||
|
GroupAllOnEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(LoadingNewSate(whModel: deviceStatus));
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < groupWaterHeaterList.length; i++) {
|
for (int i = 0; i < groupWaterHeaterList.length; i++) {
|
||||||
groupWaterHeaterList[i].firstSwitch = true;
|
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(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
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));
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < groupWaterHeaterList.length; i++) {
|
for (int i = 0; i < groupWaterHeaterList.length; i++) {
|
||||||
groupWaterHeaterList[i].firstSwitch = false;
|
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(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.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_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/water_leak_bloc/water_leak_state.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<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
||||||
on<ToggleWaterLeakAlarmEvent>(_toggleWaterLeakAlarm);
|
on<ToggleWaterLeakAlarmEvent>(_toggleWaterLeakAlarm);
|
||||||
}
|
}
|
||||||
Timer? _timer;
|
|
||||||
bool lowBattery = false;
|
bool lowBattery = false;
|
||||||
bool closingReminder = false;
|
bool closingReminder = false;
|
||||||
bool waterAlarm = false;
|
bool waterAlarm = false;
|
||||||
@ -134,32 +132,42 @@ class WaterLeakBloc extends Bloc<WaterLeakEvent, WaterLeakState> {
|
|||||||
emit(WaterLeakFailedState(errorMessage: errorMessage));
|
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() {
|
// _streamSubscription = stream.listen((DatabaseEvent event) async {
|
||||||
try {
|
// if (_timer != null) {
|
||||||
DatabaseReference ref =
|
// await Future.delayed(const Duration(seconds: 2));
|
||||||
FirebaseDatabase.instance.ref('device-status/$WLId');
|
// }
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
// 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 {
|
// @override
|
||||||
if (_timer != null) {
|
// Future<void> close() async {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
// _streamSubscription?.cancel();
|
||||||
}
|
// _streamSubscription = null;
|
||||||
Map<dynamic, dynamic> usersMap =
|
// return super.close();
|
||||||
event.snapshot.value as Map<dynamic, dynamic>;
|
// }
|
||||||
List<StatusModel> statusList = [];
|
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
|
||||||
statusList.add(StatusModel(code: element['code'], value: true));
|
|
||||||
});
|
|
||||||
|
|
||||||
deviceStatus = WaterLeakModel.fromJson(statusList);
|
|
||||||
if (!isClosed) {
|
|
||||||
add(
|
|
||||||
WaterLeakSwitch(switchD: deviceStatus.waterContactState),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (_) {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,24 +27,24 @@ class AcStatusModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
factory AcStatusModel.fromJson(String id, List<StatusModel> jsonList) {
|
factory AcStatusModel.fromJson(String id, List<StatusModel> jsonList) {
|
||||||
late bool _acSwitch;
|
bool _acSwitch = false;
|
||||||
late String _mode;
|
String _mode = '';
|
||||||
late int _tempSet;
|
int _tempSet = 210;
|
||||||
late int _currentTemp;
|
int _currentTemp = 210;
|
||||||
late String _fanSpeeds;
|
String _fanSpeeds = '';
|
||||||
late int _countdown1;
|
int _countdown1 = 0;
|
||||||
late bool _childLock;
|
bool _childLock = false;
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'switch') {
|
if (jsonList[i].code == 'switch') {
|
||||||
_acSwitch = jsonList[i].value ?? false;
|
_acSwitch = jsonList[i].value ?? false;
|
||||||
} else if (jsonList[i].code == 'mode') {
|
} else if (jsonList[i].code == 'mode') {
|
||||||
_mode = jsonList[i].value ?? TempModes.cold;
|
_mode = jsonList[i].value ?? '';
|
||||||
} else if (jsonList[i].code == 'temp_set') {
|
} else if (jsonList[i].code == 'temp_set') {
|
||||||
_tempSet = jsonList[i].value ?? 210;
|
_tempSet = jsonList[i].value ?? 210;
|
||||||
} else if (jsonList[i].code == 'temp_current') {
|
} else if (jsonList[i].code == 'temp_current') {
|
||||||
_currentTemp = jsonList[i].value ?? 210;
|
_currentTemp = jsonList[i].value ?? 210;
|
||||||
} else if (jsonList[i].code == 'level') {
|
} else if (jsonList[i].code == 'level') {
|
||||||
_fanSpeeds = jsonList[i].value ?? 210;
|
_fanSpeeds = jsonList[i].value ?? '';
|
||||||
} else if (jsonList[i].code == 'child_lock') {
|
} else if (jsonList[i].code == 'child_lock') {
|
||||||
_childLock = jsonList[i].value ?? false;
|
_childLock = jsonList[i].value ?? false;
|
||||||
} else if (jsonList[i].code == 'countdown_time') {
|
} else if (jsonList[i].code == 'countdown_time') {
|
||||||
|
|||||||
@ -23,9 +23,9 @@ class CeilingSensorModel {
|
|||||||
required this.bodyMovement});
|
required this.bodyMovement});
|
||||||
|
|
||||||
factory CeilingSensorModel.fromJson(List<StatusModel> jsonList) {
|
factory CeilingSensorModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late String _presenceState;
|
String _presenceState = 'none';
|
||||||
late int _sensitivity;
|
int _sensitivity = 1;
|
||||||
late String _checkingResult;
|
String _checkingResult = '';
|
||||||
int _presenceRange = 1;
|
int _presenceRange = 1;
|
||||||
int _sportsPara = 1;
|
int _sportsPara = 1;
|
||||||
int _moving_max_dis = 0;
|
int _moving_max_dis = 0;
|
||||||
|
|||||||
@ -10,11 +10,11 @@ class CurtainModel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory CurtainModel.fromJson(List<StatusModel> jsonList) {
|
factory CurtainModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late String _control;
|
String _control = '';
|
||||||
late int _percent;
|
int _percent = 0;
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'control') {
|
if (jsonList[i].code == 'control') {
|
||||||
_control = jsonList[i].value ?? false;
|
_control = jsonList[i].value ?? '';
|
||||||
}
|
}
|
||||||
if (jsonList[i].code == 'percent_control') {
|
if (jsonList[i].code == 'percent_control') {
|
||||||
_percent = jsonList[i].value ?? 0;
|
_percent = jsonList[i].value ?? 0;
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
class DeviceInfoModel {
|
class DeviceInfoModel {
|
||||||
final int activeTime;
|
final int activeTime;
|
||||||
final String category;
|
final String category;
|
||||||
|
|||||||
@ -10,6 +10,9 @@ class DeviceModel {
|
|||||||
String? model;
|
String? model;
|
||||||
String? name;
|
String? name;
|
||||||
String? icon;
|
String? icon;
|
||||||
|
String? categoryName;
|
||||||
|
bool? toggleStatus = false;
|
||||||
|
|
||||||
String? type;
|
String? type;
|
||||||
bool? isOnline;
|
bool? isOnline;
|
||||||
List<StatusModel> status = [];
|
List<StatusModel> status = [];
|
||||||
@ -21,6 +24,8 @@ class DeviceModel {
|
|||||||
DeviceType? productType;
|
DeviceType? productType;
|
||||||
bool isSelected = false;
|
bool isSelected = false;
|
||||||
late List<FunctionModel> functions;
|
late List<FunctionModel> functions;
|
||||||
|
DeviceSubspace? subspace;
|
||||||
|
|
||||||
DeviceModel(
|
DeviceModel(
|
||||||
{this.activeTime,
|
{this.activeTime,
|
||||||
this.productUuid,
|
this.productUuid,
|
||||||
@ -34,6 +39,9 @@ class DeviceModel {
|
|||||||
this.updateTime,
|
this.updateTime,
|
||||||
this.uuid,
|
this.uuid,
|
||||||
this.productType,
|
this.productType,
|
||||||
|
this.categoryName,
|
||||||
|
this.subspace,
|
||||||
|
this.toggleStatus,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.type}) {
|
this.type}) {
|
||||||
functions = getFunctions(productType!);
|
functions = getFunctions(productType!);
|
||||||
@ -87,23 +95,74 @@ class DeviceModel {
|
|||||||
} else {
|
} else {
|
||||||
tempIcon = Assets.assetsIconsLogo;
|
tempIcon = Assets.assetsIconsLogo;
|
||||||
}
|
}
|
||||||
|
// Step 1: Parse `status` as before
|
||||||
|
final statusList = (json['status'] as List<dynamic>?)
|
||||||
|
?.map((st) => StatusModel.fromJson(st as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
// Step 2: Check whether ANY status means "off"
|
||||||
|
final anyOff = statusList?.any((s) {
|
||||||
|
final code = s.code;
|
||||||
|
if (code == null) return false;
|
||||||
|
|
||||||
|
// 1) Handle "switch" or "switch_x"
|
||||||
|
if (code == 'switch' || code.startsWith('switch_')) {
|
||||||
|
// If it's false, we consider that "off"
|
||||||
|
return s.value == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) If code == "control" and value == "stop", consider "off"
|
||||||
|
if (s.value == 'open') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) If code == "percent_control" and value == 0, maybe "off"
|
||||||
|
if (code == 'percent_control' && s.value == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add more conditions for other codes as needed
|
||||||
|
|
||||||
|
// Default: if none of the above apply, it's not "off"
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 3: Decide final toggleStatus (true = fully "on", false = partially/fully "off")
|
||||||
|
bool computedToggleStatus = !(anyOff ?? false);
|
||||||
|
|
||||||
return DeviceModel(
|
return DeviceModel(
|
||||||
icon: tempIcon,
|
icon: tempIcon,
|
||||||
activeTime: json['activeTime'],
|
activeTime: json['activeTime'],
|
||||||
// id: json['id'],
|
categoryName: json['categoryName'],
|
||||||
localKey: json['localKey'],
|
localKey: json['localKey'],
|
||||||
model: json['model'],
|
model: json['model'],
|
||||||
name: json['name'],
|
name: json['name'],
|
||||||
isOnline: json['online'],
|
isOnline: json['online'],
|
||||||
productName: json['productName'],
|
productName: json['productName'],
|
||||||
timeZone: json['timeZone'],
|
timeZone: json['timeZone'],
|
||||||
updateTime: json['updateTime'],
|
updateTime: json['updateTime'],
|
||||||
uuid: json['uuid'],
|
uuid: json['uuid'],
|
||||||
productType: type,
|
productType: type,
|
||||||
type: json['productType'],
|
type: json['productType'],
|
||||||
status: [],
|
|
||||||
productUuid: json['productUuid']);
|
// Use the newly computed toggleStatus:
|
||||||
|
toggleStatus: computedToggleStatus,
|
||||||
|
|
||||||
|
// Or if you prefer to use the value returned by the backend when available:
|
||||||
|
// toggleStatus: json['toggleStatus'] ?? computedToggleStatus,
|
||||||
|
|
||||||
|
status: statusList ?? [],
|
||||||
|
subspace: json['subspace'] != null
|
||||||
|
? DeviceSubspace.fromJson(json['subspace'])
|
||||||
|
: DeviceSubspace(
|
||||||
|
createdAt: null,
|
||||||
|
disabled: false,
|
||||||
|
subspaceName: '',
|
||||||
|
updatedAt: null,
|
||||||
|
uuid: '',
|
||||||
|
),
|
||||||
|
productUuid: json['productUuid'],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
@ -118,9 +177,50 @@ class DeviceModel {
|
|||||||
'updateTime': updateTime,
|
'updateTime': updateTime,
|
||||||
'uuid': uuid,
|
'uuid': uuid,
|
||||||
'productType': productType,
|
'productType': productType,
|
||||||
|
'subspace': subspace?.toJson(), // serialize subspace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FunctionModel> getFunctions(DeviceType type) =>
|
List<FunctionModel> getFunctions(DeviceType type) =>
|
||||||
devicesFunctionsMap[productType] ?? [];
|
devicesFunctionsMap[productType] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeviceSubspace {
|
||||||
|
String? uuid;
|
||||||
|
DateTime? createdAt;
|
||||||
|
DateTime? updatedAt;
|
||||||
|
String? subspaceName;
|
||||||
|
bool? disabled;
|
||||||
|
|
||||||
|
DeviceSubspace({
|
||||||
|
this.uuid,
|
||||||
|
this.createdAt,
|
||||||
|
this.updatedAt,
|
||||||
|
this.subspaceName,
|
||||||
|
this.disabled,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory DeviceSubspace.fromJson(Map<String, dynamic> json) {
|
||||||
|
return DeviceSubspace(
|
||||||
|
uuid: json['uuid'],
|
||||||
|
createdAt: json['createdAt'] != null
|
||||||
|
? DateTime.tryParse(json['createdAt'])
|
||||||
|
: null,
|
||||||
|
updatedAt: json['updatedAt'] != null
|
||||||
|
? DateTime.tryParse(json['updatedAt'])
|
||||||
|
: null,
|
||||||
|
subspaceName: json['subspaceName'],
|
||||||
|
disabled: json['disabled'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'uuid': uuid,
|
||||||
|
'createdAt': createdAt?.toIso8601String(),
|
||||||
|
'updatedAt': updatedAt?.toIso8601String(),
|
||||||
|
'subspaceName': subspaceName,
|
||||||
|
'disabled': disabled,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,27 +1,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
|
|
||||||
class DoorSensorModel {
|
class DoorSensorModel {
|
||||||
bool doorContactState;
|
bool doorContactState;
|
||||||
int batteryPercentage;
|
int batteryPercentage;
|
||||||
|
|
||||||
DoorSensorModel(
|
DoorSensorModel({
|
||||||
{required this.doorContactState,
|
required this.doorContactState,
|
||||||
required this.batteryPercentage,
|
required this.batteryPercentage,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory DoorSensorModel.fromJson(List<StatusModel> jsonList) {
|
factory DoorSensorModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late bool _doorContactState;
|
bool _doorContactState = false;
|
||||||
late int _batteryPercentage;
|
int _batteryPercentage = 0;
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'doorcontact_state') {
|
if (jsonList[i].code == 'doorcontact_state') {
|
||||||
_doorContactState = jsonList[i].value ?? false;
|
_doorContactState = jsonList[i].value ?? false;
|
||||||
} else if (jsonList[i].code == 'battery_percentage') {
|
} else if (jsonList[i].code == 'battery_percentage') {
|
||||||
_batteryPercentage = jsonList[i].value ?? 0;
|
_batteryPercentage = jsonList[i].value ?? 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,15 +24,15 @@ class GarageDoorModel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory GarageDoorModel.fromJson(List<StatusModel> jsonList) {
|
factory GarageDoorModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late bool _switch1 = false;
|
bool _switch1 = false;
|
||||||
late bool _doorContactState = false;
|
bool _doorContactState = false;
|
||||||
late int _countdown1 = 0;
|
int _countdown1 = 0;
|
||||||
late int _countdownAlarm = 0;
|
int _countdownAlarm = 0;
|
||||||
late String _doorControl1 = "closed";
|
String _doorControl1 = "closed";
|
||||||
late bool _voiceControl1 = false;
|
bool _voiceControl1 = false;
|
||||||
late String _doorState1 = "closed";
|
String _doorState1 = "closed";
|
||||||
late int _batteryPercentage = 0;
|
int _batteryPercentage = 0;
|
||||||
late int _tr_timecon = 0;
|
int _tr_timecon = 0;
|
||||||
|
|
||||||
for (var status in jsonList) {
|
for (var status in jsonList) {
|
||||||
switch (status.code) {
|
switch (status.code) {
|
||||||
|
|||||||
@ -1,29 +1,27 @@
|
|||||||
|
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
|
|
||||||
class OneGangModel {
|
class OneGangModel {
|
||||||
bool firstSwitch;
|
bool firstSwitch;
|
||||||
int firstCountDown;
|
int firstCountDown;
|
||||||
|
|
||||||
OneGangModel(
|
OneGangModel({
|
||||||
{required this.firstSwitch,
|
required this.firstSwitch,
|
||||||
required this.firstCountDown,
|
required this.firstCountDown,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory OneGangModel.fromJson(List<StatusModel> jsonList) {
|
factory OneGangModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late bool _switch;
|
bool _switch = false;
|
||||||
late int _count;
|
int _count = 0;
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'switch_1') {
|
if (jsonList[i].code == 'switch_1') {
|
||||||
_switch = jsonList[i].value ?? false;
|
_switch = jsonList[i].value ?? false;
|
||||||
} else if (jsonList[i].code == 'countdown_1') {
|
} else if (jsonList[i].code == 'countdown_1') {
|
||||||
_count = jsonList[i].value ?? 0;
|
_count = jsonList[i].value ?? 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OneGangModel(
|
return OneGangModel(
|
||||||
firstSwitch: _switch,
|
firstSwitch: _switch,
|
||||||
firstCountDown: _count,
|
firstCountDown: _count,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
|
|
||||||
@ -15,15 +13,14 @@ class OneTouchModel {
|
|||||||
required this.firstCountDown,
|
required this.firstCountDown,
|
||||||
required this.light_mode,
|
required this.light_mode,
|
||||||
required this.relay,
|
required this.relay,
|
||||||
required this.relay_status_1
|
required this.relay_status_1});
|
||||||
});
|
|
||||||
|
|
||||||
factory OneTouchModel.fromJson(List<StatusModel> jsonList) {
|
factory OneTouchModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late bool _switch;
|
bool _switch = false;
|
||||||
late int _count;
|
int _count = 0;
|
||||||
late String _relay;
|
String _relay = '';
|
||||||
late String _light_mode;
|
String _light_mode = '';
|
||||||
late String relay_status_1;
|
String relay_status_1 = '';
|
||||||
|
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'switch_1') {
|
if (jsonList[i].code == 'switch_1') {
|
||||||
@ -41,10 +38,8 @@ class OneTouchModel {
|
|||||||
return OneTouchModel(
|
return OneTouchModel(
|
||||||
firstSwitch: _switch,
|
firstSwitch: _switch,
|
||||||
firstCountDown: _count,
|
firstCountDown: _count,
|
||||||
light_mode: lightStatusExtension.fromString(_light_mode) ,
|
light_mode: lightStatusExtension.fromString(_light_mode),
|
||||||
relay: StatusExtension.fromString(_relay ) ,
|
relay: StatusExtension.fromString(_relay),
|
||||||
relay_status_1: StatusExtension.fromString(relay_status_1 )
|
relay_status_1: StatusExtension.fromString(relay_status_1));
|
||||||
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,14 +22,14 @@ class SixSceneModel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory SixSceneModel.fromJson(List<StatusModel> jsonList) {
|
factory SixSceneModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late dynamic _scene_1;
|
dynamic _scene_1 = '';
|
||||||
late dynamic _scene_2;
|
dynamic _scene_2 = '';
|
||||||
late dynamic _scene_3;
|
dynamic _scene_3 = '';
|
||||||
late dynamic _scene_4;
|
dynamic _scene_4 = '';
|
||||||
late dynamic _scene_5;
|
dynamic _scene_5 = '';
|
||||||
late dynamic _scene_6;
|
dynamic _scene_6 = '';
|
||||||
late dynamic _scene_id_group_id;
|
dynamic _scene_id_group_id = 0;
|
||||||
late dynamic _switch_backlight;
|
dynamic _switch_backlight = false;
|
||||||
|
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'scene_1') {
|
if (jsonList[i].code == 'scene_1') {
|
||||||
|
|||||||
@ -39,23 +39,23 @@ class SmartDoorModel {
|
|||||||
required this.normalOpenSwitch});
|
required this.normalOpenSwitch});
|
||||||
|
|
||||||
factory SmartDoorModel.fromJson(List<StatusModel> jsonList) {
|
factory SmartDoorModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late int _unlockFingerprint;
|
int _unlockFingerprint = 0;
|
||||||
late int _unlockPassword;
|
int _unlockPassword = 0;
|
||||||
late int _unlockTemporary;
|
int _unlockTemporary = 0;
|
||||||
late int _unlockCard;
|
int _unlockCard = 0;
|
||||||
late String _unlockAlarm;
|
String _unlockAlarm = '';
|
||||||
late int _unlockRequest;
|
int _unlockRequest = 0;
|
||||||
late int _residualElectricity;
|
int _residualElectricity = 0;
|
||||||
late bool _reverseLock;
|
bool _reverseLock = false;
|
||||||
late int _unlockApp;
|
int _unlockApp = 0;
|
||||||
late bool _hijack;
|
bool _hijack = false;
|
||||||
late bool _doorbell;
|
bool _doorbell = false;
|
||||||
late String _unlockOfflinePd;
|
String _unlockOfflinePd = '';
|
||||||
late String _unlockOfflineClear;
|
String _unlockOfflineClear = '';
|
||||||
late String _unlockDoubleKit;
|
String _unlockDoubleKit = '';
|
||||||
late String _remoteNoPdSetkey;
|
String _remoteNoPdSetkey = '';
|
||||||
late String _remoteNoDpKey;
|
String _remoteNoDpKey = '';
|
||||||
late bool _normalOpenSwitch;
|
bool _normalOpenSwitch = false;
|
||||||
|
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'unlock_fingerprint') {
|
if (jsonList[i].code == 'unlock_fingerprint') {
|
||||||
|
|||||||
@ -10,8 +10,8 @@ class SosModel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory SosModel.fromJson(List<StatusModel> jsonList) {
|
factory SosModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late String _sosContactState;
|
String _sosContactState = '';
|
||||||
late int _batteryPercentage;
|
int _batteryPercentage = 0;
|
||||||
|
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'sos') {
|
if (jsonList[i].code == 'sos') {
|
||||||
|
|||||||
@ -9,17 +9,18 @@ class WallSensorModel {
|
|||||||
int currentDistance;
|
int currentDistance;
|
||||||
int illuminance;
|
int illuminance;
|
||||||
bool indicator;
|
bool indicator;
|
||||||
|
int noOneTime;
|
||||||
|
|
||||||
WallSensorModel({
|
WallSensorModel(
|
||||||
required this.presenceState,
|
{required this.presenceState,
|
||||||
required this.farDetection,
|
required this.farDetection,
|
||||||
required this.presenceTime,
|
required this.presenceTime,
|
||||||
required this.motionSensitivity,
|
required this.motionSensitivity,
|
||||||
required this.motionlessSensitivity,
|
required this.motionlessSensitivity,
|
||||||
required this.currentDistance,
|
required this.currentDistance,
|
||||||
required this.illuminance,
|
required this.illuminance,
|
||||||
required this.indicator,
|
required this.indicator,
|
||||||
});
|
required this.noOneTime});
|
||||||
|
|
||||||
factory WallSensorModel.fromJson(List<StatusModel> jsonList) {
|
factory WallSensorModel.fromJson(List<StatusModel> jsonList) {
|
||||||
late String _presenceState;
|
late String _presenceState;
|
||||||
@ -30,6 +31,7 @@ class WallSensorModel {
|
|||||||
late int _currentDistance;
|
late int _currentDistance;
|
||||||
late int _illuminance;
|
late int _illuminance;
|
||||||
late bool _indicator;
|
late bool _indicator;
|
||||||
|
late int _noOneTime;
|
||||||
|
|
||||||
for (int i = 0; i < jsonList.length; i++) {
|
for (int i = 0; i < jsonList.length; i++) {
|
||||||
if (jsonList[i].code == 'presence_state') {
|
if (jsonList[i].code == 'presence_state') {
|
||||||
@ -48,6 +50,8 @@ class WallSensorModel {
|
|||||||
_illuminance = jsonList[i].value ?? 0;
|
_illuminance = jsonList[i].value ?? 0;
|
||||||
} else if (jsonList[i].code == 'indicator') {
|
} else if (jsonList[i].code == 'indicator') {
|
||||||
_indicator = jsonList[i].value ?? false;
|
_indicator = jsonList[i].value ?? false;
|
||||||
|
} else if (jsonList[i].code == 'no_one_time') {
|
||||||
|
_noOneTime = jsonList[i].value ?? 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return WallSensorModel(
|
return WallSensorModel(
|
||||||
@ -58,6 +62,7 @@ class WallSensorModel {
|
|||||||
motionlessSensitivity: _motionlessSensitivity,
|
motionlessSensitivity: _motionlessSensitivity,
|
||||||
currentDistance: _currentDistance,
|
currentDistance: _currentDistance,
|
||||||
illuminance: _illuminance,
|
illuminance: _illuminance,
|
||||||
indicator: _indicator);
|
indicator: _indicator,
|
||||||
|
noOneTime: _noOneTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,8 +38,10 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
|
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
|
||||||
return state is DeviceSettingLoadingState
|
return state is DeviceSettingLoadingState
|
||||||
? const Center(
|
? const Center(
|
||||||
child:
|
child: DefaultContainer(
|
||||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator()),
|
||||||
)
|
)
|
||||||
: RefreshIndicator(
|
: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
@ -55,15 +57,18 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.sosHomeIcon,
|
Assets.sosHomeIcon,
|
||||||
fit: BoxFit.fitHeight,
|
fit: BoxFit.fitHeight,
|
||||||
height: MediaQuery.of(context).size.height * 0.13,
|
height:
|
||||||
|
MediaQuery.of(context).size.height * 0.13,
|
||||||
))
|
))
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
radius: 55,
|
radius: 55,
|
||||||
backgroundColor: ColorsManager.graysColor,
|
backgroundColor: ColorsManager.graysColor,
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment:
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
@ -71,7 +76,10 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
? Assets.fourSceneIcon
|
? Assets.fourSceneIcon
|
||||||
: Assets.sixSceneIcon,
|
: Assets.sixSceneIcon,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
height: MediaQuery.of(context).size.height * 0.08,
|
height: MediaQuery.of(context)
|
||||||
|
.size
|
||||||
|
.height *
|
||||||
|
0.08,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -89,7 +97,8 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
IntrinsicWidth(
|
IntrinsicWidth(
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 200),
|
constraints:
|
||||||
|
const BoxConstraints(maxWidth: 200),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
maxLength: 30,
|
maxLength: 30,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@ -122,7 +131,8 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
Assets.sosEditProfile,
|
Assets.sosEditProfile,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
height: MediaQuery.of(context).size.height * 0.02,
|
height: MediaQuery.of(context).size.height *
|
||||||
|
0.02,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -141,15 +151,17 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
bool? val = await Navigator.of(context).push(
|
if (HomeCubit.visitorPasswordManagement) {
|
||||||
MaterialPageRoute(
|
bool? val = await Navigator.of(context).push(
|
||||||
builder: (context) => LocationSettingPage(
|
MaterialPageRoute(
|
||||||
space: spaces!.first,
|
builder: (context) => LocationSettingPage(
|
||||||
deviceId: device?.uuid ?? '',
|
space: spaces!.first,
|
||||||
)),
|
deviceId: device?.uuid ?? '',
|
||||||
);
|
)),
|
||||||
if (val != null && val == true) {
|
);
|
||||||
_bloc.add(const DeviceSettingInitialInfo());
|
if (val != null && val == true) {
|
||||||
|
_bloc.add(const DeviceSettingInitialInfo());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -162,7 +174,8 @@ class SettingProfilePage extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
child: BodyMedium(
|
child: BodyMedium(
|
||||||
text: _bloc.deviceInfo.subspace.subspaceName,
|
text: _bloc
|
||||||
|
.deviceInfo.subspace.subspaceName,
|
||||||
fontColor: ColorsManager.textGray,
|
fontColor: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_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_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.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/ac_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_controls.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_controls.dart';
|
||||||
@ -71,6 +73,7 @@ class AcInterface extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<ACsBloc>(context)
|
BlocProvider.of<ACsBloc>(context)
|
||||||
.add(AcSwitch(acSwitch: statusModel.acSwitch));
|
.add(AcSwitch(acSwitch: statusModel.acSwitch));
|
||||||
|
|
||||||
},
|
},
|
||||||
child: SvgPicture.asset(Assets.acSwitchIcon))
|
child: SvgPicture.asset(Assets.acSwitchIcon))
|
||||||
],
|
],
|
||||||
|
|||||||
@ -43,6 +43,7 @@ class AcInterfaceControls extends StatelessWidget {
|
|||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
AcTimerPage(
|
AcTimerPage(
|
||||||
|
deviceStatus: deviceStatus,
|
||||||
device: deviceModel,
|
device: deviceModel,
|
||||||
deviceCode: deviceModel.type!,
|
deviceCode: deviceModel.type!,
|
||||||
switchCode: '',
|
switchCode: '',
|
||||||
|
|||||||
@ -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_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.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/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/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/custom_halfhour_timer_picker.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';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
@ -20,10 +20,13 @@ class AcTimerPage extends StatelessWidget {
|
|||||||
final DeviceModel device;
|
final DeviceModel device;
|
||||||
final String deviceCode;
|
final String deviceCode;
|
||||||
final String switchCode;
|
final String switchCode;
|
||||||
|
final AcStatusModel deviceStatus;
|
||||||
|
|
||||||
const AcTimerPage(
|
const AcTimerPage(
|
||||||
{required this.device,
|
{required this.device,
|
||||||
required this.deviceCode,
|
required this.deviceCode,
|
||||||
required this.switchCode,
|
required this.switchCode,
|
||||||
|
required this.deviceStatus,
|
||||||
super.key});
|
super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -37,27 +40,24 @@ class AcTimerPage extends StatelessWidget {
|
|||||||
create: (context) => ACsBloc(acId: device.uuid ?? ''),
|
create: (context) => ACsBloc(acId: device.uuid ?? ''),
|
||||||
child: BlocBuilder<ACsBloc, AcsState>(
|
child: BlocBuilder<ACsBloc, AcsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final oneGangBloc = BlocProvider.of<ACsBloc>(context);
|
final acBloc = BlocProvider.of<ACsBloc>(context);
|
||||||
Duration duration = Duration.zero;
|
Duration duration = Duration.zero;
|
||||||
int selectedValue = 0;
|
int selectedValue = 0;
|
||||||
|
|
||||||
int countNum = 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;
|
countNum = state.seconds;
|
||||||
} else if (state is TimerRunInProgress) {
|
} else if (state is TimerRunInProgress) {
|
||||||
countNum = state.remainingTime;
|
countNum = state.remainingTime;
|
||||||
} else if (state is TimerRunComplete) {
|
} else if (state is TimerRunComplete) {
|
||||||
countNum = 0;
|
countNum = 0;
|
||||||
}
|
}
|
||||||
// else if (state is LoadingNewSate) {
|
|
||||||
// countNum = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
onPopInvoked: (didPop) {
|
onPopInvoked: (didPop) {
|
||||||
if (!didPop) {
|
if (!didPop) {
|
||||||
oneGangBloc.add(OnClose());
|
acBloc.add(OnClose());
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -90,7 +90,7 @@ class AcTimerPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: SizedBox(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
MainAxisAlignment.center,
|
MainAxisAlignment.center,
|
||||||
@ -102,7 +102,7 @@ class AcTimerPage extends StatelessWidget {
|
|||||||
.slidingBlueColor,
|
.slidingBlueColor,
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
)
|
)
|
||||||
: Container(
|
: SizedBox(
|
||||||
child: CustomHalfHourPicker(
|
child: CustomHalfHourPicker(
|
||||||
onValueChanged: (value) {
|
onValueChanged: (value) {
|
||||||
selectedValue =
|
selectedValue =
|
||||||
@ -120,8 +120,6 @@ class AcTimerPage extends StatelessWidget {
|
|||||||
countNum =
|
countNum =
|
||||||
duration.inSeconds;
|
duration.inSeconds;
|
||||||
}
|
}
|
||||||
print(
|
|
||||||
"Selected Value: $selectedValue, Duration: $duration");
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -131,12 +129,14 @@ class AcTimerPage extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (countNum > 0) {
|
if (countNum > 0) {
|
||||||
oneGangBloc.add(SetCounterValue(
|
acBloc.add(SetCounterValue(
|
||||||
seconds: countNum,
|
seconds: countNum,
|
||||||
deviceCode:'countdown_time',
|
deviceCode:
|
||||||
|
'countdown_time',
|
||||||
duration: selectedValue));
|
duration: selectedValue));
|
||||||
} else if (duration != Duration.zero) {
|
} else if (duration !=
|
||||||
oneGangBloc.add(SetCounterValue(
|
Duration.zero) {
|
||||||
|
acBloc.add(SetCounterValue(
|
||||||
seconds: 0,
|
seconds: 0,
|
||||||
deviceCode:
|
deviceCode:
|
||||||
'countdown_time',
|
'countdown_time',
|
||||||
|
|||||||
@ -31,7 +31,7 @@ class ACsList extends StatelessWidget {
|
|||||||
List<DeviceModel> devicesList = [];
|
List<DeviceModel> devicesList = [];
|
||||||
bool allOn = false;
|
bool allOn = false;
|
||||||
bool allTempSame = false;
|
bool allTempSame = false;
|
||||||
int temperature = 20;
|
int temperature = 250;
|
||||||
if (state is GetAllAcsStatusState) {
|
if (state is GetAllAcsStatusState) {
|
||||||
devicesStatuesList = state.allAcsStatues;
|
devicesStatuesList = state.allAcsStatues;
|
||||||
devicesList = state.allAcs;
|
devicesList = state.allAcs;
|
||||||
|
|||||||
@ -22,9 +22,8 @@ class ACsView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
print("ACsView deviceModel UUID: ${deviceModel?.uuid}");
|
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
|
|
||||||
create: (context) => ACsBloc(acId: deviceModel?.uuid ?? '')
|
create: (context) => ACsBloc(acId: deviceModel?.uuid ?? '')
|
||||||
..add(AcsInitial(allAcs: deviceModel != null ? false : true)),
|
..add(AcsInitial(allAcs: deviceModel != null ? false : true)),
|
||||||
child: BlocBuilder<ACsBloc, AcsState>(
|
child: BlocBuilder<ACsBloc, AcsState>(
|
||||||
@ -40,6 +39,7 @@ class ACsView extends StatelessWidget {
|
|||||||
extendBody: true,
|
extendBody: true,
|
||||||
appBar: deviceModel != null
|
appBar: deviceModel != null
|
||||||
? DeviceAppbar(
|
? DeviceAppbar(
|
||||||
|
value: true,
|
||||||
deviceName: deviceModel!.name!,
|
deviceName: deviceModel!.name!,
|
||||||
deviceUuid: deviceModel!.uuid!,
|
deviceUuid: deviceModel!.uuid!,
|
||||||
)
|
)
|
||||||
|
|||||||
110
lib/features/devices/view/widgets/all_devices.dart
Normal file
110
lib/features/devices/view/widgets/all_devices.dart
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
|
class AllDevices extends StatefulWidget {
|
||||||
|
const AllDevices({super.key, required this.allDevices});
|
||||||
|
|
||||||
|
final List<DeviceModel> allDevices;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AllDevicesState createState() => _AllDevicesState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AllDevicesState extends State<AllDevices> {
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
List<DeviceModel> _filteredDevices = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_filteredDevices = widget.allDevices ?? [];
|
||||||
|
_searchController.addListener(_filterDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_searchController.removeListener(_filterDevices);
|
||||||
|
_searchController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _filterDevices() {
|
||||||
|
final query = _searchController.text.toLowerCase();
|
||||||
|
setState(() {
|
||||||
|
_filteredDevices = widget.allDevices!
|
||||||
|
.where((device) => device.name!.toLowerCase().contains(query))
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
if (widget.allDevices.isNotEmpty)
|
||||||
|
TextFormField(
|
||||||
|
controller: _searchController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Search',
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
prefixIcon: Container(
|
||||||
|
padding: const EdgeInsets.all(5.0),
|
||||||
|
margin: const EdgeInsets.all(10.0),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.searchIcon,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_filteredDevices.isNotEmpty
|
||||||
|
? Expanded(
|
||||||
|
child: GridView.builder(
|
||||||
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
crossAxisSpacing: 10,
|
||||||
|
mainAxisSpacing: 10,
|
||||||
|
childAspectRatio: 1.5,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
itemCount: _filteredDevices.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return RoomPageSwitch(
|
||||||
|
allDevices: _filteredDevices,
|
||||||
|
isAllDevices: true,
|
||||||
|
device: _filteredDevices[index]);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: widget.allDevices.isNotEmpty
|
||||||
|
? const Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
'No Results Found',
|
||||||
|
style: TextStyle(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -250,7 +250,9 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
] else if (button['title'] == 'Space Type') ...[
|
] else if (button['title'] == 'Space Type') ...[
|
||||||
Text(
|
Text(
|
||||||
model.spaceType.name.toString(),
|
model.spaceType.name.toString() == "none"
|
||||||
|
? "Office"
|
||||||
|
: model.spaceType.name.toString(),
|
||||||
style: const TextStyle(color: Colors.black),
|
style: const TextStyle(color: Colors.black),
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
@ -299,7 +301,13 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
bloc.add(ChangeValueEvent(
|
bloc.add(ChangeValueEvent(
|
||||||
type: title.toString(), value: result, code: 'nobody_time'));
|
type: title.toString(),
|
||||||
|
value: result
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.replaceAll('sec', 's')
|
||||||
|
.replaceAll('1hr', '1hour'),
|
||||||
|
code: 'nobody_time'));
|
||||||
}
|
}
|
||||||
} else if (title == 'Maximum Distance') {
|
} else if (title == 'Maximum Distance') {
|
||||||
final result = await _showDialog(
|
final result = await _showDialog(
|
||||||
@ -324,7 +332,7 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
title: title.toString(),
|
title: title.toString(),
|
||||||
sensor: ceilingSensor,
|
sensor: ceilingSensor,
|
||||||
value: model.sensitivity,
|
value: model.sensitivity,
|
||||||
min: 0,
|
min: 1,
|
||||||
max: 10,
|
max: 10,
|
||||||
));
|
));
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@ -336,7 +344,7 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => const CeilingHelpDescription()),
|
MaterialPageRoute(builder: (context) => const CeilingHelpDescription()),
|
||||||
);
|
);
|
||||||
} else if (title == 'Induction History') {
|
} else if (title == 'Presence Record') {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@ -385,7 +393,7 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
'val': nobodyTimeVal,
|
'val': nobodyTimeVal,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Induction History',
|
'title': 'Presence Record',
|
||||||
'icon': Assets.assetsIconsPresenceSensorAssetsInductionRecording,
|
'icon': Assets.assetsIconsPresenceSensorAssetsInductionRecording,
|
||||||
'page': null,
|
'page': null,
|
||||||
'withArrow': false,
|
'withArrow': false,
|
||||||
|
|||||||
@ -31,12 +31,12 @@ class MaxDistanceControl extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int _parseValue(String value) {
|
int _parseValue(String value) {
|
||||||
if (value.endsWith('sec')) {
|
if (value.endsWith('s')) {
|
||||||
return int.parse(value.replaceAll('sec', '').trim());
|
return int.parse(value.replaceAll('s', '').trim());
|
||||||
} else if (value.endsWith('min')) {
|
} else if (value.endsWith('min')) {
|
||||||
return int.parse(value.replaceAll('min', '').trim()) * 60;
|
return int.parse(value.replaceAll('min', '').trim()) * 60;
|
||||||
} else if (value.endsWith('hr')) {
|
} else if (value.endsWith('hour')) {
|
||||||
return int.parse(value.replaceAll('hr', '').trim()) * 3600;
|
return int.parse(value.replaceAll('hour', '').trim()) * 3600;
|
||||||
}
|
}
|
||||||
return 0; // Default to 0 if the format is unrecognized
|
return 0; // Default to 0 if the format is unrecognized
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ class MaxDistanceControlState extends State<MaxDistanceControl> {
|
|||||||
|
|
||||||
String _formatLabel(double seconds) {
|
String _formatLabel(double seconds) {
|
||||||
if (seconds == 0) return 'None';
|
if (seconds == 0) return 'None';
|
||||||
if (seconds < 60) return '${seconds.toInt()}sec';
|
if (seconds < 60) return '${seconds.toInt()}s';
|
||||||
if (seconds < 3600) {
|
if (seconds < 3600) {
|
||||||
final minutes = (seconds / 60).round();
|
final minutes = (seconds / 60).round();
|
||||||
return '${minutes}min';
|
return '${minutes}min';
|
||||||
@ -90,7 +90,6 @@ class MaxDistanceControlState extends State<MaxDistanceControl> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final double currentSeconds = _stepValues[_currentIndex];
|
final double currentSeconds = _stepValues[_currentIndex];
|
||||||
|
|
||||||
return Dialog(
|
return Dialog(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -128,7 +127,9 @@ class MaxDistanceControlState extends State<MaxDistanceControl> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
TitleMedium(
|
TitleMedium(
|
||||||
text: _formatLabel(currentSeconds),
|
text: _formatLabel(currentSeconds)
|
||||||
|
.replaceAll('1hr', '1hour')
|
||||||
|
.replaceAllMapped(RegExp(r's$'), (match) => 'sec'),
|
||||||
style: context.titleMedium.copyWith(
|
style: context.titleMedium.copyWith(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: FontsManager.bold,
|
fontWeight: FontsManager.bold,
|
||||||
|
|||||||
@ -90,9 +90,7 @@ class PresenceRecord extends StatelessWidget {
|
|||||||
: Colors.grey,
|
: Colors.grey,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
record.value == 'true'
|
record.value.toString(),
|
||||||
? "Opened"
|
|
||||||
: "Closed",
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
|
|||||||
@ -106,12 +106,11 @@ class _PresenceSpaceTypeDialogState extends State<PresenceSpaceTypeDialog> {
|
|||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
icon,
|
icon,
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
title,
|
title == "None" ? "Office" : title,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodySmall
|
.bodySmall
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dar
|
|||||||
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_buttons.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_buttons.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
@ -33,11 +34,17 @@ class CurtainView extends StatelessWidget {
|
|||||||
// blindHeight = state.blindHeight;
|
// blindHeight = state.blindHeight;
|
||||||
}
|
}
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
|
appBar: DeviceAppbar(
|
||||||
|
deviceName: curtain!.name!,
|
||||||
|
deviceUuid: curtain!.uuid!,
|
||||||
|
),
|
||||||
title: curtain.name,
|
title: curtain.name,
|
||||||
child: state is CurtainLoadingState
|
child: state is CurtainLoadingState
|
||||||
? const Center(
|
? const Center(
|
||||||
child:
|
child: DefaultContainer(
|
||||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator()),
|
||||||
)
|
)
|
||||||
: RefreshIndicator(
|
: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
@ -62,37 +69,56 @@ class CurtainView extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
Assets.assetsIconsCurtainsIconCurtainHolder,
|
Assets.assetsIconsCurtainsIconCurtainHolder,
|
||||||
width: MediaQuery.sizeOf(context).width * 0.75,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width * 0.75,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.75,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width * 0.75,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.025,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.025,
|
||||||
),
|
),
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration:
|
||||||
|
const Duration(milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
height: MediaQuery.sizeOf(context).height * 0.35,
|
height: MediaQuery.sizeOf(context)
|
||||||
width: MediaQuery.sizeOf(context).width * 0.35,
|
.height *
|
||||||
|
0.35,
|
||||||
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.35,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
4,
|
4,
|
||||||
(index) {
|
(index) {
|
||||||
double spacing = curtainWidth / 7.5;
|
double spacing =
|
||||||
double leftMostPosition = index * spacing;
|
curtainWidth / 7.5;
|
||||||
|
double leftMostPosition =
|
||||||
|
index * spacing;
|
||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(
|
||||||
|
milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
left: leftMostPosition,
|
left: leftMostPosition,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height:
|
height: MediaQuery.sizeOf(
|
||||||
MediaQuery.sizeOf(context).height * 0.35,
|
context)
|
||||||
width: MediaQuery.sizeOf(context).width * 0.08,
|
.height *
|
||||||
|
0.35,
|
||||||
|
width: MediaQuery.sizeOf(
|
||||||
|
context)
|
||||||
|
.width *
|
||||||
|
0.08,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.assetsIconsCurtainsIconVerticalBlade,
|
Assets
|
||||||
|
.assetsIconsCurtainsIconVerticalBlade,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -102,23 +128,37 @@ class CurtainView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration:
|
||||||
|
const Duration(milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
height: MediaQuery.sizeOf(context).height * 0.35,
|
height: MediaQuery.sizeOf(context)
|
||||||
width: MediaQuery.sizeOf(context).width * 0.35,
|
.height *
|
||||||
|
0.35,
|
||||||
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.35,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
4,
|
4,
|
||||||
(index) {
|
(index) {
|
||||||
double spacing = curtainWidth / 7.5;
|
double spacing =
|
||||||
double rightMostPosition = index * spacing;
|
curtainWidth / 7.5;
|
||||||
|
double rightMostPosition =
|
||||||
|
index * spacing;
|
||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(
|
||||||
|
milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
right: rightMostPosition,
|
right: rightMostPosition,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: MediaQuery.sizeOf(context).height * 0.35,
|
height: MediaQuery.sizeOf(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.08,
|
context)
|
||||||
|
.height *
|
||||||
|
0.35,
|
||||||
|
width: MediaQuery.sizeOf(
|
||||||
|
context)
|
||||||
|
.width *
|
||||||
|
0.08,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.rightVerticalBlade,
|
Assets.rightVerticalBlade,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
@ -130,7 +170,9 @@ class CurtainView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.025,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.025,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
@ -6,14 +7,27 @@ import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
|||||||
class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget {
|
class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
final String deviceName;
|
final String deviceName;
|
||||||
final String deviceUuid;
|
final String deviceUuid;
|
||||||
|
final bool? value;
|
||||||
|
|
||||||
final double appBarHeight = 56.0;
|
final double appBarHeight = 56.0;
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
const DeviceAppbar(
|
const DeviceAppbar(
|
||||||
{super.key, required this.deviceName, required this.deviceUuid, this.onPressed});
|
{super.key,
|
||||||
|
required this.deviceName,
|
||||||
|
this.value,
|
||||||
|
required this.deviceUuid,
|
||||||
|
this.onPressed});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppBar(
|
return AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(value ?? true);
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
Platform.isIOS ? Icons.arrow_back_ios : Icons.arrow_back,
|
||||||
|
)),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
title: BodyLarge(
|
title: BodyLarge(
|
||||||
|
|||||||
@ -3,10 +3,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/bloc/home_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/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/room_page.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
|
|
||||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
@ -14,103 +14,120 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.da
|
|||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||||
|
|
||||||
class DevicesViewPage extends StatelessWidget {
|
|
||||||
const DevicesViewPage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocProvider(
|
|
||||||
create: (context) => SceneBloc(), // Initialize your SceneBloc here
|
|
||||||
child: DevicesViewBody(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DevicesViewBody extends StatelessWidget {
|
class DevicesViewBody extends StatelessWidget {
|
||||||
const DevicesViewBody({
|
const DevicesViewBody({super.key});
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
return BlocBuilder<HomeCubit, HomeState>(
|
||||||
builder: (context, state) {
|
builder: (context, homeState) {
|
||||||
if (state is DevicesLoading ||
|
final homeCubit = HomeCubit.getInstance();
|
||||||
state is GetDevicesLoading ||
|
// Handle state priority: Errors first
|
||||||
state is DevicesCategoriesLoading) {
|
if (homeState is ActivationError) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const CreateUnitWidget();
|
||||||
} else {
|
|
||||||
return HomeCubit.getInstance().spaces?.isEmpty ?? true
|
|
||||||
? const CreateUnitWidget()
|
|
||||||
: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
TitleMedium(
|
|
||||||
text: StringsManager.devices,
|
|
||||||
style: context.titleMedium.copyWith(
|
|
||||||
fontSize: 25,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: MediaQuery.of(context).size.height * 0.1,
|
|
||||||
child: const SceneView(
|
|
||||||
pageType: true,
|
|
||||||
)),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
const RoomsSlider(),
|
|
||||||
const SizedBox(
|
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: PageView(
|
|
||||||
controller: HomeCubit.getInstance().devicesPageController,
|
|
||||||
onPageChanged: (index) {
|
|
||||||
HomeCubit.getInstance().devicesPageChanged(index);
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
WizardPage(
|
|
||||||
groupsList: DevicesCubit.getInstance().allCategories ?? [],
|
|
||||||
),
|
|
||||||
if (HomeCubit.getInstance().selectedSpace != null)
|
|
||||||
...HomeCubit.getInstance().selectedSpace!.subspaces.map(
|
|
||||||
(room) {
|
|
||||||
return RoomPage(
|
|
||||||
room: room,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
HomeCubit.getInstance().selectedSpace != null
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 7,
|
|
||||||
),
|
|
||||||
child: SmoothPageIndicator(
|
|
||||||
controller: HomeCubit.getInstance().devicesPageController,
|
|
||||||
count: HomeCubit.getInstance().selectedSpace!.subspaces.length + 1,
|
|
||||||
effect: const WormEffect(
|
|
||||||
paintStyle: PaintingStyle.stroke,
|
|
||||||
dotHeight: 8,
|
|
||||||
dotWidth: 8,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: const Center(
|
|
||||||
child: BodyLarge(text: 'No Home Found'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
// 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 GetSpaceRoomsSuccess) {
|
||||||
|
// Show empty state if no spaces
|
||||||
|
if (homeCubit.spaces.isEmpty) {
|
||||||
|
return const CreateUnitWidget();
|
||||||
|
}
|
||||||
|
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||||
|
builder: (context, devicesState) {
|
||||||
|
// Devices loading states
|
||||||
|
if (devicesState is DevicesLoading ||
|
||||||
|
devicesState is DevicesCategoriesLoading ||
|
||||||
|
devicesState is GetDevicesLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
// Devices error state
|
||||||
|
if (devicesState is GetDevicesError) {
|
||||||
|
return Center(child: BodyLarge(text: devicesState.errorMsg));
|
||||||
|
}
|
||||||
|
// Main content for both GetSpacesSuccess and RoomUnSelected
|
||||||
|
return _buildMainContent(context, homeCubit);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Fallback for unknown states
|
||||||
|
return const Center(child: BodyLarge(text: ''));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildMainContent(BuildContext context, HomeCubit homeCubit) {
|
||||||
|
final devicesCubit = context.read<DevicesCubit>();
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
TitleMedium(
|
||||||
|
text: StringsManager.devices,
|
||||||
|
style: context.titleMedium.copyWith(fontSize: 25),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SceneView(pageType: true),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
const RoomsSlider(),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Expanded(
|
||||||
|
child: PageView(
|
||||||
|
controller: homeCubit.devicesPageController,
|
||||||
|
onPageChanged: (index) {
|
||||||
|
homeCubit.devicesPageChanged(index);
|
||||||
|
if (index == 0) {
|
||||||
|
devicesCubit.fetchAllDevices(homeCubit.selectedSpace);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
AllDevices(
|
||||||
|
allDevices: devicesCubit.allDevices,
|
||||||
|
),
|
||||||
|
WizardPage(
|
||||||
|
groupsList: devicesCubit.allCategories ?? [],
|
||||||
|
),
|
||||||
|
if (homeCubit.selectedSpace != null)
|
||||||
|
...homeCubit.selectedSpace!.subspaces.map(
|
||||||
|
(room) => RoomPage(room: room),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_buildPageIndicator(homeCubit),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPageIndicator(HomeCubit homeCubit) {
|
||||||
|
return homeCubit.selectedSpace != null
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 7),
|
||||||
|
child: SmoothPageIndicator(
|
||||||
|
controller: homeCubit.devicesPageController,
|
||||||
|
count: homeCubit.selectedSpace!.subspaces.length + 2,
|
||||||
|
effect: const WormEffect(
|
||||||
|
paintStyle: PaintingStyle.stroke,
|
||||||
|
dotHeight: 8,
|
||||||
|
dotWidth: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Center(
|
||||||
|
child: BodyLarge(text: 'No Home Found'),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -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';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
|
|
||||||
class GarageList extends StatelessWidget {
|
class GarageList extends StatelessWidget {
|
||||||
const GarageList(
|
const GarageList({super.key, required this.garageList, required this.allSwitches});
|
||||||
{super.key, required this.garageList, required this.allSwitches});
|
|
||||||
|
|
||||||
final List<GroupGarageModel> garageList;
|
final List<GroupGarageModel> garageList;
|
||||||
final bool allSwitches;
|
final bool allSwitches;
|
||||||
@ -23,43 +22,42 @@ class GarageList extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
const BodySmall(text: 'All Lights'),
|
const BodySmall(text: 'All Garages'),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
DevicesDefaultSwitch(
|
DevicesDefaultSwitch(
|
||||||
off: 'OFF',
|
off: 'Close',
|
||||||
on: 'ON',
|
on: 'Open',
|
||||||
switchValue: allSwitches,
|
switchValue: allSwitches,
|
||||||
action: () {
|
action: () => BlocProvider.of<GarageDoorBloc>(context).add(
|
||||||
BlocProvider.of<GarageDoorBloc>(context)
|
GroupAllOnEvent(),
|
||||||
.add(GroupAllOnEvent());
|
),
|
||||||
},
|
secondAction: () => BlocProvider.of<GarageDoorBloc>(context).add(
|
||||||
secondAction: () {
|
GroupAllOffEvent(),
|
||||||
BlocProvider.of<GarageDoorBloc>(context)
|
),
|
||||||
.add(GroupAllOffEvent());
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListView.builder(
|
ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
padding: const EdgeInsets.all(0),
|
padding: EdgeInsetsDirectional.zero,
|
||||||
itemCount: garageList.length,
|
itemCount: garageList.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
final garageDoor = garageList[index];
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
BodySmall(text: garageList[index].deviceName),
|
BodySmall(text: garageDoor.deviceName),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
DevicesDefaultSwitch(
|
DevicesDefaultSwitch(
|
||||||
off: 'OFF',
|
off: 'Close',
|
||||||
on: 'ON',
|
on: 'Open',
|
||||||
switchValue: garageList[index].firstSwitch,
|
switchValue: garageDoor.firstSwitch,
|
||||||
action: () {
|
action: () => BlocProvider.of<GarageDoorBloc>(context).add(
|
||||||
BlocProvider.of<GarageDoorBloc>(context).add(
|
ChangeFirstWizardSwitchStatusEvent(
|
||||||
ChangeFirstWizardSwitchStatusEvent(
|
value: garageDoor.firstSwitch,
|
||||||
value: garageList[index].firstSwitch,
|
deviceId: garageDoor.deviceId,
|
||||||
deviceId: garageList[index].deviceId));
|
),
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -20,8 +20,9 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => OneGangBloc(switchCode: 'switch_1', oneGangId: device?.uuid ?? '')
|
create: (context) =>
|
||||||
..add(const InitialEvent(groupScreen: false)),
|
OneGangBloc(switchCode: 'switch_1', oneGangId: device?.uuid ?? '')
|
||||||
|
..add(const InitialEvent(groupScreen: false)),
|
||||||
child: BlocBuilder<OneGangBloc, OneGangState>(
|
child: BlocBuilder<OneGangBloc, OneGangState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
OneGangModel oneGangModel = OneGangModel(
|
OneGangModel oneGangModel = OneGangModel(
|
||||||
@ -36,13 +37,15 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
return state is LoadingInitialState
|
return state is LoadingInitialState
|
||||||
? const Center(
|
? const Center(
|
||||||
child:
|
child: DefaultContainer(
|
||||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator()),
|
||||||
)
|
)
|
||||||
: RefreshIndicator(
|
: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
BlocProvider.of<OneGangBloc>(context)
|
BlocProvider.of<OneGangBloc>(context).add(InitialEvent(
|
||||||
.add(InitialEvent(groupScreen: device != null ? false : true));
|
groupScreen: device != null ? false : true));
|
||||||
},
|
},
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
@ -55,7 +58,8 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
const Expanded(child: SizedBox.shrink()),
|
const Expanded(child: SizedBox.shrink()),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceAround,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
@ -64,9 +68,10 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
threeGangSwitch: device!,
|
threeGangSwitch: device!,
|
||||||
value: oneGangModel.firstSwitch,
|
value: oneGangModel.firstSwitch,
|
||||||
action: () {
|
action: () {
|
||||||
BlocProvider.of<OneGangBloc>(context).add(
|
BlocProvider.of<OneGangBloc>(context)
|
||||||
ChangeFirstSwitchStatusEvent(
|
.add(ChangeFirstSwitchStatusEvent(
|
||||||
value: oneGangModel.firstSwitch));
|
value: oneGangModel
|
||||||
|
.firstSwitch));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
@ -74,7 +79,8 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
width: 70,
|
width: 70,
|
||||||
child: BodySmall(
|
child: BodySmall(
|
||||||
text: " Entrance Light",
|
text: " Entrance Light",
|
||||||
fontColor: ColorsManager.textPrimaryColor,
|
fontColor:
|
||||||
|
ColorsManager.textPrimaryColor,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -94,20 +100,24 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
Card(
|
Card(
|
||||||
elevation: 3,
|
elevation: 3,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(100),
|
borderRadius:
|
||||||
|
BorderRadius.circular(100),
|
||||||
),
|
),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder:
|
pageBuilder: (context,
|
||||||
(context, animation1, animation2) =>
|
animation1,
|
||||||
TimerScheduleScreen(
|
animation2) =>
|
||||||
switchCode: 'switch_1',
|
TimerScheduleScreen(
|
||||||
device: device!,
|
switchCode:
|
||||||
deviceCode: 'countdown_1',
|
'switch_1',
|
||||||
)));
|
device: device!,
|
||||||
|
deviceCode:
|
||||||
|
'countdown_1',
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
@ -117,7 +127,9 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey[300],
|
color: Colors.grey[300],
|
||||||
borderRadius: BorderRadius.circular(100),
|
borderRadius:
|
||||||
|
BorderRadius.circular(
|
||||||
|
100),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
@ -125,12 +137,15 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
height: 40,
|
height: 40,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(100),
|
borderRadius:
|
||||||
|
BorderRadius.circular(
|
||||||
|
100),
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.access_time,
|
Icons.access_time,
|
||||||
color: ColorsManager.primaryColorWithOpacity,
|
color: ColorsManager
|
||||||
|
.primaryColorWithOpacity,
|
||||||
size: 25,
|
size: 25,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.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/bloc/devices_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart';
|
||||||
@ -28,23 +29,31 @@ import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interf
|
|||||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/water_heater/water_heater_page.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/water_heater/water_heater_page.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/water_leak/water_leak_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/water_leak/water_leak_screen.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
|
|
||||||
class RoomPageSwitch extends StatelessWidget {
|
class RoomPageSwitch extends StatelessWidget {
|
||||||
const RoomPageSwitch({
|
const RoomPageSwitch(
|
||||||
super.key,
|
{super.key,
|
||||||
required this.device,
|
required this.device,
|
||||||
});
|
this.isAllDevices = false,
|
||||||
|
this.allDevices});
|
||||||
|
|
||||||
final DeviceModel device;
|
final DeviceModel device;
|
||||||
|
final List<DeviceModel>? allDevices;
|
||||||
|
final bool isAllDevices;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDeviceInterface(device, context);
|
showDeviceInterface(
|
||||||
|
device: device,
|
||||||
|
context: context,
|
||||||
|
isAllDevices: isAllDevices,
|
||||||
|
allDevices: allDevices);
|
||||||
},
|
},
|
||||||
child: DefaultContainer(
|
child: DefaultContainer(
|
||||||
padding: const EdgeInsets.all(15),
|
padding: const EdgeInsets.all(15),
|
||||||
@ -60,23 +69,52 @@ class RoomPageSwitch extends StatelessWidget {
|
|||||||
device.icon!,
|
device.icon!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
// CustomSwitch(
|
isAllDevices
|
||||||
// device: device,
|
? CustomSwitch(
|
||||||
// ),
|
device: device,
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Flexible(
|
LayoutBuilder(
|
||||||
child: FittedBox(
|
builder: (context, constraints) {
|
||||||
child: Text(
|
final text = device.name ?? "";
|
||||||
device.name ?? "",
|
final textPainter = TextPainter(
|
||||||
overflow: TextOverflow.ellipsis,
|
text: TextSpan(
|
||||||
maxLines: 2,
|
text: text,
|
||||||
|
style: context.bodyLarge.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
);
|
||||||
|
|
||||||
|
textPainter.layout(maxWidth: constraints.maxWidth);
|
||||||
|
|
||||||
|
final exceeded = textPainter.didExceedMaxLines;
|
||||||
|
|
||||||
|
return Text(
|
||||||
|
exceeded ? '${text.substring(0, 10)}...' : text,
|
||||||
style: context.bodyLarge.copyWith(
|
style: context.bodyLarge.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
overflow: TextOverflow.clip,
|
||||||
|
maxLines: 1,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
device.subspace!.subspaceName ?? '',
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: context.bodySmall.copyWith(
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontSize: 10,
|
||||||
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -89,14 +127,24 @@ class RoomPageSwitch extends StatelessWidget {
|
|||||||
/// Shows the device interface based on the product type of the device.
|
/// Shows the device interface based on the product type of the device.
|
||||||
///
|
///
|
||||||
/// The [device] parameter represents the device model.
|
/// The [device] parameter represents the device model.
|
||||||
void showDeviceInterface(DeviceModel device, BuildContext context) {
|
Future<void> showDeviceInterface(
|
||||||
|
{required DeviceModel device,
|
||||||
|
required BuildContext context,
|
||||||
|
required isAllDevices,
|
||||||
|
List<DeviceModel>? allDevices}) async {
|
||||||
|
|
||||||
|
final devicesCubit = context.read<DevicesCubit>();
|
||||||
|
|
||||||
switch (device.productType) {
|
switch (device.productType) {
|
||||||
case DeviceType.AC:
|
case DeviceType.AC:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
ACsView(deviceModel: device)));
|
ACsView(deviceModel: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
// navigateToInterface(ACsView(deviceModel: device), context);
|
// navigateToInterface(ACsView(deviceModel: device), context);
|
||||||
break;
|
break;
|
||||||
case DeviceType.WallSensor:
|
case DeviceType.WallSensor:
|
||||||
@ -116,12 +164,15 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
// navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
|
// navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
|
||||||
break;
|
break;
|
||||||
case DeviceType.Curtain:
|
case DeviceType.Curtain:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => CurtainView(
|
pageBuilder: (context, animation1, animation2) => CurtainView(
|
||||||
curtain: device,
|
curtain: device,
|
||||||
)));
|
)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DeviceType.Blind:
|
case DeviceType.Blind:
|
||||||
break;
|
break;
|
||||||
@ -143,30 +194,43 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
case DeviceType.LightBulb:
|
case DeviceType.LightBulb:
|
||||||
navigateToInterface(LightInterface(light: device), context);
|
navigateToInterface(LightInterface(light: device), context);
|
||||||
case DeviceType.OneGang:
|
case DeviceType.OneGang:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
OneGangInterface(gangSwitch: device)));
|
OneGangInterface(gangSwitch: device)));
|
||||||
|
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.TwoGang:
|
case DeviceType.TwoGang:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
TwoGangInterface(gangSwitch: device)));
|
TwoGangInterface(gangSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.ThreeGang:
|
case DeviceType.ThreeGang:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
ThreeGangInterface(gangSwitch: device)));
|
ThreeGangInterface(gangSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.WH:
|
case DeviceType.WH:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
WaterHeaterPage(device: device)));
|
WaterHeaterPage(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.DS:
|
case DeviceType.DS:
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
@ -182,31 +246,43 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
PowerClampPage(device: device)));
|
PowerClampPage(device: device)));
|
||||||
|
|
||||||
case DeviceType.OneTouch:
|
case DeviceType.OneTouch:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
OneTouchScreen(device: device)));
|
OneTouchScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.TowTouch:
|
case DeviceType.TowTouch:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
TwoTouchInterface(touchSwitch: device)));
|
TwoTouchInterface(touchSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.ThreeTouch:
|
case DeviceType.ThreeTouch:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
ThreeTouchInterface(touchSwitch: device)));
|
ThreeTouchInterface(touchSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.GarageDoor:
|
case DeviceType.GarageDoor:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
GarageDoorScreen(device: device)));
|
GarageDoorScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.WaterLeak:
|
case DeviceType.WaterLeak:
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -216,18 +292,24 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
WaterLeakScreen(device: device)));
|
WaterLeakScreen(device: device)));
|
||||||
|
|
||||||
case DeviceType.SixScene:
|
case DeviceType.SixScene:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
SixSceneScreen(device: device)));
|
SixSceneScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.FourScene:
|
case DeviceType.FourScene:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
FourSceneScreen(device: device)));
|
FourSceneScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.SOS:
|
case DeviceType.SOS:
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|||||||
@ -23,6 +23,21 @@ class RoomsSlider extends StatelessWidget {
|
|||||||
HomeCubit.getInstance().roomSliderPageChanged(index);
|
HomeCubit.getInstance().roomSliderPageChanged(index);
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
HomeCubit.getInstance().unselectRoom();
|
||||||
|
},
|
||||||
|
child: TitleMedium(
|
||||||
|
text: 'All Devices',
|
||||||
|
style: context.titleMedium.copyWith(
|
||||||
|
fontSize: 25,
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
@ -43,7 +58,10 @@ class RoomsSlider extends StatelessWidget {
|
|||||||
(room) => InkWell(
|
(room) => InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
HomeCubit.getInstance().roomSliderPageChanged(
|
HomeCubit.getInstance().roomSliderPageChanged(
|
||||||
HomeCubit.getInstance().selectedSpace!.subspaces.indexOf(room));
|
HomeCubit.getInstance()
|
||||||
|
.selectedSpace!
|
||||||
|
.subspaces
|
||||||
|
.indexOf(room));
|
||||||
},
|
},
|
||||||
child: TitleMedium(
|
child: TitleMedium(
|
||||||
text: room.name!,
|
text: room.name!,
|
||||||
@ -51,7 +69,8 @@ class RoomsSlider extends StatelessWidget {
|
|||||||
fontSize: 25,
|
fontSize: 25,
|
||||||
color: HomeCubit.getInstance().selectedRoom == room
|
color: HomeCubit.getInstance().selectedRoom == room
|
||||||
? ColorsManager.textPrimaryColor
|
? ColorsManager.textPrimaryColor
|
||||||
: ColorsManager.textPrimaryColor.withOpacity(.2),
|
: ColorsManager.textPrimaryColor
|
||||||
|
.withOpacity(.2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,14 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.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/smart_scene/smart_scene_select_dart_bloc.dart';
|
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart';
|
||||||
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
|
|
||||||
import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart';
|
|
||||||
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
|
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
|
||||||
|
|
||||||
class SceneListview extends StatelessWidget {
|
class SceneListview extends StatelessWidget {
|
||||||
final List<ScenesModel> scenes;
|
final List<ScenesModel> scenes;
|
||||||
@ -31,23 +28,28 @@ class SceneListview extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.only(right: 10),
|
padding: const EdgeInsets.only(right: 10),
|
||||||
child: DefaultContainer(
|
child: DefaultContainer(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(
|
context
|
||||||
context,
|
.read<SceneBloc>()
|
||||||
Routes.sceneTasksRoute,
|
.add(SceneTrigger(scene.id, scene.name));
|
||||||
arguments: SceneSettingsRouteArguments(
|
// Navigator.pushNamed(
|
||||||
sceneType: CreateSceneEnum.tabToRun.name,
|
// context,
|
||||||
sceneId: scene.id,
|
// Routes.sceneTasksRoute,
|
||||||
sceneName: scene.name,
|
// arguments: SceneSettingsRouteArguments(
|
||||||
),
|
// sceneType: CreateSceneEnum.tabToRun.name,
|
||||||
);
|
// sceneId: scene.id,
|
||||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
// sceneName: scene.name,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// context.read<SmartSceneSelectBloc>()
|
||||||
|
// .add(const SmartSceneClearEvent());
|
||||||
|
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
// BlocProvider.of<CreateSceneBloc>(context).add(
|
||||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
// FetchSceneTasksEvent(
|
||||||
|
// sceneId: scene.id, isAutomation: false));
|
||||||
|
|
||||||
/// the state to set the scene type must be after the fetch
|
// /// the state to set the scene type must be after the fetch
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
// BlocProvider.of<CreateSceneBloc>(context)
|
||||||
.add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
// .add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: MediaQuery.of(context).size.width * 0.4,
|
width: MediaQuery.of(context).size.width * 0.4,
|
||||||
@ -62,7 +64,8 @@ class SceneListview extends StatelessWidget {
|
|||||||
height: 32,
|
height: 32,
|
||||||
width: 32,
|
width: 32,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
errorBuilder: (context, error, stackTrace) => Image.asset(
|
errorBuilder: (context, error, stackTrace) =>
|
||||||
|
Image.asset(
|
||||||
Assets.assetsIconsLogo,
|
Assets.assetsIconsLogo,
|
||||||
height: 32,
|
height: 32,
|
||||||
width: 32,
|
width: 32,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/members_management_view.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/members_management_view.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/smart_linkage_view.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/smart_linkage_view.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/temporary_password_page.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/smart_door/temporary_password_page.dart';
|
||||||
@ -14,6 +15,8 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final buttons = doorLockButtons(val: uuid);
|
||||||
|
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
@ -23,14 +26,15 @@ class DoorLockGrid extends StatelessWidget {
|
|||||||
crossAxisSpacing: 10,
|
crossAxisSpacing: 10,
|
||||||
childAspectRatio: 1.75 / 1,
|
childAspectRatio: 1.75 / 1,
|
||||||
),
|
),
|
||||||
itemCount: 4,
|
itemCount: buttons.length,
|
||||||
itemBuilder: (context, index) => DefaultContainer(
|
itemBuilder: (context, index) => DefaultContainer(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
//TODO: remove checking after adding the pages
|
//TODO: remove checking after adding the pages
|
||||||
doorLockButtons()[index]['page'] != null
|
doorLockButtons()[index]['page'] != null
|
||||||
? Navigator.of(context).push(
|
? Navigator.of(context).push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => doorLockButtons(val: uuid)[index]['page'] as Widget,
|
builder: (context) =>
|
||||||
|
doorLockButtons(val: uuid)[index]['page'] as Widget,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
@ -75,11 +79,12 @@ List<Map<String, dynamic>> doorLockButtons({val}) => [
|
|||||||
'image': Assets.assetsIconsDoorlockAssetsMembersManagement,
|
'image': Assets.assetsIconsDoorlockAssetsMembersManagement,
|
||||||
'page': const MembersManagementView(),
|
'page': const MembersManagementView(),
|
||||||
},
|
},
|
||||||
{
|
if (HomeCubit.manageDeviceLocation)
|
||||||
'title': 'Temporary Password',
|
{
|
||||||
'image': Assets.assetsIconsDoorlockAssetsTemporaryPassword,
|
'title': 'Temporary Password',
|
||||||
'page': TemporaryPasswordPage(deviceId: val),
|
'image': Assets.assetsIconsDoorlockAssetsTemporaryPassword,
|
||||||
},
|
'page': TemporaryPasswordPage(deviceId: val),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'title': 'Smart Linkage',
|
'title': 'Smart Linkage',
|
||||||
'image': Assets.assetsIconsDoorlockAssetsSmartLinkage,
|
'image': Assets.assetsIconsDoorlockAssetsSmartLinkage,
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_screen.dart';
|
||||||
@ -26,6 +28,7 @@ class TwoTouchInterface extends StatelessWidget {
|
|||||||
extendBody: true,
|
extendBody: true,
|
||||||
appBar: touchSwitch != null
|
appBar: touchSwitch != null
|
||||||
? DeviceAppbar(
|
? DeviceAppbar(
|
||||||
|
value: true,
|
||||||
deviceName: touchSwitch!.name!,
|
deviceName: touchSwitch!.name!,
|
||||||
deviceUuid: touchSwitch!.uuid!,
|
deviceUuid: touchSwitch!.uuid!,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -215,8 +215,7 @@ class ParametersList extends StatelessWidget {
|
|||||||
{
|
{
|
||||||
'icon': Assets.assetsIconsPresenceSensorAssetsEmpty,
|
'icon': Assets.assetsIconsPresenceSensorAssetsEmpty,
|
||||||
'title': 'Nobody Time',
|
'title': 'Nobody Time',
|
||||||
'code': null,
|
'code': 'no_one_time',
|
||||||
//TODO: Implement the nobody time
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'icon': Assets.assetsIconsPresenceSensorAssetsIndicator,
|
'icon': Assets.assetsIconsPresenceSensorAssetsIndicator,
|
||||||
@ -231,7 +230,7 @@ class ParametersList extends StatelessWidget {
|
|||||||
{
|
{
|
||||||
'icon': Assets.assetsIconsPresenceSensorAssetsIlluminanceRecord,
|
'icon': Assets.assetsIconsPresenceSensorAssetsIlluminanceRecord,
|
||||||
'title': 'Illuminance Record',
|
'title': 'Illuminance Record',
|
||||||
'code': null
|
'code': 'illuminance_value'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -240,6 +239,7 @@ Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, Dev
|
|||||||
WallSensorModel wallSensorStatus) {
|
WallSensorModel wallSensorStatus) {
|
||||||
String? unit;
|
String? unit;
|
||||||
dynamic value;
|
dynamic value;
|
||||||
|
int noBodyTimeValue;
|
||||||
if (wallSensorButton['code'] != null) {
|
if (wallSensorButton['code'] != null) {
|
||||||
// if (wallSensor.status.any((element) => element.code == wallSensorButton['code'] as String)) {
|
// if (wallSensor.status.any((element) => element.code == wallSensorButton['code'] as String)) {
|
||||||
// unit = unitsMap[wallSensorButton['code'] as String];
|
// unit = unitsMap[wallSensorButton['code'] as String];
|
||||||
@ -256,12 +256,15 @@ Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, Dev
|
|||||||
} else if (wallSensorButton['code'] == 'illuminance_value') {
|
} else if (wallSensorButton['code'] == 'illuminance_value') {
|
||||||
unit = unitsMap[wallSensorButton['code'] as String];
|
unit = unitsMap[wallSensorButton['code'] as String];
|
||||||
value = wallSensorStatus.illuminance;
|
value = wallSensorStatus.illuminance;
|
||||||
|
} else if (wallSensorButton['code'] == 'no_one_time') {
|
||||||
|
unit = unitsMap[wallSensorButton['code'] as String];
|
||||||
|
value = wallSensorStatus.noOneTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DefaultContainer(
|
return DefaultContainer(
|
||||||
margin: const EdgeInsets.only(bottom: 5),
|
margin: const EdgeInsets.only(bottom: 5),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
if (wallSensorButton['page'] != null) {
|
if (wallSensorButton['page'] != null) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
@ -270,6 +273,42 @@ Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, Dev
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (wallSensorButton['title'] == 'Presence Record') {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => PresenceRecords(
|
||||||
|
deviceId: wallSensor.uuid!,
|
||||||
|
code: 'presence_state',
|
||||||
|
title: 'Presence Record',
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wallSensorButton['title'] == 'Illuminance Record') {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => PresenceRecords(
|
||||||
|
deviceId: wallSensor.uuid!,
|
||||||
|
code: 'illuminance_value',
|
||||||
|
title: 'Illuminance Record',
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wallSensorButton['title'] == 'Nobody Time') {
|
||||||
|
int noBodyTimeValue = value as int;
|
||||||
|
String controlCode = 'no_one_time';
|
||||||
|
final result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => ParameterControlDialog(
|
||||||
|
title: 'Nobody Time', sensor: wallSensor, value: noBodyTimeValue, min: 0, max: 10000),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
BlocProvider.of<WallSensorBloc>(context)
|
||||||
|
.add(ChangeValueEvent(value: result, code: controlCode));
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@ -0,0 +1,120 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
|
class PresenceRecords extends StatelessWidget {
|
||||||
|
final String deviceId;
|
||||||
|
final String code;
|
||||||
|
final String title;
|
||||||
|
const PresenceRecords(
|
||||||
|
{super.key, required this.deviceId, required this.code, required this.title});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DefaultScaffold(
|
||||||
|
title: title,
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) => WallSensorBloc(deviceId: deviceId)
|
||||||
|
..add(GetDeviceReportsEvent(deviceUuid: deviceId, code: code)),
|
||||||
|
child: BlocBuilder<WallSensorBloc, WallSensorState>(builder: (context, state) {
|
||||||
|
final Map<String, List<DeviceEvent>> groupedRecords = {};
|
||||||
|
|
||||||
|
if (state is LoadingInitialState) {
|
||||||
|
return const Center(
|
||||||
|
child: DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
|
);
|
||||||
|
} else if (state is DeviceReportsState) {
|
||||||
|
for (var record in state.deviceReport.data ?? []) {
|
||||||
|
final DateTime eventDateTime = DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
|
||||||
|
final String formattedDate = DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
|
||||||
|
|
||||||
|
// Group by formatted date
|
||||||
|
if (groupedRecords.containsKey(formattedDate)) {
|
||||||
|
groupedRecords[formattedDate]!.add(record);
|
||||||
|
} else {
|
||||||
|
groupedRecords[formattedDate] = [record];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groupedRecords.isEmpty
|
||||||
|
? const Center(
|
||||||
|
child: Text('No records found'),
|
||||||
|
)
|
||||||
|
: ListView.builder(
|
||||||
|
itemCount: groupedRecords.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final String date = groupedRecords.keys.elementAt(index);
|
||||||
|
final List<DeviceEvent> recordsForDate = groupedRecords[date]!;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 5, top: 10),
|
||||||
|
child: Text(
|
||||||
|
date,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DefaultContainer(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
...recordsForDate.asMap().entries.map((entry) {
|
||||||
|
final int idx = entry.key;
|
||||||
|
final DeviceEvent record = entry.value;
|
||||||
|
final DateTime eventDateTime =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
|
||||||
|
final String formattedTime =
|
||||||
|
DateFormat('HH:mm:ss').format(eventDateTime);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
child: ListTile(
|
||||||
|
leading: Icon(
|
||||||
|
record.value == 'true'
|
||||||
|
? Icons.radio_button_checked
|
||||||
|
: Icons.radio_button_unchecked,
|
||||||
|
color: record.value == 'true' ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
record.value == 'true' ? "Opened" : "Closed",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text('$formattedTime'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (idx != recordsForDate.length - 1)
|
||||||
|
const Divider(
|
||||||
|
color: ColorsManager.graysColor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -9,6 +11,8 @@ import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_e
|
|||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart';
|
import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_records_screen.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/persence_records.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
@ -41,7 +45,8 @@ class WallMountedInterface extends StatelessWidget {
|
|||||||
motionlessSensitivity: 0,
|
motionlessSensitivity: 0,
|
||||||
currentDistance: 0,
|
currentDistance: 0,
|
||||||
illuminance: 0,
|
illuminance: 0,
|
||||||
indicator: false);
|
indicator: false,
|
||||||
|
noOneTime: 0);
|
||||||
|
|
||||||
if (state is UpdateState) {
|
if (state is UpdateState) {
|
||||||
wallSensorModel = state.wallSensorModel;
|
wallSensorModel = state.wallSensorModel;
|
||||||
|
|||||||
@ -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';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
|
|
||||||
class WHList extends StatelessWidget {
|
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 List<GroupWHModel> whList;
|
||||||
final bool allSwitches;
|
final bool allSwitches;
|
||||||
@ -22,43 +26,42 @@ class WHList extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
const BodySmall(text: 'All Lights'),
|
const BodySmall(text: 'All Water Heaters'),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
DevicesDefaultSwitch(
|
DevicesDefaultSwitch(
|
||||||
off: 'OFF',
|
off: 'OFF',
|
||||||
on: 'ON',
|
on: 'ON',
|
||||||
switchValue: allSwitches,
|
switchValue: allSwitches,
|
||||||
action: () {
|
action: () => context.read<WaterHeaterBloc>().add(
|
||||||
BlocProvider.of<WaterHeaterBloc>(context)
|
GroupAllOnEvent(),
|
||||||
.add(GroupAllOnEvent());
|
),
|
||||||
},
|
secondAction: () => context.read<WaterHeaterBloc>().add(
|
||||||
secondAction: () {
|
GroupAllOffEvent(),
|
||||||
BlocProvider.of<WaterHeaterBloc>(context)
|
),
|
||||||
.add(GroupAllOffEvent());
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListView.builder(
|
ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
padding: const EdgeInsets.all(0),
|
padding: EdgeInsetsDirectional.zero,
|
||||||
itemCount: whList.length,
|
itemCount: whList.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
final waterHeater = whList[index];
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
BodySmall(text: whList[index].deviceName),
|
BodySmall(text: waterHeater.deviceName),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
DevicesDefaultSwitch(
|
DevicesDefaultSwitch(
|
||||||
off: 'OFF',
|
off: 'OFF',
|
||||||
on: 'ON',
|
on: 'ON',
|
||||||
switchValue: whList[index].firstSwitch,
|
switchValue: waterHeater.firstSwitch,
|
||||||
action: () {
|
action: () => context.read<WaterHeaterBloc>().add(
|
||||||
BlocProvider.of<WaterHeaterBloc>(context).add(
|
|
||||||
ChangeFirstWizardSwitchStatusEvent(
|
ChangeFirstWizardSwitchStatusEvent(
|
||||||
value: whList[index].firstSwitch,
|
value: waterHeater.firstSwitch,
|
||||||
deviceId: whList[index].deviceId));
|
deviceId: waterHeater.deviceId,
|
||||||
},
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.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/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/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_event.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_state.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/services/api/home_creation_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/helpers/snack_bar.dart';
|
||||||
|
|
||||||
class CreateUnitBloc extends Bloc<CreateUnitEvent, CreateUnitState> {
|
class CreateUnitBloc extends Bloc<CreateUnitEvent, CreateUnitState> {
|
||||||
@ -239,8 +241,13 @@ Future<String> _createNewRoom(
|
|||||||
required String communityId}) async {
|
required String communityId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {'subspaceName': roomName};
|
Map<String, String> body = {'subspaceName': roomName};
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
final response = await HomeCreation.createRoom(
|
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'] != '') {
|
// if (response['data']['uuid'] != '') {
|
||||||
// final result = await _assignToRoom(roomId: response['data']['uuid'], userId: userId);
|
// final result = await _assignToRoom(roomId: response['data']['uuid'], userId: userId);
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.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/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/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_event.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_state.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_creation_api.dart';
|
||||||
import 'package:syncrow_app/services/api/home_management_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/services/api/spaces_api.dart';
|
||||||
|
import 'package:syncrow_app/utils/constants/temp_const.dart';
|
||||||
|
|
||||||
class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
||||||
List<DeviceModel> allDevices = [];
|
List<DeviceModel> allDevices = [];
|
||||||
@ -24,8 +26,12 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
FetchRoomsEvent event, Emitter<ManageUnitState> emit) async {
|
FetchRoomsEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
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));
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(const ErrorState(message: 'Something went wrong'));
|
emit(const ErrorState(message: 'Something went wrong'));
|
||||||
@ -37,12 +43,16 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
FetchDevicesByRoomIdEvent event, Emitter<ManageUnitState> emit) async {
|
FetchDevicesByRoomIdEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
try {
|
try {
|
||||||
Map<String, bool> roomDevicesId = {};
|
Map<String, bool> roomDevicesId = {};
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: event.unit.community.uuid,
|
communityUuid: event.unit.community.uuid,
|
||||||
spaceUuid: event.unit.id,
|
spaceUuid: event.unit.id,
|
||||||
roomId: event.roomId);
|
roomId: event.roomId,
|
||||||
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
|
allDevices = await HomeManagementAPI.fetchDevices(
|
||||||
|
project?.uuid ?? TempConst.projectIdDev);
|
||||||
|
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
|
|
||||||
@ -72,14 +82,21 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
AssignRoomEvent event, Emitter<ManageUnitState> emit) async {
|
AssignRoomEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
try {
|
try {
|
||||||
Map<String, bool> roomDevicesId = {};
|
Map<String, bool> roomDevicesId = {};
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
|
|
||||||
await HomeManagementAPI.assignDeviceToRoom(
|
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(
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: event.unit.community.uuid,
|
communityUuid: event.unit.community.uuid,
|
||||||
spaceUuid: event.unit.id,
|
spaceUuid: event.unit.id,
|
||||||
roomId: event.roomId);
|
roomId: event.roomId,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
|
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
|
|
||||||
@ -105,19 +122,25 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _unassignDevice(
|
void _unassignDevice(
|
||||||
UnassignRoomEvent event, Emitter<ManageUnitState> emit) async {
|
UnassignRoomEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
try {
|
try {
|
||||||
Map<String, bool> roomDevicesId = {};
|
Map<String, bool> roomDevicesId = {};
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
|
|
||||||
await HomeManagementAPI.unAssignDeviceToRoom(
|
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(
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: event.unit.community.uuid,
|
communityUuid: event.unit.community.uuid,
|
||||||
spaceUuid: event.unit.id,
|
spaceUuid: event.unit.id,
|
||||||
roomId: event.roomId);
|
roomId: event.roomId,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
|
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
|
|
||||||
@ -143,18 +166,22 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_addNewRoom(AddNewRoom event, Emitter<ManageUnitState> emit) async {
|
_addNewRoom(AddNewRoom event, Emitter<ManageUnitState> emit) async {
|
||||||
Map<String, String> body = {'subspaceName': event.roomName};
|
Map<String, String> body = {'subspaceName': event.roomName};
|
||||||
try {
|
try {
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
|
Project? project = HomeCubit.getInstance().project;
|
||||||
|
|
||||||
final response = await HomeCreation.createRoom(
|
final response = await HomeCreation.createRoom(
|
||||||
communityId: event.unit.community.uuid,
|
communityId: event.unit.community.uuid,
|
||||||
spaceId: event.unit.id,
|
spaceId: event.unit.id,
|
||||||
body: body);
|
body: body,
|
||||||
|
projectId: project?.uuid ?? TempConst.projectIdDev);
|
||||||
if (response['data']['uuid'] != '') {
|
if (response['data']['uuid'] != '') {
|
||||||
final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
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();
|
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
|
||||||
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
||||||
await HomeCubit.getInstance().fetchUnitsByUserId();
|
await HomeCubit.getInstance().fetchUnitsByUserId();
|
||||||
|
|||||||
@ -1,12 +1,184 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/bloc/privacy_policy.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/bloc/user_agreement.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/view/widgets/join_home/join_home_view.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/view/widgets/manage_home/manage_home_view.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/view/widgets/securty/view/securty_view.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/services/api/profile_api.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
part 'menu_state.dart';
|
part 'menu_state.dart';
|
||||||
|
|
||||||
class MenuCubit extends Cubit<MenuState> {
|
class MenuCubit extends Cubit<MenuState> {
|
||||||
MenuCubit() : super(MenuInitial());
|
MenuCubit() : super(MenuInitial());
|
||||||
|
|
||||||
static MenuCubit of(context) => BlocProvider.of<MenuCubit>(context);
|
static MenuCubit of(context) => BlocProvider.of<MenuCubit>(context);
|
||||||
|
|
||||||
String name = '';
|
String name = '';
|
||||||
|
String userAgreementHtml = "";
|
||||||
|
String privacyPolicyHtml = "";
|
||||||
|
|
||||||
|
Future<void> fetchAgreement() async {
|
||||||
|
try {
|
||||||
|
emit(MenuLoading());
|
||||||
|
final response = await ProfileApi().fetchUserAgreement();
|
||||||
|
userAgreementHtml = response;
|
||||||
|
emit(MenuLoaded(userAgreementHtml));
|
||||||
|
} catch (error) {
|
||||||
|
emit(MenuError(error.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> fetchPrivacyPolicy() async {
|
||||||
|
try {
|
||||||
|
emit(MenuLoading());
|
||||||
|
final response = await ProfileApi().fetchPrivacyPolicy();
|
||||||
|
privacyPolicyHtml = response;
|
||||||
|
emit(MenuLoaded(privacyPolicyHtml));
|
||||||
|
} catch (error) {
|
||||||
|
emit(MenuError(error.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> menuSections = [
|
||||||
|
//Home Management
|
||||||
|
{
|
||||||
|
'title': 'Home Management',
|
||||||
|
'color': ColorsManager.primaryColor,
|
||||||
|
'buttons': [
|
||||||
|
// {
|
||||||
|
// 'title': 'Create a Unit',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsCreateHome,
|
||||||
|
// 'page': const CreateUnitView()
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
'title': 'Join a Unit',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsJoinAHome,
|
||||||
|
'page': const JoinHomeView()
|
||||||
|
},
|
||||||
|
if (HomeCubit.manageSupSpace)
|
||||||
|
{
|
||||||
|
'title': 'Manage Your Units',
|
||||||
|
'Icon':
|
||||||
|
Assets.assetsIconsMenuIconsHomeManagementIconsManageYourHome,
|
||||||
|
'page': const ManageHomeView()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//General Settings
|
||||||
|
// {
|
||||||
|
// 'title': 'General Settings',
|
||||||
|
// 'color': const Color(0xFF023DFE),
|
||||||
|
// 'buttons': [
|
||||||
|
// {
|
||||||
|
// 'title': 'Voice Assistant',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsVoiceAssistant,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Temperature unit',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsTemperatureUnit,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Touch tone on panel',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsTouchTone,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Language',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsLanguage,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Network Diagnosis',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsNetworkDiagnosis,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Clear Cache',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsGeneralSettingsIconsClearCach,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// //Messages Center
|
||||||
|
// {
|
||||||
|
// 'title': 'Messages Center',
|
||||||
|
// 'color': const Color(0xFF0088FF),
|
||||||
|
// 'buttons': [
|
||||||
|
// {
|
||||||
|
// 'title': 'Alerts',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsAlerts,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Messages',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsMessages,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'FAQs',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsFAQs,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// 'title': 'Help & Feedback',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsHelpAndFeedback,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
//Security And Privacy
|
||||||
|
{
|
||||||
|
'title': 'Security And Privacy',
|
||||||
|
'color': const Color(0xFF8AB9FF),
|
||||||
|
'buttons': [
|
||||||
|
{
|
||||||
|
'title': 'Security',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsSecurityAndPrivacyIconsSecurty,
|
||||||
|
'page': const SecurtyView()
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// 'title': 'Privacy',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsSecurityAndPrivacyIconsPrivacy,
|
||||||
|
// 'page': const PrivacyView()
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//Legal Information
|
||||||
|
{
|
||||||
|
'title': 'Legal Information',
|
||||||
|
'color': const Color(0xFF001B72),
|
||||||
|
'buttons': [
|
||||||
|
// {
|
||||||
|
// 'title': 'About',
|
||||||
|
// 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout,
|
||||||
|
// 'page': null
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
'title': 'Privacy Policy',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy,
|
||||||
|
'page': const PrivacyPolicy()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'User Agreement',
|
||||||
|
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsUserAgreement,
|
||||||
|
'page': const UserAgreement()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
Future<void> fetchMenuSections() async {
|
||||||
|
emit(MenuLoading());
|
||||||
|
try {
|
||||||
|
emit(MenuItemsLoaded(menuSections));
|
||||||
|
} catch (e) {
|
||||||
|
emit(MenuError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,3 +3,27 @@ part of 'menu_cubit.dart';
|
|||||||
abstract class MenuState {}
|
abstract class MenuState {}
|
||||||
|
|
||||||
class MenuInitial extends MenuState {}
|
class MenuInitial extends MenuState {}
|
||||||
|
|
||||||
|
class MenuLoading extends MenuState {}
|
||||||
|
|
||||||
|
class MenuLoaded extends MenuState {
|
||||||
|
final String userAgreementHtml;
|
||||||
|
MenuLoaded(this.userAgreementHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MenuItemsLoaded extends MenuState {
|
||||||
|
final List<Map<String, Object>> menuSections;
|
||||||
|
MenuItemsLoaded(this.menuSections);
|
||||||
|
}
|
||||||
|
class MenuError extends MenuState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
MenuError(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MenuNameUpdated extends MenuState {
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
MenuNameUpdated(this.name);
|
||||||
|
}
|
||||||
|
|||||||
57
lib/features/menu/bloc/privacy_policy.dart
Normal file
57
lib/features/menu/bloc/privacy_policy.dart
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_html/flutter_html.dart';
|
||||||
|
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class PrivacyPolicy extends StatefulWidget {
|
||||||
|
const PrivacyPolicy({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PrivacyPolicyState createState() => _PrivacyPolicyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PrivacyPolicyState extends State<PrivacyPolicy> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
MenuCubit.of(context).fetchPrivacyPolicy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DefaultScaffold(
|
||||||
|
title: 'Privacy Policy',
|
||||||
|
child: BlocBuilder<MenuCubit, MenuState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is MenuLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is MenuLoaded) {
|
||||||
|
return ListView(
|
||||||
|
children: [
|
||||||
|
Html(
|
||||||
|
data: state.userAgreementHtml.isNotEmpty
|
||||||
|
? state.userAgreementHtml
|
||||||
|
: '',
|
||||||
|
onLinkTap: (url, attributes, element) async {
|
||||||
|
final uri = Uri.parse(url!);
|
||||||
|
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (state is MenuError) {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
'Error: ${state.message}',
|
||||||
|
style: const TextStyle(color: Colors.red),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const Center(child: Text('Loading User Agreement...'));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user