Compare commits
17 Commits
automation
...
chore/depe
| Author | SHA1 | Date | |
|---|---|---|---|
| 4785c6a46e | |||
| 032a28d47a | |||
| dcc98445d7 | |||
| 611c515173 | |||
| e733dd9230 | |||
| 8e104aeea7 | |||
| f6fbf452a0 | |||
| 5aec3d37fb | |||
| a32d885e50 | |||
| afe37dd68a | |||
| f83224ce60 | |||
| 0ef2f3b866 | |||
| 3f0fcc79aa | |||
| 33ec234c0d | |||
| 905399f037 | |||
| c31e54afc6 | |||
| 14825524e8 |
162
ios/Podfile.lock
@ -1,46 +1,54 @@
|
||||
PODS:
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- Firebase/Analytics (10.20.0):
|
||||
- Firebase/Analytics (10.25.0):
|
||||
- Firebase/Core
|
||||
- Firebase/Core (10.20.0):
|
||||
- Firebase/Core (10.25.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (~> 10.20.0)
|
||||
- Firebase/CoreOnly (10.20.0):
|
||||
- FirebaseCore (= 10.20.0)
|
||||
- Firebase/Crashlytics (10.20.0):
|
||||
- FirebaseAnalytics (~> 10.25.0)
|
||||
- Firebase/CoreOnly (10.25.0):
|
||||
- FirebaseCore (= 10.25.0)
|
||||
- Firebase/Crashlytics (10.25.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseCrashlytics (~> 10.20.0)
|
||||
- firebase_analytics (10.8.7):
|
||||
- Firebase/Analytics (= 10.20.0)
|
||||
- FirebaseCrashlytics (~> 10.25.0)
|
||||
- Firebase/Database (10.25.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseDatabase (~> 10.25.0)
|
||||
- firebase_analytics (10.10.7):
|
||||
- Firebase/Analytics (= 10.25.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_core (2.25.5):
|
||||
- Firebase/CoreOnly (= 10.20.0)
|
||||
- firebase_core (2.32.0):
|
||||
- Firebase/CoreOnly (= 10.25.0)
|
||||
- Flutter
|
||||
- firebase_crashlytics (3.4.16):
|
||||
- Firebase/Crashlytics (= 10.20.0)
|
||||
- firebase_crashlytics (3.5.7):
|
||||
- Firebase/Crashlytics (= 10.25.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseAnalytics (10.20.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 10.20.0)
|
||||
- firebase_database (10.5.7):
|
||||
- Firebase/Database (= 10.25.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseAnalytics (10.25.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 10.25.0)
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
||||
- GoogleUtilities/Network (~> 7.11)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (10.20.0):
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (10.25.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleAppMeasurement (= 10.20.0)
|
||||
- GoogleAppMeasurement (= 10.25.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
||||
- GoogleUtilities/Network (~> 7.11)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseCore (10.20.0):
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- FirebaseAppCheckInterop (10.29.0)
|
||||
- FirebaseCore (10.25.0):
|
||||
- FirebaseCoreInternal (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.12)
|
||||
- GoogleUtilities/Logger (~> 7.12)
|
||||
@ -48,19 +56,27 @@ PODS:
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseCoreInternal (10.29.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- FirebaseCrashlytics (10.20.0):
|
||||
- FirebaseCrashlytics (10.25.0):
|
||||
- FirebaseCore (~> 10.5)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- FirebaseRemoteConfigInterop (~> 10.23)
|
||||
- FirebaseSessions (~> 10.5)
|
||||
- GoogleDataTransport (~> 9.2)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- PromisesObjC (~> 2.1)
|
||||
- FirebaseDatabase (10.25.0):
|
||||
- FirebaseAppCheckInterop (~> 10.17)
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseSharedSwift (~> 10.0)
|
||||
- GoogleUtilities/UserDefaults (~> 7.13)
|
||||
- leveldb-library (~> 1.22)
|
||||
- FirebaseInstallations (10.29.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- GoogleUtilities/UserDefaults (~> 7.8)
|
||||
- PromisesObjC (~> 2.1)
|
||||
- FirebaseRemoteConfigInterop (10.29.0)
|
||||
- FirebaseSessions (10.29.0):
|
||||
- FirebaseCore (~> 10.5)
|
||||
- FirebaseCoreExtension (~> 10.0)
|
||||
@ -70,31 +86,32 @@ PODS:
|
||||
- GoogleUtilities/UserDefaults (~> 7.13)
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- PromisesSwift (~> 2.1)
|
||||
- FirebaseSharedSwift (10.29.0)
|
||||
- Flutter (1.0.0)
|
||||
- flutter_localization (0.0.1):
|
||||
- Flutter
|
||||
- flutter_secure_storage (6.0.0):
|
||||
- Flutter
|
||||
- GoogleAppMeasurement (10.20.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 10.20.0)
|
||||
- GoogleAppMeasurement (10.25.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 10.25.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
||||
- GoogleUtilities/Network (~> 7.11)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (10.20.0):
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 10.20.0)
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (10.25.0):
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 10.25.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
||||
- GoogleUtilities/Network (~> 7.11)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (10.20.0):
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (10.25.0):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.11)
|
||||
- GoogleUtilities/Network (~> 7.11)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.11)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- GoogleDataTransport (9.4.1):
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
@ -129,17 +146,18 @@ PODS:
|
||||
- GoogleUtilities/Privacy
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- nanopb (2.30909.1):
|
||||
- nanopb/decode (= 2.30909.1)
|
||||
- nanopb/encode (= 2.30909.1)
|
||||
- nanopb/decode (2.30909.1)
|
||||
- nanopb/encode (2.30909.1)
|
||||
- onesignal_flutter (5.2.0):
|
||||
- leveldb-library (1.22.5)
|
||||
- nanopb (2.30910.0):
|
||||
- nanopb/decode (= 2.30910.0)
|
||||
- nanopb/encode (= 2.30910.0)
|
||||
- nanopb/decode (2.30910.0)
|
||||
- nanopb/encode (2.30910.0)
|
||||
- onesignal_flutter (5.2.3):
|
||||
- Flutter
|
||||
- OneSignalXCFramework (= 5.2.0)
|
||||
- OneSignalXCFramework (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalComplete (= 5.2.0)
|
||||
- OneSignalXCFramework/OneSignal (5.2.0):
|
||||
- OneSignalXCFramework (= 5.2.3)
|
||||
- OneSignalXCFramework (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalComplete (= 5.2.3)
|
||||
- OneSignalXCFramework/OneSignal (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalExtension
|
||||
- OneSignalXCFramework/OneSignalLiveActivities
|
||||
@ -147,38 +165,38 @@ PODS:
|
||||
- OneSignalXCFramework/OneSignalOSCore
|
||||
- OneSignalXCFramework/OneSignalOutcomes
|
||||
- OneSignalXCFramework/OneSignalUser
|
||||
- OneSignalXCFramework/OneSignalComplete (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalComplete (5.2.3):
|
||||
- OneSignalXCFramework/OneSignal
|
||||
- OneSignalXCFramework/OneSignalInAppMessages
|
||||
- OneSignalXCFramework/OneSignalLocation
|
||||
- OneSignalXCFramework/OneSignalCore (5.2.0)
|
||||
- OneSignalXCFramework/OneSignalExtension (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalCore (5.2.3)
|
||||
- OneSignalXCFramework/OneSignalExtension (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalOutcomes
|
||||
- OneSignalXCFramework/OneSignalInAppMessages (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalInAppMessages (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalNotifications
|
||||
- OneSignalXCFramework/OneSignalOSCore
|
||||
- OneSignalXCFramework/OneSignalOutcomes
|
||||
- OneSignalXCFramework/OneSignalUser
|
||||
- OneSignalXCFramework/OneSignalLiveActivities (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalLiveActivities (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalOSCore
|
||||
- OneSignalXCFramework/OneSignalUser
|
||||
- OneSignalXCFramework/OneSignalLocation (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalLocation (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalNotifications
|
||||
- OneSignalXCFramework/OneSignalOSCore
|
||||
- OneSignalXCFramework/OneSignalUser
|
||||
- OneSignalXCFramework/OneSignalNotifications (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalNotifications (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalExtension
|
||||
- OneSignalXCFramework/OneSignalOutcomes
|
||||
- OneSignalXCFramework/OneSignalOSCore (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalOSCore (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalOutcomes (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalOutcomes (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalUser (5.2.0):
|
||||
- OneSignalXCFramework/OneSignalUser (5.2.3):
|
||||
- OneSignalXCFramework/OneSignalCore
|
||||
- OneSignalXCFramework/OneSignalNotifications
|
||||
- OneSignalXCFramework/OneSignalOSCore
|
||||
@ -207,6 +225,7 @@ DEPENDENCIES:
|
||||
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
||||
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||
- firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
|
||||
- firebase_database (from `.symlinks/plugins/firebase_database/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_localization (from `.symlinks/plugins/flutter_localization/ios`)
|
||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||
@ -223,15 +242,20 @@ SPEC REPOS:
|
||||
trunk:
|
||||
- Firebase
|
||||
- FirebaseAnalytics
|
||||
- FirebaseAppCheckInterop
|
||||
- FirebaseCore
|
||||
- FirebaseCoreExtension
|
||||
- FirebaseCoreInternal
|
||||
- FirebaseCrashlytics
|
||||
- FirebaseDatabase
|
||||
- FirebaseInstallations
|
||||
- FirebaseRemoteConfigInterop
|
||||
- FirebaseSessions
|
||||
- FirebaseSharedSwift
|
||||
- GoogleAppMeasurement
|
||||
- GoogleDataTransport
|
||||
- GoogleUtilities
|
||||
- leveldb-library
|
||||
- nanopb
|
||||
- OneSignalXCFramework
|
||||
- PromisesObjC
|
||||
@ -246,6 +270,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/firebase_core/ios"
|
||||
firebase_crashlytics:
|
||||
:path: ".symlinks/plugins/firebase_crashlytics/ios"
|
||||
firebase_database:
|
||||
:path: ".symlinks/plugins/firebase_database/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_localization:
|
||||
@ -271,35 +297,41 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
||||
Firebase: 10c8cb12fb7ad2ae0c09ffc86cd9c1ab392a0031
|
||||
firebase_analytics: 2c1c3057d5da3bd3aab819f7e6ee153a4e46c59e
|
||||
firebase_core: c8628c7ce80f79439149549052bff22f6784fbf5
|
||||
firebase_crashlytics: 012078b4eec6fc9716f97ba3da0f0e44a04e95b1
|
||||
FirebaseAnalytics: a2731bf3670747ce8f65368b118d18aa8e368246
|
||||
FirebaseCore: 28045c1560a2600d284b9c45a904fe322dc890b6
|
||||
Firebase: 0312a2352584f782ea56f66d91606891d4607f06
|
||||
firebase_analytics: cc06e24d6a2343c44f845b3112143db72d10ef78
|
||||
firebase_core: a626d00494efa398e7c54f25f1454a64c8abf197
|
||||
firebase_crashlytics: 17e856fabec68d993662abaf2f6fe2413f0abece
|
||||
firebase_database: 2713033e426b176d4fe5e7195f3d19aa1b549a91
|
||||
FirebaseAnalytics: ec00fe8b93b41dc6fe4a28784b8e51da0647a248
|
||||
FirebaseAppCheckInterop: 6a1757cfd4067d8e00fccd14fcc1b8fd78cfac07
|
||||
FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483
|
||||
FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f
|
||||
FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934
|
||||
FirebaseCrashlytics: 81530595edb6d99f1918f723a6c33766a24a4c86
|
||||
FirebaseCrashlytics: 4b96efb0ce73b38b2a85e8b8bd1bd8f63f09d015
|
||||
FirebaseDatabase: faa489a42f5f868d23a55dd442d6e2099348458e
|
||||
FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd
|
||||
FirebaseRemoteConfigInterop: 6efda51fb5e2f15b16585197e26eaa09574e8a4d
|
||||
FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc
|
||||
FirebaseSharedSwift: 20530f495084b8d840f78a100d8c5ee613375f6e
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_localization: f43b18844a2b3d2c71fd64f04ffd6b1e64dd54d4
|
||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
||||
GoogleAppMeasurement: bb3c564c3efb933136af0e94899e0a46167466a8
|
||||
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
|
||||
GoogleAppMeasurement: 9abf64b682732fed36da827aa2a68f0221fd2356
|
||||
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
|
||||
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5
|
||||
onesignal_flutter: 5ce68a29861960168e81101cb1bd685d264361de
|
||||
OneSignalXCFramework: bdf74fdc06888f9466dc21e826fe1549ed143095
|
||||
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||
leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28
|
||||
nanopb: 438bc412db1928dac798aa6fd75726007be04262
|
||||
onesignal_flutter: aecb9bab7b87b6b6a0887c103932c9f5488759e5
|
||||
OneSignalXCFramework: 356e59953e157f6e45a7fdfc863073b3168b2d01
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
|
||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
||||
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
|
||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||
|
||||
PODFILE CHECKSUM: 4243bd7f9184f79552dd731a7c9d5cad03bd2706
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objectVersion = 60;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@ -514,8 +514,8 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
CURRENT_PROJECT_VERSION = 20;
|
||||
DEVELOPMENT_TEAM = 48V27SBR8J;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||
@ -524,7 +524,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
MARKETING_VERSION = 1.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -706,8 +706,8 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
CURRENT_PROJECT_VERSION = 20;
|
||||
DEVELOPMENT_TEAM = 48V27SBR8J;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||
@ -716,7 +716,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
MARKETING_VERSION = 1.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -736,8 +736,8 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
CURRENT_PROJECT_VERSION = 20;
|
||||
DEVELOPMENT_TEAM = 48V27SBR8J;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Syncrow;
|
||||
@ -746,7 +746,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
MARKETING_VERSION = 1.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import UIKit
|
||||
import Flutter
|
||||
|
||||
@UIApplicationMain
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
|
||||
@ -1,115 +1,115 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "logo-20@2x.png",
|
||||
"filename" : "Syncrow Icon-20@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-20@3x.png",
|
||||
"filename" : "Syncrow Icon-20@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-29.png",
|
||||
"filename" : "Syncrow Icon-29.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-29@2x.png",
|
||||
"filename" : "Syncrow Icon-29@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-29@3x.png",
|
||||
"filename" : "Syncrow Icon-29@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-40@2x.png",
|
||||
"filename" : "Syncrow Icon-40@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-40@3x.png",
|
||||
"filename" : "Syncrow Icon-40@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-60@2x.png",
|
||||
"filename" : "Syncrow Icon-60@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-60@3x.png",
|
||||
"filename" : "Syncrow Icon-60@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-20.png",
|
||||
"filename" : "Syncrow Icon-20.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-20@2x 1.png",
|
||||
"filename" : "Syncrow Icon-20@2x 1.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-29 1.png",
|
||||
"filename" : "Syncrow Icon-29 1.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-29@2x 1.png",
|
||||
"filename" : "Syncrow Icon-29@2x 1.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-40.png",
|
||||
"filename" : "Syncrow Icon-40.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-40@2x 1.png",
|
||||
"filename" : "Syncrow Icon-40@2x 1.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-76.png",
|
||||
"filename" : "Syncrow Icon-76.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-76@2x.png",
|
||||
"filename" : "Syncrow Icon-76@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-83.5@2x.png",
|
||||
"filename" : "Syncrow Icon-83.5@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"filename" : "logo-1024.png",
|
||||
"filename" : "Syncrow Icon-1024.png",
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
|
||||
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@ -2,8 +2,6 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need access to your photo library to allow you to select and upload photos.</string>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
@ -28,6 +26,8 @@
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need access to your photo library to allow you to select and upload photos.</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
|
||||
@ -11,10 +11,7 @@ import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdo
|
||||
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/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
||||
import 'package:syncrow_app/features/menu/view/menu_view.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
@ -22,10 +19,7 @@ import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_b
|
||||
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
|
||||
import 'package:syncrow_app/features/scene/model/create_automation_model.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart';
|
||||
import 'package:syncrow_app/features/scene/view/create_scene_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/navigation/navigation_service.dart';
|
||||
@ -33,10 +27,8 @@ import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||
import 'package:syncrow_app/services/api/profile_api.dart';
|
||||
import 'package:syncrow_app/services/api/spaces_api.dart';
|
||||
import 'package:syncrow_app/utils/helpers/custom_page_route.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/constants.dart';
|
||||
|
||||
part 'home_state.dart';
|
||||
|
||||
@ -161,7 +153,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
}
|
||||
|
||||
_sendSubscriptionId() async {
|
||||
String? subscriptionId = OneSignal.User.pushSubscription.id ?? '';
|
||||
// String? subscriptionId = OneSignal.User.pushSubscription.id ?? '';
|
||||
//TODO send the subscription id to BE
|
||||
}
|
||||
|
||||
@ -349,47 +341,47 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
// ),
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
// IconButton(
|
||||
// icon: const Icon(
|
||||
// Icons.add,
|
||||
// size: 32,
|
||||
// ),
|
||||
// style: ButtonStyle(
|
||||
// foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// Navigator.pushNamed(
|
||||
// NavigationService.navigatorKey.currentContext!,
|
||||
// Routes.sceneTasksRoute,
|
||||
// arguments: SceneSettingsRouteArguments(
|
||||
// sceneType: '',
|
||||
// sceneId: '',
|
||||
// sceneName: '',
|
||||
// ),
|
||||
// );
|
||||
// NavigationService.navigatorKey.currentContext!
|
||||
// .read<CreateSceneBloc>()
|
||||
// .add(const ClearTaskListEvent());
|
||||
// NavigationService.navigatorKey.currentContext!
|
||||
// .read<CreateSceneBloc>()
|
||||
// .add(const SceneTypeEvent(CreateSceneEnum.none));
|
||||
// NavigationService.navigatorKey.currentContext!
|
||||
// .read<SmartSceneSelectBloc>()
|
||||
// .add(const SmartSceneClearEvent());
|
||||
// BlocProvider.of<EffectPeriodBloc>(NavigationService.navigatorKey.currentState!.context)
|
||||
// .add(ResetEffectivePeriod());
|
||||
// },
|
||||
// ),
|
||||
// IconButton(
|
||||
// icon: const Icon(
|
||||
// Icons.more_vert,
|
||||
// size: 28,
|
||||
// ),
|
||||
// style: ButtonStyle(
|
||||
// foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||
// ),
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
size: 32,
|
||||
),
|
||||
style: ButtonStyle(
|
||||
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(
|
||||
NavigationService.navigatorKey.currentContext!,
|
||||
Routes.sceneTasksRoute,
|
||||
arguments: SceneSettingsRouteArguments(
|
||||
sceneType: '',
|
||||
sceneId: '',
|
||||
sceneName: '',
|
||||
),
|
||||
);
|
||||
NavigationService.navigatorKey.currentContext!
|
||||
.read<CreateSceneBloc>()
|
||||
.add(const ClearTaskListEvent());
|
||||
NavigationService.navigatorKey.currentContext!
|
||||
.read<CreateSceneBloc>()
|
||||
.add(const SceneTypeEvent(CreateSceneEnum.none));
|
||||
NavigationService.navigatorKey.currentContext!
|
||||
.read<SmartSceneSelectBloc>()
|
||||
.add(const SmartSceneClearEvent());
|
||||
BlocProvider.of<EffectPeriodBloc>(NavigationService.navigatorKey.currentState!.context)
|
||||
.add(ResetEffectivePeriod());
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
size: 28,
|
||||
),
|
||||
style: ButtonStyle(
|
||||
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
'Menu': [
|
||||
IconButton(
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
||||
@ -40,6 +40,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
||||
on<ChangeAllSwitch>(_changeAllAcSwitch);
|
||||
on<IncreaseAllTemp>(_increaseAllTemp);
|
||||
on<DecreaseAllTemp>(_decreaseAllTemp);
|
||||
on<AcUpdated>(_onAcUpdated);
|
||||
}
|
||||
|
||||
void _fetchAcsStatus(AcsInitial event, Emitter<AcsState> emit) async {
|
||||
@ -62,6 +63,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
||||
}
|
||||
deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList);
|
||||
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
||||
Future.delayed(const Duration(milliseconds: 500));
|
||||
_listenToChanges();
|
||||
}
|
||||
} catch (e) {
|
||||
emit(AcsFailedState(errorMessage: e.toString()));
|
||||
@ -69,6 +72,29 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
||||
}
|
||||
}
|
||||
|
||||
_listenToChanges() {
|
||||
try {
|
||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$acId');
|
||||
Stream<DatabaseEvent> stream = ref.onValue;
|
||||
|
||||
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']));
|
||||
});
|
||||
|
||||
deviceStatus = AcStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||
add(AcUpdated());
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
_onAcUpdated(AcUpdated event, Emitter<AcsState> emit) {
|
||||
emit(GetAcStatusState(acStatusModel: deviceStatus));
|
||||
}
|
||||
|
||||
_getAllAcs() async {
|
||||
deviceStatusList = [];
|
||||
devicesList = [];
|
||||
@ -164,7 +190,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
||||
deviceStatus.childLock = lockValue;
|
||||
emit(AcModifyingState(acStatusModel: deviceStatus));
|
||||
|
||||
_runDeBouncerForOneDevice(deviceId: acId, code: 'child_lock', value: lockValue);
|
||||
await _runDeBouncerForOneDevice(deviceId: acId, code: 'child_lock', value: lockValue);
|
||||
}
|
||||
|
||||
void _increaseCoolTo(IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
||||
|
||||
@ -20,6 +20,8 @@ class AcSwitch extends AcsEvent {
|
||||
List<Object> get props => [acSwitch, deviceId, productId];
|
||||
}
|
||||
|
||||
class AcUpdated extends AcsEvent {}
|
||||
|
||||
class AcsInitial extends AcsEvent {
|
||||
final bool allAcs;
|
||||
const AcsInitial({required this.allAcs});
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_state.dart';
|
||||
@ -15,6 +16,7 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
||||
CeilingSensorBloc({required this.deviceId}) : super(InitialState()) {
|
||||
on<InitialEvent>(_fetchCeilingSensorStatus);
|
||||
on<ChangeValueEvent>(_changeValue);
|
||||
on<CeilingSensorUpdated>(_onCeilingSensorUpdated);
|
||||
}
|
||||
|
||||
void _fetchCeilingSensorStatus(InitialEvent event, Emitter<CeilingSensorState> emit) async {
|
||||
@ -27,12 +29,36 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
||||
}
|
||||
deviceStatus = CeilingSensorModel.fromJson(statusModelList);
|
||||
emit(UpdateState(ceilingSensorModel: deviceStatus));
|
||||
_listenToChanges();
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_listenToChanges() {
|
||||
try {
|
||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||
Stream<DatabaseEvent> stream = ref.onValue;
|
||||
|
||||
stream.listen((DatabaseEvent event) {
|
||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
||||
List<StatusModel> statusList = [];
|
||||
|
||||
usersMap['status'].forEach((element) {
|
||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
||||
});
|
||||
|
||||
deviceStatus = CeilingSensorModel.fromJson(statusList);
|
||||
add(CeilingSensorUpdated());
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
_onCeilingSensorUpdated(CeilingSensorUpdated event, Emitter<CeilingSensorState> emit) {
|
||||
emit(UpdateState(ceilingSensorModel: deviceStatus));
|
||||
}
|
||||
|
||||
void _changeValue(ChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
|
||||
emit(LoadingNewSate(ceilingSensorModel: deviceStatus));
|
||||
try {
|
||||
|
||||
@ -11,6 +11,8 @@ class LoadingEvent extends CeilingSensorEvent {}
|
||||
|
||||
class InitialEvent extends CeilingSensorEvent {}
|
||||
|
||||
class CeilingSensorUpdated extends CeilingSensorEvent {}
|
||||
|
||||
class ChangeValueEvent extends CeilingSensorEvent {
|
||||
final int value;
|
||||
final String code;
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
import 'dart:math';
|
||||
import 'package:day_picker/model/day_in_week.dart';
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/offline_password_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/offline_temporary_password.dart';
|
||||
import 'package:syncrow_app/features/devices/model/smart_door_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/create_temporary_password_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/hour_picker_dialog.dart';
|
||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
@ -17,21 +20,77 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
final String deviceId;
|
||||
late SmartDoorModel deviceStatus;
|
||||
static String pageType = '';
|
||||
bool isSavingPassword = false;
|
||||
|
||||
SmartDoorBloc({required this.deviceId}) : super(InitialState()) {
|
||||
on<InitialEvent>(_fetchSmartDoorStatus);
|
||||
on<DoorLockUpdated>(_doorLockUpdated);
|
||||
on<InitialPasswordsPage>(getTemporaryPasswords);
|
||||
on<InitialOneTimePassword>(getOneTimePasswords);
|
||||
on<InitialTimeLimitPassword>(getTimeLimitPasswords);
|
||||
on<UpdateLockEvent>(_updateLock);
|
||||
on<SavePasswordEvent>(savePassword);
|
||||
on<ToggleRepeatEvent>(toggleRepeat);
|
||||
on<SetStartEndTimeEvent>(setStartEndTime);
|
||||
on<ChangeTimeEvent>(changeTime);
|
||||
on<GeneratePasswordEvent>(generate7DigitNumber);
|
||||
on<SelectTimeEvent>(selectTime);
|
||||
on<SelectTimeEvent>(selectTimeOfLinePassword);
|
||||
on<SelectTimeOnlinePasswordEvent>(selectTimeOnlinePassword);
|
||||
on<DeletePasswordEvent>(deletePassword);
|
||||
on<GenerateAndSavePasswordTimeLimitEvent>(generateAndSavePasswordTimeLimited);
|
||||
on<GenerateAndSavePasswordOneTimeEvent>(generateAndSavePasswordOneTime);
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
on<RenamePasswordEvent>(_renamePassword);
|
||||
}
|
||||
|
||||
TextEditingController passwordController = TextEditingController();
|
||||
TextEditingController passwordNameController = TextEditingController();
|
||||
String effectiveTime = 'Select Time';
|
||||
String passwordId = '';
|
||||
int? effectiveTimeTimeStamp;
|
||||
String expirationTime = 'Select Time';
|
||||
int? expirationTimeTimeStamp;
|
||||
bool repeat = false;
|
||||
bool isStartEndTime = true;
|
||||
DateTime? startTime;
|
||||
DateTime? endTime;
|
||||
List<TemporaryPassword>? temporaryPasswords = [];
|
||||
List<OfflinePasswordModel>? oneTimePasswords = [];
|
||||
List<OfflinePasswordModel>? timeLimitPasswords = [];
|
||||
|
||||
Future generate7DigitNumber(GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
passwordController.clear();
|
||||
Random random = Random();
|
||||
int min = 1000000;
|
||||
int max = 9999999;
|
||||
passwordController.text = (min + random.nextInt(max - min + 1)).toString();
|
||||
emit(GeneratePasswordState());
|
||||
return passwordController.text;
|
||||
}
|
||||
|
||||
Future generateAndSavePasswordOneTime(
|
||||
GenerateAndSavePasswordOneTimeEvent event, Emitter<SmartDoorState> emit) async {
|
||||
try {
|
||||
if (isSavingPassword) return;
|
||||
isSavingPassword = true;
|
||||
emit(LoadingInitialState());
|
||||
var res = await DevicesAPI.generateOneTimePassword(deviceId: deviceId);
|
||||
ApiResponse pass = ApiResponse.fromJson(res);
|
||||
passwordController.text = pass.data.offlineTempPassword;
|
||||
passwordId = pass.data.offlineTempPasswordId;
|
||||
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
Clipboard.setData(ClipboardData(text: passwordController.text));
|
||||
});
|
||||
emit(const GeneratePasswordOneTimestate(generated: true));
|
||||
} catch (_) {
|
||||
emit(FailedState(errorMessage: _.toString()));
|
||||
} finally {
|
||||
isSavingPassword = false;
|
||||
}
|
||||
}
|
||||
|
||||
void _fetchSmartDoorStatus(InitialEvent event, Emitter<SmartDoorState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
@ -42,6 +101,44 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
}
|
||||
deviceStatus = SmartDoorModel.fromJson(statusModelList);
|
||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||
_listenToChanges();
|
||||
} catch (e) {
|
||||
emit(FailedState(errorMessage: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_listenToChanges() {
|
||||
try {
|
||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||
Stream<DatabaseEvent> stream = ref.onValue;
|
||||
|
||||
stream.listen((DatabaseEvent event) {
|
||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
||||
List<StatusModel> statusList = [];
|
||||
|
||||
usersMap['status'].forEach((element) {
|
||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
||||
});
|
||||
|
||||
deviceStatus = SmartDoorModel.fromJson(statusList);
|
||||
add(DoorLockUpdated());
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
_doorLockUpdated(DoorLockUpdated event, Emitter<SmartDoorState> emit) {
|
||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||
}
|
||||
|
||||
void _renamePassword(RenamePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
await DevicesAPI.renamePass(
|
||||
name: passwordNameController.text, doorLockUuid: deviceId, passwordId: passwordId);
|
||||
add(InitialOneTimePassword());
|
||||
add(InitialTimeLimitPassword());
|
||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||
} catch (e) {
|
||||
emit(FailedState(errorMessage: e.toString()));
|
||||
return;
|
||||
@ -51,15 +148,14 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
void getTemporaryPasswords(InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
pageType = event.type!;
|
||||
var response = await DevicesAPI.getTemporaryPasswords(deviceId, pageType);
|
||||
var response = await DevicesAPI.getTemporaryPasswords(
|
||||
deviceId,
|
||||
);
|
||||
if (response is List) {
|
||||
temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList();
|
||||
} else if (response is Map && response.containsKey('data')) {
|
||||
temporaryPasswords =
|
||||
(response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList();
|
||||
} else {
|
||||
throw Exception("Unexpected response format");
|
||||
}
|
||||
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||
} catch (e) {
|
||||
@ -67,69 +163,125 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
}
|
||||
}
|
||||
|
||||
TextEditingController passwordController = TextEditingController();
|
||||
TextEditingController passwordNameController = TextEditingController();
|
||||
String effectiveTime = 'Select Time';
|
||||
int? effectiveTimeTimeStamp;
|
||||
String expirationTime = 'Select Time';
|
||||
int? expirationTimeTimeStamp;
|
||||
bool repeat = false;
|
||||
bool isStartEndTime = true;
|
||||
List<String>? selectedDay;
|
||||
DateTime? startTime;
|
||||
DateTime? endTime;
|
||||
List<TemporaryPassword>? temporaryPasswords = [];
|
||||
List<TemporaryPassword>? oneTimePasswords = [];
|
||||
void getOneTimePasswords(InitialOneTimePassword event, Emitter<SmartDoorState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
var response = await DevicesAPI.getOneTimePasswords(deviceId);
|
||||
if (response is List) {
|
||||
oneTimePasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
|
||||
}
|
||||
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||
} catch (e) {
|
||||
emit(FailedState(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void getTimeLimitPasswords(InitialTimeLimitPassword event, Emitter<SmartDoorState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
var response = await DevicesAPI.getTimeLimitPasswords(deviceId);
|
||||
if (response is List) {
|
||||
timeLimitPasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
|
||||
}
|
||||
|
||||
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||
} catch (e) {
|
||||
emit(FailedState(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
changeTime(ChangeTimeEvent event, Emitter<SmartDoorState> emit) {
|
||||
emit(LoadingInitialState());
|
||||
if (event.isStartEndTime == true) {
|
||||
startTime = event.val;
|
||||
} else {
|
||||
endTime = event.val;
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
}
|
||||
|
||||
bool toggleRepeat(ToggleRepeatEvent event, Emitter<SmartDoorState> emit) {
|
||||
emit(LoadingInitialState());
|
||||
repeat = !repeat;
|
||||
emit(IsRepeatState());
|
||||
emit(IsRepeatState(repeat: repeat));
|
||||
return repeat;
|
||||
}
|
||||
|
||||
bool setStartEndTime(SetStartEndTimeEvent event, Emitter<SmartDoorState> emit) {
|
||||
emit(LoadingInitialState());
|
||||
isStartEndTime = event.val;
|
||||
emit(IsStartEndState());
|
||||
emit(IsStartEndState(isStartEndTime: isStartEndTime));
|
||||
return isStartEndTime;
|
||||
}
|
||||
|
||||
void _updateLock(UpdateLockEvent event, Emitter<SmartDoorState> emit) async {
|
||||
emit(LoadingNewSate(smartDoorModel: deviceStatus));
|
||||
try {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(deviceId: deviceId, code: 'normal_open_switch', value: !event.value),
|
||||
deviceId);
|
||||
// final response = await DevicesAPI.controlDevice(
|
||||
// DeviceControlModel(deviceId: deviceId, code: 'normal_open_switch', value: !event.value),
|
||||
// deviceId);
|
||||
|
||||
if (response['success'] ?? false) {
|
||||
final response = await DevicesAPI.openDoorLock(deviceId);
|
||||
|
||||
if (response) {
|
||||
deviceStatus.normalOpenSwitch = !event.value;
|
||||
}
|
||||
} catch (_) {}
|
||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||
}
|
||||
|
||||
void generate7DigitNumber(GeneratePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
passwordController.clear();
|
||||
Random random = Random();
|
||||
int min = 1000000;
|
||||
int max = 9999999;
|
||||
passwordController.text = (min + random.nextInt(max - min + 1)).toString();
|
||||
emit(GeneratePasswordState());
|
||||
Future<void> selectTimeOfLinePassword(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
||||
emit(ChangeTimeState());
|
||||
final DateTime? picked = await showDatePicker(
|
||||
context: event.context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime.now(),
|
||||
lastDate: DateTime(2101),
|
||||
);
|
||||
if (picked != null) {
|
||||
final TimeOfDay? timePicked = await showHourPicker(
|
||||
context: event.context,
|
||||
initialTime: TimeOfDay.now(),
|
||||
);
|
||||
if (timePicked != null) {
|
||||
final selectedDateTime = DateTime(
|
||||
picked.year,
|
||||
picked.month,
|
||||
picked.day,
|
||||
timePicked.hour,
|
||||
0,
|
||||
);
|
||||
final selectedTimestamp = DateTime(
|
||||
selectedDateTime.year,
|
||||
selectedDateTime.month,
|
||||
selectedDateTime.day,
|
||||
selectedDateTime.hour,
|
||||
selectedDateTime.minute,
|
||||
).millisecondsSinceEpoch ~/
|
||||
1000; // Divide by 1000 to remove milliseconds
|
||||
if (event.isEffective) {
|
||||
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
|
||||
} else {
|
||||
effectiveTime =
|
||||
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||
effectiveTimeTimeStamp = selectedTimestamp;
|
||||
}
|
||||
} else {
|
||||
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Expiration Time cannot be earlier than Effective Time.');
|
||||
} else {
|
||||
expirationTime =
|
||||
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||
expirationTimeTimeStamp = selectedTimestamp;
|
||||
}
|
||||
}
|
||||
emit(TimeSelectedState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> selectTime(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
||||
Future<void> selectTimeOnlinePassword(
|
||||
SelectTimeOnlinePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||
emit(ChangeTimeState());
|
||||
final DateTime? picked = await showDatePicker(
|
||||
context: event.context,
|
||||
@ -166,7 +318,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
timePicked.hour,
|
||||
timePicked.minute,
|
||||
);
|
||||
// Convert selectedDateTime to a timestamp without seconds and milliseconds
|
||||
final selectedTimestamp = DateTime(
|
||||
selectedDateTime.year,
|
||||
selectedDateTime.month,
|
||||
@ -185,7 +336,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
}
|
||||
} else {
|
||||
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
|
||||
CustomSnackBar.displaySnackBar(
|
||||
'Expiration Time cannot be earlier than Effective Time.');
|
||||
} else {
|
||||
expirationTime =
|
||||
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||
@ -202,8 +354,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
try {
|
||||
isSavingPassword = true;
|
||||
emit(LoadingSaveState());
|
||||
var res = await DevicesAPI.createPassword(
|
||||
pageType: pageType,
|
||||
await DevicesAPI.createPassword(
|
||||
deviceId: deviceId,
|
||||
effectiveTime: effectiveTimeTimeStamp.toString(),
|
||||
invalidTime: expirationTimeTimeStamp.toString(),
|
||||
@ -214,24 +365,52 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
Schedule(
|
||||
effectiveTime: getTimeOnly(startTime),
|
||||
invalidTime: getTimeOnly(endTime).toString(),
|
||||
workingDay: selectedDay!,
|
||||
workingDay: selectedDays,
|
||||
),
|
||||
],
|
||||
);
|
||||
Navigator.of(event.context).pop(true);
|
||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||
emit(SaveState());
|
||||
} catch (_) {}finally {
|
||||
} catch (_) {
|
||||
} finally {
|
||||
isSavingPassword = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> generateAndSavePasswordTimeLimited(
|
||||
GenerateAndSavePasswordTimeLimitEvent event, Emitter<SmartDoorState> emit) async {
|
||||
if (timeLimitValidate() || isSavingPassword) return;
|
||||
try {
|
||||
isSavingPassword = true;
|
||||
emit(LoadingInitialState());
|
||||
var res = await DevicesAPI.generateMultiTimePassword(
|
||||
deviceId: deviceId,
|
||||
effectiveTime: effectiveTimeTimeStamp.toString(),
|
||||
invalidTime: expirationTimeTimeStamp.toString(),
|
||||
);
|
||||
ApiResponse pass = ApiResponse.fromJson(res);
|
||||
passwordController.text = pass.data.offlineTempPassword;
|
||||
passwordId = pass.data.offlineTempPasswordId;
|
||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||
add(InitialTimeLimitPassword());
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
Clipboard.setData(ClipboardData(text: passwordController.text));
|
||||
});
|
||||
emit(const GeneratePasswordOneTimestate(generated: true));
|
||||
} catch (_) {
|
||||
add(InitialPasswordsPage());
|
||||
} finally {
|
||||
isSavingPassword = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deletePassword(DeletePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
var response =
|
||||
await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId)
|
||||
.then((value) async {
|
||||
add(InitialPasswordsPage(type: pageType));
|
||||
await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId)
|
||||
.then((value) async {
|
||||
add(InitialPasswordsPage());
|
||||
});
|
||||
} catch (e) {
|
||||
emit(FailedState(errorMessage: e.toString()));
|
||||
@ -243,6 +422,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
CustomSnackBar.displaySnackBar('Password less than 7');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (passwordController.text.isEmpty) {
|
||||
CustomSnackBar.displaySnackBar('Password required');
|
||||
return true;
|
||||
@ -251,6 +431,25 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
CustomSnackBar.displaySnackBar('Password name required');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
||||
CustomSnackBar.displaySnackBar('Select effective time');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expirationTime == 'Select Time' || expirationTimeTimeStamp == null) {
|
||||
CustomSnackBar.displaySnackBar('Select expiration time');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (repeat == true && (endTime == null || startTime == null)) {
|
||||
CustomSnackBar.displaySnackBar('Start Time and End time and the days required ');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool timeLimitValidate() {
|
||||
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
||||
CustomSnackBar.displaySnackBar('Select effective time');
|
||||
return true;
|
||||
@ -259,23 +458,34 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
||||
CustomSnackBar.displaySnackBar('Select expiration time');
|
||||
return true;
|
||||
}
|
||||
if (repeat == true && (endTime == null || startTime == null || selectedDay == null)) {
|
||||
CustomSnackBar.displaySnackBar('Start Time and End time and the days required ');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
List<DayInWeek> days = [
|
||||
DayInWeek("S", dayKey: 'Sun'),
|
||||
DayInWeek("M", dayKey: 'Mon'),
|
||||
DayInWeek("T", dayKey: 'Tue'),
|
||||
DayInWeek("W", dayKey: 'Wed'),
|
||||
DayInWeek("T", dayKey: 'Thu'),
|
||||
DayInWeek("F", dayKey: 'Fri'),
|
||||
DayInWeek("S", dayKey: 'Sat'),
|
||||
List<Map<String, String>> days = [
|
||||
{"day": "Sun", "key": "Sun"},
|
||||
{"day": "Mon", "key": "Mon"},
|
||||
{"day": "Tue", "key": "Tue"},
|
||||
{"day": "Wed", "key": "Wed"},
|
||||
{"day": "Thu", "key": "Thu"},
|
||||
{"day": "Fri", "key": "Fri"},
|
||||
{"day": "Sat", "key": "Sat"},
|
||||
];
|
||||
|
||||
List<String> selectedDays = [];
|
||||
|
||||
Future<void> toggleDaySelection(
|
||||
ToggleDaySelectionEvent event,
|
||||
Emitter<SmartDoorState> emit,
|
||||
) async {
|
||||
emit(LoadingInitialState());
|
||||
if (selectedDays.contains(event.key)) {
|
||||
selectedDays.remove(event.key);
|
||||
} else {
|
||||
selectedDays.add(event.key);
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
}
|
||||
|
||||
String getTimeOnly(DateTime? dateTime) {
|
||||
if (dateTime == null) return '';
|
||||
return DateFormat('HH:mm').format(dateTime);
|
||||
|
||||
@ -9,12 +9,15 @@ abstract class SmartDoorEvent extends Equatable {
|
||||
}
|
||||
|
||||
class InitialEvent extends SmartDoorEvent {}
|
||||
class InitialPasswordsPage extends SmartDoorEvent {
|
||||
final String? type;
|
||||
const InitialPasswordsPage({ this.type});
|
||||
}
|
||||
|
||||
class InitialPasswordsPage extends SmartDoorEvent {}
|
||||
|
||||
class InitialOneTimePassword extends SmartDoorEvent {}
|
||||
|
||||
class InitialTimeLimitPassword extends SmartDoorEvent {}
|
||||
|
||||
class DoorLockUpdated extends SmartDoorEvent {}
|
||||
|
||||
class UpdateLockEvent extends SmartDoorEvent {
|
||||
final bool value;
|
||||
const UpdateLockEvent({required this.value});
|
||||
@ -29,39 +32,70 @@ class SavePasswordEvent extends SmartDoorEvent {
|
||||
List<Object> get props => [context];
|
||||
}
|
||||
|
||||
class GeneratePasswordEvent extends SmartDoorEvent {}
|
||||
class SelectTimeEvent extends SmartDoorEvent {
|
||||
final BuildContext context;
|
||||
final bool isEffective;
|
||||
const SelectTimeEvent({required this.context,required this.isEffective});
|
||||
class GenerateAndSavePasswordTimeLimitEvent extends SmartDoorEvent {
|
||||
final BuildContext context;
|
||||
const GenerateAndSavePasswordTimeLimitEvent({required this.context});
|
||||
@override
|
||||
List<Object> get props => [context,isEffective];
|
||||
List<Object> get props => [context];
|
||||
}
|
||||
|
||||
class GenerateAndSavePasswordOneTimeEvent extends SmartDoorEvent {
|
||||
final BuildContext context;
|
||||
const GenerateAndSavePasswordOneTimeEvent({required this.context});
|
||||
@override
|
||||
List<Object> get props => [context];
|
||||
}
|
||||
|
||||
class GeneratePasswordEvent extends SmartDoorEvent {}
|
||||
|
||||
class SelectTimeEvent extends SmartDoorEvent {
|
||||
final BuildContext context;
|
||||
final bool isEffective;
|
||||
const SelectTimeEvent({required this.context, required this.isEffective});
|
||||
@override
|
||||
List<Object> get props => [context, isEffective];
|
||||
}
|
||||
|
||||
class SelectTimeOnlinePasswordEvent extends SmartDoorEvent {
|
||||
final BuildContext context;
|
||||
final bool isEffective;
|
||||
const SelectTimeOnlinePasswordEvent({required this.context, required this.isEffective});
|
||||
@override
|
||||
List<Object> get props => [context, isEffective];
|
||||
}
|
||||
|
||||
class ToggleRepeatEvent extends SmartDoorEvent {}
|
||||
|
||||
class SetStartEndTimeEvent extends SmartDoorEvent {
|
||||
final bool val;
|
||||
|
||||
const SetStartEndTimeEvent({required this.val});
|
||||
@override
|
||||
List<Object> get props => [val];
|
||||
}
|
||||
|
||||
class DeletePasswordEvent extends SmartDoorEvent {
|
||||
final String passwordId;
|
||||
final String passwordId;
|
||||
|
||||
const DeletePasswordEvent({required this.passwordId});
|
||||
@override
|
||||
List<Object> get props => [passwordId];
|
||||
}
|
||||
|
||||
class ToggleDaySelectionEvent extends SmartDoorEvent {
|
||||
final String key;
|
||||
|
||||
const ToggleDaySelectionEvent({required this.key});
|
||||
@override
|
||||
List<Object> get props => [key];
|
||||
}
|
||||
|
||||
class ChangeTimeEvent extends SmartDoorEvent {
|
||||
final dynamic val;
|
||||
final bool isStartEndTime;
|
||||
|
||||
const ChangeTimeEvent({required this.val,required this.isStartEndTime});
|
||||
const ChangeTimeEvent({required this.val, required this.isStartEndTime});
|
||||
@override
|
||||
List<Object> get props => [val,isStartEndTime];
|
||||
List<Object> get props => [val, isStartEndTime];
|
||||
}
|
||||
|
||||
|
||||
class RenamePasswordEvent extends SmartDoorEvent {}
|
||||
|
||||
@ -38,13 +38,27 @@ class FailedState extends SmartDoorState {
|
||||
List<Object> get props => [errorMessage];
|
||||
}
|
||||
|
||||
class GeneratePasswordState extends SmartDoorState {}
|
||||
class GeneratePasswordState extends SmartDoorState {
|
||||
}
|
||||
|
||||
class TimeSelectedState extends SmartDoorState {}
|
||||
|
||||
class IsRepeatState extends SmartDoorState {}
|
||||
class IsRepeatState extends SmartDoorState {
|
||||
final bool repeat;
|
||||
const IsRepeatState({required this.repeat});
|
||||
|
||||
class IsStartEndState extends SmartDoorState {}
|
||||
@override
|
||||
List<Object> get props => [repeat];
|
||||
|
||||
}
|
||||
|
||||
class IsStartEndState extends SmartDoorState {
|
||||
final bool isStartEndTime;
|
||||
const IsStartEndState({required this.isStartEndTime});
|
||||
|
||||
@override
|
||||
List<Object> get props => [isStartEndTime];
|
||||
}
|
||||
|
||||
class ChangeStartTimeState extends SmartDoorState {}
|
||||
|
||||
@ -56,6 +70,12 @@ class SaveState extends SmartDoorState {}
|
||||
|
||||
class LoadingSaveState extends SmartDoorState {}
|
||||
|
||||
class GeneratePasswordOneTimestate extends SmartDoorState {
|
||||
final bool generated;
|
||||
const GeneratePasswordOneTimestate({required this.generated});
|
||||
List<Object> get props => [generated];
|
||||
}
|
||||
|
||||
class TemporaryPasswordsLoadedState extends SmartDoorState {
|
||||
final List<TemporaryPassword> temporaryPassword;
|
||||
const TemporaryPasswordsLoadedState({required this.temporaryPassword});
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
|
||||
@ -20,6 +21,10 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
secondCountDown: 0,
|
||||
thirdCountDown: 0);
|
||||
Timer? _timer;
|
||||
// Timer? _firstSwitchTimer;
|
||||
// Timer? _secondSwitchTimer;
|
||||
// Timer? _thirdSwitchTimer;
|
||||
|
||||
bool threeGangGroup = false;
|
||||
List<DeviceModel> devicesList = [];
|
||||
List<GroupThreeGangModel> groupThreeGangList = [];
|
||||
@ -27,6 +32,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
|
||||
ThreeGangBloc({required this.threeGangId}) : super(InitialState()) {
|
||||
on<InitialEvent>(_fetchThreeGangStatus);
|
||||
on<ThreeGangUpdated>(_threeGangUpdated);
|
||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||
on<ChangeSecondSwitchStatusEvent>(_changeSecondSwitch);
|
||||
on<ChangeThirdSwitchStatusEvent>(_changeThirdSwitch);
|
||||
@ -85,6 +91,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
}
|
||||
deviceStatus = ThreeGangModel.fromJson(statusModelList);
|
||||
emit(UpdateState(threeGangModel: deviceStatus));
|
||||
_listenToChanges();
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
@ -92,6 +99,34 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
}
|
||||
}
|
||||
|
||||
_listenToChanges() {
|
||||
try {
|
||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeGangId');
|
||||
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: element['value']));
|
||||
});
|
||||
|
||||
deviceStatus = ThreeGangModel.fromJson(statusList);
|
||||
if (!isClosed) {
|
||||
add(ThreeGangUpdated());
|
||||
}
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
_threeGangUpdated(ThreeGangUpdated event, Emitter<ThreeGangState> emit) {
|
||||
emit(UpdateState(threeGangModel: deviceStatus));
|
||||
}
|
||||
|
||||
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
|
||||
emit(LoadingNewSate(threeGangModel: deviceStatus));
|
||||
try {
|
||||
@ -111,16 +146,22 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
emit(UpdateState(threeGangModel: deviceStatus));
|
||||
}
|
||||
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: threeGangGroup ? event.deviceId : threeGangId,
|
||||
code: 'switch_1',
|
||||
value: !event.value),
|
||||
threeGangGroup ? event.deviceId : threeGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: threeGangGroup ? event.deviceId : threeGangId,
|
||||
code: 'switch_1',
|
||||
value: !event.value),
|
||||
threeGangGroup ? event.deviceId : threeGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
}
|
||||
@ -146,16 +187,22 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
emit(UpdateState(threeGangModel: deviceStatus));
|
||||
}
|
||||
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: threeGangGroup ? event.deviceId : threeGangId,
|
||||
code: 'switch_2',
|
||||
value: !event.value),
|
||||
threeGangGroup ? event.deviceId : threeGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: threeGangGroup ? event.deviceId : threeGangId,
|
||||
code: 'switch_2',
|
||||
value: !event.value),
|
||||
threeGangGroup ? event.deviceId : threeGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
}
|
||||
@ -180,16 +227,22 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
emit(UpdateState(threeGangModel: deviceStatus));
|
||||
}
|
||||
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: threeGangGroup ? event.deviceId : threeGangId,
|
||||
code: 'switch_3',
|
||||
value: !event.value),
|
||||
threeGangGroup ? event.deviceId : threeGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: threeGangGroup ? event.deviceId : threeGangId,
|
||||
code: 'switch_3',
|
||||
value: !event.value),
|
||||
threeGangGroup ? event.deviceId : threeGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
add(InitialEvent(groupScreen: threeGangGroup));
|
||||
}
|
||||
@ -407,6 +460,9 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
|
||||
void _onClose(OnClose event, Emitter<ThreeGangState> emit) {
|
||||
_timer?.cancel();
|
||||
// _firstSwitchTimer?.cancel();
|
||||
// _secondSwitchTimer?.cancel();
|
||||
// _thirdSwitchTimer?.cancel();
|
||||
}
|
||||
|
||||
void _onStartTimer(int seconds) {
|
||||
|
||||
@ -9,6 +9,8 @@ abstract class ThreeGangEvent extends Equatable {
|
||||
|
||||
class LoadingEvent extends ThreeGangEvent {}
|
||||
|
||||
class ThreeGangUpdated extends ThreeGangEvent {}
|
||||
|
||||
class InitialEvent extends ThreeGangEvent {
|
||||
final bool groupScreen;
|
||||
const InitialEvent({required this.groupScreen});
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart';
|
||||
@ -16,6 +17,7 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
||||
on<InitialEvent>(_fetchCeilingSensorStatus);
|
||||
on<ChangeIndicatorEvent>(_changeIndicator);
|
||||
on<ChangeValueEvent>(_changeValue);
|
||||
on<WallSensorUpdatedEvent>(_wallSensorUpdated);
|
||||
}
|
||||
|
||||
void _fetchCeilingSensorStatus(InitialEvent event, Emitter<WallSensorState> emit) async {
|
||||
@ -28,12 +30,36 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
||||
}
|
||||
deviceStatus = WallSensorModel.fromJson(statusModelList);
|
||||
emit(UpdateState(wallSensorModel: deviceStatus));
|
||||
_listenToChanges();
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_listenToChanges() {
|
||||
try {
|
||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||
Stream<DatabaseEvent> stream = ref.onValue;
|
||||
|
||||
stream.listen((DatabaseEvent event) {
|
||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
||||
List<StatusModel> statusList = [];
|
||||
|
||||
usersMap['status'].forEach((element) {
|
||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
||||
});
|
||||
|
||||
deviceStatus = WallSensorModel.fromJson(statusList);
|
||||
add(WallSensorUpdatedEvent());
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
_wallSensorUpdated(WallSensorUpdatedEvent event, Emitter<WallSensorState> emit) {
|
||||
emit(UpdateState(wallSensorModel: deviceStatus));
|
||||
}
|
||||
|
||||
void _changeIndicator(ChangeIndicatorEvent event, Emitter<WallSensorState> emit) async {
|
||||
emit(LoadingNewSate(wallSensorModel: deviceStatus));
|
||||
try {
|
||||
|
||||
@ -11,6 +11,8 @@ class LoadingEvent extends WallSensorEvent {}
|
||||
|
||||
class InitialEvent extends WallSensorEvent {}
|
||||
|
||||
class WallSensorUpdatedEvent extends WallSensorEvent {}
|
||||
|
||||
class ChangeIndicatorEvent extends WallSensorEvent {
|
||||
final bool value;
|
||||
const ChangeIndicatorEvent({required this.value});
|
||||
|
||||
@ -4,28 +4,47 @@ class CeilingSensorModel {
|
||||
String presenceState;
|
||||
int sensitivity;
|
||||
String checkingResult;
|
||||
int presenceRange;
|
||||
int sportsPara;
|
||||
String bodyMovement;
|
||||
|
||||
CeilingSensorModel({
|
||||
required this.presenceState,
|
||||
required this.sensitivity,
|
||||
required this.checkingResult,
|
||||
});
|
||||
CeilingSensorModel(
|
||||
{required this.presenceState,
|
||||
required this.sensitivity,
|
||||
required this.checkingResult,
|
||||
required this.presenceRange,
|
||||
required this.sportsPara,
|
||||
required this.bodyMovement});
|
||||
|
||||
factory CeilingSensorModel.fromJson(List<StatusModel> jsonList) {
|
||||
late String _presenceState;
|
||||
late int _sensitivity;
|
||||
late String _checkingResult;
|
||||
int _presenceRange = 1;
|
||||
int _sportsPara = 1;
|
||||
String _bodyMovement = 'none';
|
||||
|
||||
for (int i = 0; i < jsonList.length; i++) {
|
||||
if (jsonList[i].code == 'presence_state') {
|
||||
_presenceState = jsonList[i].value ?? 'none';
|
||||
} else if (jsonList[i].code == 'sensitivity') {
|
||||
_sensitivity = jsonList[i].value ?? false;
|
||||
_sensitivity = jsonList[i].value ?? 1;
|
||||
} else if (jsonList[i].code == 'checking_result') {
|
||||
_checkingResult = jsonList[i].value ?? false;
|
||||
_checkingResult = jsonList[i].value ?? '';
|
||||
} else if (jsonList[i].code == 'presence_range') {
|
||||
_presenceRange = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'sports_para') {
|
||||
_sportsPara = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'body_movement') {
|
||||
_bodyMovement = jsonList[i].value ?? '';
|
||||
}
|
||||
}
|
||||
return CeilingSensorModel(
|
||||
presenceState: _presenceState, sensitivity: _sensitivity, checkingResult: _checkingResult);
|
||||
presenceState: _presenceState,
|
||||
sensitivity: _sensitivity,
|
||||
checkingResult: _checkingResult,
|
||||
presenceRange: _presenceRange,
|
||||
sportsPara: _sportsPara,
|
||||
bodyMovement: _bodyMovement);
|
||||
}
|
||||
}
|
||||
|
||||
63
lib/features/devices/model/offline_password_model.dart
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
|
||||
class OfflinePasswordModel {
|
||||
final dynamic gmtCreate;
|
||||
final dynamic gmtExpired;
|
||||
final dynamic gmtStart;
|
||||
final bool hasClearPwd;
|
||||
final String optUid;
|
||||
final String pwd;
|
||||
final dynamic pwdId;
|
||||
final String pwdName;
|
||||
final String pwdTypeCode;
|
||||
final String revokedPwdName;
|
||||
final dynamic status;
|
||||
|
||||
OfflinePasswordModel({
|
||||
required this.gmtCreate,
|
||||
required this.gmtExpired,
|
||||
required this.gmtStart,
|
||||
required this.hasClearPwd,
|
||||
required this.optUid,
|
||||
required this.pwd,
|
||||
required this.pwdId,
|
||||
required this.pwdName,
|
||||
required this.pwdTypeCode,
|
||||
required this.revokedPwdName,
|
||||
required this.status,
|
||||
});
|
||||
|
||||
// Factory method to create a Password from a JSON map
|
||||
factory OfflinePasswordModel.fromJson(Map<String, dynamic> json) {
|
||||
return OfflinePasswordModel(
|
||||
gmtCreate: json['gmtCreate'],
|
||||
gmtExpired: json['gmtExpired'],
|
||||
gmtStart: json['gmtStart'],
|
||||
hasClearPwd: json['hasClearPwd'],
|
||||
optUid: json['optUid'],
|
||||
pwd: json['pwd'],
|
||||
pwdId: json['pwdId'],
|
||||
pwdName: json['pwdName'],
|
||||
pwdTypeCode: json['pwdTypeCode'],
|
||||
revokedPwdName: json['revokedPwdName'],
|
||||
status: json['status'],
|
||||
);
|
||||
}
|
||||
|
||||
// Method to convert a Password object to a JSON map
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'gmtCreate': gmtCreate,
|
||||
'gmtExpired': gmtExpired,
|
||||
'gmtStart': gmtStart,
|
||||
'hasClearPwd': hasClearPwd,
|
||||
'optUid': optUid,
|
||||
'pwd': pwd,
|
||||
'pwdId': pwdId,
|
||||
'pwdName': pwdName,
|
||||
'pwdTypeCode': pwdTypeCode,
|
||||
'revokedPwdName': revokedPwdName,
|
||||
'status': status,
|
||||
};
|
||||
}
|
||||
}
|
||||
69
lib/features/devices/model/offline_temporary_password.dart
Normal file
@ -0,0 +1,69 @@
|
||||
class OfflineTemporaryPassword {
|
||||
dynamic effectiveTime;
|
||||
dynamic invalidTime;
|
||||
dynamic offlineTempPassword;
|
||||
dynamic offlineTempPasswordId;
|
||||
dynamic offlineTempPasswordName;
|
||||
|
||||
OfflineTemporaryPassword({
|
||||
required this.effectiveTime,
|
||||
required this.invalidTime,
|
||||
required this.offlineTempPassword,
|
||||
required this.offlineTempPasswordId,
|
||||
required this.offlineTempPasswordName,
|
||||
});
|
||||
|
||||
factory OfflineTemporaryPassword.fromJson(Map<String, dynamic> json) {
|
||||
return OfflineTemporaryPassword(
|
||||
effectiveTime: json['effective_time'],
|
||||
invalidTime: json['invalid_time'],
|
||||
offlineTempPassword: json['offline_temp_password'],
|
||||
offlineTempPasswordId: json['offline_temp_password_id'],
|
||||
offlineTempPasswordName: json['offline_temp_password_name'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'effective_time': effectiveTime,
|
||||
'invalid_time': invalidTime,
|
||||
'offline_temp_password': offlineTempPassword,
|
||||
'offline_temp_password_id': offlineTempPasswordId,
|
||||
'offline_temp_password_name': offlineTempPasswordName,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ApiResponse {
|
||||
int statusCode;
|
||||
bool success;
|
||||
String message;
|
||||
OfflineTemporaryPassword data;
|
||||
|
||||
ApiResponse({
|
||||
required this.statusCode,
|
||||
required this.success,
|
||||
required this.message,
|
||||
required this.data,
|
||||
});
|
||||
|
||||
factory ApiResponse.fromJson(Map<String, dynamic> json) {
|
||||
return ApiResponse(
|
||||
statusCode: json['statusCode'],
|
||||
success: json['success'],
|
||||
message: json['message'],
|
||||
data: OfflineTemporaryPassword.fromJson(json['data']['result']),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'statusCode': statusCode,
|
||||
'success': success,
|
||||
'message': message,
|
||||
'data': {
|
||||
'result': data.toJson(),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -35,9 +35,9 @@ class WallSensorModel {
|
||||
if (jsonList[i].code == 'presence_state') {
|
||||
_presenceState = jsonList[i].value ?? 'none';
|
||||
} else if (jsonList[i].code == 'far_detection') {
|
||||
_farDetection = jsonList[i].value ?? false;
|
||||
_farDetection = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'presence_time') {
|
||||
_presenceTime = jsonList[i].value ?? false;
|
||||
_presenceTime = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'motion_sensitivity_value') {
|
||||
_motionSensitivity = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'motionless_sensitivity') {
|
||||
@ -47,7 +47,7 @@ class WallSensorModel {
|
||||
} else if (jsonList[i].code == 'illuminance_value') {
|
||||
_illuminance = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'indicator') {
|
||||
_indicator = jsonList[i].value ?? 0;
|
||||
_indicator = jsonList[i].value ?? false;
|
||||
}
|
||||
}
|
||||
return WallSensorModel(
|
||||
|
||||
@ -34,8 +34,13 @@ class CeilingSensorInterface extends StatelessWidget {
|
||||
create: (context) =>
|
||||
CeilingSensorBloc(deviceId: ceilingSensor.uuid ?? '')..add(InitialEvent()),
|
||||
child: BlocBuilder<CeilingSensorBloc, CeilingSensorState>(builder: (context, state) {
|
||||
CeilingSensorModel ceilingSensorModel =
|
||||
CeilingSensorModel(presenceState: 'none', sensitivity: 1, checkingResult: '');
|
||||
CeilingSensorModel ceilingSensorModel = CeilingSensorModel(
|
||||
presenceState: 'none',
|
||||
sensitivity: 1,
|
||||
checkingResult: '',
|
||||
presenceRange: 1,
|
||||
sportsPara: 1,
|
||||
bodyMovement: 'none');
|
||||
if (state is UpdateState) {
|
||||
ceilingSensorModel = state.ceilingSensorModel;
|
||||
} else if (state is LoadingNewSate) {
|
||||
@ -178,7 +183,8 @@ class CeilingSensorInterface extends StatelessWidget {
|
||||
children: [
|
||||
const BodySmall(text: 'Sports Para'),
|
||||
BodyLarge(
|
||||
text: '0',
|
||||
text: ceilingSensorModel.sportsPara
|
||||
.toString(),
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
@ -204,7 +210,8 @@ class CeilingSensorInterface extends StatelessWidget {
|
||||
textOverflow: TextOverflow.ellipsis,
|
||||
),
|
||||
BodyLarge(
|
||||
text: '0.0M',
|
||||
text:
|
||||
'${ceilingSensorModel.presenceRange}M',
|
||||
textOverflow: TextOverflow.ellipsis,
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
@ -231,7 +238,7 @@ class CeilingSensorInterface extends StatelessWidget {
|
||||
textOverflow: TextOverflow.ellipsis,
|
||||
),
|
||||
BodyLarge(
|
||||
text: 'none',
|
||||
text: ceilingSensorModel.bodyMovement,
|
||||
textOverflow: TextOverflow.ellipsis,
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
|
||||
92
lib/features/devices/view/widgets/hour_picker_dialog.dart
Normal file
@ -0,0 +1,92 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HourPickerDialog extends StatefulWidget {
|
||||
final TimeOfDay initialTime;
|
||||
HourPickerDialog({required this.initialTime});
|
||||
|
||||
@override
|
||||
_HourPickerDialogState createState() => _HourPickerDialogState();
|
||||
}
|
||||
|
||||
class _HourPickerDialogState extends State<HourPickerDialog> {
|
||||
late int _selectedHour;
|
||||
bool _isPm = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedHour = widget.initialTime.hour > 12 ? widget.initialTime.hour - 12 : widget.initialTime.hour;
|
||||
_isPm = widget.initialTime.period == DayPeriod.pm;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text('Select Hour'),
|
||||
content: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
DropdownButton<int>(
|
||||
value: _selectedHour,
|
||||
items: List.generate(12, (index) {
|
||||
int displayHour = index + 1;
|
||||
return DropdownMenuItem(
|
||||
value: displayHour,
|
||||
child: Text(displayHour.toString()),
|
||||
);
|
||||
}),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedHour = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
SizedBox(width: 16.0),
|
||||
DropdownButton<bool>(
|
||||
value: _isPm,
|
||||
items: [
|
||||
DropdownMenuItem(
|
||||
value: false,
|
||||
child: Text('AM'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: true,
|
||||
child: Text('PM'),
|
||||
),
|
||||
],
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_isPm = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(null),
|
||||
child: Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
int hour = _isPm ? _selectedHour + 12 : _selectedHour;
|
||||
Navigator.of(context).pop(TimeOfDay(hour: hour, minute: 0));
|
||||
},
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<TimeOfDay?> showHourPicker({
|
||||
required BuildContext context,
|
||||
required TimeOfDay initialTime,
|
||||
}) {
|
||||
return showDialog<TimeOfDay>(
|
||||
context: context,
|
||||
builder: (context) => HourPickerDialog(initialTime: initialTime),
|
||||
);
|
||||
}
|
||||
116
lib/features/devices/view/widgets/name_time_widget.dart
Normal file
@ -0,0 +1,116 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.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/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class NameTimeWidget extends StatelessWidget {
|
||||
const NameTimeWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultContainer(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: const BodyMedium(
|
||||
text: 'Password Name',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2.6,
|
||||
child: TextFormField(
|
||||
controller: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.passwordNameController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Enter The Name',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14, color: ColorsManager.textGray)),
|
||||
)),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(
|
||||
child: BodyMedium(
|
||||
text: 'Effective Time',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 3.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(SelectTimeOnlinePasswordEvent(context: context, isEffective: true));
|
||||
},
|
||||
child: Text(
|
||||
BlocProvider.of<SmartDoorBloc>(context).effectiveTime,
|
||||
style: TextStyle(fontSize: 14,
|
||||
color: BlocProvider.of<SmartDoorBloc>(context).effectiveTime ==
|
||||
'Select Time'
|
||||
? ColorsManager.textGray
|
||||
: null),
|
||||
),
|
||||
)),
|
||||
],),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(
|
||||
child: BodyMedium(
|
||||
text: 'Expiration Time',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 3.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(
|
||||
SelectTimeOnlinePasswordEvent(
|
||||
context: context, isEffective: false));
|
||||
},
|
||||
child: Text(
|
||||
BlocProvider.of<SmartDoorBloc>(context).expirationTime,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: BlocProvider.of<SmartDoorBloc>(context).expirationTime == 'Select Time'
|
||||
? ColorsManager.textGray
|
||||
: null),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,224 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/repeat_widget.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_button.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/door_lock_button.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/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class OfflineOneTimePasswordPage extends StatelessWidget {
|
||||
final String? deviceId;
|
||||
final String? type;
|
||||
const OfflineOneTimePasswordPage({super.key, this.deviceId, this.type});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isRepeat = false;
|
||||
bool generated = false;
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
|
||||
if (state is FailedState) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
state.errorMessage
|
||||
);
|
||||
}
|
||||
if (state is IsRepeatState){
|
||||
isRepeat = state.repeat;
|
||||
}
|
||||
if (state is GeneratePasswordOneTimestate ){
|
||||
generated = state.generated;
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultScaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: const BodyLarge(
|
||||
text: 'Create One-Time Password',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back)
|
||||
),
|
||||
),
|
||||
child: state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const BodyMedium(
|
||||
text: 'Save the password immediately. The password is not displayed in the app.',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const BodyMedium(
|
||||
text: '7-Digit Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children:smartDoorBloc.passwordController.text.isEmpty?
|
||||
List.generate(10, (index) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.0,vertical: 15),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 20.0,
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
}) :[
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: BodyLarge(
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
letterSpacing: 8.0 ,
|
||||
fontSize: 25,
|
||||
wordSpacing: 2),
|
||||
textAlign: TextAlign.center,
|
||||
text: smartDoorBloc.passwordController.text,
|
||||
fontSize: 23,
|
||||
),),
|
||||
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
await Clipboard.setData(ClipboardData(
|
||||
text: smartDoorBloc.passwordController.text));
|
||||
},
|
||||
icon: const Icon(Icons.copy)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
if(smartDoorBloc.passwordController.text.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: const BodyMedium(
|
||||
text: 'Password Name',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2.6,
|
||||
child: TextFormField(
|
||||
controller: BlocProvider.of<SmartDoorBloc>(context).passwordNameController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Enter The Name',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14, color: ColorsManager.textGray)),
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const BodyMedium(
|
||||
textAlign: TextAlign.center,
|
||||
text: 'Save the password immediately. The password is not displayed in the app.',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
|
||||
// NameTimeWidget(type:type!),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width/1.5,
|
||||
child: DoorLockButton(
|
||||
isDone: generated,
|
||||
isLoading: smartDoorBloc.isSavingPassword ,
|
||||
borderRadius: 30,
|
||||
backgroundColor:ColorsManager.primaryColor ,
|
||||
onPressed: () async {
|
||||
if(generated==false){
|
||||
smartDoorBloc.add(GenerateAndSavePasswordOneTimeEvent(context: context));
|
||||
}else{
|
||||
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
||||
smartDoorBloc.add(RenamePasswordEvent());
|
||||
}
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
},
|
||||
child: const BodyMedium(
|
||||
text: 'Obtain Password',
|
||||
fontWeight: FontWeight.bold,
|
||||
fontColor: Colors.white,
|
||||
),),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
isRepeat? const RepeatWidget():const SizedBox(),
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,3 @@
|
||||
import 'package:day_picker/day_picker.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -7,6 +6,8 @@ import 'package:pin_code_fields/pin_code_fields.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/name_time_widget.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/repeat_widget.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/text_widgets/body_large.dart';
|
||||
@ -14,15 +15,15 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
|
||||
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/font_manager.dart';
|
||||
import 'package:time_picker_spinner/time_picker_spinner.dart';
|
||||
|
||||
class CreateTemporaryPassword extends StatelessWidget {
|
||||
final String? deviceId;
|
||||
final String? type;
|
||||
|
||||
const CreateTemporaryPassword({super.key, this.deviceId, this.type});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isRepeat = false;
|
||||
bool generated = false;
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
|
||||
@ -34,7 +35,14 @@ class CreateTemporaryPassword extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
if (state is IsRepeatState){
|
||||
isRepeat = state.repeat;
|
||||
}
|
||||
if (state is GeneratePasswordOneTimestate ){
|
||||
generated = state.generated;
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultScaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
@ -46,360 +54,143 @@ class CreateTemporaryPassword extends StatelessWidget {
|
||||
),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop('UpdatePage');
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back)
|
||||
),
|
||||
actions: [
|
||||
actions:
|
||||
type == 'Online Password'?[
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.add(SavePasswordEvent(context: context));
|
||||
smartDoorBloc.add(SavePasswordEvent(context: context));
|
||||
},
|
||||
child: const Text('Save')
|
||||
)
|
||||
],
|
||||
]:null,
|
||||
),
|
||||
child: state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const BodyMedium(
|
||||
text: 'Save the password immediately. The password is not displayed in the app.',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const BodyMedium(
|
||||
text: '7-Digit Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: PinCodeTextField(
|
||||
onCompleted: (value) {
|
||||
if (value.split('').every((char) => char == '1')) {
|
||||
BlocProvider.of<SmartDoorBloc>(context).passwordController.clear();
|
||||
CustomSnackBar.displaySnackBar('All characters cannot be 1.');
|
||||
}
|
||||
},
|
||||
autoDisposeControllers: false,
|
||||
keyboardType: TextInputType.phone,
|
||||
length: 7,
|
||||
enabled: true,
|
||||
obscureText: false,
|
||||
animationType: AnimationType.fade,
|
||||
pinTheme: PinTheme(
|
||||
shape: PinCodeFieldShape.underline,
|
||||
fieldHeight: 45,
|
||||
fieldWidth: 20,
|
||||
activeFillColor: Colors.white,
|
||||
disabledColor: Colors.grey,
|
||||
activeColor: Colors.grey,
|
||||
errorBorderColor: Colors.grey,
|
||||
inactiveColor: Colors.grey,
|
||||
inactiveFillColor: Colors.grey,
|
||||
selectedColor: Colors.grey),
|
||||
animationDuration: const Duration(milliseconds: 300),
|
||||
backgroundColor: Colors.white,
|
||||
enableActiveFill: false,
|
||||
controller: BlocProvider.of<SmartDoorBloc>(context).passwordController,
|
||||
appContext: context,
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.add(GeneratePasswordEvent());
|
||||
},
|
||||
child: const BodyMedium(
|
||||
text: 'Generate Randomly',
|
||||
fontWeight: FontWeight.bold,
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
BlocProvider.of<SmartDoorBloc>(context).passwordController.text.isNotEmpty
|
||||
? TextButton(
|
||||
onPressed: () async {
|
||||
await Clipboard.setData(ClipboardData(
|
||||
text: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.passwordController
|
||||
.text));
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const BodyMedium(
|
||||
text: 'Save the password immediately. The password is not displayed in the app.',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const BodyMedium(
|
||||
text: '7-Digit Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: type == 'Online Password'?0:25),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: PinCodeTextField(
|
||||
onCompleted: (value) {
|
||||
if (value.split('').every((char) => char == '1')) {
|
||||
smartDoorBloc.passwordController.clear();
|
||||
CustomSnackBar.displaySnackBar('All characters cannot be 1.');
|
||||
}
|
||||
},
|
||||
child: const Text('Copy'))
|
||||
: const SizedBox(),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: const BodyMedium(
|
||||
text: 'Password Name',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2.6,
|
||||
child: TextFormField(
|
||||
controller: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.passwordNameController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Enter The Name',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14, color: ColorsManager.textGray)),
|
||||
)),
|
||||
],
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(
|
||||
child: BodyMedium(
|
||||
text: 'Effective Time',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 3.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(
|
||||
SelectTimeEvent(
|
||||
context: context, isEffective: true));
|
||||
},
|
||||
child: Text(
|
||||
BlocProvider.of<SmartDoorBloc>(context).effectiveTime,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.effectiveTime ==
|
||||
'Select Time'
|
||||
? ColorsManager.textGray
|
||||
: null),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(
|
||||
child: BodyMedium(
|
||||
text: 'Expiration Time',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 3.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(
|
||||
SelectTimeEvent(
|
||||
context: context, isEffective: false));
|
||||
},
|
||||
child: Text(
|
||||
BlocProvider.of<SmartDoorBloc>(context).expirationTime,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.expirationTime ==
|
||||
'Select Time'
|
||||
? ColorsManager.textGray
|
||||
: null),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
if (type == 'Online Password')
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const BodyMedium(
|
||||
text: 'Repeat',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
trailing: Transform.scale(
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: BlocProvider.of<SmartDoorBloc>(context).repeat,
|
||||
onChanged: (value) {
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.add(ToggleRepeatEvent());
|
||||
},
|
||||
applyTheme: true,
|
||||
)),
|
||||
),
|
||||
autoDisposeControllers: false,
|
||||
keyboardType: TextInputType.phone,
|
||||
length: 7,
|
||||
// enabled:type == 'Online Password'? true:false,
|
||||
obscureText: false,
|
||||
animationType: AnimationType.fade,
|
||||
pinTheme: PinTheme(
|
||||
shape: PinCodeFieldShape.underline,
|
||||
fieldHeight: 45,
|
||||
fieldWidth: 20,
|
||||
activeFillColor: Colors.white,
|
||||
disabledColor: Colors.grey,
|
||||
activeColor: Colors.grey,
|
||||
errorBorderColor: Colors.grey,
|
||||
inactiveColor: Colors.grey,
|
||||
inactiveFillColor: Colors.grey,
|
||||
selectedColor: Colors.grey),
|
||||
animationDuration: const Duration(milliseconds: 300),
|
||||
backgroundColor: Colors.white,
|
||||
enableActiveFill: false,
|
||||
controller: smartDoorBloc.passwordController,
|
||||
appContext: context,
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
BlocProvider.of<SmartDoorBloc>(context).repeat
|
||||
? DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.add(const SetStartEndTimeEvent(val: true));
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'Start',
|
||||
fontColor: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.isStartEndTime ==
|
||||
false
|
||||
? Colors.black
|
||||
: Colors.blue,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.add(const SetStartEndTimeEvent(val: false));
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'End',
|
||||
fontColor: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.isStartEndTime
|
||||
? Colors.black
|
||||
: Colors.blue,
|
||||
fontSize: 18,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Container(
|
||||
height: 110,
|
||||
child: BlocProvider.of<SmartDoorBloc>(context).isStartEndTime
|
||||
? TimePickerSpinner(
|
||||
time:
|
||||
BlocProvider.of<SmartDoorBloc>(context).startTime,
|
||||
is24HourMode: false,
|
||||
itemHeight: 40,
|
||||
normalTextStyle: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 24,
|
||||
),
|
||||
highlightedTextStyle:
|
||||
const TextStyle(fontSize: 30, color: Colors.blue),
|
||||
onTimeChange: (time) {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(
|
||||
ChangeTimeEvent(
|
||||
val: time,
|
||||
isStartEndTime:
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.isStartEndTime));
|
||||
},
|
||||
)
|
||||
: Container(
|
||||
child: TimePickerSpinner(
|
||||
time:
|
||||
BlocProvider.of<SmartDoorBloc>(context).endTime,
|
||||
is24HourMode: false,
|
||||
itemHeight: 40,
|
||||
normalTextStyle: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 24,
|
||||
),
|
||||
highlightedTextStyle: const TextStyle(
|
||||
fontSize: 30, color: Colors.blue),
|
||||
onTimeChange: (time) {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(
|
||||
ChangeTimeEvent(
|
||||
val: time,
|
||||
isStartEndTime:
|
||||
BlocProvider.of<SmartDoorBloc>(
|
||||
context)
|
||||
.isStartEndTime));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SelectWeekDays(
|
||||
width: MediaQuery.of(context).size.width / 1,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
days: BlocProvider.of<SmartDoorBloc>(context).days,
|
||||
border: false,
|
||||
selectedDayTextColor: Colors.black,
|
||||
unSelectedDayTextColor: Colors.grey,
|
||||
boxDecoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
color: Colors.white),
|
||||
onSelect: (values) {
|
||||
BlocProvider.of<SmartDoorBloc>(context).selectedDay =
|
||||
values;
|
||||
},
|
||||
),
|
||||
],
|
||||
))
|
||||
: const SizedBox(),
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
)
|
||||
],
|
||||
if(type == 'Online Password')
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
smartDoorBloc.add(GeneratePasswordEvent());
|
||||
},
|
||||
child: const BodyMedium(
|
||||
text: 'Generate Randomly',
|
||||
fontWeight: FontWeight.bold,
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if(smartDoorBloc.passwordController.text.isNotEmpty)
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
await Clipboard.setData(ClipboardData(
|
||||
text: smartDoorBloc.passwordController.text));
|
||||
},
|
||||
child: const Text('Copy')
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
NameTimeWidget(),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const BodyMedium(
|
||||
text: 'Repeat',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
trailing: Transform.scale(
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: smartDoorBloc.repeat,
|
||||
onChanged: (value) {
|
||||
smartDoorBloc.add(ToggleRepeatEvent());
|
||||
},
|
||||
applyTheme: true,
|
||||
)),
|
||||
),
|
||||
) ,
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
isRepeat? const RepeatWidget():const SizedBox(),
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.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/smart_door_model.dart';
|
||||
// import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_status_bar.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
@ -37,34 +33,41 @@ class _DoorLockButtonState extends State<DoorLockButton> with SingleTickerProvid
|
||||
super.initState();
|
||||
_animationController = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(seconds: 2),
|
||||
value: smartDoorModel.unlockRequest > 0 ? 1 : 0,
|
||||
duration: Duration(seconds: smartDoorModel.unlockRequest),
|
||||
);
|
||||
_animation = Tween<double>(begin: 0, end: 1.0).animate(_animationController)
|
||||
if (smartDoorModel.unlockRequest > 0) {
|
||||
_animationController.reverse();
|
||||
}
|
||||
|
||||
_animation = Tween<double>(begin: 0, end: 1).animate(_animationController)
|
||||
..addListener(() {
|
||||
if (_animation.status == AnimationStatus.completed) {
|
||||
// if (widget.doorLock.status
|
||||
// .firstWhere((element) => element.code == 'normal_open_switch')
|
||||
// .value !=
|
||||
// true) {
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: widget.doorLock.uuid, code: 'normal_open_switch', value: true),
|
||||
// widget.doorLock.uuid ?? "");
|
||||
// }
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.add(UpdateLockEvent(value: smartDoorModel.normalOpenSwitch));
|
||||
_animationController.reverse();
|
||||
} else if (_animation.status == AnimationStatus.dismissed) {
|
||||
// if (widget.doorLock.status
|
||||
// .firstWhere((element) => element.code == 'normal_open_switch')
|
||||
// .value !=
|
||||
// false) {
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: widget.doorLock.uuid, code: 'normal_open_switch', value: false),
|
||||
// widget.doorLock.uuid ?? "");
|
||||
// }
|
||||
}
|
||||
// if (_animation.status == AnimationStatus.completed) {
|
||||
// if (widget.doorLock.status
|
||||
// .firstWhere((element) => element.code == 'normal_open_switch')
|
||||
// .value !=
|
||||
// true) {
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: widget.doorLock.uuid, code: 'normal_open_switch', value: true),
|
||||
// widget.doorLock.uuid ?? "");
|
||||
// }
|
||||
// BlocProvider.of<SmartDoorBloc>(context)
|
||||
// .add(UpdateLockEvent(value: smartDoorModel.normalOpenSwitch));
|
||||
// _animationController.reverse();
|
||||
// }
|
||||
// } else if (_animation.status == AnimationStatus.dismissed) {
|
||||
// // if (widget.doorLock.status
|
||||
// // .firstWhere((element) => element.code == 'normal_open_switch')
|
||||
// // .value !=
|
||||
// // false) {
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: widget.doorLock.uuid, code: 'normal_open_switch', value: false),
|
||||
// widget.doorLock.uuid ?? "");
|
||||
// // }
|
||||
// _animationController.forward();
|
||||
// }
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
@ -88,14 +91,18 @@ class _DoorLockButtonState extends State<DoorLockButton> with SingleTickerProvid
|
||||
WidgetStateProperty.all(ColorsManager.primaryColorWithOpacity.withOpacity(0.1)),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
onTapDown: (details) {
|
||||
if (_animationController.status == AnimationStatus.dismissed) {
|
||||
_animationController.forward();
|
||||
} else if (_animationController.status == AnimationStatus.completed) {
|
||||
_animationController.reverse();
|
||||
} else if (_animationController.status == AnimationStatus.forward) {
|
||||
_animationController.reverse();
|
||||
} else if (_animationController.status == AnimationStatus.reverse) {
|
||||
_animationController.forward();
|
||||
// if (_animationController.status == AnimationStatus.dismissed) {
|
||||
// _animationController.forward();
|
||||
// } else if (_animationController.status == AnimationStatus.completed) {
|
||||
// _animationController.reverse();
|
||||
// } else if (_animationController.status == AnimationStatus.forward) {
|
||||
// _animationController.reverse();
|
||||
// } else if (_animationController.status == AnimationStatus.reverse) {
|
||||
// _animationController.forward();
|
||||
// }
|
||||
if (smartDoorModel.unlockRequest > 0) {
|
||||
BlocProvider.of<SmartDoorBloc>(context)
|
||||
.add(UpdateLockEvent(value: smartDoorModel.normalOpenSwitch));
|
||||
}
|
||||
},
|
||||
onTapUp: (details) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:syncrow_app/features/devices/model/offline_password_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
@ -7,13 +8,15 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class DoorDialog extends StatefulWidget {
|
||||
final String title;
|
||||
final TemporaryPassword value;
|
||||
final String? title;
|
||||
final TemporaryPassword? temporaryPassword;
|
||||
final OfflinePasswordModel? offline;
|
||||
|
||||
const DoorDialog({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.value,
|
||||
this.title,
|
||||
this.offline,
|
||||
this.temporaryPassword,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -28,16 +31,18 @@ class DoorDialogState extends State<DoorDialog> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final effectiveTime = widget.temporaryPassword?.effectiveTime ??int.parse( widget.offline?.gmtStart);
|
||||
final invalidTime = widget.temporaryPassword?.invalidTime ?? int.parse(widget.offline?.gmtExpired);
|
||||
|
||||
final DateTime effectiveDateTime =
|
||||
DateTime.fromMillisecondsSinceEpoch(widget.value.effectiveTime * 1000, isUtc: false);
|
||||
DateTime.fromMillisecondsSinceEpoch(effectiveTime! * 1000, isUtc: false);
|
||||
String formattedDateEffectiveTime = DateFormat('yyyy-MM-dd').format(effectiveDateTime);
|
||||
String formattedTimeEffectiveTime = DateFormat('HH:mm:ss').format(effectiveDateTime);
|
||||
String formattedTimeEffectiveTime = DateFormat('hh:mm a').format(effectiveDateTime);
|
||||
|
||||
final DateTime expiredDateTime =
|
||||
DateTime.fromMillisecondsSinceEpoch(widget.value.invalidTime * 1000, isUtc: false);
|
||||
DateTime.fromMillisecondsSinceEpoch(invalidTime! * 1000, isUtc: false);
|
||||
String formattedDateExpiredDateTime = DateFormat('yyyy-MM-dd').format(expiredDateTime);
|
||||
String formattedTimeExpiredDateTime = DateFormat('HH:mm:ss').format(expiredDateTime);
|
||||
|
||||
String formattedTimeExpiredDateTime = DateFormat('hh:mm a').format(expiredDateTime);
|
||||
return Dialog(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
@ -49,7 +54,7 @@ class DoorDialogState extends State<DoorDialog> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: widget.title,
|
||||
text: widget.title ?? '',
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontsManager.extraBold,
|
||||
@ -111,6 +116,7 @@ class DoorDialogState extends State<DoorDialog> {
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
widget.temporaryPassword?.effectiveTime!=null?
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
@ -142,6 +148,27 @@ class DoorDialogState extends State<DoorDialog> {
|
||||
),
|
||||
),
|
||||
],
|
||||
):
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Container(
|
||||
height: 50,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: 'Cancel',
|
||||
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@ -7,27 +7,22 @@ import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_sta
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/smart_door_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/popup_menu_widget.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_button.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_grid.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_status_bar.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.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/font_manager.dart';
|
||||
|
||||
class DoorInterface extends StatelessWidget {
|
||||
|
||||
DoorInterface({super.key, required this.doorLock});
|
||||
const DoorInterface({super.key, required this.doorLock});
|
||||
|
||||
final DeviceModel doorLock;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => SmartDoorBloc(deviceId: doorLock.uuid ?? '')..add(InitialEvent()),
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||
listener: (context, state) {
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
|
||||
if (state is FailedState) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
@ -63,32 +58,32 @@ class DoorInterface extends StatelessWidget {
|
||||
}
|
||||
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: DeviceAppbar(
|
||||
deviceName: doorLock.name!,
|
||||
deviceUuid: doorLock.uuid!,
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.assetsImagesBackground,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: DeviceAppbar(
|
||||
deviceName: doorLock.name!,
|
||||
deviceUuid: doorLock.uuid!,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.assetsImagesBackground,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: Constants.appBarHeight,
|
||||
left: Constants.defaultPadding,
|
||||
@ -98,38 +93,35 @@ class DoorInterface extends StatelessWidget {
|
||||
? const Center(
|
||||
child: RefreshProgressIndicator(),
|
||||
)
|
||||
:
|
||||
|
||||
RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(InitialEvent());
|
||||
},
|
||||
child:
|
||||
ListView(
|
||||
children: [
|
||||
DoorLockStatusBar(
|
||||
smartDoorModel: smartDoorModel,
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
DoorLockButton(
|
||||
doorLock: doorLock,
|
||||
smartDoorModel: smartDoorModel,
|
||||
),
|
||||
DoorLockGrid( uuid: doorLock.uuid!, ),
|
||||
|
||||
],
|
||||
)
|
||||
],
|
||||
)),
|
||||
: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(InitialEvent());
|
||||
},
|
||||
child: ListView(
|
||||
children: [
|
||||
DoorLockStatusBar(
|
||||
smartDoorModel: smartDoorModel,
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
DoorLockButton(
|
||||
doorLock: doorLock,
|
||||
smartDoorModel: smartDoorModel,
|
||||
),
|
||||
DoorLockGrid(
|
||||
uuid: doorLock.uuid!,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
));
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,288 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/repeat_widget.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/door_lock_button.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/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class CreateOfflineTimeLimitPasswordPage extends StatelessWidget {
|
||||
final String? deviceId;
|
||||
final String? type;
|
||||
const CreateOfflineTimeLimitPasswordPage({super.key, this.deviceId, this.type});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isRepeat = false;
|
||||
bool generated = false;
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||
listener: (context, state) {
|
||||
if (state is FailedState) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
state.errorMessage
|
||||
);
|
||||
}
|
||||
if (state is IsRepeatState) {
|
||||
isRepeat = state.repeat;
|
||||
}
|
||||
if (state is GeneratePasswordOneTimestate) {
|
||||
generated = state.generated;
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultScaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: const BodyLarge(
|
||||
text: 'Create Time-Limited Password',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back)),
|
||||
),
|
||||
child: state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const BodyMedium(
|
||||
text:
|
||||
'Save the password immediately. The password is not displayed in the app.',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10, vertical: 15),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: smartDoorBloc.passwordController.text.isEmpty ?
|
||||
List.generate(10, (index) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 15),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 20.0,
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
}) : [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: BodyLarge(
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
letterSpacing: 8.0,
|
||||
fontSize: 25,
|
||||
wordSpacing: 2),
|
||||
textAlign: TextAlign.center,
|
||||
text: smartDoorBloc.passwordController.text,
|
||||
fontSize: 25,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
await Clipboard.setData(
|
||||
ClipboardData(text: smartDoorBloc.passwordController.text)
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.copy)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: const BodyMedium(
|
||||
text: 'Password Name',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2.6,
|
||||
child: TextFormField(
|
||||
controller: BlocProvider.of<SmartDoorBloc>(context).passwordNameController,
|
||||
decoration:
|
||||
const InputDecoration(
|
||||
hintText: 'Enter The Name',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: ColorsManager.textGray)
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
const Divider(color: ColorsManager.graysColor,),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(
|
||||
child: BodyMedium(
|
||||
text: 'Effective Time',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 3.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(SelectTimeEvent(context: context, isEffective: true));
|
||||
},
|
||||
child: Text(
|
||||
BlocProvider.of<SmartDoorBloc>(context).effectiveTime,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: BlocProvider.of<SmartDoorBloc>(context).effectiveTime ==
|
||||
'Select Time' ? ColorsManager.textGray : null),
|
||||
),
|
||||
)),],
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Row(mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(
|
||||
child: BodyMedium(
|
||||
text: 'Expiration Time',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 3.5,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<SmartDoorBloc>(context).add(SelectTimeEvent(
|
||||
context: context,
|
||||
isEffective: false));
|
||||
},
|
||||
child: Text(
|
||||
BlocProvider.of<SmartDoorBloc>(context).expirationTime,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: BlocProvider.of<SmartDoorBloc>(context)
|
||||
.expirationTime == 'Select Time' ? ColorsManager
|
||||
.textGray : null),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const BodyMedium(
|
||||
textAlign: TextAlign.center,
|
||||
text: 'Use the time-limited password at least once within 24 hours after the password takes effect. Otherwise, the password becomes invalid.',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.grayColor,
|
||||
),
|
||||
// NameTimeWidget(type:type!),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 1.5,
|
||||
child: DoorLockButton(
|
||||
isDone: generated,
|
||||
isLoading: smartDoorBloc.isSavingPassword,
|
||||
borderRadius: 30,
|
||||
backgroundColor: ColorsManager.primaryColor,
|
||||
onPressed: () async {
|
||||
if (generated == false) {
|
||||
smartDoorBloc.add(GenerateAndSavePasswordTimeLimitEvent(context: context));
|
||||
} else {
|
||||
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
||||
smartDoorBloc.add(RenamePasswordEvent());
|
||||
}
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
},
|
||||
child: const BodyMedium(
|
||||
text: 'Obtain Password',
|
||||
fontWeight: FontWeight.bold,
|
||||
fontColor: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/offline_one_time_password_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_dialog.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/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class OnetimePasswordPage extends StatelessWidget {
|
||||
final String? deviceId;
|
||||
const OnetimePasswordPage({super.key, this.deviceId,});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialOneTimePassword( )),
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||
listener: (context, state) {
|
||||
if (state is FailedState) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.errorMessage),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultScaffold(
|
||||
title: 'Passwords',
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => OfflineOneTimePasswordPage(deviceId: deviceId, )
|
||||
)).then((result) {
|
||||
if(result!=null){
|
||||
smartDoorBloc.add(InitialOneTimePassword());
|
||||
smartDoorBloc.add(InitialOneTimePassword());
|
||||
}
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.add)
|
||||
)
|
||||
],
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Center(
|
||||
child: smartDoorBloc.oneTimePasswords!.isNotEmpty
|
||||
? ListView.builder(
|
||||
itemCount: smartDoorBloc.oneTimePasswords!.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon),
|
||||
title: BodyMedium(
|
||||
text: 'Password Name: ${smartDoorBloc.oneTimePasswords![index].pwdName}',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () async {
|
||||
final result = await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return DoorDialog(
|
||||
title: 'Password Information',
|
||||
offline: smartDoorBloc.oneTimePasswords![index],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
) : Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(Assets.noValidPasswords),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const BodyMedium(text: 'No Valid Passwords')
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
125
lib/features/devices/view/widgets/smart_door/repeat_widget.dart
Normal file
@ -0,0 +1,125 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.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/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class RepeatWidget extends StatelessWidget {
|
||||
const RepeatWidget({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return BlocBuilder<SmartDoorBloc, SmartDoorState>(
|
||||
builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
||||
child: Column(children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
smartDoorBloc.add(const SetStartEndTimeEvent(val: true));
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'Start',
|
||||
fontColor: smartDoorBloc.isStartEndTime == false
|
||||
? Colors.black
|
||||
: Colors.blue,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
smartDoorBloc.add(const SetStartEndTimeEvent(val: false));
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'End',
|
||||
fontColor: smartDoorBloc.isStartEndTime
|
||||
? Colors.black
|
||||
: Colors.blue,
|
||||
fontSize: 18,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
smartDoorBloc.isStartEndTime
|
||||
? Container(
|
||||
height: 110,
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
initialDateTime:smartDoorBloc.startTime,
|
||||
onDateTimeChanged: (startTime) {
|
||||
smartDoorBloc.add(ChangeTimeEvent(val: startTime, isStartEndTime: true));
|
||||
},
|
||||
)
|
||||
):SizedBox(
|
||||
height: 110,
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
initialDateTime:smartDoorBloc.endTime,
|
||||
onDateTimeChanged: (endTime) {
|
||||
smartDoorBloc.add(ChangeTimeEvent(val: endTime, isStartEndTime: false));
|
||||
},
|
||||
)
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height *0.10,
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: smartDoorBloc.days.map((day) {
|
||||
bool isSelected = smartDoorBloc.selectedDays.contains(day['key']);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
smartDoorBloc.add(ToggleDaySelectionEvent(key:day['key']!));
|
||||
},
|
||||
child: Container(
|
||||
width: 70,
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: isSelected?
|
||||
Colors.black:ColorsManager.grayColor
|
||||
),
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(55),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
day['day']!,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: isSelected ? Colors.black : ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
)
|
||||
)
|
||||
]));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/onetime_password_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/timelimited_password_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/view_temporary_password.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
@ -10,7 +12,7 @@ import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class TemporaryPasswordPage extends StatelessWidget {
|
||||
final String? deviceId;
|
||||
final String? deviceId;
|
||||
const TemporaryPasswordPage({super.key,this.deviceId});
|
||||
|
||||
@override
|
||||
@ -40,13 +42,17 @@ class TemporaryPasswordPage extends StatelessWidget {
|
||||
child:ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(
|
||||
Assets.timeLimitedPasswordIcon),
|
||||
Assets.timeLimitedPasswordIcon),
|
||||
title: const BodyMedium(
|
||||
text: 'Time-Limited Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'Online Password'),));
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) =>
|
||||
ViewTemporaryPassword(
|
||||
deviceId:deviceId,
|
||||
type:'Online Password'),
|
||||
));
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
@ -57,7 +63,6 @@ class TemporaryPasswordPage extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 10),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@ -75,46 +80,45 @@ class TemporaryPasswordPage extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
child: Column(children: [
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(Assets.oneTimePassword),
|
||||
title:
|
||||
const BodyMedium(
|
||||
text: 'One-Time Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'One-Time'),));
|
||||
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
|
||||
const Divider(color:ColorsManager.graysColor,),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(
|
||||
Assets.timeLimitedPassword),
|
||||
title: const BodyMedium(
|
||||
text: 'Time-Limited Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ViewTemporaryPassword(deviceId:deviceId,type:'Time-Limited'),));
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
],)
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(Assets.oneTimePassword),
|
||||
title:
|
||||
const BodyMedium(
|
||||
text: 'One-Time Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => OnetimePasswordPage(deviceId:deviceId,),));
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
const Divider(color:ColorsManager.graysColor,),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(
|
||||
Assets.timeLimitedPassword),
|
||||
title: const BodyMedium(
|
||||
text: 'Time-Limited Password',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => TimeLimitedPasswordPage(deviceId:deviceId,),));
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
],)
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -0,0 +1,105 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/offline_timeLimit_password_page.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/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'door_dialog.dart';
|
||||
|
||||
class TimeLimitedPasswordPage extends StatelessWidget {
|
||||
final String? deviceId;
|
||||
const TimeLimitedPasswordPage({super.key, this.deviceId});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialTimeLimitPassword()),
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||
listener: (context, state) {
|
||||
if (state is FailedState) {
|
||||
CustomSnackBar.displaySnackBar(
|
||||
state.errorMessage
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultScaffold(
|
||||
title: 'Passwords',
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => CreateOfflineTimeLimitPasswordPage(deviceId: deviceId,)
|
||||
)).then((result) {
|
||||
smartDoorBloc.add(InitialTimeLimitPassword());
|
||||
smartDoorBloc.add(InitialTimeLimitPassword());
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.add)
|
||||
)
|
||||
],
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Center(
|
||||
child: smartDoorBloc.timeLimitPasswords!.isNotEmpty
|
||||
? ListView.builder(
|
||||
itemCount: smartDoorBloc.timeLimitPasswords!.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon),
|
||||
title: BodyMedium(
|
||||
text: 'Password Name: ${smartDoorBloc.timeLimitPasswords![index].pwdName}',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () async {
|
||||
final result = await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return DoorDialog(
|
||||
title: 'Password Information',
|
||||
offline: smartDoorBloc.timeLimitPasswords![index],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
) : Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(Assets.noValidPasswords),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const BodyMedium(text: 'No Valid Passwords')
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -20,8 +20,7 @@ class ViewTemporaryPassword extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) =>
|
||||
SmartDoorBloc(deviceId: deviceId!)..add(InitialPasswordsPage(type:type )),
|
||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialPasswordsPage( )),
|
||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||
listener: (context, state) {
|
||||
if (state is FailedState) {
|
||||
@ -32,84 +31,86 @@ class ViewTemporaryPassword extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultScaffold(
|
||||
title: 'Passwords',
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => CreateTemporaryPassword(deviceId: deviceId, type: type),
|
||||
)).then((result) {
|
||||
if (result != null && result) {
|
||||
smartDoorBloc.add(InitialPasswordsPage(type:type ));
|
||||
}
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.add))
|
||||
],
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Center(
|
||||
child: smartDoorBloc.temporaryPasswords!.isNotEmpty
|
||||
? ListView.builder(
|
||||
itemCount: smartDoorBloc.temporaryPasswords!.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15, vertical: 10),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(
|
||||
Assets.timeLimitedPasswordIcon),
|
||||
title: BodyMedium(
|
||||
text:
|
||||
'Password Name: ${smartDoorBloc.temporaryPasswords![index].name}',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () async {
|
||||
final result = await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return DoorDialog(
|
||||
title: 'Password Information',
|
||||
value: smartDoorBloc.temporaryPasswords![index],
|
||||
);
|
||||
},
|
||||
);
|
||||
if(result=='delete'){
|
||||
smartDoorBloc.add(DeletePasswordEvent(passwordId: smartDoorBloc.temporaryPasswords![index].id.toString()));
|
||||
}
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
|
||||
return DefaultScaffold(
|
||||
title: 'Passwords',
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) =>
|
||||
CreateTemporaryPassword(deviceId: deviceId, type: type))).then((result) {
|
||||
if (result != null && result) {
|
||||
smartDoorBloc.add(InitialPasswordsPage());
|
||||
smartDoorBloc.add(InitialPasswordsPage());
|
||||
}
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.add)
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(Assets.noValidPasswords),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
],
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Center(
|
||||
child: smartDoorBloc.temporaryPasswords!.isNotEmpty
|
||||
? ListView.builder(
|
||||
itemCount: smartDoorBloc.temporaryPasswords!.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: SvgPicture.asset(
|
||||
Assets.timeLimitedPasswordIcon),
|
||||
title: BodyMedium(
|
||||
text: 'Password Name: ${smartDoorBloc.temporaryPasswords![index].name}',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
onTap: () async {
|
||||
final result = await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return DoorDialog(
|
||||
title: 'Password Information',
|
||||
temporaryPassword: smartDoorBloc.temporaryPasswords![index],
|
||||
);
|
||||
},
|
||||
);
|
||||
if(result=='delete'){
|
||||
smartDoorBloc.add(DeletePasswordEvent(passwordId: smartDoorBloc.temporaryPasswords![index].id.toString()));
|
||||
}
|
||||
},
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(Assets.noValidPasswords),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const BodyMedium(text: 'No Valid Passwords')
|
||||
],
|
||||
),
|
||||
const BodyMedium(text: 'No Valid Passwords')
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
}));
|
||||
);
|
||||
},
|
||||
));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ class ManageHomeView extends StatelessWidget {
|
||||
title: 'Manage Your Home',
|
||||
child: spaces == null
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
child: BodyMedium(text: 'No spaces found'),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
@ -30,8 +30,7 @@ class ManageHomeView extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children:
|
||||
List.generate(
|
||||
children: List.generate(
|
||||
spaces.length,
|
||||
(index) {
|
||||
if (index == spaces.length - 1) {
|
||||
@ -43,12 +42,10 @@ class ManageHomeView extends StatelessWidget {
|
||||
)));
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: StringHelpers.toTitleCase(
|
||||
spaces[index].name ?? "")),
|
||||
text: StringHelpers.toTitleCase(spaces[index].name ?? "")),
|
||||
const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
@ -76,14 +73,10 @@ class ManageHomeView extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: HomeCubit.getInstance()
|
||||
.spaces![index]
|
||||
.name ??
|
||||
""),
|
||||
text: HomeCubit.getInstance().spaces![index].name ?? ""),
|
||||
const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
@ -92,8 +85,7 @@ class ManageHomeView extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
Container(
|
||||
margin:
|
||||
const EdgeInsets.symmetric(vertical: 15),
|
||||
margin: const EdgeInsets.symmetric(vertical: 15),
|
||||
height: 1,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bloc/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/effective_period/effect_period_event.dart';
|
||||
@ -10,6 +9,16 @@ import 'package:syncrow_app/features/scene/model/create_automation_model.dart';
|
||||
import 'package:syncrow_app/navigation/navigation_service.dart';
|
||||
|
||||
class EffectPeriodBloc extends Bloc<EffectPeriodEvent, EffectPeriodState> {
|
||||
final daysMap = {
|
||||
'Sun': 'S',
|
||||
'Mon': 'M',
|
||||
'Tue': 'T',
|
||||
'Wed': 'W',
|
||||
'Thu': 'T',
|
||||
'Fri': 'F',
|
||||
'Sat': 'S',
|
||||
};
|
||||
|
||||
EffectPeriodBloc() : super(EffectPeriodState.initial()) {
|
||||
on<SetPeriod>(_onSetPeriod);
|
||||
on<ToggleDay>(_onToggleDay);
|
||||
@ -44,20 +53,17 @@ class EffectPeriodBloc extends Bloc<EffectPeriodEvent, EffectPeriodState> {
|
||||
break;
|
||||
}
|
||||
|
||||
BlocProvider.of<CreateSceneBloc>(
|
||||
NavigationService.navigatorKey.currentContext!)
|
||||
.add(EffectiveTimePeriodEvent(EffectiveTime(
|
||||
start: startTime, end: endTime, loops: state.selectedDaysBinary)));
|
||||
BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
|
||||
EffectiveTimePeriodEvent(
|
||||
EffectiveTime(start: startTime, end: endTime, loops: state.selectedDaysBinary)));
|
||||
|
||||
emit(state.copyWith(
|
||||
selectedPeriod: event.period,
|
||||
customStartTime: startTime,
|
||||
customEndTime: endTime));
|
||||
selectedPeriod: event.period, customStartTime: startTime, customEndTime: endTime));
|
||||
}
|
||||
|
||||
void _onToggleDay(ToggleDay event, Emitter<EffectPeriodState> emit) {
|
||||
final daysList = state.selectedDaysBinary.split('');
|
||||
final dayIndex = _getDayIndex(event.day);
|
||||
final dayIndex = getDayIndex(event.day);
|
||||
if (daysList[dayIndex] == '1') {
|
||||
daysList[dayIndex] = '0';
|
||||
} else {
|
||||
@ -66,9 +72,8 @@ class EffectPeriodBloc extends Bloc<EffectPeriodEvent, EffectPeriodState> {
|
||||
final newDaysBinary = daysList.join();
|
||||
emit(state.copyWith(selectedDaysBinary: newDaysBinary));
|
||||
|
||||
BlocProvider.of<CreateSceneBloc>(
|
||||
NavigationService.navigatorKey.currentContext!)
|
||||
.add(EffectiveTimePeriodEvent(EffectiveTime(
|
||||
BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
|
||||
EffectiveTimePeriodEvent(EffectiveTime(
|
||||
start: state.customStartTime ?? '00:00',
|
||||
end: state.customEndTime ?? '23:59',
|
||||
loops: newDaysBinary)));
|
||||
@ -90,37 +95,31 @@ class EffectPeriodBloc extends Bloc<EffectPeriodEvent, EffectPeriodState> {
|
||||
period = EnumEffectivePeriodOptions.custom;
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
customStartTime: startTime,
|
||||
customEndTime: endTime,
|
||||
selectedPeriod: period));
|
||||
emit(
|
||||
state.copyWith(customStartTime: startTime, customEndTime: endTime, selectedPeriod: period));
|
||||
|
||||
BlocProvider.of<CreateSceneBloc>(
|
||||
NavigationService.navigatorKey.currentContext!)
|
||||
.add(EffectiveTimePeriodEvent(EffectiveTime(
|
||||
start: startTime, end: endTime, loops: state.selectedDaysBinary)));
|
||||
BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
|
||||
EffectiveTimePeriodEvent(
|
||||
EffectiveTime(start: startTime, end: endTime, loops: state.selectedDaysBinary)));
|
||||
}
|
||||
|
||||
void _onResetEffectivePeriod(
|
||||
ResetEffectivePeriod event, Emitter<EffectPeriodState> emit) {
|
||||
void _onResetEffectivePeriod(ResetEffectivePeriod event, Emitter<EffectPeriodState> emit) {
|
||||
emit(state.copyWith(
|
||||
selectedPeriod: EnumEffectivePeriodOptions.allDay,
|
||||
customStartTime: '00:00',
|
||||
customEndTime: '23:59',
|
||||
selectedDaysBinary: '1111111'));
|
||||
|
||||
BlocProvider.of<CreateSceneBloc>(
|
||||
NavigationService.navigatorKey.currentContext!)
|
||||
.add(EffectiveTimePeriodEvent(
|
||||
EffectiveTime(start: '00:00', end: '23:59', loops: '1111111')));
|
||||
BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
|
||||
EffectiveTimePeriodEvent(EffectiveTime(start: '00:00', end: '23:59', loops: '1111111')));
|
||||
}
|
||||
|
||||
void _onResetDays(ResetDays event, Emitter<EffectPeriodState> emit) {
|
||||
emit(state.copyWith(selectedDaysBinary: '1111111'));
|
||||
}
|
||||
|
||||
int _getDayIndex(String day) {
|
||||
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
int getDayIndex(String day) {
|
||||
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||
return days.indexOf(day);
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ mixin SceneLogicHelper {
|
||||
required List<SceneStaticFunction> conditions,
|
||||
}) {
|
||||
final sceneBloc = context.read<CreateSceneBloc>();
|
||||
final effectiveTime = sceneBloc.effectiveTime;
|
||||
|
||||
if (isOnlyDelayOrDelayLast(actions)) {
|
||||
context.showCustomSnackbar(
|
||||
@ -46,6 +47,17 @@ mixin SceneLogicHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAutomation == true && effectiveTime?.loops == '0000000') {
|
||||
context.showCustomSnackbar(
|
||||
message: 'At least one day in Effective Period must be selected!',
|
||||
icon: const Icon(
|
||||
Icons.error,
|
||||
color: Colors.red,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAutomation) {
|
||||
final createAutomationModel = CreateAutomationModel(
|
||||
unitUuid: HomeCubit.getInstance().selectedSpace!.id ?? '',
|
||||
@ -81,7 +93,7 @@ mixin SceneLogicHelper {
|
||||
executorProperty: CreateSceneExecutorProperty(
|
||||
functionCode: '',
|
||||
functionValue: '',
|
||||
delaySeconds: task.functionValue,
|
||||
delaySeconds: task.functionValue ?? 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -159,21 +171,24 @@ mixin SceneLogicHelper {
|
||||
}
|
||||
}
|
||||
|
||||
Widget getTheCorrectDialogBody(SceneStaticFunction taskItem, dynamic functionValue,
|
||||
Widget getTheCorrectDialogBody(
|
||||
SceneStaticFunction taskItem, dynamic functionValue,
|
||||
{required bool isAutomation}) {
|
||||
if (taskItem.operationDialogType == OperationDialogType.temperature) {
|
||||
return AlertDialogTemperatureBody(
|
||||
taskItem: taskItem,
|
||||
functionValue: functionValue ?? taskItem.functionValue,
|
||||
);
|
||||
} else if ((taskItem.operationDialogType == OperationDialogType.countdown) ||
|
||||
} else if ((taskItem.operationDialogType ==
|
||||
OperationDialogType.countdown) ||
|
||||
(taskItem.operationDialogType == OperationDialogType.delay)) {
|
||||
return AlertDialogCountdown(
|
||||
durationValue: taskItem.functionValue ?? 0,
|
||||
functionValue: functionValue ?? taskItem.functionValue,
|
||||
function: taskItem,
|
||||
);
|
||||
} else if (taskItem.operationDialogType == OperationDialogType.integerSteps) {
|
||||
} else if (taskItem.operationDialogType ==
|
||||
OperationDialogType.integerSteps) {
|
||||
return AlertDialogSliderSteps(
|
||||
taskItem: taskItem,
|
||||
functionValue: functionValue ?? taskItem.functionValue,
|
||||
|
||||
@ -15,10 +15,12 @@ class SceneAutoSettings extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sceneSettings = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>? ?? {};
|
||||
final sceneSettings =
|
||||
ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>? ??
|
||||
{};
|
||||
final sceneId = sceneSettings['sceneId'] as String? ?? '';
|
||||
final isAutomation =
|
||||
context.read<CreateSceneBloc>().sceneType == CreateSceneEnum.deviceStatusChanges;
|
||||
final isAutomation = context.read<CreateSceneBloc>().sceneType ==
|
||||
CreateSceneEnum.deviceStatusChanges;
|
||||
final sceneName = sceneSettings['sceneName'] as String? ?? '';
|
||||
|
||||
return DefaultScaffold(
|
||||
@ -48,9 +50,11 @@ class SceneAutoSettings extends StatelessWidget {
|
||||
Visibility(
|
||||
visible: isAutomation,
|
||||
child: SceneListTile(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16, vertical: 8),
|
||||
titleString: "Effective Period",
|
||||
trailingWidget: const Icon(Icons.arrow_forward_ios_rounded),
|
||||
trailingWidget:
|
||||
const Icon(Icons.arrow_forward_ios_rounded),
|
||||
onPressed: () {
|
||||
context.customBottomSheet(
|
||||
child: const EffectPeriodBottomSheetContent(),
|
||||
|
||||
@ -48,12 +48,21 @@ class _AlertDialogSliderStepsState extends State<AlertDialogSliderSteps> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (widget.functionValue != null) {
|
||||
groupValue = _normalizeValue(widget.functionValue);
|
||||
if (widget.taskItem.code == 'temp_current') {
|
||||
if (widget.functionValue != null) {
|
||||
groupValue = _normalizeValue(
|
||||
double.tryParse(widget.functionValue.toString()) ??
|
||||
widget.taskItem.operationalValues[0].minValue);
|
||||
} else {
|
||||
groupValue = widget.taskItem.operationalValues[0].minValue;
|
||||
}
|
||||
} else {
|
||||
groupValue =
|
||||
_normalizeValue(widget.taskItem.operationalValues[0].minValue);
|
||||
if (widget.functionValue != null) {
|
||||
groupValue = _normalizeValue(widget.functionValue);
|
||||
} else {
|
||||
groupValue =
|
||||
_normalizeValue(widget.taskItem.operationalValues[0].minValue);
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {});
|
||||
@ -68,14 +77,6 @@ class _AlertDialogSliderStepsState extends State<AlertDialogSliderSteps> {
|
||||
);
|
||||
}
|
||||
|
||||
double _normalizeValue(dynamic value) {
|
||||
if (((widget.taskItem.code == "temp_set" && value > 199) ||
|
||||
widget.taskItem.code == "temp_current")) {
|
||||
return (value) / 10;
|
||||
}
|
||||
return value.toDouble();
|
||||
}
|
||||
|
||||
int _comparatorToIndex(String? comparator) {
|
||||
switch (comparator) {
|
||||
case "<":
|
||||
@ -216,7 +217,7 @@ class _AlertDialogSliderStepsState extends State<AlertDialogSliderSteps> {
|
||||
: null,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
groupValue = normalizeValue(value);
|
||||
groupValue = normalizeToDoubleValue(value);
|
||||
});
|
||||
context.read<CreateSceneBloc>().add(SelectedValueEvent(
|
||||
value: _deNormalizeValue(groupValue),
|
||||
@ -237,8 +238,16 @@ class _AlertDialogSliderStepsState extends State<AlertDialogSliderSteps> {
|
||||
);
|
||||
}
|
||||
|
||||
double normalizeValue(double value) {
|
||||
return double.parse(value.toStringAsFixed(1));
|
||||
double _normalizeValue(dynamic value) {
|
||||
if ((widget.taskItem.code == "temp_set" && value > 199) ||
|
||||
(widget.taskItem.code == "temp_current" && value >= -99.0)) {
|
||||
return (value) / 10;
|
||||
}
|
||||
return value.toDouble();
|
||||
}
|
||||
|
||||
double? normalizeToDoubleValue(double value) {
|
||||
return double.tryParse(value.toStringAsFixed(1));
|
||||
}
|
||||
|
||||
double _deNormalizeValue(double? value) {
|
||||
|
||||
@ -50,10 +50,10 @@ class _AlertDialogTemperatureBodyState
|
||||
});
|
||||
}
|
||||
|
||||
// context.read<CreateSceneBloc>().add(SelectedValueEvent(
|
||||
// value: temperature * 10,
|
||||
// code: widget.taskItem.code,
|
||||
// ));
|
||||
context.read<CreateSceneBloc>().add(SelectedValueEvent(
|
||||
value: temperature * 10,
|
||||
code: widget.taskItem.code,
|
||||
));
|
||||
}
|
||||
|
||||
int _normalizeTemperature(dynamic value) {
|
||||
|
||||
@ -19,18 +19,8 @@ class EffectPeriodBottomSheetContent extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// Expanded(
|
||||
// child: TextButton(
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
// child: BodySmall(
|
||||
// text: 'Save',
|
||||
// style:
|
||||
// context.bodySmall.copyWith(color: ColorsManager.primaryColorWithOpacity),
|
||||
// )),
|
||||
// ),
|
||||
const Spacer(),
|
||||
Expanded(
|
||||
// flex: 2,
|
||||
child: BodyMedium(
|
||||
text: 'Effective Period',
|
||||
fontColor: ColorsManager.primaryColorWithOpacity,
|
||||
|
||||
@ -4,22 +4,16 @@ import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_b
|
||||
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class RepeatDays extends StatelessWidget {
|
||||
const RepeatDays({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final daysMap = {
|
||||
'Mon': 'M',
|
||||
'Tue': 'T',
|
||||
'Wed': 'W',
|
||||
'Thu': 'T',
|
||||
'Fri': 'F',
|
||||
'Sat': 'S',
|
||||
'Sun': 'S',
|
||||
};
|
||||
|
||||
final effectiveBloc = context.read<EffectPeriodBloc>();
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
@ -27,53 +21,61 @@ class RepeatDays extends StatelessWidget {
|
||||
const SizedBox(width: 8),
|
||||
BlocBuilder<EffectPeriodBloc, EffectPeriodState>(
|
||||
builder: (context, state) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: daysMap.entries.map((entry) {
|
||||
final day = entry.key;
|
||||
final abbreviation = entry.value;
|
||||
final dayIndex = _getDayIndex(day);
|
||||
final isSelected = state.selectedDaysBinary[dayIndex] == '1';
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
context.read<EffectPeriodBloc>().add(ToggleDay(day));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color:
|
||||
isSelected ? Colors.grey : Colors.grey.shade300,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: 15,
|
||||
backgroundColor: Colors.white,
|
||||
child: Text(
|
||||
abbreviation,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color:
|
||||
isSelected ? Colors.grey : Colors.grey.shade300,
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: effectiveBloc.daysMap.entries.map((entry) {
|
||||
final day = entry.key;
|
||||
final abbreviation = entry.value;
|
||||
final dayIndex = effectiveBloc.getDayIndex(day);
|
||||
final isSelected = state.selectedDaysBinary[dayIndex] == '1';
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
effectiveBloc.add(ToggleDay(day));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: isSelected ? Colors.grey : Colors.grey.shade300,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: 15,
|
||||
backgroundColor: Colors.white,
|
||||
child: Text(
|
||||
abbreviation,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: isSelected ? Colors.grey : Colors.grey.shade300,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (state.selectedDaysBinary == '0000000')
|
||||
BodySmall(
|
||||
text: 'At least one day must be selected',
|
||||
style: context.bodyMedium.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
int _getDayIndex(String day) {
|
||||
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
return days.indexOf(day);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ class _SmartSceneSelectTabToRunListState extends State<SmartSceneSelectTabToRunL
|
||||
.read<SmartSceneSelectBloc>()
|
||||
.add(SmartSceneEnableEvent(SmartSceneEnable(
|
||||
entityId: scene.id,
|
||||
actionExecutor: 'rule_enable',
|
||||
actionExecutor: 'rule_trigger',
|
||||
sceneORAutomationName: scene.name,
|
||||
type: scene.type,
|
||||
isAutomation: false,
|
||||
@ -109,7 +109,7 @@ class _SmartSceneSelectTabToRunListState extends State<SmartSceneSelectTabToRunL
|
||||
});
|
||||
context.read<SmartSceneSelectBloc>().add(SmartSceneEnableEvent(SmartSceneEnable(
|
||||
entityId: scene.id,
|
||||
actionExecutor: 'rule_enable',
|
||||
actionExecutor: 'rule_trigger',
|
||||
sceneORAutomationName: scene.name,
|
||||
type: scene.type,
|
||||
isAutomation: false,
|
||||
|
||||
99
lib/features/shared_widgets/door_lock_button.dart
Normal file
@ -0,0 +1,99 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class DoorLockButton extends StatelessWidget {
|
||||
const DoorLockButton({
|
||||
super.key,
|
||||
this.enabled = true,
|
||||
this.onPressed,
|
||||
required this.child,
|
||||
this.isSecondary = false,
|
||||
this.isLoading = false,
|
||||
this.isDone = false,
|
||||
this.customTextStyle,
|
||||
this.customButtonStyle,
|
||||
this.backgroundColor,
|
||||
this.foregroundColor,
|
||||
this.borderRadius,
|
||||
this.height,
|
||||
this.padding,
|
||||
});
|
||||
|
||||
final void Function()? onPressed;
|
||||
final Widget child;
|
||||
final double? height;
|
||||
final bool isSecondary;
|
||||
final double? borderRadius;
|
||||
final bool enabled;
|
||||
final double? padding;
|
||||
final bool isDone;
|
||||
final bool isLoading;
|
||||
final TextStyle? customTextStyle;
|
||||
|
||||
final ButtonStyle? customButtonStyle;
|
||||
|
||||
final Color? backgroundColor;
|
||||
|
||||
final Color? foregroundColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ElevatedButton(
|
||||
onPressed: enabled ? onPressed : null,
|
||||
style: isSecondary
|
||||
? null
|
||||
: customButtonStyle ??
|
||||
ButtonStyle(
|
||||
textStyle: MaterialStateProperty.all(
|
||||
customTextStyle ??
|
||||
context.bodyMedium.copyWith(
|
||||
fontSize: 16,
|
||||
color: foregroundColor,
|
||||
),
|
||||
),
|
||||
foregroundColor: MaterialStateProperty.all(
|
||||
isSecondary
|
||||
? Colors.black
|
||||
: enabled
|
||||
? foregroundColor ?? Colors.white
|
||||
: Colors.black,
|
||||
),
|
||||
backgroundColor: MaterialStateProperty.resolveWith<Color>(
|
||||
(Set<MaterialState> states) {
|
||||
return enabled
|
||||
? backgroundColor ?? ColorsManager.primaryColor
|
||||
: Colors.grey;
|
||||
}),
|
||||
shape: MaterialStateProperty.all(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(borderRadius ?? 20),
|
||||
),
|
||||
),
|
||||
fixedSize: MaterialStateProperty.all(
|
||||
const Size.fromHeight(50),
|
||||
),
|
||||
padding: MaterialStateProperty.all(
|
||||
EdgeInsets.all(padding ?? 10),
|
||||
),
|
||||
minimumSize: MaterialStateProperty.all(
|
||||
const Size.fromHeight(50),
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
height: height ?? 50,
|
||||
child: Center(
|
||||
child: isLoading
|
||||
? const SizedBox.square(
|
||||
dimension: 24,
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
),
|
||||
)
|
||||
: isDone
|
||||
? const Text('Done') :child ,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -81,8 +81,7 @@ abstract class ApiEndpoints {
|
||||
static const String controlGroup = '/group/control';
|
||||
//GET
|
||||
static const String groupBySpace = '/group/{unitUuid}';
|
||||
static const String devicesByGroupName =
|
||||
'/group/{unitUuid}/devices/{groupName}';
|
||||
static const String devicesByGroupName = '/group/{unitUuid}/devices/{groupName}';
|
||||
|
||||
static const String groupByUuid = '/group/{groupUuid}';
|
||||
//DELETE
|
||||
@ -94,18 +93,17 @@ abstract class ApiEndpoints {
|
||||
static const String addDeviceToRoom = '/device/room';
|
||||
static const String addDeviceToGroup = '/device/group';
|
||||
static const String controlDevice = '/device/{deviceUuid}/control';
|
||||
static const String firmwareDevice =
|
||||
'/device/{deviceUuid}/firmware/{firmwareVersion}';
|
||||
static const String firmwareDevice = '/device/{deviceUuid}/firmware/{firmwareVersion}';
|
||||
static const String getDevicesByUserId = '/device/user/{userId}';
|
||||
static const String getDevicesByUnitId = '/device/unit/{unitUuid}';
|
||||
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
||||
|
||||
//GET
|
||||
static const String deviceByRoom = '/device/room';
|
||||
static const String deviceByUuid = '/device/{deviceUuid}';
|
||||
static const String deviceFunctions = '/device/{deviceUuid}/functions';
|
||||
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
||||
static const String deviceFunctionsStatus =
|
||||
'/device/{deviceUuid}/functions/status';
|
||||
static const String deviceFunctionsStatus = '/device/{deviceUuid}/functions/status';
|
||||
|
||||
///Device Permission Module
|
||||
//POST
|
||||
@ -130,29 +128,24 @@ abstract class ApiEndpoints {
|
||||
|
||||
static const String getUnitAutomation = '/automation/{unitUuid}';
|
||||
|
||||
static const String getAutomationDetails =
|
||||
'/automation/details/{automationId}';
|
||||
static const String getAutomationDetails = '/automation/details/{automationId}';
|
||||
|
||||
/// PUT
|
||||
static const String updateScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
static const String updateAutomation = '/automation/{automationId}';
|
||||
|
||||
static const String updateAutomationStatus =
|
||||
'/automation/status/{automationId}';
|
||||
static const String updateAutomationStatus = '/automation/status/{automationId}';
|
||||
|
||||
/// DELETE
|
||||
static const String deleteScene = '/scene/tap-to-run/{unitUuid}/{sceneId}';
|
||||
|
||||
static const String deleteAutomation =
|
||||
'/automation/{unitUuid}/{automationId}';
|
||||
static const String deleteAutomation = '/automation/{unitUuid}/{automationId}';
|
||||
|
||||
//////////////////////Door Lock //////////////////////
|
||||
//online
|
||||
static const String addTemporaryPassword =
|
||||
'/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
static const String getTemporaryPassword =
|
||||
'/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
static const String addTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
static const String getTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
|
||||
//one-time offline
|
||||
static const String addOneTimeTemporaryPassword =
|
||||
@ -160,16 +153,6 @@ abstract class ApiEndpoints {
|
||||
static const String getOneTimeTemporaryPassword =
|
||||
'/door-lock/temporary-password/offline/one-time/{doorLockUuid}';
|
||||
|
||||
//multiple-time offline
|
||||
static const String addMultipleTimeTemporaryPassword =
|
||||
'/door-lock/temporary-password/offline/multiple-time/{doorLockUuid}';
|
||||
static const String getMultipleTimeTemporaryPassword =
|
||||
'/door-lock/temporary-password/offline/multiple-time/{doorLockUuid}';
|
||||
|
||||
//multiple-time offline
|
||||
static const String deleteTemporaryPassword =
|
||||
'/door-lock/temporary-password/{doorLockUuid}/{passwordId}';
|
||||
|
||||
//user
|
||||
|
||||
static const String getUser = '/user/{userUuid}';
|
||||
@ -179,4 +162,17 @@ abstract class ApiEndpoints {
|
||||
static const String sendPicture = '/user/profile-picture/{userUuid}';
|
||||
static const String getRegion = '/region';
|
||||
static const String getTimezone = '/timezone';
|
||||
|
||||
//multiple-time offline
|
||||
static const String addMultipleTimeTemporaryPassword =
|
||||
'/door-lock/temporary-password/offline/multiple-time/{doorLockUuid}';
|
||||
static const String getMultipleTimeTemporaryPassword =
|
||||
'/door-lock/temporary-password/offline/multiple-time/{doorLockUuid}';
|
||||
|
||||
static const String renamePassword =
|
||||
'/door-lock/temporary-password/{doorLockUuid}/offline/{passwordId}';
|
||||
|
||||
//multiple-time offline
|
||||
static const String deleteTemporaryPassword =
|
||||
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
||||
}
|
||||
|
||||
@ -46,6 +46,17 @@ class DevicesAPI {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> openDoorLock(String deviceId) async {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.openDoorLock.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json['success'] ?? false;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<List<DevicesCategoryModel>> fetchGroups(String spaceId) async {
|
||||
// Map<String, dynamic> params = {"homeId": spaceId, "pageSize": 100, "pageNo": 1};
|
||||
|
||||
@ -69,6 +80,20 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> renamePass(
|
||||
{required String name, required String doorLockUuid, required String passwordId}) async {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.renamePassword
|
||||
.replaceAll('{doorLockUuid}', doorLockUuid)
|
||||
.replaceAll('{passwordId}', passwordId),
|
||||
body: {"name": name},
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
/// Get Device Functions
|
||||
static Future<FunctionModel> deviceFunctions(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
@ -138,14 +163,11 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future getTemporaryPasswords(String deviceId, pageType) async {
|
||||
static Future getTemporaryPasswords(
|
||||
String deviceId,
|
||||
) async {
|
||||
final response = await _httpService.get(
|
||||
path: pageType == 'One-Time'
|
||||
? ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId)
|
||||
: pageType == 'Online Password'
|
||||
? ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId)
|
||||
: ApiEndpoints.getMultipleTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -154,37 +176,49 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
//create password
|
||||
static Future getOneTimePasswords(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future getTimeLimitPasswords(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
//create password
|
||||
static Future createPassword({
|
||||
required String name,
|
||||
required String password,
|
||||
required String effectiveTime,
|
||||
required String invalidTime,
|
||||
required String deviceId,
|
||||
required String pageType,
|
||||
List<Schedule>? scheduleList,
|
||||
}) async {
|
||||
String endpointPath;
|
||||
if (pageType == 'Online Password') {
|
||||
endpointPath = ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId);
|
||||
} else if (pageType == 'One-Time') {
|
||||
endpointPath =
|
||||
ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId);
|
||||
} else {
|
||||
endpointPath =
|
||||
ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId);
|
||||
}
|
||||
Map<String, dynamic> body = {
|
||||
"name": name,
|
||||
"password": password,
|
||||
"effectiveTime": effectiveTime,
|
||||
"invalidTime": invalidTime,
|
||||
};
|
||||
if (pageType == 'Online Password' && scheduleList != null) {
|
||||
print('createPassword =$body');
|
||||
if (scheduleList != null) {
|
||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||
}
|
||||
final response = await _httpService.post(
|
||||
path: endpointPath,
|
||||
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
body: body,
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => json,
|
||||
@ -192,6 +226,37 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future generateOneTimePassword({deviceId}) async {
|
||||
try {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
|
||||
try {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: true,
|
||||
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> deletePassword(
|
||||
{required String passwordId, required String deviceId}) async {
|
||||
final response = await _httpService.delete(
|
||||
|
||||
352
pubspec.lock
@ -5,18 +5,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: fe4c077084ddda88f327dc1c96d16631cd68d4948644593fcbcd911c2c89e2fa
|
||||
sha256: "37a42d06068e2fe3deddb2da079a8c4d105f241225ba27b7122b37e9865fd8f7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.23"
|
||||
version: "1.3.35"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
||||
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.5.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -29,10 +29,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
sha256: f53a110e3b48dcd78136c10daa5d51512443cea5e1348c9d80a320095fa2db9e
|
||||
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.3"
|
||||
version: "8.1.4"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -45,26 +45,26 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cached_network_image
|
||||
sha256: "28ea9690a8207179c319965c13cd8df184d5ee721ae2ce60f398ced1219cea1f"
|
||||
sha256: "4a5d8d2c728b0f3d0245f69f921d7be90cae4c2fd5288f773088672c0893f819"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
version: "3.4.0"
|
||||
cached_network_image_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_platform_interface
|
||||
sha256: "9e90e78ae72caa874a323d78fa6301b3fb8fa7ea76a8f96dc5b5bf79f283bf2f"
|
||||
sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
version: "4.1.1"
|
||||
cached_network_image_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_web
|
||||
sha256: "42a835caa27c220d1294311ac409a43361088625a4f23c820b006dd9bffb3316"
|
||||
sha256: "6322dde7a5ad92202e64df659241104a43db20ed594c41ca18de1014598d7996"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.3.0"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -93,18 +93,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cross_file
|
||||
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
|
||||
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.4+1"
|
||||
version: "0.3.4+2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
||||
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
version: "3.0.5"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -117,10 +117,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cupertino_icons
|
||||
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
|
||||
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
version: "1.0.8"
|
||||
day_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -133,26 +133,34 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91
|
||||
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.1.0"
|
||||
version: "10.1.2"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
|
||||
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
version: "7.0.1"
|
||||
dio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dio
|
||||
sha256: "49af28382aefc53562459104f64d16b9dfd1e8ef68c862d5af436cc8356ce5a8"
|
||||
sha256: "0dfb6b6a1979dac1c1245e17cef824d7b452ea29bd33d3467269f9bef3715fb0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.1"
|
||||
version: "5.6.0"
|
||||
dio_web_adapter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio_web_adapter
|
||||
sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
equatable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -173,10 +181,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.3"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -213,74 +221,98 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0
|
||||
sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+1"
|
||||
version: "0.9.3+2"
|
||||
firebase_analytics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_analytics
|
||||
sha256: c6220b23397f9302a42617227ee8fb1c5d718097a5351fcce53561d73fc10339
|
||||
sha256: dbf1e7ab22cfb1f4a4adb103b46a26276b4edc593d4a78ef6fb942bafc92e035
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.8.7"
|
||||
version: "10.10.7"
|
||||
firebase_analytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_analytics_platform_interface
|
||||
sha256: "7f1c02cdd93a5e0a561af2f551465ffb6abdd541dbd0c8a9b8628d9ae0a5d024"
|
||||
sha256: "3729b74f8cf1d974a27ba70332ecb55ff5ff560edc8164a6469f4a055b429c37"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.9.7"
|
||||
version: "3.10.8"
|
||||
firebase_analytics_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_analytics_web
|
||||
sha256: ebb857c23f35fed52220b6c3271c12eeb6137de3930845223e3d0590b6fd0649
|
||||
sha256: "019cd7eee74254d33fbd2e29229367ce33063516bf6b3258a341d89e3b0f1655"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.5+19"
|
||||
version: "0.5.7+7"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "797379ea206eaeeb62499775de812761493d0692890fdc7f90b6183a3369176d"
|
||||
sha256: "26de145bb9688a90962faec6f838247377b0b0d32cc0abecd9a4e43525fc856c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.25.5"
|
||||
version: "2.32.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63
|
||||
sha256: f7d7180c7f99babd4b4c517754d41a09a4943a0f7a69b65c894ca5c68ba66315
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
version: "5.2.1"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: "22fcb352744908224fc7be3caae254836099786acfe5df6e9fe901e9c2575a41"
|
||||
sha256: "362e52457ed2b7b180964769c1e04d1e0ea0259fdf7025fdfedd019d4ae2bd88"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.17.1"
|
||||
version: "2.17.5"
|
||||
firebase_crashlytics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_crashlytics
|
||||
sha256: "0126fa101b74fb981796b3e6f47ccf7fc40237ec918327aaec7c0a06fd1bb4c1"
|
||||
sha256: "9897c01efaa950d2f6da8317d12452749a74dc45f33b46390a14cfe28067f271"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.16"
|
||||
version: "3.5.7"
|
||||
firebase_crashlytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_crashlytics_platform_interface
|
||||
sha256: cdfa0a20d66e1b32de542883c0ddf651ee9b66b12cebf73067e4d2cdc0865d17
|
||||
sha256: "16a71e08fbf6e00382816e1b13397898c29a54fa0ad969c2c2a3b82a704877f0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.6.23"
|
||||
version: "3.6.35"
|
||||
firebase_database:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_database
|
||||
sha256: "3b9ca306d26ad243ccbc4c717ff6e8563a080ebe11ee77fa7349b419c894b42d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.5.7"
|
||||
firebase_database_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_database_platform_interface
|
||||
sha256: "5864cc362275465e9bd682b243f19419c9d78b861c2db820241eea596ae3b320"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.5+35"
|
||||
firebase_database_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_database_web
|
||||
sha256: a6008395dd20e8b8dde0691b441c181a1216c3866f89f48dcb6889d34fd35905
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.5+7"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -314,18 +346,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
sha256: "87325da1ac757fcc4813e6b34ed5dd61169973871fdf181d6c2109dd6935ece1"
|
||||
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.4"
|
||||
version: "8.1.6"
|
||||
flutter_cache_manager:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_cache_manager
|
||||
sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba"
|
||||
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
version: "3.4.1"
|
||||
flutter_dotenv:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -338,18 +370,18 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
|
||||
sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
flutter_localization:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_localization
|
||||
sha256: faaeb1eba307473032e2c2af737f36ced61fc98735608410d0a6d9c231b50912
|
||||
sha256: c2918388c56fe2d555074215dba44bc47bd5c1036e6b237f72f210b7136cfe61
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "0.2.1"
|
||||
flutter_localizations:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -359,58 +391,58 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e
|
||||
sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.20"
|
||||
version: "2.0.22"
|
||||
flutter_secure_storage:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage
|
||||
sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685
|
||||
sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.0"
|
||||
version: "9.2.2"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_linux
|
||||
sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e"
|
||||
sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_macos
|
||||
sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c
|
||||
sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.1.2"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e"
|
||||
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.1.2"
|
||||
flutter_secure_storage_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_web
|
||||
sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20"
|
||||
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_windows
|
||||
sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108"
|
||||
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.1.2"
|
||||
flutter_svg:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -433,10 +465,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: get_it
|
||||
sha256: e6017ce7fdeaf218dc51a100344d8cb70134b80e28b760f8bb23c242437bafd7
|
||||
sha256: d85128a5dae4ea777324730dc65edd9c9f43155c109d5cc0a69cab74139fbac1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.6.7"
|
||||
version: "7.7.0"
|
||||
html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -449,10 +481,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
|
||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -473,18 +505,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: "4161e1f843d8480d2e9025ee22411778c3c9eb7e40076dcf2da23d8242b7b51c"
|
||||
sha256: c0a6763d50b354793d0192afd0a12560b823147d3ded7c6b77daf658fa05cc85
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+3"
|
||||
version: "0.8.12+13"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_for_web
|
||||
sha256: "5d6eb13048cd47b60dbf1a5495424dea226c5faf3950e20bf8120a58efb5b5f3"
|
||||
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.4"
|
||||
version: "3.0.5"
|
||||
image_picker_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -545,18 +577,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.4"
|
||||
version: "10.0.5"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
version: "3.0.5"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -585,26 +617,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.0"
|
||||
version: "0.11.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.0"
|
||||
version: "1.15.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
|
||||
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
version: "1.0.6"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -617,18 +649,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: octo_image
|
||||
sha256: "45b40f99622f11901238e18d48f5f12ea36426d8eced9f4cbf58479c7aa2430d"
|
||||
sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
onesignal_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: onesignal_flutter
|
||||
sha256: f3940387d6c7033a9c341aa0548f24d98217fce9182f9ad80bf2554b9dd3dc1a
|
||||
sha256: e733de4494edb651f768600c00481753a9015dc23518eadce72f339154454531
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
version: "5.2.3"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -649,26 +681,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
|
||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.4"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
||||
sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "2.2.10"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.4.0"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -689,10 +721,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
||||
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.3.0"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -705,34 +737,34 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_android
|
||||
sha256: "8bb852cd759488893805c3161d0b2b5db55db52f773dbb014420b304055ba2c5"
|
||||
sha256: "76e4ab092c1b240d31177bb64d2b0bea43f43d0e23541ec866151b9f7b2490fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.0.6"
|
||||
version: "12.0.12"
|
||||
permission_handler_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_apple
|
||||
sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662
|
||||
sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.4.4"
|
||||
version: "9.4.5"
|
||||
permission_handler_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_html
|
||||
sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
|
||||
sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.1"
|
||||
version: "0.1.3+2"
|
||||
permission_handler_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_platform_interface
|
||||
sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
|
||||
sha256: fe0ffe274d665be8e34f9c59705441a7d248edebbe5d9e3ec2665f88b79358ea
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.1"
|
||||
version: "4.2.2"
|
||||
permission_handler_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -761,10 +793,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "3.1.5"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -777,18 +809,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: provider
|
||||
sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
|
||||
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.1"
|
||||
version: "6.1.2"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: rxdart
|
||||
sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
|
||||
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.27.7"
|
||||
version: "0.28.0"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -809,58 +841,58 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
|
||||
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "2.3.2"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
|
||||
sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.3.2"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.5"
|
||||
version: "2.5.2"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
|
||||
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.4.1"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
|
||||
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.4.1"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
|
||||
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.4.2"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_windows
|
||||
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
|
||||
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.4.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -878,10 +910,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: smooth_page_indicator
|
||||
sha256: "725bc638d5e79df0c84658e1291449996943f93bacbc2cec49963dbbab48d8ae"
|
||||
sha256: "3b28b0c545fa67ed9e5997d9f9720d486f54c0c607e056a1094544e36934dff3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0+3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -902,18 +934,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite
|
||||
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
|
||||
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.3.3+1"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5"
|
||||
sha256: "7b41b6c3507854a159e24ae90a8e3e9cc01eb26a477c118d6dca065b5f55453e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.3"
|
||||
version: "2.5.4+2"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -942,10 +974,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: synchronized
|
||||
sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
|
||||
sha256: a824e842b8a054f91a728b783c177c1e4731f6b124f9192468457a8913371255
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0+1"
|
||||
version: "3.2.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -958,10 +990,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
version: "0.7.2"
|
||||
time_picker_spinner:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -982,74 +1014,74 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
|
||||
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.5"
|
||||
version: "6.3.0"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745
|
||||
sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.0"
|
||||
version: "6.3.10"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
|
||||
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.4"
|
||||
version: "6.3.1"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
|
||||
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
version: "3.2.0"
|
||||
url_launcher_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
|
||||
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.2.0"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_platform_interface
|
||||
sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f
|
||||
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
version: "2.3.2"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
|
||||
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
version: "2.3.3"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
|
||||
sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
version: "3.1.2"
|
||||
uuid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8"
|
||||
sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
version: "4.4.2"
|
||||
vector_graphics:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1086,10 +1118,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.1"
|
||||
version: "14.2.4"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1102,18 +1134,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
|
||||
sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
version: "5.5.4"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32_registry
|
||||
sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a"
|
||||
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.1.4"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1131,5 +1163,5 @@ packages:
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
sdks:
|
||||
dart: ">=3.4.0 <4.0.0"
|
||||
flutter: ">=3.22.0"
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
||||
@ -5,7 +5,7 @@ description: This is the mobile application project, developed with Flutter for
|
||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
version: 1.0.2+16
|
||||
version: 1.0.3+21
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.6 <4.0.0"
|
||||
@ -45,6 +45,7 @@ dependencies:
|
||||
time_picker_spinner: ^1.0.0
|
||||
image_picker: ^1.1.2
|
||||
device_info_plus: ^10.1.0
|
||||
firebase_database: ^10.5.7
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^3.0.1
|
||||
|
||||