mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
Merge branch 'dev' into link_space_model_spaces
This commit is contained in:
@ -1,5 +1,9 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.android.application"
|
id "com.android.application"
|
||||||
|
// START: FlutterFire Configuration
|
||||||
|
id 'com.google.gms.google-services'
|
||||||
|
id 'com.google.firebase.crashlytics'
|
||||||
|
// END: FlutterFire Configuration
|
||||||
id "kotlin-android"
|
id "kotlin-android"
|
||||||
id "dev.flutter.flutter-gradle-plugin"
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
}
|
}
|
||||||
|
68
android/app/google-services.json
Normal file
68
android/app/google-services.json
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "427332280600",
|
||||||
|
"firebase_url": "https://test2-8a3d2-default-rtdb.firebaseio.com",
|
||||||
|
"project_id": "test2-8a3d2",
|
||||||
|
"storage_bucket": "test2-8a3d2.firebasestorage.app"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:427332280600:android:550f67441246cb1a0c7e6d",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.example.syncrow.app"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:427332280600:android:bb6047adeeb80fb00c7e6d",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.example.syncrow_application"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:427332280600:android:2bc36fbe82994a3e0c7e6d",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.example.syncrow_web"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
@ -20,6 +20,10 @@ pluginManagement {
|
|||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
id "com.android.application" version "7.3.0" apply false
|
id "com.android.application" version "7.3.0" apply false
|
||||||
|
// START: FlutterFire Configuration
|
||||||
|
id "com.google.gms.google-services" version "4.3.15" apply false
|
||||||
|
id "com.google.firebase.crashlytics" version "2.8.1" apply false
|
||||||
|
// END: FlutterFire Configuration
|
||||||
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
|
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
assets/icons/delete_space_model.svg
Normal file
6
assets/icons/delete_space_model.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14.4 2.10938H11.7333V1.58203C11.7333 0.709699 11.0156 0 10.1333 0H5.86667C4.98443 0 4.26667 0.709699 4.26667 1.58203V2.10938H1.6C0.71776 2.10938 0 2.81907 0 3.69141C0 4.392 0.463111 4.9873 1.1024 5.19472L2.05369 16.5493C2.1222 17.3628 2.82258 18 3.64814 18H12.3519C13.1775 18 13.8778 17.3628 13.9464 16.5491L14.8976 5.19469C15.5369 4.9873 16 4.392 16 3.69141C16 2.81907 15.2822 2.10938 14.4 2.10938ZM5.33333 1.58203C5.33333 1.29125 5.57259 1.05469 5.86667 1.05469H10.1333C10.4274 1.05469 10.6667 1.29125 10.6667 1.58203V2.10938H5.33333V1.58203ZM12.8833 16.4618C12.8605 16.7329 12.6271 16.9453 12.3519 16.9453H3.64814C3.37298 16.9453 3.13952 16.7329 3.11673 16.462L2.17934 5.27344H13.8207L12.8833 16.4618ZM14.4 4.21875H1.6C1.30592 4.21875 1.06667 3.98218 1.06667 3.69141C1.06667 3.40063 1.30592 3.16406 1.6 3.16406H14.4C14.6941 3.16406 14.9333 3.40063 14.9333 3.69141C14.9333 3.98218 14.6941 4.21875 14.4 4.21875Z" fill="#999999"/>
|
||||||
|
<path d="M5.86561 15.3307L5.33228 6.82286C5.31404 6.53215 5.05957 6.31106 4.76698 6.32916C4.47297 6.3472 4.24943 6.59744 4.26764 6.88811L4.80097 15.396C4.8185 15.6756 5.05331 15.8907 5.33278 15.8907C5.64165 15.8907 5.88456 15.6335 5.86561 15.3307Z" fill="#999999"/>
|
||||||
|
<path d="M7.99989 6.32812C7.70534 6.32812 7.46655 6.56423 7.46655 6.85547V15.3633C7.46655 15.6545 7.70534 15.8906 7.99989 15.8906C8.29443 15.8906 8.53322 15.6545 8.53322 15.3633V6.85547C8.53322 6.56423 8.29443 6.32812 7.99989 6.32812Z" fill="#999999"/>
|
||||||
|
<path d="M11.233 6.32915C10.9396 6.31112 10.6859 6.53215 10.6677 6.82285L10.1343 15.3307C10.1162 15.6213 10.3397 15.8716 10.6337 15.8896C10.9278 15.9076 11.1808 15.6865 11.199 15.3959L11.7323 6.8881C11.7505 6.5974 11.527 6.34715 11.233 6.32915Z" fill="#999999"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
1
firebase.json
Normal file
1
firebase.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"flutter":{"platforms":{"android":{"default":{"projectId":"test2-8a3d2","appId":"1:427332280600:android:2bc36fbe82994a3e0c7e6d","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"test2-8a3d2","appId":"1:427332280600:ios:14346b200780dc760c7e6d","uploadDebugSymbols":true,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"macos":{"default":{"projectId":"test2-8a3d2","appId":"1:427332280600:ios:14346b200780dc760c7e6d","uploadDebugSymbols":true,"fileOutput":"macos/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"test2-8a3d2","configurations":{"android":"1:427332280600:android:2bc36fbe82994a3e0c7e6d","ios":"1:427332280600:ios:14346b200780dc760c7e6d","macos":"1:427332280600:ios:14346b200780dc760c7e6d","web":"1:427332280600:web:ad50516a87a35a1a0c7e6d","windows":"1:427332280600:web:f7a25537ccd5a7bd0c7e6d"}}}}}}
|
@ -15,6 +15,7 @@
|
|||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||||
E44A9405B1EB1B638DD05A58 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */; };
|
E44A9405B1EB1B638DD05A58 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */; };
|
||||||
|
F2A3345EC3021060731668D3 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B14AB50E8716720E10D074BD /* GoogleService-Info.plist */; };
|
||||||
FF49F60EC38658783D8D66DA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */; };
|
FF49F60EC38658783D8D66DA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@ -64,6 +65,7 @@
|
|||||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
B14AB50E8716720E10D074BD /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
D3AD250AADBF93406007C9EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
D3AD250AADBF93406007C9EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@ -138,6 +140,7 @@
|
|||||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||||
1454C118FFCECEEDF59152D2 /* Pods */,
|
1454C118FFCECEEDF59152D2 /* Pods */,
|
||||||
20A3C64D2B1CFED5A81C3251 /* Frameworks */,
|
20A3C64D2B1CFED5A81C3251 /* Frameworks */,
|
||||||
|
B14AB50E8716720E10D074BD /* GoogleService-Info.plist */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@ -199,6 +202,7 @@
|
|||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */,
|
33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */,
|
||||||
|
7A77858F6F15CB76D2D3A872 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -264,6 +268,7 @@
|
|||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||||
|
F2A3345EC3021060731668D3 /* GoogleService-Info.plist in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -303,6 +308,24 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||||
};
|
};
|
||||||
|
7A77858F6F15CB76D2D3A872 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\"\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --platform=ios --apple-project-path=\"${SRCROOT}\" --env-platform-name=\"${PLATFORM_NAME}\" --env-configuration=\"${CONFIGURATION}\" --env-project-dir=\"${PROJECT_DIR}\" --env-built-products-dir=\"${BUILT_PRODUCTS_DIR}\" --env-dwarf-dsym-folder-path=\"${DWARF_DSYM_FOLDER_PATH}\" --env-dwarf-dsym-file-name=\"${DWARF_DSYM_FILE_NAME}\" --env-infoplist-path=\"${INFOPLIST_PATH}\" --default-config=default\n";
|
||||||
|
};
|
||||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
|
32
ios/Runner/GoogleService-Info.plist
Normal file
32
ios/Runner/GoogleService-Info.plist
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>427332280600</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>com.example.syncrowWeb</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>test2-8a3d2</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>test2-8a3d2.firebasestorage.app</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:427332280600:ios:14346b200780dc760c7e6d</string>
|
||||||
|
<key>DATABASE_URL</key>
|
||||||
|
<string>https://test2-8a3d2-default-rtdb.firebaseio.com</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -20,15 +20,22 @@ class DialogTextfieldDropdown extends StatefulWidget {
|
|||||||
|
|
||||||
class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
||||||
bool _isOpen = false;
|
bool _isOpen = false;
|
||||||
late OverlayEntry _overlayEntry;
|
OverlayEntry? _overlayEntry;
|
||||||
final TextEditingController _controller = TextEditingController();
|
final TextEditingController _controller = TextEditingController();
|
||||||
late List<String> _filteredItems; // Filtered items list
|
final FocusNode _focusNode = FocusNode();
|
||||||
|
List<String> _filteredItems = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_controller.text = widget.initialValue ?? 'Select Tag';
|
_controller.text = widget.initialValue ?? '';
|
||||||
_filteredItems = List.from(widget.items); // Initialize filtered items
|
_filteredItems = List.from(widget.items);
|
||||||
|
|
||||||
|
_focusNode.addListener(() {
|
||||||
|
if (!_focusNode.hasFocus) {
|
||||||
|
_closeDropdown();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleDropdown() {
|
void _toggleDropdown() {
|
||||||
@ -41,14 +48,17 @@ class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
|||||||
|
|
||||||
void _openDropdown() {
|
void _openDropdown() {
|
||||||
_overlayEntry = _createOverlayEntry();
|
_overlayEntry = _createOverlayEntry();
|
||||||
Overlay.of(context).insert(_overlayEntry);
|
Overlay.of(context).insert(_overlayEntry!);
|
||||||
_isOpen = true;
|
_isOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _closeDropdown() {
|
void _closeDropdown() {
|
||||||
_overlayEntry.remove();
|
if (_isOpen && _overlayEntry != null) {
|
||||||
|
_overlayEntry!.remove();
|
||||||
|
_overlayEntry = null;
|
||||||
_isOpen = false;
|
_isOpen = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OverlayEntry _createOverlayEntry() {
|
OverlayEntry _createOverlayEntry() {
|
||||||
final renderBox = context.findRenderObject() as RenderBox;
|
final renderBox = context.findRenderObject() as RenderBox;
|
||||||
@ -58,9 +68,7 @@ class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
|||||||
return OverlayEntry(
|
return OverlayEntry(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: _closeDropdown,
|
||||||
_closeDropdown();
|
|
||||||
},
|
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
@ -72,14 +80,15 @@ class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
|||||||
elevation: 4.0,
|
elevation: 4.0,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.whiteColors,
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(maxHeight: 200.0),
|
||||||
maxHeight: 200.0,
|
child: StatefulBuilder(
|
||||||
),
|
builder: (context, setStateDropdown) {
|
||||||
child: ListView.builder(
|
return ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: _filteredItems.length,
|
itemCount: _filteredItems.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = _filteredItems[index];
|
final item = _filteredItems[index];
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
border: Border(
|
border: Border(
|
||||||
@ -95,7 +104,8 @@ class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium
|
.bodyMedium
|
||||||
?.copyWith(
|
?.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor)),
|
color: ColorsManager
|
||||||
|
.textPrimaryColor)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_controller.text = item;
|
_controller.text = item;
|
||||||
widget.onSelected(item);
|
widget.onSelected(item);
|
||||||
@ -108,6 +118,8 @@ class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -122,7 +134,8 @@ class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: _toggleDropdown,
|
onTap: () => FocusScope.of(context).unfocus(),
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -135,23 +148,26 @@ class _DialogTextfieldDropdownState extends State<DialogTextfieldDropdown> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
onChanged: (value) {
|
focusNode: _focusNode,
|
||||||
setState(() {
|
onFieldSubmitted: (value) {
|
||||||
_filteredItems = widget.items
|
|
||||||
.where((item) =>
|
|
||||||
item.toLowerCase().contains(value.toLowerCase()))
|
|
||||||
.toList(); // Filter items dynamically
|
|
||||||
});
|
|
||||||
widget.onSelected(value);
|
widget.onSelected(value);
|
||||||
|
_closeDropdown();
|
||||||
|
},
|
||||||
|
onTapOutside: (event) {
|
||||||
|
widget.onSelected(_controller.text);
|
||||||
|
_closeDropdown();
|
||||||
},
|
},
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
hintText: 'Enter or Select tag',
|
hintText: 'Enter or Select a tag',
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Icon(Icons.arrow_drop_down),
|
GestureDetector(
|
||||||
|
onTap: _toggleDropdown,
|
||||||
|
child: const Icon(Icons.arrow_drop_down),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
93
lib/firebase_options_dev.dart
Normal file
93
lib/firebase_options_dev.dart
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// File generated by FlutterFire CLI.
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
|
||||||
|
import 'package:flutter/foundation.dart'
|
||||||
|
show defaultTargetPlatform, kIsWeb, TargetPlatform;
|
||||||
|
|
||||||
|
/// Default [FirebaseOptions] for use with your Firebase apps.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// import 'firebase_options.dart';
|
||||||
|
/// // ...
|
||||||
|
/// await Firebase.initializeApp(
|
||||||
|
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
class DefaultFirebaseOptionsDev {
|
||||||
|
static FirebaseOptions get currentPlatform {
|
||||||
|
if (kIsWeb) {
|
||||||
|
return web;
|
||||||
|
}
|
||||||
|
switch (defaultTargetPlatform) {
|
||||||
|
case TargetPlatform.android:
|
||||||
|
return android;
|
||||||
|
case TargetPlatform.iOS:
|
||||||
|
return ios;
|
||||||
|
case TargetPlatform.macOS:
|
||||||
|
return macos;
|
||||||
|
case TargetPlatform.windows:
|
||||||
|
return windows;
|
||||||
|
case TargetPlatform.linux:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for linux - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions are not supported for this platform.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FirebaseOptions web = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyCVEvKsJYzhWDFM-9Od68FE0nPpP933st0',
|
||||||
|
appId: '1:427332280600:web:ad50516a87a35a1a0c7e6d',
|
||||||
|
messagingSenderId: '427332280600',
|
||||||
|
projectId: 'test2-8a3d2',
|
||||||
|
authDomain: 'test2-8a3d2.firebaseapp.com',
|
||||||
|
databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'test2-8a3d2.firebasestorage.app',
|
||||||
|
measurementId: 'G-Z1RTTTV5H9',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions android = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyA5qOErxdm0zJmoHIB0TixfebYEsNRpwV0',
|
||||||
|
appId: '1:427332280600:android:2bc36fbe82994a3e0c7e6d',
|
||||||
|
messagingSenderId: '427332280600',
|
||||||
|
projectId: 'test2-8a3d2',
|
||||||
|
databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'test2-8a3d2.firebasestorage.app',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions ios = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw',
|
||||||
|
appId: '1:427332280600:ios:14346b200780dc760c7e6d',
|
||||||
|
messagingSenderId: '427332280600',
|
||||||
|
projectId: 'test2-8a3d2',
|
||||||
|
databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'test2-8a3d2.firebasestorage.app',
|
||||||
|
iosBundleId: 'com.example.syncrowWeb',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions macos = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw',
|
||||||
|
appId: '1:427332280600:ios:14346b200780dc760c7e6d',
|
||||||
|
messagingSenderId: '427332280600',
|
||||||
|
projectId: 'test2-8a3d2',
|
||||||
|
databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'test2-8a3d2.firebasestorage.app',
|
||||||
|
iosBundleId: 'com.example.syncrowWeb',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions windows = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyDizKjPC5rdkEjDxwXjM-RU5unB0Ziq3iw',
|
||||||
|
appId: '1:427332280600:web:f7a25537ccd5a7bd0c7e6d',
|
||||||
|
messagingSenderId: '427332280600',
|
||||||
|
projectId: 'test2-8a3d2',
|
||||||
|
authDomain: 'test2-8a3d2.firebaseapp.com',
|
||||||
|
databaseURL: 'https://test2-8a3d2-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'test2-8a3d2.firebasestorage.app',
|
||||||
|
measurementId: 'G-4LFVXEXWKY',
|
||||||
|
);
|
||||||
|
}
|
77
lib/firebase_options_prod.dart
Normal file
77
lib/firebase_options_prod.dart
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// File generated by FlutterFire CLI.
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
|
||||||
|
import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb, TargetPlatform;
|
||||||
|
|
||||||
|
/// Default [FirebaseOptions] for use with your Firebase apps.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// import 'firebase_options.dart';
|
||||||
|
/// // ...
|
||||||
|
/// await Firebase.initializeApp(
|
||||||
|
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
class DefaultFirebaseOptionsStaging {
|
||||||
|
static FirebaseOptions get currentPlatform {
|
||||||
|
if (kIsWeb) {
|
||||||
|
return web;
|
||||||
|
}
|
||||||
|
switch (defaultTargetPlatform) {
|
||||||
|
case TargetPlatform.android:
|
||||||
|
return android;
|
||||||
|
case TargetPlatform.iOS:
|
||||||
|
return ios;
|
||||||
|
case TargetPlatform.macOS:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for macos - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
case TargetPlatform.windows:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for windows - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
case TargetPlatform.linux:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for linux - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions are not supported for this platform.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FirebaseOptions android = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyDP9GpYfLE8gHTj3kZ1hW8fx_FkJqOqSQk',
|
||||||
|
appId: '1:786692570726:android:0ef7079c2b978d4417b7a7',
|
||||||
|
messagingSenderId: '786692570726',
|
||||||
|
projectId: 'syncrow-staging',
|
||||||
|
databaseURL: 'https://syncrow-staging-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'syncrow-staging.appspot.com',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions ios = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyAWlRiuJ75FMlf2_UDdri1voWKvkaSHtRg',
|
||||||
|
appId: '1:786692570726:ios:455a6fcff77e130f17b7a7',
|
||||||
|
messagingSenderId: '786692570726',
|
||||||
|
projectId: 'syncrow-staging',
|
||||||
|
databaseURL: 'https://syncrow-staging-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'syncrow-staging.appspot.com',
|
||||||
|
iosBundleId: 'com.example.syncrow.app',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions web = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyDyGaQ3sZhb4meaY6sGke-YglhdhJ2is8Q',
|
||||||
|
appId: '1:786692570726:web:93c931e6701797b317b7a7',
|
||||||
|
messagingSenderId: '786692570726',
|
||||||
|
projectId: 'syncrow-staging',
|
||||||
|
authDomain: 'syncrow-staging.firebaseapp.com',
|
||||||
|
databaseURL: 'https://syncrow-staging-default-rtdb.firebaseio.com',
|
||||||
|
storageBucket: 'syncrow-staging.appspot.com',
|
||||||
|
measurementId: 'G-CZ3J3G6LMQ',
|
||||||
|
);
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:syncrow_web/firebase_options_dev.dart';
|
||||||
|
import 'package:syncrow_web/firebase_options_prod.dart';
|
||||||
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
||||||
@ -18,9 +21,13 @@ import 'package:syncrow_web/utils/theme/theme.dart';
|
|||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
try {
|
try {
|
||||||
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
const environment =
|
||||||
|
String.fromEnvironment('FLAVOR', defaultValue: 'production');
|
||||||
await dotenv.load(fileName: '.env.$environment');
|
await dotenv.load(fileName: '.env.$environment');
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
await Firebase.initializeApp(
|
||||||
|
options: DefaultFirebaseOptionsStaging.currentPlatform,
|
||||||
|
);
|
||||||
initialSetup();
|
initialSetup();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
@ -49,7 +56,8 @@ class MyApp extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
BlocProvider(
|
||||||
|
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||||
BlocProvider<VisitorPasswordBloc>(
|
BlocProvider<VisitorPasswordBloc>(
|
||||||
create: (context) => VisitorPasswordBloc(),
|
create: (context) => VisitorPasswordBloc(),
|
||||||
),
|
),
|
||||||
|
84
lib/main_dev.dart
Normal file
84
lib/main_dev.dart
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:syncrow_web/firebase_options_dev.dart';
|
||||||
|
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
||||||
|
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
|
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
||||||
|
import 'package:syncrow_web/services/locator.dart';
|
||||||
|
import 'package:syncrow_web/utils/app_routes.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
||||||
|
import 'package:syncrow_web/utils/theme/theme.dart';
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
try {
|
||||||
|
const environment =
|
||||||
|
String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
||||||
|
await dotenv.load(fileName: '.env.$environment');
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
await Firebase.initializeApp(
|
||||||
|
options: DefaultFirebaseOptionsDev.currentPlatform,
|
||||||
|
);
|
||||||
|
initialSetup();
|
||||||
|
} catch (_) {}
|
||||||
|
runApp(MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
MyApp({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final GoRouter _router = GoRouter(
|
||||||
|
initialLocation: RoutesConst.auth,
|
||||||
|
routes: AppRoutes.getRoutes(),
|
||||||
|
redirect: (context, state) async {
|
||||||
|
String checkToken = await AuthBloc.getTokenAndValidate();
|
||||||
|
final loggedIn = checkToken == 'Success';
|
||||||
|
final goingToLogin = state.uri.toString() == RoutesConst.auth;
|
||||||
|
|
||||||
|
if (!loggedIn && !goingToLogin) return RoutesConst.auth;
|
||||||
|
if (loggedIn && goingToLogin) return RoutesConst.home;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MultiBlocProvider(
|
||||||
|
providers: [
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||||
|
BlocProvider<VisitorPasswordBloc>(
|
||||||
|
create: (context) => VisitorPasswordBloc(),
|
||||||
|
),
|
||||||
|
BlocProvider<RoutineBloc>(
|
||||||
|
create: (context) => RoutineBloc(),
|
||||||
|
),
|
||||||
|
BlocProvider<SpaceTreeBloc>(
|
||||||
|
create: (context) => SpaceTreeBloc()..add(InitialEvent()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: MaterialApp.router(
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
scrollBehavior: const MaterialScrollBehavior().copyWith(
|
||||||
|
dragDevices: {
|
||||||
|
PointerDeviceKind.mouse,
|
||||||
|
PointerDeviceKind.touch,
|
||||||
|
PointerDeviceKind.stylus,
|
||||||
|
PointerDeviceKind.unknown,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
theme: myTheme,
|
||||||
|
routerConfig: _router,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ import 'package:syncrow_web/utils/constants/assets.dart';
|
|||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
|
|
||||||
class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
||||||
@ -33,11 +34,9 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
|
|
||||||
return WebScaffold(
|
return WebScaffold(
|
||||||
enableMenuSidebar: false,
|
enableMenuSidebar: false,
|
||||||
appBarTitle: FittedBox(
|
appBarTitle: Text(
|
||||||
child: Text(
|
|
||||||
'Access Management',
|
'Access Management',
|
||||||
style: Theme.of(context).textTheme.headlineLarge,
|
style: ResponsiveTextTheme.of(context).deviceManagementTitle,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
rightBody: const NavigateHomeGridView(),
|
rightBody: const NavigateHomeGridView(),
|
||||||
scaffoldBody: BlocProvider(
|
scaffoldBody: BlocProvider(
|
||||||
|
@ -10,9 +10,12 @@ import 'package:syncrow_web/pages/auth/model/region_model.dart';
|
|||||||
import 'package:syncrow_web/pages/auth/model/token.dart';
|
import 'package:syncrow_web/pages/auth/model/token.dart';
|
||||||
import 'package:syncrow_web/pages/auth/model/user_model.dart';
|
import 'package:syncrow_web/pages/auth/model/user_model.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
import 'package:syncrow_web/services/auth_api.dart';
|
import 'package:syncrow_web/services/auth_api.dart';
|
||||||
import 'package:syncrow_web/utils/constants/strings_manager.dart';
|
import 'package:syncrow_web/utils/constants/strings_manager.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart';
|
import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart';
|
||||||
|
import 'package:syncrow_web/utils/navigation_service.dart';
|
||||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||||
|
|
||||||
class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
||||||
@ -32,8 +35,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
|
|
||||||
////////////////////////////// forget password //////////////////////////////////
|
////////////////////////////// forget password //////////////////////////////////
|
||||||
final TextEditingController forgetEmailController = TextEditingController();
|
final TextEditingController forgetEmailController = TextEditingController();
|
||||||
final TextEditingController forgetPasswordController =
|
final TextEditingController forgetPasswordController = TextEditingController();
|
||||||
TextEditingController();
|
|
||||||
final TextEditingController forgetOtp = TextEditingController();
|
final TextEditingController forgetOtp = TextEditingController();
|
||||||
final forgetFormKey = GlobalKey<FormState>();
|
final forgetFormKey = GlobalKey<FormState>();
|
||||||
final forgetEmailKey = GlobalKey<FormState>();
|
final forgetEmailKey = GlobalKey<FormState>();
|
||||||
@ -50,8 +52,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_remainingTime = 1;
|
_remainingTime = 1;
|
||||||
add(UpdateTimerEvent(
|
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
|
||||||
remainingTime: _remainingTime, isButtonEnabled: false));
|
|
||||||
try {
|
try {
|
||||||
forgetEmailValidate = '';
|
forgetEmailValidate = '';
|
||||||
_remainingTime = (await AuthenticationAPI.sendOtp(
|
_remainingTime = (await AuthenticationAPI.sendOtp(
|
||||||
@ -88,8 +89,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
|
add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
|
||||||
} else {
|
} else {
|
||||||
add(UpdateTimerEvent(
|
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
|
||||||
remainingTime: _remainingTime, isButtonEnabled: false));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -99,8 +99,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
|
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changePassword(
|
Future<void> changePassword(ChangePasswordEvent event, Emitter<AuthState> emit) async {
|
||||||
ChangePasswordEvent event, Emitter<AuthState> emit) async {
|
|
||||||
emit(LoadingForgetState());
|
emit(LoadingForgetState());
|
||||||
try {
|
try {
|
||||||
var response = await AuthenticationAPI.verifyOtp(
|
var response = await AuthenticationAPI.verifyOtp(
|
||||||
@ -116,8 +115,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
}
|
}
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
String errorMessage =
|
String errorMessage = errorData['error']['message'] ?? 'something went wrong';
|
||||||
errorData['error']['message'] ?? 'something went wrong';
|
|
||||||
validate = errorMessage;
|
validate = errorMessage;
|
||||||
emit(AuthInitialState());
|
emit(AuthInitialState());
|
||||||
}
|
}
|
||||||
@ -131,9 +129,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) {
|
void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) {
|
||||||
emit(TimerState(
|
emit(TimerState(isButtonEnabled: event.isButtonEnabled, remainingTime: event.remainingTime));
|
||||||
isButtonEnabled: event.isButtonEnabled,
|
|
||||||
remainingTime: event.remainingTime));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////// login /////////////////////////////////////
|
///////////////////////////////////// login /////////////////////////////////////
|
||||||
@ -183,15 +179,13 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
|
|
||||||
if (token.accessTokenIsNotEmpty) {
|
if (token.accessTokenIsNotEmpty) {
|
||||||
FlutterSecureStorage storage = const FlutterSecureStorage();
|
FlutterSecureStorage storage = const FlutterSecureStorage();
|
||||||
await storage.write(
|
await storage.write(key: Token.loginAccessTokenKey, value: token.accessToken);
|
||||||
key: Token.loginAccessTokenKey, value: token.accessToken);
|
|
||||||
const FlutterSecureStorage().write(
|
const FlutterSecureStorage().write(
|
||||||
key: UserModel.userUuidKey,
|
key: UserModel.userUuidKey,
|
||||||
value: Token.decodeToken(token.accessToken)['uuid'].toString());
|
value: Token.decodeToken(token.accessToken)['uuid'].toString());
|
||||||
user = UserModel.fromToken(token);
|
user = UserModel.fromToken(token);
|
||||||
loginEmailController.clear();
|
loginEmailController.clear();
|
||||||
loginPasswordController.clear();
|
loginPasswordController.clear();
|
||||||
debugPrint("token " + token.accessToken);
|
|
||||||
emit(LoginSuccess());
|
emit(LoginSuccess());
|
||||||
} else {
|
} else {
|
||||||
emit(const LoginFailure(error: 'Something went wrong'));
|
emit(const LoginFailure(error: 'Something went wrong'));
|
||||||
@ -342,14 +336,12 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
static Future<String> getTokenAndValidate() async {
|
static Future<String> getTokenAndValidate() async {
|
||||||
try {
|
try {
|
||||||
const storage = FlutterSecureStorage();
|
const storage = FlutterSecureStorage();
|
||||||
final firstLaunch = await SharedPreferencesHelper.readBoolFromSP(
|
final firstLaunch =
|
||||||
StringsManager.firstLaunch) ??
|
await SharedPreferencesHelper.readBoolFromSP(StringsManager.firstLaunch) ?? true;
|
||||||
true;
|
|
||||||
if (firstLaunch) {
|
if (firstLaunch) {
|
||||||
storage.deleteAll();
|
storage.deleteAll();
|
||||||
}
|
}
|
||||||
await SharedPreferencesHelper.saveBoolToSP(
|
await SharedPreferencesHelper.saveBoolToSP(StringsManager.firstLaunch, false);
|
||||||
StringsManager.firstLaunch, false);
|
|
||||||
final value = await storage.read(key: Token.loginAccessTokenKey) ?? '';
|
final value = await storage.read(key: Token.loginAccessTokenKey) ?? '';
|
||||||
if (value.isEmpty) {
|
if (value.isEmpty) {
|
||||||
return 'Token not found';
|
return 'Token not found';
|
||||||
@ -402,9 +394,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
final String formattedTime = [
|
final String formattedTime = [
|
||||||
if (days > 0) '${days}d', // Append 'd' for days
|
if (days > 0) '${days}d', // Append 'd' for days
|
||||||
if (days > 0 || hours > 0)
|
if (days > 0 || hours > 0)
|
||||||
hours
|
hours.toString().padLeft(2, '0'), // Show hours if there are days or hours
|
||||||
.toString()
|
|
||||||
.padLeft(2, '0'), // Show hours if there are days or hours
|
|
||||||
minutes.toString().padLeft(2, '0'),
|
minutes.toString().padLeft(2, '0'),
|
||||||
seconds.toString().padLeft(2, '0'),
|
seconds.toString().padLeft(2, '0'),
|
||||||
].join(':');
|
].join(':');
|
||||||
@ -445,6 +435,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|||||||
static Future<void> logout(BuildContext context) async {
|
static Future<void> logout(BuildContext context) async {
|
||||||
final storage = FlutterSecureStorage();
|
final storage = FlutterSecureStorage();
|
||||||
ProjectManager.clearProjectUUID();
|
ProjectManager.clearProjectUUID();
|
||||||
|
context.read<SpaceTreeBloc>().add(ClearAllData());
|
||||||
storage.deleteAll();
|
storage.deleteAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ class ForgetPasswordPage extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const ResponsiveLayout(
|
return const ResponsiveLayout(
|
||||||
desktopBody: ForgetPasswordWebPage(), mobileBody: ForgetPasswordWebPage());
|
tablet: ForgetPasswordWebPage(),
|
||||||
|
desktopBody: ForgetPasswordWebPage(),
|
||||||
|
mobileBody: ForgetPasswordWebPage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ class LoginPage extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const ResponsiveLayout(
|
return const ResponsiveLayout(
|
||||||
desktopBody: LoginWebPage(), mobileBody: LoginWebPage());
|
tablet: LoginWebPage(),
|
||||||
|
desktopBody: LoginWebPage(),
|
||||||
|
mobileBody: LoginWebPage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
@ -19,6 +20,7 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
on<AcControlEvent>(_onAcControl);
|
on<AcControlEvent>(_onAcControl);
|
||||||
on<AcBatchControlEvent>(_onAcBatchControl);
|
on<AcBatchControlEvent>(_onAcBatchControl);
|
||||||
on<AcFactoryResetEvent>(_onFactoryReset);
|
on<AcFactoryResetEvent>(_onFactoryReset);
|
||||||
|
on<AcStatusUpdated>(_onAcStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onFetchAcStatus(
|
FutureOr<void> _onFetchAcStatus(
|
||||||
@ -28,12 +30,64 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
final status =
|
final status =
|
||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status);
|
deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
emit(ACStatusLoaded(deviceStatus));
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(AcsFailedState(error: e.toString()));
|
emit(AcsFailedState(error: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
try {
|
||||||
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
|
stream.listen((DatabaseEvent event) async {
|
||||||
|
if (event.snapshot.value == null) return;
|
||||||
|
|
||||||
|
if (_timer != null) {
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
}
|
||||||
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
|
|
||||||
|
List<Status> statusList = [];
|
||||||
|
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus =
|
||||||
|
AcStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(AcStatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onAcStatusUpdated(AcStatusUpdated event, Emitter<AcsState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future<void> testFirebaseConnection() async {
|
||||||
|
// // Reference to a test node in your database
|
||||||
|
// final testRef = FirebaseDatabase.instance.ref("test");
|
||||||
|
|
||||||
|
// // Write a test value
|
||||||
|
// await testRef.set("Hello, Firebase!");
|
||||||
|
|
||||||
|
// // Listen for changes on the test node
|
||||||
|
// testRef.onValue.listen((DatabaseEvent event) {
|
||||||
|
// final data = event.snapshot.value;
|
||||||
|
// print("Data from Firebase: $data");
|
||||||
|
// // If you see "Hello, Firebase!" printed in your console, it means the connection works.
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
FutureOr<void> _onAcControl(
|
FutureOr<void> _onAcControl(
|
||||||
AcControlEvent event, Emitter<AcsState> emit) async {
|
AcControlEvent event, Emitter<AcsState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
|
||||||
sealed class AcsEvent extends Equatable {
|
sealed class AcsEvent extends Equatable {
|
||||||
@ -7,6 +8,7 @@ sealed class AcsEvent extends Equatable {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
class AcUpdated extends AcsEvent {}
|
||||||
|
|
||||||
class AcFetchDeviceStatusEvent extends AcsEvent {
|
class AcFetchDeviceStatusEvent extends AcsEvent {
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
@ -16,7 +18,10 @@ class AcFetchDeviceStatusEvent extends AcsEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId];
|
List<Object> get props => [deviceId];
|
||||||
}
|
}
|
||||||
|
class AcStatusUpdated extends AcsEvent {
|
||||||
|
final AcStatusModel deviceStatus;
|
||||||
|
AcStatusUpdated(this.deviceStatus);
|
||||||
|
}
|
||||||
class AcFetchBatchStatusEvent extends AcsEvent {
|
class AcFetchBatchStatusEvent extends AcsEvent {
|
||||||
final List<String> devicesIds;
|
final List<String> devicesIds;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/routines/view/routines_view.dart';
|
|||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
|
|
||||||
class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
||||||
@ -25,13 +26,12 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: WebScaffold(
|
child: WebScaffold(
|
||||||
appBarTitle: FittedBox(
|
appBarTitle: Text(
|
||||||
child: Text(
|
|
||||||
'Device Management',
|
'Device Management',
|
||||||
style: Theme.of(context).textTheme.headlineLarge,
|
style: ResponsiveTextTheme.of(context).deviceManagementTitle,
|
||||||
),
|
),
|
||||||
),
|
centerBody:
|
||||||
centerBody: BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
|
BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@ -48,8 +48,11 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'Devices',
|
'Devices',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
color: !state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor,
|
color: !state.routineTab
|
||||||
fontWeight: !state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
? ColorsManager.whiteColors
|
||||||
|
: ColorsManager.grayColor,
|
||||||
|
fontWeight:
|
||||||
|
!state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -58,13 +61,18 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
backgroundColor: null,
|
backgroundColor: null,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<RoutineBloc>().add(const TriggerSwitchTabsEvent(isRoutineTab: true));
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(const TriggerSwitchTabsEvent(isRoutineTab: true));
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Routines',
|
'Routines',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
color: state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor,
|
color: state.routineTab
|
||||||
fontWeight: state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
? ColorsManager.whiteColors
|
||||||
|
: ColorsManager.grayColor,
|
||||||
|
fontWeight:
|
||||||
|
state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -72,7 +80,8 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
rightBody: const NavigateHomeGridView(),
|
rightBody: const NavigateHomeGridView(),
|
||||||
scaffoldBody: BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
|
scaffoldBody:
|
||||||
|
BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
|
||||||
if (state.routineTab) {
|
if (state.routineTab) {
|
||||||
return const RoutinesView();
|
return const RoutinesView();
|
||||||
}
|
}
|
||||||
@ -87,7 +96,8 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
} else if (deviceState is DeviceManagementLoaded) {
|
} else if (deviceState is DeviceManagementLoaded) {
|
||||||
return DeviceManagementBody(devices: deviceState.devices);
|
return DeviceManagementBody(devices: deviceState.devices);
|
||||||
} else if (deviceState is DeviceManagementFiltered) {
|
} else if (deviceState is DeviceManagementFiltered) {
|
||||||
return DeviceManagementBody(devices: deviceState.filteredDevices);
|
return DeviceManagementBody(
|
||||||
|
devices: deviceState.filteredDevices);
|
||||||
} else {
|
} else {
|
||||||
return const Center(child: Text('Error fetching Devices'));
|
return const Center(child: Text('Error fetching Devices'));
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo
|
|||||||
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_search_filters.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_search_filters.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||||
import 'package:syncrow_web/utils/format_date_time.dart';
|
import 'package:syncrow_web/utils/format_date_time.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
@ -95,7 +94,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
const DeviceSearchFilters(),
|
const DeviceSearchFilters(),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Container(
|
Container(
|
||||||
height: 45,
|
// height: 45,
|
||||||
width: 125,
|
width: 125,
|
||||||
decoration: containerDecoration,
|
decoration: containerDecoration,
|
||||||
child: Center(
|
child: Center(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart';
|
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart';
|
||||||
@ -22,42 +23,55 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
on<ShowCeilingDescriptionEvent>(_showDescription);
|
on<ShowCeilingDescriptionEvent>(_showDescription);
|
||||||
on<BackToCeilingGridViewEvent>(_backToGridView);
|
on<BackToCeilingGridViewEvent>(_backToGridView);
|
||||||
on<CeilingFactoryResetEvent>(_onFactoryReset);
|
on<CeilingFactoryResetEvent>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchCeilingSensorStatus(
|
void _fetchCeilingSensorStatus(
|
||||||
CeilingInitialEvent event, Emitter<CeilingSensorState> emit) async {
|
CeilingInitialEvent event, Emitter<CeilingSensorState> emit) async {
|
||||||
emit(CeilingLoadingInitialState());
|
emit(CeilingLoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
var response =
|
||||||
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus = CeilingSensorModel.fromJson(response.status);
|
deviceStatus = CeilingSensorModel.fromJson(response.status);
|
||||||
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
|
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges(event.deviceId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(CeilingFailedState(error: e.toString()));
|
emit(CeilingFailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _listenToChanges() {
|
_listenToChanges(deviceId) {
|
||||||
// try {
|
try {
|
||||||
// DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
DatabaseReference ref =
|
||||||
// Stream<DatabaseEvent> stream = ref.onValue;
|
FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
// stream.listen((DatabaseEvent event) {
|
stream.listen((DatabaseEvent event) {
|
||||||
// Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
Map<dynamic, dynamic> usersMap =
|
||||||
// List<StatusModel> statusList = [];
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
|
|
||||||
// usersMap['status'].forEach((element) {
|
List<Status> statusList = [];
|
||||||
// statusList.add(StatusModel(code: element['code'], value: element['value']));
|
usersMap['status'].forEach((element) {
|
||||||
// });
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
// deviceStatus = WallSensorModel.fromJson(statusList);
|
deviceStatus = CeilingSensorModel.fromJson(statusList);
|
||||||
// add(WallSensorUpdatedEvent());
|
if (!isClosed) {
|
||||||
// });
|
add(StatusUpdated(deviceStatus));
|
||||||
// } catch (_) {}
|
}
|
||||||
// }
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
void _changeValue(CeilingChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
|
void _onStatusUpdated(StatusUpdated event, Emitter<CeilingSensorState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _changeValue(
|
||||||
|
CeilingChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
|
||||||
emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus));
|
emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus));
|
||||||
if (event.code == 'sensitivity') {
|
if (event.code == 'sensitivity') {
|
||||||
deviceStatus.sensitivity = event.value;
|
deviceStatus.sensitivity = event.value;
|
||||||
@ -122,7 +136,8 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
try {
|
try {
|
||||||
late bool response;
|
late bool response;
|
||||||
if (isBatch) {
|
if (isBatch) {
|
||||||
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
response = await DevicesManagementApi()
|
||||||
|
.deviceBatchControl(deviceId, code, value);
|
||||||
} else {
|
} else {
|
||||||
response = await DevicesManagementApi()
|
response = await DevicesManagementApi()
|
||||||
.deviceControl(deviceId, Status(code: code, value: value));
|
.deviceControl(deviceId, Status(code: code, value: value));
|
||||||
@ -143,8 +158,8 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _getDeviceReports(
|
FutureOr<void> _getDeviceReports(GetCeilingDeviceReportsEvent event,
|
||||||
GetCeilingDeviceReportsEvent event, Emitter<CeilingSensorState> emit) async {
|
Emitter<CeilingSensorState> emit) async {
|
||||||
if (event.code.isEmpty) {
|
if (event.code.isEmpty) {
|
||||||
emit(ShowCeilingDescriptionState(description: reportString));
|
emit(ShowCeilingDescriptionState(description: reportString));
|
||||||
return;
|
return;
|
||||||
@ -155,7 +170,8 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// await DevicesManagementApi.getDeviceReportsByDate(deviceId, event.code, from.toString(), to.toString())
|
// await DevicesManagementApi.getDeviceReportsByDate(deviceId, event.code, from.toString(), to.toString())
|
||||||
await DevicesManagementApi.getDeviceReports(deviceId, event.code).then((value) {
|
await DevicesManagementApi.getDeviceReports(deviceId, event.code)
|
||||||
|
.then((value) {
|
||||||
emit(CeilingReportsState(deviceReport: value));
|
emit(CeilingReportsState(deviceReport: value));
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -165,19 +181,23 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showDescription(ShowCeilingDescriptionEvent event, Emitter<CeilingSensorState> emit) {
|
void _showDescription(
|
||||||
|
ShowCeilingDescriptionEvent event, Emitter<CeilingSensorState> emit) {
|
||||||
emit(ShowCeilingDescriptionState(description: event.description));
|
emit(ShowCeilingDescriptionState(description: event.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _backToGridView(BackToCeilingGridViewEvent event, Emitter<CeilingSensorState> emit) {
|
void _backToGridView(
|
||||||
|
BackToCeilingGridViewEvent event, Emitter<CeilingSensorState> emit) {
|
||||||
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
|
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _fetchCeilingSensorBatchControl(
|
FutureOr<void> _fetchCeilingSensorBatchControl(
|
||||||
CeilingFetchDeviceStatusEvent event, Emitter<CeilingSensorState> emit) async {
|
CeilingFetchDeviceStatusEvent event,
|
||||||
|
Emitter<CeilingSensorState> emit) async {
|
||||||
emit(CeilingLoadingInitialState());
|
emit(CeilingLoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
var response =
|
||||||
|
await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
||||||
deviceStatus = CeilingSensorModel.fromJson(response.status);
|
deviceStatus = CeilingSensorModel.fromJson(response.status);
|
||||||
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
|
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
|
||||||
|
|
||||||
abstract class CeilingSensorEvent extends Equatable {
|
abstract class CeilingSensorEvent extends Equatable {
|
||||||
const CeilingSensorEvent();
|
const CeilingSensorEvent();
|
||||||
@ -83,3 +84,12 @@ class CeilingFactoryResetEvent extends CeilingSensorEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [devicesId, factoryResetModel];
|
List<Object> get props => [devicesId, factoryResetModel];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class StatusUpdated extends CeilingSensorEvent {
|
||||||
|
final CeilingSensorModel deviceStatus;
|
||||||
|
const StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart';
|
import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart';
|
||||||
@ -16,6 +17,7 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
|
|||||||
on<CurtainControl>(_onCurtainControl);
|
on<CurtainControl>(_onCurtainControl);
|
||||||
on<CurtainBatchControl>(_onCurtainBatchControl);
|
on<CurtainBatchControl>(_onCurtainBatchControl);
|
||||||
on<CurtainFactoryReset>(_onFactoryReset);
|
on<CurtainFactoryReset>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onFetchDeviceStatus(
|
FutureOr<void> _onFetchDeviceStatus(
|
||||||
@ -24,7 +26,7 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
|
|||||||
try {
|
try {
|
||||||
final status =
|
final status =
|
||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
deviceStatus = _checkStatus(status.status[0].value);
|
deviceStatus = _checkStatus(status.status[0].value);
|
||||||
|
|
||||||
emit(CurtainStatusLoaded(deviceStatus));
|
emit(CurtainStatusLoaded(deviceStatus));
|
||||||
@ -33,6 +35,48 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _listenToChanges(String deviceId) {
|
||||||
|
try {
|
||||||
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
|
stream.listen((DatabaseEvent event) {
|
||||||
|
final data = event.snapshot.value as Map<dynamic, dynamic>?;
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
|
List<Status> statusList = [];
|
||||||
|
if (data['status'] != null) {
|
||||||
|
for (var element in data['status']) {
|
||||||
|
statusList.add(
|
||||||
|
Status(
|
||||||
|
code: element['code'].toString(),
|
||||||
|
value: element['value'].toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (statusList.isNotEmpty) {
|
||||||
|
bool newStatus = _checkStatus(statusList[0].value);
|
||||||
|
if (newStatus != deviceStatus) {
|
||||||
|
deviceStatus = newStatus;
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
emit(CurtainError('Failed to listen to changes: $e'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(StatusUpdated event, Emitter<CurtainState> emit) {
|
||||||
|
emit(CurtainStatusLoading());
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(CurtainStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
FutureOr<void> _onCurtainControl(
|
FutureOr<void> _onCurtainControl(
|
||||||
CurtainControl event, Emitter<CurtainState> emit) async {
|
CurtainControl event, Emitter<CurtainState> emit) async {
|
||||||
final oldValue = deviceStatus;
|
final oldValue = deviceStatus;
|
||||||
|
@ -60,3 +60,7 @@ class CurtainFactoryReset extends CurtainEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId, factoryReset];
|
List<Object> get props => [deviceId, factoryReset];
|
||||||
}
|
}
|
||||||
|
class StatusUpdated extends CurtainEvent {
|
||||||
|
final bool deviceStatus;
|
||||||
|
const StatusUpdated(this.deviceStatus);
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_event.dart';
|
import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_event.dart';
|
||||||
@ -18,6 +19,39 @@ class DoorLockBloc extends Bloc<DoorLockEvent, DoorLockState> {
|
|||||||
//on<DoorLockControl>(_onDoorLockControl);
|
//on<DoorLockControl>(_onDoorLockControl);
|
||||||
on<UpdateLockEvent>(_updateLock);
|
on<UpdateLockEvent>(_updateLock);
|
||||||
on<DoorLockFactoryReset>(_onFactoryReset);
|
on<DoorLockFactoryReset>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus =
|
||||||
|
DoorLockStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(StatusUpdated event, Emitter<DoorLockState> emit) {
|
||||||
|
emit(DoorLockStatusLoading());
|
||||||
|
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(DoorLockStatusLoaded(deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onFetchDeviceStatus(
|
FutureOr<void> _onFetchDeviceStatus(
|
||||||
@ -28,6 +62,8 @@ class DoorLockBloc extends Bloc<DoorLockEvent, DoorLockState> {
|
|||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
DoorLockStatusModel.fromJson(event.deviceId, status.status);
|
DoorLockStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
|
|
||||||
emit(DoorLockStatusLoaded(deviceStatus));
|
emit(DoorLockStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(DoorLockControlError(e.toString()));
|
emit(DoorLockControlError(e.toString()));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/door_lock/models/door_lock_status_model.dart';
|
||||||
|
|
||||||
sealed class DoorLockEvent extends Equatable {
|
sealed class DoorLockEvent extends Equatable {
|
||||||
const DoorLockEvent();
|
const DoorLockEvent();
|
||||||
@ -51,3 +52,10 @@ class DoorLockFactoryReset extends DoorLockEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId, factoryReset];
|
List<Object> get props => [deviceId, factoryReset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends DoorLockEvent {
|
||||||
|
final DoorLockStatusModel deviceStatus;
|
||||||
|
const StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
|
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
|
||||||
@ -39,31 +40,68 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
on<GarageDoorFetchBatchStatusEvent>(_onFetchBatchStatus);
|
on<GarageDoorFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
on<GarageDoorFactoryResetEvent>(_onFactoryReset);
|
on<GarageDoorFactoryResetEvent>(_onFactoryReset);
|
||||||
on<EditGarageDoorScheduleEvent>(_onEditSchedule);
|
on<EditGarageDoorScheduleEvent>(_onEditSchedule);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
|
}
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus =
|
||||||
|
GarageDoorStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchGarageDoorStatus(GarageDoorInitialEvent event, Emitter<GarageDoorState> emit) async {
|
void _onStatusUpdated(StatusUpdated event, Emitter<GarageDoorState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _fetchGarageDoorStatus(
|
||||||
|
GarageDoorInitialEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
var response =
|
||||||
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status);
|
deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status);
|
||||||
|
_listenToChanges(deviceId);
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(GarageDoorErrorState(message: e.toString()));
|
emit(GarageDoorErrorState(message: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event,
|
||||||
|
Emitter<GarageDoorState> emit) async {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
final status =
|
||||||
deviceStatus = GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status);
|
await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus =
|
||||||
|
GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status);
|
||||||
emit(GarageDoorBatchStatusLoaded(deviceStatus));
|
emit(GarageDoorBatchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(GarageDoorBatchControlError(e.toString()));
|
emit(GarageDoorBatchControlError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _addSchedule(AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _addSchedule(
|
||||||
|
AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
ScheduleEntry newSchedule = ScheduleEntry(
|
ScheduleEntry newSchedule = ScheduleEntry(
|
||||||
category: event.category,
|
category: event.category,
|
||||||
@ -71,9 +109,11 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
function: Status(code: 'switch_1', value: event.functionOn),
|
function: Status(code: 'switch_1', value: event.functionOn),
|
||||||
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
|
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
|
||||||
);
|
);
|
||||||
bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
|
bool success =
|
||||||
|
await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
|
||||||
if (success) {
|
if (success) {
|
||||||
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
|
add(FetchGarageDoorSchedulesEvent(
|
||||||
|
deviceId: deviceId, category: 'switch_1'));
|
||||||
} else {
|
} else {
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
}
|
}
|
||||||
@ -82,16 +122,19 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onUpdateCountdownAlarm(UpdateCountdownAlarmEvent event, Emitter<GarageDoorState> emit) {
|
void _onUpdateCountdownAlarm(
|
||||||
|
UpdateCountdownAlarmEvent event, Emitter<GarageDoorState> emit) {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is GarageDoorLoadedState) {
|
if (currentState is GarageDoorLoadedState) {
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
status: currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
|
status:
|
||||||
|
currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onUpdateTrTimeCon(UpdateTrTimeConEvent event, Emitter<GarageDoorState> emit) {
|
void _onUpdateTrTimeCon(
|
||||||
|
UpdateTrTimeConEvent event, Emitter<GarageDoorState> emit) {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is GarageDoorLoadedState) {
|
if (currentState is GarageDoorLoadedState) {
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
@ -100,7 +143,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event,
|
||||||
|
Emitter<GarageDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
final updatedSchedules = deviceStatus.schedules?.map((schedule) {
|
final updatedSchedules = deviceStatus.schedules?.map((schedule) {
|
||||||
if (schedule.scheduleId == event.scheduleId) {
|
if (schedule.scheduleId == event.scheduleId) {
|
||||||
@ -127,12 +171,15 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event,
|
||||||
|
Emitter<GarageDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
bool success = await DevicesManagementApi().deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
|
bool success = await DevicesManagementApi()
|
||||||
|
.deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
|
||||||
if (success) {
|
if (success) {
|
||||||
final updatedSchedules =
|
final updatedSchedules = deviceStatus.schedules
|
||||||
deviceStatus.schedules?.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
|
?.where((schedule) => schedule.scheduleId != event.scheduleId)
|
||||||
|
.toList();
|
||||||
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
|
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
} else {
|
} else {
|
||||||
@ -143,11 +190,12 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event,
|
||||||
|
Emitter<GarageDoorState> emit) async {
|
||||||
emit(ScheduleGarageLoadingState());
|
emit(ScheduleGarageLoadingState());
|
||||||
try {
|
try {
|
||||||
List<ScheduleModel> schedules =
|
List<ScheduleModel> schedules = await DevicesManagementApi()
|
||||||
await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
|
.getDeviceSchedules(deviceStatus.uuid, event.category);
|
||||||
deviceStatus = deviceStatus.copyWith(schedules: schedules);
|
deviceStatus = deviceStatus.copyWith(schedules: schedules);
|
||||||
emit(
|
emit(
|
||||||
GarageDoorLoadedState(
|
GarageDoorLoadedState(
|
||||||
@ -165,30 +213,37 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateSelectedTime(UpdateSelectedTimeEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _updateSelectedTime(
|
||||||
|
UpdateSelectedTimeEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is GarageDoorLoadedState) {
|
if (currentState is GarageDoorLoadedState) {
|
||||||
emit(currentState.copyWith(selectedTime: event.selectedTime));
|
emit(currentState.copyWith(selectedTime: event.selectedTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateSelectedDay(UpdateSelectedDayEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _updateSelectedDay(
|
||||||
|
UpdateSelectedDayEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is GarageDoorLoadedState) {
|
if (currentState is GarageDoorLoadedState) {
|
||||||
List<bool> updatedDays = List.from(currentState.selectedDays);
|
List<bool> updatedDays = List.from(currentState.selectedDays);
|
||||||
updatedDays[event.dayIndex] = event.isSelected;
|
updatedDays[event.dayIndex] = event.isSelected;
|
||||||
emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
|
emit(currentState.copyWith(
|
||||||
|
selectedDays: updatedDays, selectedTime: currentState.selectedTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateFunctionOn(UpdateFunctionOnEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _updateFunctionOn(
|
||||||
|
UpdateFunctionOnEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is GarageDoorLoadedState) {
|
if (currentState is GarageDoorLoadedState) {
|
||||||
emit(currentState.copyWith(functionOn: event.functionOn, selectedTime: currentState.selectedTime));
|
emit(currentState.copyWith(
|
||||||
|
functionOn: event.functionOn,
|
||||||
|
selectedTime: currentState.selectedTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initializeAddSchedule(InitializeAddScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _initializeAddSchedule(
|
||||||
|
InitializeAddScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is GarageDoorLoadedState) {
|
if (currentState is GarageDoorLoadedState) {
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
@ -200,20 +255,25 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _fetchRecords(FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _fetchRecords(
|
||||||
|
FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
emit(GarageDoorReportsLoadingState());
|
emit(GarageDoorReportsLoadingState());
|
||||||
try {
|
try {
|
||||||
final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
|
final from = DateTime.now()
|
||||||
|
.subtract(const Duration(days: 30))
|
||||||
|
.millisecondsSinceEpoch;
|
||||||
final to = DateTime.now().millisecondsSinceEpoch;
|
final to = DateTime.now().millisecondsSinceEpoch;
|
||||||
final DeviceReport records =
|
final DeviceReport records =
|
||||||
await DevicesManagementApi.getDeviceReportsByDate(event.deviceId, 'switch_1', from.toString(), to.toString());
|
await DevicesManagementApi.getDeviceReportsByDate(
|
||||||
|
event.deviceId, 'switch_1', from.toString(), to.toString());
|
||||||
emit(GarageDoorReportsState(deviceReport: records));
|
emit(GarageDoorReportsState(deviceReport: records));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(GarageDoorReportsFailedState(error: e.toString()));
|
emit(GarageDoorReportsFailedState(error: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onBatchControl(GarageDoorBatchControlEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _onBatchControl(
|
||||||
|
GarageDoorBatchControlEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
final oldValue = event.code == 'switch_1' ? deviceStatus.switch1 : false;
|
final oldValue = event.code == 'switch_1' ? deviceStatus.switch1 : false;
|
||||||
|
|
||||||
_updateLocalValue(event.code, event.value);
|
_updateLocalValue(event.code, event.value);
|
||||||
@ -233,11 +293,13 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _backToGridView(BackToGarageDoorGridViewEvent event, Emitter<GarageDoorState> emit) {
|
void _backToGridView(
|
||||||
|
BackToGarageDoorGridViewEvent event, Emitter<GarageDoorState> emit) {
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleUpdate(GarageDoorUpdatedEvent event, Emitter<GarageDoorState> emit) {
|
void _handleUpdate(
|
||||||
|
GarageDoorUpdatedEvent event, Emitter<GarageDoorState> emit) {
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,9 +315,11 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
late bool status;
|
late bool status;
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
if (isBatch) {
|
if (isBatch) {
|
||||||
status = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
status = await DevicesManagementApi()
|
||||||
|
.deviceBatchControl(deviceId, code, value);
|
||||||
} else {
|
} else {
|
||||||
status = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
status = await DevicesManagementApi()
|
||||||
|
.deviceControl(deviceId, Status(code: code, value: value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@ -270,10 +334,12 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFactoryReset(GarageDoorFactoryResetEvent event, Emitter<GarageDoorState> emit) async {
|
Future<void> _onFactoryReset(
|
||||||
|
GarageDoorFactoryResetEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
emit(GarageDoorLoadingState());
|
emit(GarageDoorLoadingState());
|
||||||
try {
|
try {
|
||||||
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
final response = await DevicesManagementApi()
|
||||||
|
.factoryReset(event.factoryReset, event.deviceId);
|
||||||
if (!response) {
|
if (!response) {
|
||||||
emit(const GarageDoorErrorState(message: 'Failed to reset device'));
|
emit(const GarageDoorErrorState(message: 'Failed to reset device'));
|
||||||
} else {
|
} else {
|
||||||
@ -284,34 +350,47 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _increaseDelay(IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
|
void _increaseDelay(
|
||||||
|
IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
// if (deviceStatus.countdown1 != 0) {
|
// if (deviceStatus.countdown1 != 0) {
|
||||||
try {
|
try {
|
||||||
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay + Duration(minutes: 10));
|
deviceStatus = deviceStatus.copyWith(
|
||||||
|
delay: deviceStatus.delay + Duration(minutes: 10));
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
|
add(GarageDoorControlEvent(
|
||||||
|
deviceId: event.deviceId,
|
||||||
|
value: deviceStatus.delay.inSeconds,
|
||||||
|
code: 'countdown_1'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(GarageDoorErrorState(message: e.toString()));
|
emit(GarageDoorErrorState(message: e.toString()));
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void _decreaseDelay(DecreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
|
void _decreaseDelay(
|
||||||
|
DecreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
// if (deviceStatus.countdown1 != 0) {
|
// if (deviceStatus.countdown1 != 0) {
|
||||||
try {
|
try {
|
||||||
if (deviceStatus.delay.inMinutes > 10) {
|
if (deviceStatus.delay.inMinutes > 10) {
|
||||||
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay - Duration(minutes: 10));
|
deviceStatus = deviceStatus.copyWith(
|
||||||
|
delay: deviceStatus.delay - Duration(minutes: 10));
|
||||||
}
|
}
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
|
add(GarageDoorControlEvent(
|
||||||
|
deviceId: event.deviceId,
|
||||||
|
value: deviceStatus.delay.inSeconds,
|
||||||
|
code: 'countdown_1'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(GarageDoorErrorState(message: e.toString()));
|
emit(GarageDoorErrorState(message: e.toString()));
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _garageDoorControlEvent(GarageDoorControlEvent event, Emitter<GarageDoorState> emit) async {
|
void _garageDoorControlEvent(
|
||||||
final oldValue = event.code == 'countdown_1' ? deviceStatus.countdown1 : deviceStatus.switch1;
|
GarageDoorControlEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
|
final oldValue = event.code == 'countdown_1'
|
||||||
|
? deviceStatus.countdown1
|
||||||
|
: deviceStatus.switch1;
|
||||||
_updateLocalValue(event.code, event.value);
|
_updateLocalValue(event.code, event.value);
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
final success = await _runDeBouncer(
|
final success = await _runDeBouncer(
|
||||||
@ -327,7 +406,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _revertValue(String code, dynamic oldValue, Emitter<GarageDoorState> emit) {
|
void _revertValue(
|
||||||
|
String code, dynamic oldValue, Emitter<GarageDoorState> emit) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 'switch_1':
|
case 'switch_1':
|
||||||
if (oldValue is bool) {
|
if (oldValue is bool) {
|
||||||
@ -336,7 +416,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
break;
|
break;
|
||||||
case 'countdown_1':
|
case 'countdown_1':
|
||||||
if (oldValue is int) {
|
if (oldValue is int) {
|
||||||
deviceStatus = deviceStatus.copyWith(countdown1: oldValue, delay: Duration(seconds: oldValue));
|
deviceStatus = deviceStatus.copyWith(
|
||||||
|
countdown1: oldValue, delay: Duration(seconds: oldValue));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// Add other cases if needed
|
// Add other cases if needed
|
||||||
@ -358,7 +439,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
break;
|
break;
|
||||||
case 'countdown_1':
|
case 'countdown_1':
|
||||||
if (value is int) {
|
if (value is int) {
|
||||||
deviceStatus = deviceStatus.copyWith(countdown1: value, delay: Duration(seconds: value));
|
deviceStatus = deviceStatus.copyWith(
|
||||||
|
countdown1: value, delay: Duration(seconds: value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'countdown_alarm':
|
case 'countdown_alarm':
|
||||||
@ -401,7 +483,8 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onEditSchedule(EditGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
FutureOr<void> _onEditSchedule(
|
||||||
|
EditGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
ScheduleEntry newSchedule = ScheduleEntry(
|
ScheduleEntry newSchedule = ScheduleEntry(
|
||||||
scheduleId: event.scheduleId,
|
scheduleId: event.scheduleId,
|
||||||
@ -410,9 +493,11 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
|
|||||||
function: Status(code: 'switch_1', value: event.functionOn),
|
function: Status(code: 'switch_1', value: event.functionOn),
|
||||||
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
|
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
|
||||||
);
|
);
|
||||||
bool success = await DevicesManagementApi().editScheduleRecord(deviceId, newSchedule);
|
bool success = await DevicesManagementApi()
|
||||||
|
.editScheduleRecord(deviceId, newSchedule);
|
||||||
if (success) {
|
if (success) {
|
||||||
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
|
add(FetchGarageDoorSchedulesEvent(
|
||||||
|
deviceId: deviceId, category: 'switch_1'));
|
||||||
} else {
|
} else {
|
||||||
emit(GarageDoorLoadedState(status: deviceStatus));
|
emit(GarageDoorLoadedState(status: deviceStatus));
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
|
||||||
|
|
||||||
abstract class GarageDoorEvent extends Equatable {
|
abstract class GarageDoorEvent extends Equatable {
|
||||||
const GarageDoorEvent();
|
const GarageDoorEvent();
|
||||||
@ -25,7 +26,8 @@ class GarageDoorControlEvent extends GarageDoorEvent {
|
|||||||
final dynamic value;
|
final dynamic value;
|
||||||
final String code;
|
final String code;
|
||||||
|
|
||||||
const GarageDoorControlEvent({required this.deviceId, required this.value, required this.code});
|
const GarageDoorControlEvent(
|
||||||
|
{required this.deviceId, required this.value, required this.code});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [deviceId, value];
|
List<Object?> get props => [deviceId, value];
|
||||||
@ -121,7 +123,8 @@ class FetchGarageDoorRecordsEvent extends GarageDoorEvent {
|
|||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String code;
|
final String code;
|
||||||
|
|
||||||
const FetchGarageDoorRecordsEvent({required this.deviceId, required this.code});
|
const FetchGarageDoorRecordsEvent(
|
||||||
|
{required this.deviceId, required this.code});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [deviceId, code];
|
List<Object?> get props => [deviceId, code];
|
||||||
@ -232,3 +235,10 @@ class GarageDoorFactoryResetEvent extends GarageDoorEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object?> get props => [factoryReset, deviceId];
|
List<Object?> get props => [factoryReset, deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends GarageDoorEvent {
|
||||||
|
final GarageDoorStatusModel deviceStatus;
|
||||||
|
const StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
@ -16,6 +17,7 @@ class MainDoorSensorBloc
|
|||||||
on<MainDoorSensorFetchBatchEvent>(_onFetchBatchStatus);
|
on<MainDoorSensorFetchBatchEvent>(_onFetchBatchStatus);
|
||||||
on<MainDoorSensorReportsEvent>(_fetchReports);
|
on<MainDoorSensorReportsEvent>(_fetchReports);
|
||||||
on<MainDoorSensorFactoryReset>(_factoryReset);
|
on<MainDoorSensorFactoryReset>(_factoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
late MainDoorSensorStatusModel deviceStatus;
|
late MainDoorSensorStatusModel deviceStatus;
|
||||||
@ -28,7 +30,7 @@ class MainDoorSensorBloc
|
|||||||
final status = await DevicesManagementApi()
|
final status = await DevicesManagementApi()
|
||||||
.getDeviceStatus(event.deviceId)
|
.getDeviceStatus(event.deviceId)
|
||||||
.then((value) => value.status);
|
.then((value) => value.status);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
deviceStatus = MainDoorSensorStatusModel.fromJson(event.deviceId, status);
|
deviceStatus = MainDoorSensorStatusModel.fromJson(event.deviceId, status);
|
||||||
emit(MainDoorSensorDeviceStatusLoaded(deviceStatus));
|
emit(MainDoorSensorDeviceStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -156,4 +158,35 @@ class MainDoorSensorBloc
|
|||||||
emit(MainDoorSensorFailedState(error: e.toString()));
|
emit(MainDoorSensorFailedState(error: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus = MainDoorSensorStatusModel.fromJson(
|
||||||
|
usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(
|
||||||
|
StatusUpdated event, Emitter<MainDoorSensorState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(MainDoorSensorDeviceStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/main_door_sensor/models/main_door_status_model.dart';
|
||||||
|
|
||||||
import '../../all_devices/models/factory_reset_model.dart';
|
import '../../all_devices/models/factory_reset_model.dart';
|
||||||
|
|
||||||
@ -71,3 +72,10 @@ class MainDoorSensorFactoryReset extends MainDoorSensorEvent {
|
|||||||
MainDoorSensorFactoryReset(
|
MainDoorSensorFactoryReset(
|
||||||
{required this.deviceId, required this.factoryReset});
|
{required this.deviceId, required this.factoryReset});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends MainDoorSensorEvent {
|
||||||
|
final MainDoorSensorStatusModel deviceStatus;
|
||||||
|
StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
@ -10,33 +11,71 @@ import 'package:syncrow_web/services/devices_mang_api.dart';
|
|||||||
part 'one_gang_glass_switch_event.dart';
|
part 'one_gang_glass_switch_event.dart';
|
||||||
part 'one_gang_glass_switch_state.dart';
|
part 'one_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
|
class OneGangGlassSwitchBloc
|
||||||
|
extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
|
||||||
OneGangGlassStatusModel deviceStatus;
|
OneGangGlassStatusModel deviceStatus;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
OneGangGlassSwitchBloc({required String deviceId})
|
OneGangGlassSwitchBloc({required String deviceId})
|
||||||
: deviceStatus = OneGangGlassStatusModel(uuid: deviceId, switch1: false, countDown: 0),
|
: deviceStatus = OneGangGlassStatusModel(
|
||||||
|
uuid: deviceId, switch1: false, countDown: 0),
|
||||||
super(OneGangGlassSwitchInitial()) {
|
super(OneGangGlassSwitchInitial()) {
|
||||||
on<OneGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
on<OneGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
||||||
on<OneGangGlassSwitchControl>(_onControl);
|
on<OneGangGlassSwitchControl>(_onControl);
|
||||||
on<OneGangGlassSwitchBatchControl>(_onBatchControl);
|
on<OneGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
on<OneGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
on<OneGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
on<OneGangGlassFactoryResetEvent>(_onFactoryReset);
|
on<OneGangGlassFactoryResetEvent>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchDeviceStatus(
|
Future<void> _onFetchDeviceStatus(OneGangGlassSwitchFetchDeviceEvent event,
|
||||||
OneGangGlassSwitchFetchDeviceEvent event, Emitter<OneGangGlassSwitchState> emit) async {
|
Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
emit(OneGangGlassSwitchLoading());
|
emit(OneGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
final status =
|
||||||
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
|
deviceStatus =
|
||||||
|
OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(OneGangGlassSwitchError(e.toString()));
|
emit(OneGangGlassSwitchError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onControl(OneGangGlassSwitchControl event, Emitter<OneGangGlassSwitchState> emit) async {
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus = OneGangGlassStatusModel.fromJson(
|
||||||
|
usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(
|
||||||
|
StatusUpdated event, Emitter<OneGangGlassSwitchState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onControl(OneGangGlassSwitchControl event,
|
||||||
|
Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
_updateLocalValue(event.code, event.value);
|
_updateLocalValue(event.code, event.value);
|
||||||
@ -52,10 +91,12 @@ class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassS
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFactoryReset(OneGangGlassFactoryResetEvent event, Emitter<OneGangGlassSwitchState> emit) async {
|
Future<void> _onFactoryReset(OneGangGlassFactoryResetEvent event,
|
||||||
|
Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
emit(OneGangGlassSwitchLoading());
|
emit(OneGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
final response = await DevicesManagementApi()
|
||||||
|
.factoryReset(event.factoryReset, event.deviceId);
|
||||||
if (!response) {
|
if (!response) {
|
||||||
emit(OneGangGlassSwitchError('Failed to reset device'));
|
emit(OneGangGlassSwitchError('Failed to reset device'));
|
||||||
} else {
|
} else {
|
||||||
@ -66,7 +107,8 @@ class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event, Emitter<OneGangGlassSwitchState> emit) async {
|
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event,
|
||||||
|
Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
_updateLocalValue(event.code, event.value);
|
_updateLocalValue(event.code, event.value);
|
||||||
@ -83,11 +125,14 @@ class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassS
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchBatchStatus(
|
Future<void> _onFetchBatchStatus(
|
||||||
OneGangGlassSwitchFetchBatchStatusEvent event, Emitter<OneGangGlassSwitchState> emit) async {
|
OneGangGlassSwitchFetchBatchStatusEvent event,
|
||||||
|
Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
emit(OneGangGlassSwitchLoading());
|
emit(OneGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
final status =
|
||||||
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus = OneGangGlassStatusModel.fromJson(
|
||||||
|
event.deviceIds.first, status.status);
|
||||||
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(OneGangGlassSwitchError(e.toString()));
|
emit(OneGangGlassSwitchError(e.toString()));
|
||||||
@ -117,9 +162,11 @@ class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassS
|
|||||||
try {
|
try {
|
||||||
late bool response;
|
late bool response;
|
||||||
if (isBatch) {
|
if (isBatch) {
|
||||||
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
response = await DevicesManagementApi()
|
||||||
|
.deviceBatchControl(deviceId, code, value);
|
||||||
} else {
|
} else {
|
||||||
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
response = await DevicesManagementApi()
|
||||||
|
.deviceControl(deviceId, Status(code: code, value: value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
@ -131,7 +178,8 @@ class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassS
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<OneGangGlassSwitchState> emit) {
|
void _revertValueAndEmit(String deviceId, String code, bool oldValue,
|
||||||
|
Emitter<OneGangGlassSwitchState> emit) {
|
||||||
_updateLocalValue(code, oldValue);
|
_updateLocalValue(code, oldValue);
|
||||||
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,11 @@ class OneGangGlassSwitchFetchBatchStatusEvent extends OneGangGlassSwitchEvent {
|
|||||||
OneGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
OneGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends OneGangGlassSwitchEvent {
|
||||||
|
final OneGangGlassStatusModel deviceStatus;
|
||||||
|
StatusUpdated(this.deviceStatus);
|
||||||
|
}
|
||||||
|
|
||||||
class OneGangGlassFactoryResetEvent extends OneGangGlassSwitchEvent {
|
class OneGangGlassFactoryResetEvent extends OneGangGlassSwitchEvent {
|
||||||
final FactoryResetModel factoryReset;
|
final FactoryResetModel factoryReset;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/one_gang_switch/bloc/wall_light_switch_event.dart';
|
import 'package:syncrow_web/pages/device_managment/one_gang_switch/bloc/wall_light_switch_event.dart';
|
||||||
@ -16,6 +17,7 @@ class WallLightSwitchBloc
|
|||||||
on<WallLightSwitchFetchBatchEvent>(_onFetchBatchStatus);
|
on<WallLightSwitchFetchBatchEvent>(_onFetchBatchStatus);
|
||||||
on<WallLightSwitchBatchControl>(_onBatchControl);
|
on<WallLightSwitchBatchControl>(_onBatchControl);
|
||||||
on<WallLightFactoryReset>(_onFactoryReset);
|
on<WallLightFactoryReset>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
late WallLightStatusModel deviceStatus;
|
late WallLightStatusModel deviceStatus;
|
||||||
@ -31,12 +33,44 @@ class WallLightSwitchBloc
|
|||||||
|
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
WallLightStatusModel.fromJson(event.deviceId, status.status);
|
WallLightStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
emit(WallLightSwitchStatusLoaded(deviceStatus));
|
emit(WallLightSwitchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(WallLightSwitchError(e.toString()));
|
emit(WallLightSwitchError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus =
|
||||||
|
WallLightStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(
|
||||||
|
StatusUpdated event, Emitter<WallLightSwitchState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(WallLightSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
FutureOr<void> _onControl(
|
FutureOr<void> _onControl(
|
||||||
WallLightSwitchControl event, Emitter<WallLightSwitchState> emit) async {
|
WallLightSwitchControl event, Emitter<WallLightSwitchState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart';
|
||||||
|
|
||||||
class WallLightSwitchEvent extends Equatable {
|
class WallLightSwitchEvent extends Equatable {
|
||||||
@override
|
@override
|
||||||
@ -57,3 +58,10 @@ class WallLightFactoryReset extends WallLightSwitchEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId, factoryReset];
|
List<Object> get props => [deviceId, factoryReset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends WallLightSwitchEvent {
|
||||||
|
final WallLightStatusModel deviceStatus;
|
||||||
|
StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
@ -10,7 +11,8 @@ import 'package:syncrow_web/services/devices_mang_api.dart';
|
|||||||
part 'three_gang_glass_switch_event.dart';
|
part 'three_gang_glass_switch_event.dart';
|
||||||
part 'three_gang_glass_switch_state.dart';
|
part 'three_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGangGlassSwitchState> {
|
class ThreeGangGlassSwitchBloc
|
||||||
|
extends Bloc<ThreeGangGlassSwitchEvent, ThreeGangGlassSwitchState> {
|
||||||
ThreeGangGlassStatusModel deviceStatus;
|
ThreeGangGlassStatusModel deviceStatus;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
@ -29,21 +31,57 @@ class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGang
|
|||||||
on<ThreeGangGlassSwitchBatchControl>(_onBatchControl);
|
on<ThreeGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
on<ThreeGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
on<ThreeGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
on<ThreeGangGlassFactoryReset>(_onFactoryReset);
|
on<ThreeGangGlassFactoryReset>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchDeviceStatus(
|
Future<void> _onFetchDeviceStatus(ThreeGangGlassSwitchFetchDeviceEvent event,
|
||||||
ThreeGangGlassSwitchFetchDeviceEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
emit(ThreeGangGlassSwitchLoading());
|
emit(ThreeGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
final status =
|
||||||
deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
deviceStatus =
|
||||||
|
ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(ThreeGangGlassSwitchError(e.toString()));
|
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onControl(ThreeGangGlassSwitchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus = ThreeGangGlassStatusModel.fromJson(
|
||||||
|
usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(
|
||||||
|
StatusUpdated event, Emitter<ThreeGangGlassSwitchState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onControl(ThreeGangGlassSwitchControl event,
|
||||||
|
Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
_updateLocalValue(event.code, event.value);
|
_updateLocalValue(event.code, event.value);
|
||||||
@ -59,7 +97,8 @@ class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGang
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onBatchControl(ThreeGangGlassSwitchBatchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
Future<void> _onBatchControl(ThreeGangGlassSwitchBatchControl event,
|
||||||
|
Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
_updateLocalValue(event.code, event.value);
|
_updateLocalValue(event.code, event.value);
|
||||||
@ -76,21 +115,26 @@ class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGang
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchBatchStatus(
|
Future<void> _onFetchBatchStatus(
|
||||||
ThreeGangGlassSwitchFetchBatchStatusEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
ThreeGangGlassSwitchFetchBatchStatusEvent event,
|
||||||
|
Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
emit(ThreeGangGlassSwitchLoading());
|
emit(ThreeGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
final status =
|
||||||
deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus = ThreeGangGlassStatusModel.fromJson(
|
||||||
|
event.deviceIds.first, status.status);
|
||||||
emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(ThreeGangGlassSwitchError(e.toString()));
|
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFactoryReset(ThreeGangGlassFactoryReset event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
Future<void> _onFactoryReset(ThreeGangGlassFactoryReset event,
|
||||||
|
Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
emit(ThreeGangGlassSwitchLoading());
|
emit(ThreeGangGlassSwitchLoading());
|
||||||
try {
|
try {
|
||||||
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
final response = await DevicesManagementApi()
|
||||||
|
.factoryReset(event.factoryReset, event.deviceId);
|
||||||
if (!response) {
|
if (!response) {
|
||||||
emit(ThreeGangGlassSwitchError('Failed'));
|
emit(ThreeGangGlassSwitchError('Failed'));
|
||||||
} else {
|
} else {
|
||||||
@ -124,9 +168,11 @@ class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGang
|
|||||||
try {
|
try {
|
||||||
late bool response;
|
late bool response;
|
||||||
if (isBatch) {
|
if (isBatch) {
|
||||||
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
response = await DevicesManagementApi()
|
||||||
|
.deviceBatchControl(deviceId, code, value);
|
||||||
} else {
|
} else {
|
||||||
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
response = await DevicesManagementApi()
|
||||||
|
.deviceControl(deviceId, Status(code: code, value: value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
@ -138,7 +184,8 @@ class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGang
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<ThreeGangGlassSwitchState> emit) {
|
void _revertValueAndEmit(String deviceId, String code, bool oldValue,
|
||||||
|
Emitter<ThreeGangGlassSwitchState> emit) {
|
||||||
_updateLocalValue(code, oldValue);
|
_updateLocalValue(code, oldValue);
|
||||||
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
}
|
}
|
||||||
|
@ -49,3 +49,10 @@ class ThreeGangGlassFactoryReset extends ThreeGangGlassSwitchEvent {
|
|||||||
required this.factoryReset,
|
required this.factoryReset,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends ThreeGangGlassSwitchEvent {
|
||||||
|
final ThreeGangGlassStatusModel deviceStatus;
|
||||||
|
StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart';
|
import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart';
|
||||||
@ -22,6 +23,7 @@ class LivingRoomBloc extends Bloc<LivingRoomEvent, LivingRoomState> {
|
|||||||
on<LivingRoomBatchControl>(_livingRoomBatchControl);
|
on<LivingRoomBatchControl>(_livingRoomBatchControl);
|
||||||
on<LivingRoomFetchBatchEvent>(_livingRoomFetchBatchControl);
|
on<LivingRoomFetchBatchEvent>(_livingRoomFetchBatchControl);
|
||||||
on<LivingRoomFactoryResetEvent>(_livingRoomFactoryReset);
|
on<LivingRoomFactoryResetEvent>(_livingRoomFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onFetchDeviceStatus(LivingRoomFetchDeviceStatusEvent event,
|
FutureOr<void> _onFetchDeviceStatus(LivingRoomFetchDeviceStatusEvent event,
|
||||||
@ -32,6 +34,7 @@ class LivingRoomBloc extends Bloc<LivingRoomEvent, LivingRoomState> {
|
|||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
LivingRoomStatusModel.fromJson(event.deviceId, status.status);
|
LivingRoomStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
_listenToChanges(deviceId);
|
||||||
emit(LivingRoomDeviceStatusLoaded(deviceStatus));
|
emit(LivingRoomDeviceStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(LivingRoomDeviceManagementError(e.toString()));
|
emit(LivingRoomDeviceManagementError(e.toString()));
|
||||||
@ -144,6 +147,9 @@ class LivingRoomBloc extends Bloc<LivingRoomEvent, LivingRoomState> {
|
|||||||
await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
LivingRoomStatusModel.fromJson(event.devicesIds.first, status.status);
|
LivingRoomStatusModel.fromJson(event.devicesIds.first, status.status);
|
||||||
|
// for (var deviceId in event.devicesIds) {
|
||||||
|
// _listenToChanges(deviceId);
|
||||||
|
// }
|
||||||
emit(LivingRoomDeviceStatusLoaded(deviceStatus));
|
emit(LivingRoomDeviceStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(LivingRoomDeviceManagementError(e.toString()));
|
emit(LivingRoomDeviceManagementError(e.toString()));
|
||||||
@ -185,4 +191,34 @@ class LivingRoomBloc extends Bloc<LivingRoomEvent, LivingRoomState> {
|
|||||||
emit(LivingRoomDeviceManagementError(e.toString()));
|
emit(LivingRoomDeviceManagementError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus =
|
||||||
|
LivingRoomStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(StatusUpdated event, Emitter<LivingRoomState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(LivingRoomDeviceStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,3 +58,10 @@ class LivingRoomFactoryResetEvent extends LivingRoomEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [uuid, factoryReset];
|
List<Object> get props => [uuid, factoryReset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends LivingRoomEvent {
|
||||||
|
final LivingRoomStatusModel deviceStatus;
|
||||||
|
const StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
part 'two_gang_glass_switch_event.dart';
|
part 'two_gang_glass_switch_event.dart';
|
||||||
part 'two_gang_glass_switch_state.dart';
|
part 'two_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
@ -14,7 +13,6 @@ class TwoGangGlassSwitchBloc
|
|||||||
extends Bloc<TwoGangGlassSwitchEvent, TwoGangGlassSwitchState> {
|
extends Bloc<TwoGangGlassSwitchEvent, TwoGangGlassSwitchState> {
|
||||||
TwoGangGlassStatusModel deviceStatus;
|
TwoGangGlassStatusModel deviceStatus;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
TwoGangGlassSwitchBloc({required String deviceId})
|
TwoGangGlassSwitchBloc({required String deviceId})
|
||||||
: deviceStatus = TwoGangGlassStatusModel(
|
: deviceStatus = TwoGangGlassStatusModel(
|
||||||
uuid: deviceId,
|
uuid: deviceId,
|
||||||
@ -28,6 +26,7 @@ class TwoGangGlassSwitchBloc
|
|||||||
on<TwoGangGlassSwitchBatchControl>(_onBatchControl);
|
on<TwoGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
on<TwoGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
on<TwoGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
on<TwoGangGlassFactoryReset>(_onFactoryReset);
|
on<TwoGangGlassFactoryReset>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchDeviceStatus(TwoGangGlassSwitchFetchDeviceEvent event,
|
Future<void> _onFetchDeviceStatus(TwoGangGlassSwitchFetchDeviceEvent event,
|
||||||
@ -38,12 +37,44 @@ class TwoGangGlassSwitchBloc
|
|||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
TwoGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
TwoGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(TwoGangGlassSwitchError(e.toString()));
|
emit(TwoGangGlassSwitchError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _listenToChanges(String deviceId) {
|
||||||
|
try {
|
||||||
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
|
ref.onValue.listen((DatabaseEvent event) {
|
||||||
|
if (event.snapshot.value == null) return;
|
||||||
|
|
||||||
|
Map<dynamic, dynamic> data =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
|
List<Status> statusList = [];
|
||||||
|
|
||||||
|
data['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Parse the new status and add the event
|
||||||
|
final updatedStatus =
|
||||||
|
TwoGangGlassStatusModel.fromJson(data['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(updatedStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
// Handle errors and emit an error state if necessary
|
||||||
|
if (!isClosed) {
|
||||||
|
// add(TwoGangGlassSwitchError('Error listening to updates: $e'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _onControl(TwoGangGlassSwitchControl event,
|
Future<void> _onControl(TwoGangGlassSwitchControl event,
|
||||||
Emitter<TwoGangGlassSwitchState> emit) async {
|
Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
@ -178,4 +209,37 @@ class TwoGangGlassSwitchBloc
|
|||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _listenToChanges(deviceId) {
|
||||||
|
// 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<Status> statusList = [];
|
||||||
|
// usersMap['status'].forEach((element) {
|
||||||
|
// statusList
|
||||||
|
// .add(Status(code: element['code'], value: element['value']));
|
||||||
|
// });
|
||||||
|
|
||||||
|
// deviceStatus = TwoGangGlassStatusModel.fromJson(
|
||||||
|
// usersMap['productUuid'], statusList);
|
||||||
|
// if (!isClosed) {
|
||||||
|
// add(StatusUpdated(deviceStatus));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// } catch (_) {}
|
||||||
|
// }
|
||||||
|
|
||||||
|
void _onStatusUpdated(
|
||||||
|
StatusUpdated event, Emitter<TwoGangGlassSwitchState> emit) {
|
||||||
|
// Update the local deviceStatus with the new status from the event
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
// Emit the new state with the updated status
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,3 +48,11 @@ class TwoGangGlassFactoryReset extends TwoGangGlassSwitchEvent {
|
|||||||
required this.factoryReset,
|
required this.factoryReset,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends TwoGangGlassSwitchEvent {
|
||||||
|
final TwoGangGlassStatusModel deviceStatus;
|
||||||
|
StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two
|
|||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
class TwoGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
|
class TwoGangGlassSwitchControlView extends StatelessWidget
|
||||||
|
with HelperResponsiveLayout {
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
|
|
||||||
const TwoGangGlassSwitchControlView({required this.deviceId, super.key});
|
const TwoGangGlassSwitchControlView({required this.deviceId, super.key});
|
||||||
@ -14,8 +15,8 @@ class TwoGangGlassSwitchControlView extends StatelessWidget with HelperResponsiv
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) =>
|
create: (context) => TwoGangGlassSwitchBloc(deviceId: deviceId)
|
||||||
TwoGangGlassSwitchBloc(deviceId: deviceId)..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)),
|
..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)),
|
||||||
child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>(
|
child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is TwoGangGlassSwitchLoading) {
|
if (state is TwoGangGlassSwitchLoading) {
|
||||||
@ -23,16 +24,16 @@ class TwoGangGlassSwitchControlView extends StatelessWidget with HelperResponsiv
|
|||||||
} else if (state is TwoGangGlassSwitchStatusLoaded) {
|
} else if (state is TwoGangGlassSwitchStatusLoaded) {
|
||||||
return _buildStatusControls(context, state.status);
|
return _buildStatusControls(context, state.status);
|
||||||
} else if (state is TwoGangGlassSwitchError) {
|
} else if (state is TwoGangGlassSwitchError) {
|
||||||
return const Center(child: Text('Error fetching status'));
|
return Center(child: Text(state.message));
|
||||||
} else {
|
} else {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) {
|
Widget _buildStatusControls(
|
||||||
|
BuildContext context, TwoGangGlassStatusModel status) {
|
||||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
final isLarge = isLargeScreenSize(context);
|
final isLarge = isLargeScreenSize(context);
|
||||||
final isMedium = isMediumScreenSize(context);
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart';
|
import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart';
|
||||||
@ -14,6 +15,7 @@ class TwoGangSwitchBloc extends Bloc<TwoGangSwitchEvent, TwoGangSwitchState> {
|
|||||||
on<TwoGangSwitchFetchBatchEvent>(_onFetchBatchStatus);
|
on<TwoGangSwitchFetchBatchEvent>(_onFetchBatchStatus);
|
||||||
on<TwoGangSwitchBatchControl>(_onBatchControl);
|
on<TwoGangSwitchBatchControl>(_onBatchControl);
|
||||||
on<TwoGangFactoryReset>(_onFactoryReset);
|
on<TwoGangFactoryReset>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
late TwoGangStatusModel deviceStatus;
|
late TwoGangStatusModel deviceStatus;
|
||||||
@ -26,8 +28,8 @@ class TwoGangSwitchBloc extends Bloc<TwoGangSwitchEvent, TwoGangSwitchState> {
|
|||||||
try {
|
try {
|
||||||
final status =
|
final status =
|
||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
|
||||||
deviceStatus = TwoGangStatusModel.fromJson(event.deviceId, status.status);
|
deviceStatus = TwoGangStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
_listenToChanges(emit);
|
||||||
emit(TwoGangSwitchStatusLoaded(deviceStatus));
|
emit(TwoGangSwitchStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(TwoGangSwitchError(e.toString()));
|
emit(TwoGangSwitchError(e.toString()));
|
||||||
@ -174,4 +176,34 @@ class TwoGangSwitchBloc extends Bloc<TwoGangSwitchEvent, TwoGangSwitchState> {
|
|||||||
emit(TwoGangSwitchError(e.toString()));
|
emit(TwoGangSwitchError(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus =
|
||||||
|
TwoGangStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(StatusUpdated event, Emitter<TwoGangSwitchState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(TwoGangSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart';
|
||||||
|
|
||||||
class TwoGangSwitchEvent extends Equatable {
|
class TwoGangSwitchEvent extends Equatable {
|
||||||
@override
|
@override
|
||||||
@ -57,3 +58,10 @@ class TwoGangFactoryReset extends TwoGangSwitchEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId, factoryReset];
|
List<Object> get props => [deviceId, factoryReset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends TwoGangSwitchEvent {
|
||||||
|
final TwoGangStatusModel deviceStatus;
|
||||||
|
StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_event.dart';
|
import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_event.dart';
|
||||||
@ -29,7 +30,7 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
var response = await DevicesManagementApi().getDeviceStatus(deviceId);
|
var response = await DevicesManagementApi().getDeviceStatus(deviceId);
|
||||||
deviceStatus = WallSensorModel.fromJson(response.status);
|
deviceStatus = WallSensorModel.fromJson(response.status);
|
||||||
emit(WallSensorUpdateState(wallSensorModel: deviceStatus));
|
emit(WallSensorUpdateState(wallSensorModel: deviceStatus));
|
||||||
// _listenToChanges();
|
_listenToChanges(emit);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(WallSensorFailedState(error: e.toString()));
|
emit(WallSensorFailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
@ -38,10 +39,12 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
|
|
||||||
// Fetch batch status
|
// Fetch batch status
|
||||||
FutureOr<void> _fetchWallSensorBatchControl(
|
FutureOr<void> _fetchWallSensorBatchControl(
|
||||||
WallSensorFetchBatchStatusEvent event, Emitter<WallSensorState> emit) async {
|
WallSensorFetchBatchStatusEvent event,
|
||||||
|
Emitter<WallSensorState> emit) async {
|
||||||
emit(WallSensorLoadingInitialState());
|
emit(WallSensorLoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
var response =
|
||||||
|
await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
||||||
deviceStatus = WallSensorModel.fromJson(response.status);
|
deviceStatus = WallSensorModel.fromJson(response.status);
|
||||||
emit(WallSensorUpdateState(wallSensorModel: deviceStatus));
|
emit(WallSensorUpdateState(wallSensorModel: deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -49,26 +52,30 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _listenToChanges() {
|
_listenToChanges(Emitter<WallSensorState> emit) {
|
||||||
// try {
|
try {
|
||||||
// DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
DatabaseReference ref =
|
||||||
// Stream<DatabaseEvent> stream = ref.onValue;
|
FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
// stream.listen((DatabaseEvent event) {
|
stream.listen((DatabaseEvent event) {
|
||||||
// Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
Map<dynamic, dynamic> usersMap =
|
||||||
// List<StatusModel> statusList = [];
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
|
List<Status> statusList = [];
|
||||||
|
|
||||||
// usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
// statusList.add(StatusModel(code: element['code'], value: element['value']));
|
statusList
|
||||||
// });
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
// deviceStatus = WallSensorModel.fromJson(statusList);
|
deviceStatus = WallSensorModel.fromJson(statusList);
|
||||||
// add(WallSensorUpdatedEvent());
|
emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus));
|
||||||
// });
|
});
|
||||||
// } catch (_) {}
|
} catch (_) {}
|
||||||
// }
|
}
|
||||||
|
|
||||||
void _changeValue(WallSensorChangeValueEvent event, Emitter<WallSensorState> emit) async {
|
void _changeValue(
|
||||||
|
WallSensorChangeValueEvent event, Emitter<WallSensorState> emit) async {
|
||||||
emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus));
|
emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus));
|
||||||
if (event.code == 'far_detection') {
|
if (event.code == 'far_detection') {
|
||||||
deviceStatus.farDetection = event.value;
|
deviceStatus.farDetection = event.value;
|
||||||
@ -125,7 +132,8 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
try {
|
try {
|
||||||
late bool response;
|
late bool response;
|
||||||
if (isBatch) {
|
if (isBatch) {
|
||||||
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
response = await DevicesManagementApi()
|
||||||
|
.deviceBatchControl(deviceId, code, value);
|
||||||
} else {
|
} else {
|
||||||
response = await DevicesManagementApi()
|
response = await DevicesManagementApi()
|
||||||
.deviceControl(deviceId, Status(code: code, value: value));
|
.deviceControl(deviceId, Status(code: code, value: value));
|
||||||
@ -150,7 +158,8 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
try {
|
try {
|
||||||
// await DevicesManagementApi.getDeviceReportsByDate(
|
// await DevicesManagementApi.getDeviceReportsByDate(
|
||||||
// deviceId, event.code, from.toString(), to.toString())
|
// deviceId, event.code, from.toString(), to.toString())
|
||||||
await DevicesManagementApi.getDeviceReports(deviceId, event.code).then((value) {
|
await DevicesManagementApi.getDeviceReports(deviceId, event.code)
|
||||||
|
.then((value) {
|
||||||
emit(DeviceReportsState(deviceReport: value, code: event.code));
|
emit(DeviceReportsState(deviceReport: value, code: event.code));
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -159,11 +168,13 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showDescription(ShowDescriptionEvent event, Emitter<WallSensorState> emit) {
|
void _showDescription(
|
||||||
|
ShowDescriptionEvent event, Emitter<WallSensorState> emit) {
|
||||||
emit(WallSensorShowDescriptionState(description: event.description));
|
emit(WallSensorShowDescriptionState(description: event.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _backToGridView(BackToGridViewEvent event, Emitter<WallSensorState> emit) {
|
void _backToGridView(
|
||||||
|
BackToGridViewEvent event, Emitter<WallSensorState> emit) {
|
||||||
emit(WallSensorUpdateState(wallSensorModel: deviceStatus));
|
emit(WallSensorUpdateState(wallSensorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart';
|
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart';
|
||||||
@ -34,6 +35,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
on<EditWaterHeaterScheduleEvent>(_onEditSchedule);
|
on<EditWaterHeaterScheduleEvent>(_onEditSchedule);
|
||||||
on<DeleteScheduleEvent>(_onDeleteSchedule);
|
on<DeleteScheduleEvent>(_onDeleteSchedule);
|
||||||
on<UpdateScheduleEntryEvent>(_onUpdateSchedule);
|
on<UpdateScheduleEntryEvent>(_onUpdateSchedule);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
late WaterHeaterStatusModel deviceStatus;
|
late WaterHeaterStatusModel deviceStatus;
|
||||||
@ -78,7 +80,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
final updatedDays = List<bool>.from(currentState.selectedDays);
|
final updatedDays = List<bool>.from(currentState.selectedDays);
|
||||||
updatedDays[event.index] = event.value;
|
updatedDays[event.index] = event.value;
|
||||||
emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
|
emit(currentState.copyWith(
|
||||||
|
selectedDays: updatedDays, selectedTime: currentState.selectedTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _updateFunctionOn(
|
FutureOr<void> _updateFunctionOn(
|
||||||
@ -86,7 +89,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
Emitter<WaterHeaterState> emit,
|
Emitter<WaterHeaterState> emit,
|
||||||
) {
|
) {
|
||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
emit(currentState.copyWith(functionOn: event.isOn, selectedTime: currentState.selectedTime));
|
emit(currentState.copyWith(
|
||||||
|
functionOn: event.isOn, selectedTime: currentState.selectedTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _updateScheduleEvent(
|
FutureOr<void> _updateScheduleEvent(
|
||||||
@ -101,7 +105,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (event.scheduleMode == ScheduleModes.countdown) {
|
if (event.scheduleMode == ScheduleModes.countdown) {
|
||||||
final countdownRemaining = Duration(hours: event.hours, minutes: event.minutes);
|
final countdownRemaining =
|
||||||
|
Duration(hours: event.hours, minutes: event.minutes);
|
||||||
|
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
scheduleMode: ScheduleModes.countdown,
|
scheduleMode: ScheduleModes.countdown,
|
||||||
@ -111,11 +116,13 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
countdownRemaining: countdownRemaining,
|
countdownRemaining: countdownRemaining,
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!currentState.isCountdownActive! && countdownRemaining > Duration.zero) {
|
if (!currentState.isCountdownActive! &&
|
||||||
|
countdownRemaining > Duration.zero) {
|
||||||
_startCountdownTimer(emit, countdownRemaining);
|
_startCountdownTimer(emit, countdownRemaining);
|
||||||
}
|
}
|
||||||
} else if (event.scheduleMode == ScheduleModes.inching) {
|
} else if (event.scheduleMode == ScheduleModes.inching) {
|
||||||
final inchingDuration = Duration(hours: event.hours, minutes: event.minutes);
|
final inchingDuration =
|
||||||
|
Duration(hours: event.hours, minutes: event.minutes);
|
||||||
|
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
scheduleMode: ScheduleModes.inching,
|
scheduleMode: ScheduleModes.inching,
|
||||||
@ -217,7 +224,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().deviceControl(
|
final status = await DevicesManagementApi().deviceControl(
|
||||||
event.deviceId,
|
event.deviceId,
|
||||||
Status(code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0),
|
Status(
|
||||||
|
code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0),
|
||||||
);
|
);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
emit(const WaterHeaterFailedState(error: 'Failed to stop schedule.'));
|
emit(const WaterHeaterFailedState(error: 'Failed to stop schedule.'));
|
||||||
@ -235,8 +243,10 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
emit(WaterHeaterLoadingState());
|
emit(WaterHeaterLoadingState());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
final status =
|
||||||
deviceStatus = WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
deviceStatus =
|
||||||
|
WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
|
||||||
if (deviceStatus.scheduleMode == ScheduleModes.countdown) {
|
if (deviceStatus.scheduleMode == ScheduleModes.countdown) {
|
||||||
final countdownRemaining = Duration(
|
final countdownRemaining = Duration(
|
||||||
@ -300,11 +310,42 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
isInchingActive: false,
|
isInchingActive: false,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
_listenToChanges(event.deviceId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(WaterHeaterFailedState(error: e.toString()));
|
emit(WaterHeaterFailedState(error: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_listenToChanges(deviceId) {
|
||||||
|
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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus = WaterHeaterStatusModel.fromJson(
|
||||||
|
usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(StatusUpdated event, Emitter<WaterHeaterState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
void _startCountdownTimer(
|
void _startCountdownTimer(
|
||||||
Emitter<WaterHeaterState> emit,
|
Emitter<WaterHeaterState> emit,
|
||||||
Duration countdownRemaining,
|
Duration countdownRemaining,
|
||||||
@ -334,8 +375,10 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
if (state is WaterHeaterDeviceStatusLoaded) {
|
if (state is WaterHeaterDeviceStatusLoaded) {
|
||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
|
|
||||||
if (currentState.countdownRemaining != null && currentState.countdownRemaining! > Duration.zero) {
|
if (currentState.countdownRemaining != null &&
|
||||||
final newRemaining = currentState.countdownRemaining! - const Duration(minutes: 1);
|
currentState.countdownRemaining! > Duration.zero) {
|
||||||
|
final newRemaining =
|
||||||
|
currentState.countdownRemaining! - const Duration(minutes: 1);
|
||||||
|
|
||||||
if (newRemaining <= Duration.zero) {
|
if (newRemaining <= Duration.zero) {
|
||||||
_countdownTimer?.cancel();
|
_countdownTimer?.cancel();
|
||||||
@ -430,7 +473,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _revertValue(String code, dynamic oldValue, void Function(WaterHeaterState state) emit) {
|
void _revertValue(String code, dynamic oldValue,
|
||||||
|
void Function(WaterHeaterState state) emit) {
|
||||||
_updateLocalValue(code, oldValue);
|
_updateLocalValue(code, oldValue);
|
||||||
if (state is WaterHeaterDeviceStatusLoaded) {
|
if (state is WaterHeaterDeviceStatusLoaded) {
|
||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
@ -477,12 +521,13 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _getSchedule(GetSchedulesEvent event, Emitter<WaterHeaterState> emit) async {
|
FutureOr<void> _getSchedule(
|
||||||
|
GetSchedulesEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(ScheduleLoadingState());
|
emit(ScheduleLoadingState());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<ScheduleModel> schedules =
|
List<ScheduleModel> schedules = await DevicesManagementApi()
|
||||||
await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
|
.getDeviceSchedules(deviceStatus.uuid, event.category);
|
||||||
|
|
||||||
emit(WaterHeaterDeviceStatusLoaded(
|
emit(WaterHeaterDeviceStatusLoaded(
|
||||||
deviceStatus,
|
deviceStatus,
|
||||||
@ -514,7 +559,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
|
|
||||||
// emit(ScheduleLoadingState());
|
// emit(ScheduleLoadingState());
|
||||||
|
|
||||||
bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, currentState.status.uuid);
|
bool success = await DevicesManagementApi()
|
||||||
|
.addScheduleRecord(newSchedule, currentState.status.uuid);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
add(GetSchedulesEvent(category: 'switch_1', uuid: deviceStatus.uuid));
|
add(GetSchedulesEvent(category: 'switch_1', uuid: deviceStatus.uuid));
|
||||||
@ -525,7 +571,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onEditSchedule(EditWaterHeaterScheduleEvent event, Emitter<WaterHeaterState> emit) async {
|
FutureOr<void> _onEditSchedule(EditWaterHeaterScheduleEvent event,
|
||||||
|
Emitter<WaterHeaterState> emit) async {
|
||||||
if (state is WaterHeaterDeviceStatusLoaded) {
|
if (state is WaterHeaterDeviceStatusLoaded) {
|
||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
|
|
||||||
@ -594,11 +641,13 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
|
|
||||||
// emit(ScheduleLoadingState());
|
// emit(ScheduleLoadingState());
|
||||||
|
|
||||||
bool success = await DevicesManagementApi().deleteScheduleRecord(currentState.status.uuid, event.scheduleId);
|
bool success = await DevicesManagementApi()
|
||||||
|
.deleteScheduleRecord(currentState.status.uuid, event.scheduleId);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
final updatedSchedules =
|
final updatedSchedules = currentState.schedules
|
||||||
currentState.schedules.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
|
.where((schedule) => schedule.scheduleId != event.scheduleId)
|
||||||
|
.toList();
|
||||||
|
|
||||||
emit(currentState.copyWith(schedules: updatedSchedules));
|
emit(currentState.copyWith(schedules: updatedSchedules));
|
||||||
} else {
|
} else {
|
||||||
@ -608,12 +657,15 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, Emitter<WaterHeaterState> emit) async {
|
FutureOr<void> _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event,
|
||||||
|
Emitter<WaterHeaterState> emit) async {
|
||||||
emit(WaterHeaterLoadingState());
|
emit(WaterHeaterLoadingState());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final status = await DevicesManagementApi().getBatchStatus(event.devicesUuid);
|
final status =
|
||||||
deviceStatus = WaterHeaterStatusModel.fromJson(event.devicesUuid.first, status.status);
|
await DevicesManagementApi().getBatchStatus(event.devicesUuid);
|
||||||
|
deviceStatus = WaterHeaterStatusModel.fromJson(
|
||||||
|
event.devicesUuid.first, status.status);
|
||||||
|
|
||||||
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
|
emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -621,7 +673,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, Emitter<WaterHeaterState> emit) async {
|
FutureOr<void> _batchControlWaterHeater(ControlWaterHeaterBatchEvent event,
|
||||||
|
Emitter<WaterHeaterState> emit) async {
|
||||||
if (state is WaterHeaterDeviceStatusLoaded) {
|
if (state is WaterHeaterDeviceStatusLoaded) {
|
||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
|
|
||||||
|
@ -54,6 +54,15 @@ final class WaterHeaterFetchStatusEvent extends WaterHeaterEvent {
|
|||||||
|
|
||||||
final class DecrementCountdownEvent extends WaterHeaterEvent {}
|
final class DecrementCountdownEvent extends WaterHeaterEvent {}
|
||||||
|
|
||||||
|
|
||||||
|
class StatusUpdated extends WaterHeaterEvent {
|
||||||
|
final WaterHeaterStatusModel deviceStatus;
|
||||||
|
const StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
final class AddScheduleEvent extends WaterHeaterEvent {
|
final class AddScheduleEvent extends WaterHeaterEvent {
|
||||||
final List<bool> selectedDays;
|
final List<bool> selectedDays;
|
||||||
final TimeOfDay time;
|
final TimeOfDay time;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart';
|
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart';
|
||||||
@ -21,6 +22,7 @@ class WaterLeakBloc extends Bloc<WaterLeakEvent, WaterLeakState> {
|
|||||||
on<FetchWaterLeakBatchStatusEvent>(_onFetchBatchStatus);
|
on<FetchWaterLeakBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
on<FetchWaterLeakReportsEvent>(_onFetchWaterLeakReports);
|
on<FetchWaterLeakReportsEvent>(_onFetchWaterLeakReports);
|
||||||
on<WaterLeakFactoryResetEvent>(_onFactoryReset);
|
on<WaterLeakFactoryResetEvent>(_onFactoryReset);
|
||||||
|
on<StatusUpdated>(_onStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchWaterLeakStatus(
|
Future<void> _onFetchWaterLeakStatus(
|
||||||
@ -30,12 +32,43 @@ class WaterLeakBloc extends Bloc<WaterLeakEvent, WaterLeakState> {
|
|||||||
final response =
|
final response =
|
||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus = WaterLeakStatusModel.fromJson(deviceId, response.status);
|
deviceStatus = WaterLeakStatusModel.fromJson(deviceId, response.status);
|
||||||
|
_listenToChanges();
|
||||||
emit(WaterLeakLoadedState(deviceStatus!));
|
emit(WaterLeakLoadedState(deviceStatus!));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(WaterLeakErrorState(e.toString()));
|
emit(WaterLeakErrorState(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_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<Status> statusList = [];
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(Status(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus =
|
||||||
|
WaterLeakStatusModel.fromJson(usersMap['productUuid'], statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(StatusUpdated(deviceStatus!));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onStatusUpdated(StatusUpdated event, Emitter<WaterLeakState> emit) {
|
||||||
|
deviceStatus = event.deviceStatus;
|
||||||
|
emit(WaterLeakLoadedState(deviceStatus!));
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _onControl(
|
Future<void> _onControl(
|
||||||
WaterLeakControlEvent event, Emitter<WaterLeakState> emit) async {
|
WaterLeakControlEvent event, Emitter<WaterLeakState> emit) async {
|
||||||
final oldValue = deviceStatus!.watersensorState;
|
final oldValue = deviceStatus!.watersensorState;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart';
|
||||||
|
|
||||||
abstract class WaterLeakEvent extends Equatable {
|
abstract class WaterLeakEvent extends Equatable {
|
||||||
const WaterLeakEvent();
|
const WaterLeakEvent();
|
||||||
@ -17,6 +18,13 @@ class FetchWaterLeakStatusEvent extends WaterLeakEvent {
|
|||||||
List<Object> get props => [deviceId];
|
List<Object> get props => [deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StatusUpdated extends WaterLeakEvent {
|
||||||
|
final WaterLeakStatusModel deviceStatus;
|
||||||
|
const StatusUpdated(this.deviceStatus);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [deviceStatus];
|
||||||
|
}
|
||||||
|
|
||||||
class WaterLeakControlEvent extends WaterLeakEvent {
|
class WaterLeakControlEvent extends WaterLeakEvent {
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String code;
|
final String code;
|
||||||
|
@ -2,20 +2,19 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
// import 'package:graphview/GraphView.dart';
|
|
||||||
import 'package:syncrow_web/pages/auth/model/user_model.dart';
|
import 'package:syncrow_web/pages/auth/model/user_model.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
|
||||||
import 'package:syncrow_web/pages/home/home_model/home_item_model.dart';
|
import 'package:syncrow_web/pages/home/home_model/home_item_model.dart';
|
||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
import 'package:syncrow_web/services/home_api.dart';
|
import 'package:syncrow_web/services/home_api.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
||||||
import 'package:syncrow_web/utils/constants/strings_manager.dart';
|
import 'package:syncrow_web/utils/navigation_service.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart';
|
|
||||||
|
|
||||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||||
// final Graph graph = Graph()..isTree = true;
|
// final Graph graph = Graph()..isTree = true;
|
||||||
@ -52,12 +51,12 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
|
|
||||||
Future _fetchUserInfo(FetchUserInfo event, Emitter<HomeState> emit) async {
|
Future _fetchUserInfo(FetchUserInfo event, Emitter<HomeState> emit) async {
|
||||||
try {
|
try {
|
||||||
var uuid =
|
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
|
||||||
user = await HomeApi().fetchUserInfo(uuid);
|
user = await HomeApi().fetchUserInfo(uuid);
|
||||||
|
|
||||||
if (user != null && user!.project != null) {
|
if (user != null && user!.project != null) {
|
||||||
await ProjectManager.setProjectUUID(user!.project!.uuid);
|
await ProjectManager.setProjectUUID(user!.project!.uuid);
|
||||||
|
NavigationService.navigatorKey.currentContext!.read<SpaceTreeBloc>().add(InitialEvent());
|
||||||
}
|
}
|
||||||
add(FetchTermEvent());
|
add(FetchTermEvent());
|
||||||
add(FetchPolicyEvent());
|
add(FetchPolicyEvent());
|
||||||
@ -73,8 +72,6 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
emit(LoadingHome());
|
emit(LoadingHome());
|
||||||
terms = await HomeApi().fetchTerms();
|
terms = await HomeApi().fetchTerms();
|
||||||
emit(HomeInitial());
|
emit(HomeInitial());
|
||||||
|
|
||||||
// emit(PolicyAgreement());
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -84,8 +81,6 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
try {
|
try {
|
||||||
emit(LoadingHome());
|
emit(LoadingHome());
|
||||||
policy = await HomeApi().fetchPolicy();
|
policy = await HomeApi().fetchPolicy();
|
||||||
debugPrint("Fetched policy: $policy");
|
|
||||||
// Emit a state to trigger the UI update
|
|
||||||
emit(HomeInitial());
|
emit(HomeInitial());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint("Error fetching policy: $e");
|
debugPrint("Error fetching policy: $e");
|
||||||
@ -93,12 +88,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _confirmUserAgreement(
|
Future _confirmUserAgreement(ConfirmUserAgreementEvent event, Emitter<HomeState> emit) async {
|
||||||
ConfirmUserAgreementEvent event, Emitter<HomeState> emit) async {
|
|
||||||
try {
|
try {
|
||||||
emit(LoadingHome());
|
emit(LoadingHome());
|
||||||
var uuid =
|
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
|
||||||
policy = await HomeApi().confirmUserAgreements(uuid);
|
policy = await HomeApi().confirmUserAgreements(uuid);
|
||||||
emit(PolicyAgreement());
|
emit(PolicyAgreement());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -118,10 +111,11 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
|
|
||||||
List<HomeItemModel> homeItems = [
|
List<HomeItemModel> homeItems = [
|
||||||
HomeItemModel(
|
HomeItemModel(
|
||||||
title: 'Access',
|
title: 'Access Management',
|
||||||
icon: Assets.accessIcon,
|
icon: Assets.accessIcon,
|
||||||
active: true,
|
active: true,
|
||||||
onPress: (context) {
|
onPress: (context) {
|
||||||
|
context.read<SpaceTreeBloc>().add(ClearCachedData());
|
||||||
context.go(RoutesConst.accessManagementPage);
|
context.go(RoutesConst.accessManagementPage);
|
||||||
},
|
},
|
||||||
color: null,
|
color: null,
|
||||||
@ -131,21 +125,24 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
icon: Assets.spaseManagementIcon,
|
icon: Assets.spaseManagementIcon,
|
||||||
active: true,
|
active: true,
|
||||||
onPress: (context) {
|
onPress: (context) {
|
||||||
|
context.read<SpaceTreeBloc>().add(ClearCachedData());
|
||||||
context.go(RoutesConst.spacesManagementPage);
|
context.go(RoutesConst.spacesManagementPage);
|
||||||
},
|
},
|
||||||
color: ColorsManager.primaryColor,
|
color: ColorsManager.primaryColor,
|
||||||
),
|
),
|
||||||
HomeItemModel(
|
HomeItemModel(
|
||||||
title: 'Devices',
|
title: 'Devices Management',
|
||||||
icon: Assets.devicesIcon,
|
icon: Assets.devicesIcon,
|
||||||
active: true,
|
active: true,
|
||||||
onPress: (context) {
|
onPress: (context) {
|
||||||
|
context.read<SpaceTreeBloc>().add(ClearCachedData());
|
||||||
BlocProvider.of<RoutineBloc>(context)
|
BlocProvider.of<RoutineBloc>(context)
|
||||||
.add(const TriggerSwitchTabsEvent(isRoutineTab: false));
|
.add(const TriggerSwitchTabsEvent(isRoutineTab: false));
|
||||||
context.go(RoutesConst.deviceManagementPage);
|
context.go(RoutesConst.deviceManagementPage);
|
||||||
},
|
},
|
||||||
color: ColorsManager.primaryColor,
|
color: ColorsManager.primaryColor,
|
||||||
),
|
),
|
||||||
|
|
||||||
// HomeItemModel(
|
// HomeItemModel(
|
||||||
// title: 'Move in',
|
// title: 'Move in',
|
||||||
// icon: Assets.moveinIcon,
|
// icon: Assets.moveinIcon,
|
||||||
|
@ -219,6 +219,9 @@ class UserSpaceModel {
|
|||||||
final double x;
|
final double x;
|
||||||
final double y;
|
final double y;
|
||||||
final String icon;
|
final String icon;
|
||||||
|
final String communityUuid;
|
||||||
|
|
||||||
|
//communityUuid
|
||||||
|
|
||||||
UserSpaceModel({
|
UserSpaceModel({
|
||||||
required this.uuid,
|
required this.uuid,
|
||||||
@ -231,6 +234,7 @@ class UserSpaceModel {
|
|||||||
required this.x,
|
required this.x,
|
||||||
required this.y,
|
required this.y,
|
||||||
required this.icon,
|
required this.icon,
|
||||||
|
required this.communityUuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Create a [UserSpaceModel] from JSON data
|
/// Create a [UserSpaceModel] from JSON data
|
||||||
@ -246,7 +250,7 @@ class UserSpaceModel {
|
|||||||
x: (json['x'] as num).toDouble(),
|
x: (json['x'] as num).toDouble(),
|
||||||
y: (json['y'] as num).toDouble(),
|
y: (json['y'] as num).toDouble(),
|
||||||
icon: json['icon'] as String,
|
icon: json['icon'] as String,
|
||||||
);
|
communityUuid: json['communityUuid'] as String);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the [UserSpaceModel] to JSON
|
/// Convert the [UserSpaceModel] to JSON
|
||||||
@ -262,6 +266,7 @@ class UserSpaceModel {
|
|||||||
'x': x,
|
'x': x,
|
||||||
'y': y,
|
'y': y,
|
||||||
'icon': icon,
|
'icon': icon,
|
||||||
|
'communityUuid': communityUuid
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
import 'package:syncrow_web/pages/common/custom_dialog.dart';
|
import 'package:syncrow_web/pages/common/custom_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/model/edit_user_model.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/model/edit_user_model.dart';
|
||||||
@ -8,14 +9,14 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialo
|
|||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||||
import 'package:syncrow_web/services/user_permission.dart';
|
import 'package:syncrow_web/services/user_permission.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/constants/strings_manager.dart';
|
import 'package:syncrow_web/utils/navigation_service.dart';
|
||||||
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
|
||||||
import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart';
|
|
||||||
|
|
||||||
class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
||||||
UsersBloc() : super(UsersInitial()) {
|
UsersBloc() : super(UsersInitial()) {
|
||||||
@ -65,8 +66,10 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
void isCompleteSpacesFun(
|
void isCompleteSpacesFun(
|
||||||
CheckSpacesStepStatus event, Emitter<UsersState> emit) {
|
CheckSpacesStepStatus event, Emitter<UsersState> emit) {
|
||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
List<String> selectedIds = getSelectedIds(updatedCommunities);
|
var spaceBloc =
|
||||||
isCompleteSpaces = selectedIds.isNotEmpty;
|
NavigationService.navigatorKey.currentContext!.read<SpaceTreeBloc>();
|
||||||
|
|
||||||
|
isCompleteSpaces = spaceBloc.state.selectedCommunities.isNotEmpty;
|
||||||
emit(ChangeStatusSteps());
|
emit(ChangeStatusSteps());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,9 +343,11 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
List<String> selectedIds = getSelectedIds(updatedCommunities)
|
// List<String> selectedIds =
|
||||||
.where((id) => !communityIds.contains(id))
|
// getSelectedIds(updatedCommunities).where((id) => !communityIds.contains(id)).toList();
|
||||||
.toList();
|
|
||||||
|
List<String> selectedSpacesId = getSelectedSpacesIds();
|
||||||
|
// List<String> selectedIds = getSelectedIds(updatedCommunities);
|
||||||
|
|
||||||
bool res = await UserPermissionApi().sendInviteUser(
|
bool res = await UserPermissionApi().sendInviteUser(
|
||||||
email: emailController.text,
|
email: emailController.text,
|
||||||
@ -351,7 +356,7 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
lastName: lastNameController.text,
|
lastName: lastNameController.text,
|
||||||
phoneNumber: phoneController.text,
|
phoneNumber: phoneController.text,
|
||||||
roleUuid: roleSelected,
|
roleUuid: roleSelected,
|
||||||
spaceUuids: selectedIds,
|
spaceUuids: selectedSpacesId,
|
||||||
projectUuid: projectUuid);
|
projectUuid: projectUuid);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -381,12 +386,20 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> getSelectedSpacesIds() {
|
||||||
|
List<String> selectedSpacesId = [];
|
||||||
|
var spaceBloc =
|
||||||
|
NavigationService.navigatorKey.currentContext!.read<SpaceTreeBloc>();
|
||||||
|
for (var community in spaceBloc.state.selectedCommunities) {
|
||||||
|
selectedSpacesId
|
||||||
|
.addAll(spaceBloc.state.selectedCommunityAndSpaces[community] ?? []);
|
||||||
|
}
|
||||||
|
return selectedSpacesId;
|
||||||
|
}
|
||||||
|
|
||||||
_editInviteUser(EditInviteUsers event, Emitter<UsersState> emit) async {
|
_editInviteUser(EditInviteUsers event, Emitter<UsersState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
List<String> selectedIds = getSelectedIds(updatedCommunities)
|
|
||||||
.where((id) => !communityIds.contains(id))
|
|
||||||
.toList();
|
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
bool res = await UserPermissionApi().editInviteUser(
|
bool res = await UserPermissionApi().editInviteUser(
|
||||||
@ -396,7 +409,7 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
lastName: lastNameController.text,
|
lastName: lastNameController.text,
|
||||||
phoneNumber: phoneController.text,
|
phoneNumber: phoneController.text,
|
||||||
roleUuid: roleSelected,
|
roleUuid: roleSelected,
|
||||||
spaceUuids: selectedIds,
|
spaceUuids: getSelectedSpacesIds(),
|
||||||
projectUuid: projectUuid);
|
projectUuid: projectUuid);
|
||||||
if (res == true) {
|
if (res == true) {
|
||||||
showCustomDialog(
|
showCustomDialog(
|
||||||
@ -502,6 +515,8 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
var spaceBloc =
|
||||||
|
NavigationService.navigatorKey.currentContext!.read<SpaceTreeBloc>();
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
if (event.uuid?.isNotEmpty ?? false) {
|
if (event.uuid?.isNotEmpty ?? false) {
|
||||||
@ -516,13 +531,20 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
phoneController.text = res.phoneNumber ?? '';
|
phoneController.text = res.phoneNumber ?? '';
|
||||||
jobTitleController.text = res.jobTitle ?? '';
|
jobTitleController.text = res.jobTitle ?? '';
|
||||||
res.roleType;
|
res.roleType;
|
||||||
if (updatedCommunities.isNotEmpty) {
|
res.spaces.map((space) {
|
||||||
// Create a list of UUIDs to mark
|
selectedIds.add(space.uuid);
|
||||||
final uuidsToMark = res.spaces.map((space) => space.uuid).toList();
|
CommunityModel community = spaceBloc.state.communityList
|
||||||
// Print all IDs and mark nodes in updatedCommunities
|
.firstWhere((item) => item.uuid == space.communityUuid);
|
||||||
debugPrint('Printing and marking nodes in updatedCommunities:');
|
spaceBloc.add(OnSpaceSelected(community, space.uuid, []));
|
||||||
_printAndMarkNodes(updatedCommunities, uuidsToMark);
|
}).toList();
|
||||||
}
|
|
||||||
|
// if (updatedCommunities.isNotEmpty) {
|
||||||
|
// // Create a list of UUIDs to mark
|
||||||
|
// final uuidsToMark = res.spaces.map((space) => space.uuid).toList();
|
||||||
|
// // Print all IDs and mark nodes in updatedCommunities
|
||||||
|
// debugPrint('Printing and marking nodes in updatedCommunities:');
|
||||||
|
// _printAndMarkNodes(updatedCommunities, uuidsToMark);
|
||||||
|
// }
|
||||||
final roleId = roles
|
final roleId = roles
|
||||||
.firstWhere((element) =>
|
.firstWhere((element) =>
|
||||||
element.type ==
|
element.type ==
|
||||||
@ -615,4 +637,16 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
emailController.dispose();
|
||||||
|
firstNameController.dispose();
|
||||||
|
lastNameController.dispose();
|
||||||
|
emailController.dispose();
|
||||||
|
phoneController.dispose();
|
||||||
|
jobTitleController.dispose();
|
||||||
|
roleSearchController.dispose();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
|
||||||
@ -25,7 +24,7 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (BuildContext context) => UsersBloc()
|
create: (BuildContext context) => UsersBloc()
|
||||||
..add(const LoadCommunityAndSpacesEvent())
|
// ..add(const LoadCommunityAndSpacesEvent())
|
||||||
..add(const RoleEvent()),
|
..add(const RoleEvent()),
|
||||||
child: BlocConsumer<UsersBloc, UsersState>(
|
child: BlocConsumer<UsersBloc, UsersState>(
|
||||||
listener: (context, state) {},
|
listener: (context, state) {},
|
||||||
|
@ -26,13 +26,12 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (BuildContext context) => UsersBloc()
|
create: (BuildContext context) => UsersBloc()
|
||||||
..add(const LoadCommunityAndSpacesEvent())
|
// ..add(const LoadCommunityAndSpacesEvent())
|
||||||
..add(const RoleEvent())
|
..add(const RoleEvent())
|
||||||
..add(GetUserByIdEvent(uuid: widget.userId)),
|
..add(GetUserByIdEvent(uuid: widget.userId)),
|
||||||
child: BlocConsumer<UsersBloc, UsersState>(listener: (context, state) {
|
child: BlocConsumer<UsersBloc, UsersState>(listener: (context, state) {
|
||||||
if (state is SpacesLoadedState) {
|
if (state is SpacesLoadedState) {
|
||||||
BlocProvider.of<UsersBloc>(context)
|
BlocProvider.of<UsersBloc>(context).add(GetUserByIdEvent(uuid: widget.userId));
|
||||||
.add(GetUserByIdEvent(uuid: widget.userId));
|
|
||||||
}
|
}
|
||||||
}, builder: (context, state) {
|
}, builder: (context, state) {
|
||||||
final _blocRole = BlocProvider.of<UsersBloc>(context);
|
final _blocRole = BlocProvider.of<UsersBloc>(context);
|
||||||
@ -40,8 +39,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
return Dialog(
|
return Dialog(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
|
||||||
width: 900,
|
width: 900,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -70,8 +68,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
children: [
|
children: [
|
||||||
_buildStep1Indicator(1, "Basics", _blocRole),
|
_buildStep1Indicator(1, "Basics", _blocRole),
|
||||||
_buildStep2Indicator(2, "Spaces", _blocRole),
|
_buildStep2Indicator(2, "Spaces", _blocRole),
|
||||||
_buildStep3Indicator(
|
_buildStep3Indicator(3, "Role & Permissions", _blocRole),
|
||||||
3, "Role & Permissions", _blocRole),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -119,15 +116,13 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
if (currentStep < 3) {
|
if (currentStep < 3) {
|
||||||
currentStep++;
|
currentStep++;
|
||||||
if (currentStep == 2) {
|
if (currentStep == 2) {
|
||||||
_blocRole
|
_blocRole.add(CheckStepStatus(isEditUser: true));
|
||||||
.add(CheckStepStatus(isEditUser: true));
|
|
||||||
} else if (currentStep == 3) {
|
} else if (currentStep == 3) {
|
||||||
_blocRole.add(const CheckSpacesStepStatus());
|
_blocRole.add(const CheckSpacesStepStatus());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_blocRole.add(EditInviteUsers(
|
_blocRole
|
||||||
context: context,
|
.add(EditInviteUsers(context: context, userId: widget.userId!));
|
||||||
userId: widget.userId!));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -136,8 +131,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: (_blocRole.isCompleteSpaces == false ||
|
color: (_blocRole.isCompleteSpaces == false ||
|
||||||
_blocRole.isCompleteBasics == false ||
|
_blocRole.isCompleteBasics == false ||
|
||||||
_blocRole.isCompleteRolePermissions ==
|
_blocRole.isCompleteRolePermissions == false) &&
|
||||||
false) &&
|
|
||||||
currentStep == 3
|
currentStep == 3
|
||||||
? ColorsManager.grayColor
|
? ColorsManager.grayColor
|
||||||
: ColorsManager.secondaryColor),
|
: ColorsManager.secondaryColor),
|
||||||
@ -210,12 +204,8 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
label,
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: currentStep == step
|
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor,
|
||||||
? ColorsManager.blackColor
|
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal,
|
||||||
: ColorsManager.greyColor,
|
|
||||||
fontWeight: currentStep == step
|
|
||||||
? FontWeight.bold
|
|
||||||
: FontWeight.normal,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -273,12 +263,8 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
label,
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: currentStep == step
|
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor,
|
||||||
? ColorsManager.blackColor
|
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal,
|
||||||
: ColorsManager.greyColor,
|
|
||||||
fontWeight: currentStep == step
|
|
||||||
? FontWeight.bold
|
|
||||||
: FontWeight.normal,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -335,12 +321,8 @@ class _EditUserDialogState extends State<EditUserDialog> {
|
|||||||
label,
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: currentStep == step
|
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor,
|
||||||
? ColorsManager.blackColor
|
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal,
|
||||||
: ColorsManager.greyColor,
|
|
||||||
fontWeight: currentStep == step
|
|
||||||
? FontWeight.bold
|
|
||||||
: FontWeight.normal,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart';
|
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart';
|
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
|
||||||
|
|
||||||
class SpacesAccessView extends StatelessWidget {
|
class SpacesAccessView extends StatelessWidget {
|
||||||
final String? userId;
|
final String? userId;
|
||||||
@ -27,10 +22,8 @@ class SpacesAccessView extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Spaces access',
|
'Spaces access',
|
||||||
style: context.textTheme.bodyLarge?.copyWith(
|
style: context.textTheme.bodyLarge
|
||||||
fontWeight: FontWeight.w700,
|
?.copyWith(fontWeight: FontWeight.w700, fontSize: 20, color: Colors.black),
|
||||||
fontSize: 20,
|
|
||||||
color: Colors.black),
|
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 35,
|
height: 35,
|
||||||
@ -42,77 +35,78 @@ class SpacesAccessView extends StatelessWidget {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 25,
|
height: 25,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(child: SpaceTreeView(onSelect: () {}))
|
||||||
child: SizedBox(
|
// Expanded(
|
||||||
child: Column(
|
// child: SizedBox(
|
||||||
children: [
|
// child: Column(
|
||||||
Expanded(
|
// children: [
|
||||||
flex: 2,
|
// Expanded(
|
||||||
child: Container(
|
// flex: 2,
|
||||||
decoration: const BoxDecoration(
|
// child: Container(
|
||||||
color: ColorsManager.circleRolesBackground,
|
// decoration: const BoxDecoration(
|
||||||
borderRadius: BorderRadius.only(
|
// color: ColorsManager.circleRolesBackground,
|
||||||
topRight: Radius.circular(20),
|
// borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(20)),
|
// topRight: Radius.circular(20),
|
||||||
),
|
// topLeft: Radius.circular(20)),
|
||||||
child: Padding(
|
// ),
|
||||||
padding: const EdgeInsets.all(8.0),
|
// child: Padding(
|
||||||
child: Row(
|
// padding: const EdgeInsets.all(8.0),
|
||||||
children: [
|
// child: Row(
|
||||||
Expanded(
|
// children: [
|
||||||
child: Container(
|
// Expanded(
|
||||||
decoration: BoxDecoration(
|
// child: Container(
|
||||||
borderRadius: const BorderRadius.all(
|
// decoration: BoxDecoration(
|
||||||
Radius.circular(20)),
|
// borderRadius: const BorderRadius.all(
|
||||||
border: Border.all(
|
// Radius.circular(20)),
|
||||||
color: ColorsManager.grayBorder)),
|
// border: Border.all(
|
||||||
child: TextFormField(
|
// color: ColorsManager.grayBorder)),
|
||||||
style:
|
// child: TextFormField(
|
||||||
const TextStyle(color: Colors.black),
|
// style:
|
||||||
// controller: _blocRole.firstNameController,
|
// const TextStyle(color: Colors.black),
|
||||||
onChanged: (value) {
|
// // controller: _blocRole.firstNameController,
|
||||||
_blocRole.add(SearchAnode(
|
// onChanged: (value) {
|
||||||
nodes: _blocRole.updatedCommunities,
|
// _blocRole.add(SearchAnode(
|
||||||
searchTerm: value));
|
// nodes: _blocRole.updatedCommunities,
|
||||||
},
|
// searchTerm: value));
|
||||||
decoration: textBoxDecoration(radios: 20)!
|
// },
|
||||||
.copyWith(
|
// decoration: textBoxDecoration(radios: 20)!
|
||||||
fillColor: Colors.white,
|
// .copyWith(
|
||||||
suffixIcon: Padding(
|
// fillColor: Colors.white,
|
||||||
padding:
|
// suffixIcon: Padding(
|
||||||
const EdgeInsets.only(right: 16),
|
// padding:
|
||||||
child: SvgPicture.asset(
|
// const EdgeInsets.only(right: 16),
|
||||||
Assets.textFieldSearch,
|
// child: SvgPicture.asset(
|
||||||
width: 24,
|
// Assets.textFieldSearch,
|
||||||
height: 24,
|
// width: 24,
|
||||||
),
|
// height: 24,
|
||||||
),
|
// ),
|
||||||
hintStyle: context.textTheme.bodyMedium
|
// ),
|
||||||
?.copyWith(
|
// hintStyle: context.textTheme.bodyMedium
|
||||||
fontWeight: FontWeight.w400,
|
// ?.copyWith(
|
||||||
fontSize: 12,
|
// fontWeight: FontWeight.w400,
|
||||||
color: ColorsManager.textGray),
|
// fontSize: 12,
|
||||||
),
|
// color: ColorsManager.textGray),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ),
|
||||||
),
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
Expanded(
|
// ),
|
||||||
flex: 7,
|
// Expanded(
|
||||||
child: Container(
|
// flex: 7,
|
||||||
color: ColorsManager.circleRolesBackground,
|
// child: Container(
|
||||||
padding: const EdgeInsets.all(8.0),
|
// color: ColorsManager.circleRolesBackground,
|
||||||
child: Container(
|
// padding: const EdgeInsets.all(8.0),
|
||||||
color: ColorsManager.whiteColors,
|
// child: Container(
|
||||||
child: TreeView(userId: userId))))
|
// color: ColorsManager.whiteColors,
|
||||||
],
|
// child: TreeView(userId: userId))))
|
||||||
),
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
|
// ),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -13,6 +13,8 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/vi
|
|||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/name_filter.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/name_filter.dart';
|
||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/user_table.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/user_table.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
@ -25,8 +27,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final TextEditingController searchController = TextEditingController();
|
final TextEditingController searchController = TextEditingController();
|
||||||
|
|
||||||
Widget actionButton(
|
Widget actionButton({bool isActive = false, required String title, Function()? onTap}) {
|
||||||
{bool isActive = false, required String title, Function()? onTap}) {
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@ -59,8 +60,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
: ColorsManager.disabledPink.withOpacity(0.5),
|
: ColorsManager.disabledPink.withOpacity(0.5),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(left: 10, right: 10, bottom: 5, top: 5),
|
||||||
const EdgeInsets.only(left: 10, right: 10, bottom: 5, top: 5),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@ -84,15 +84,12 @@ class UsersPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget changeIconStatus(
|
Widget changeIconStatus(
|
||||||
{required String userId,
|
{required String userId, required String status, required Function()? onTap}) {
|
||||||
required String status,
|
|
||||||
required Function()? onTap}) {
|
|
||||||
return Center(
|
return Center(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(left: 5, right: 5, bottom: 5, top: 5),
|
||||||
const EdgeInsets.only(left: 5, right: 5, bottom: 5, top: 5),
|
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
status == "invited"
|
status == "invited"
|
||||||
? Assets.invitedIcon
|
? Assets.invitedIcon
|
||||||
@ -160,6 +157,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
context.read<SpaceTreeBloc>().add(ClearCachedData());
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
@ -198,14 +196,10 @@ class UsersPage extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
isSelected: _blocRole.currentSortOrder,
|
isSelected: _blocRole.currentSortOrder,
|
||||||
aToZTap: () {
|
aToZTap: () {
|
||||||
context
|
context.read<UserTableBloc>().add(const SortUsersByNameAsc());
|
||||||
.read<UserTableBloc>()
|
|
||||||
.add(const SortUsersByNameAsc());
|
|
||||||
},
|
},
|
||||||
zToaTap: () {
|
zToaTap: () {
|
||||||
context
|
context.read<UserTableBloc>().add(const SortUsersByNameDesc());
|
||||||
.read<UserTableBloc>()
|
|
||||||
.add(const SortUsersByNameDesc());
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -214,9 +208,8 @@ class UsersPage extends StatelessWidget {
|
|||||||
for (var item in _blocRole.jobTitle)
|
for (var item in _blocRole.jobTitle)
|
||||||
item: _blocRole.selectedJobTitles.contains(item),
|
item: _blocRole.selectedJobTitles.contains(item),
|
||||||
};
|
};
|
||||||
final RenderBox overlay = Overlay.of(context)
|
final RenderBox overlay =
|
||||||
.context
|
Overlay.of(context).context.findRenderObject() as RenderBox;
|
||||||
.findRenderObject() as RenderBox;
|
|
||||||
|
|
||||||
showPopUpFilterMenu(
|
showPopUpFilterMenu(
|
||||||
position: RelativeRect.fromLTRB(
|
position: RelativeRect.fromLTRB(
|
||||||
@ -256,9 +249,8 @@ class UsersPage extends StatelessWidget {
|
|||||||
for (var item in _blocRole.roleTypes)
|
for (var item in _blocRole.roleTypes)
|
||||||
item: _blocRole.selectedRoles.contains(item),
|
item: _blocRole.selectedRoles.contains(item),
|
||||||
};
|
};
|
||||||
final RenderBox overlay = Overlay.of(context)
|
final RenderBox overlay =
|
||||||
.context
|
Overlay.of(context).context.findRenderObject() as RenderBox;
|
||||||
.findRenderObject() as RenderBox;
|
|
||||||
showPopUpFilterMenu(
|
showPopUpFilterMenu(
|
||||||
position: RelativeRect.fromLTRB(
|
position: RelativeRect.fromLTRB(
|
||||||
overlay.size.width / 4,
|
overlay.size.width / 4,
|
||||||
@ -278,8 +270,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
.map((entry) => entry.key)
|
.map((entry) => entry.key)
|
||||||
.toList();
|
.toList();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
context.read<UserTableBloc>().add(
|
context.read<UserTableBloc>().add(FilterUsersByRoleEvent(
|
||||||
FilterUsersByRoleEvent(
|
|
||||||
selectedRoles: selectedItems,
|
selectedRoles: selectedItems,
|
||||||
sortOrder: _blocRole.currentSortRole));
|
sortOrder: _blocRole.currentSortRole));
|
||||||
},
|
},
|
||||||
@ -296,14 +287,10 @@ class UsersPage extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
isSelected: _blocRole.currentSortOrder,
|
isSelected: _blocRole.currentSortOrder,
|
||||||
aToZTap: () {
|
aToZTap: () {
|
||||||
context
|
context.read<UserTableBloc>().add(const DateNewestToOldestEvent());
|
||||||
.read<UserTableBloc>()
|
|
||||||
.add(const DateNewestToOldestEvent());
|
|
||||||
},
|
},
|
||||||
zToaTap: () {
|
zToaTap: () {
|
||||||
context
|
context.read<UserTableBloc>().add(const DateOldestToNewestEvent());
|
||||||
.read<UserTableBloc>()
|
|
||||||
.add(const DateOldestToNewestEvent());
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -312,9 +299,8 @@ class UsersPage extends StatelessWidget {
|
|||||||
for (var item in _blocRole.createdBy)
|
for (var item in _blocRole.createdBy)
|
||||||
item: _blocRole.selectedCreatedBy.contains(item),
|
item: _blocRole.selectedCreatedBy.contains(item),
|
||||||
};
|
};
|
||||||
final RenderBox overlay = Overlay.of(context)
|
final RenderBox overlay =
|
||||||
.context
|
Overlay.of(context).context.findRenderObject() as RenderBox;
|
||||||
.findRenderObject() as RenderBox;
|
|
||||||
showPopUpFilterMenu(
|
showPopUpFilterMenu(
|
||||||
position: RelativeRect.fromLTRB(
|
position: RelativeRect.fromLTRB(
|
||||||
overlay.size.width / 1,
|
overlay.size.width / 1,
|
||||||
@ -352,9 +338,8 @@ class UsersPage extends StatelessWidget {
|
|||||||
item: _blocRole.selectedStatuses.contains(item),
|
item: _blocRole.selectedStatuses.contains(item),
|
||||||
};
|
};
|
||||||
|
|
||||||
final RenderBox overlay = Overlay.of(context)
|
final RenderBox overlay =
|
||||||
.context
|
Overlay.of(context).context.findRenderObject() as RenderBox;
|
||||||
.findRenderObject() as RenderBox;
|
|
||||||
showPopUpFilterMenu(
|
showPopUpFilterMenu(
|
||||||
position: RelativeRect.fromLTRB(
|
position: RelativeRect.fromLTRB(
|
||||||
overlay.size.width / 0,
|
overlay.size.width / 0,
|
||||||
@ -391,14 +376,10 @@ class UsersPage extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
isSelected: _blocRole.currentSortOrderDate,
|
isSelected: _blocRole.currentSortOrderDate,
|
||||||
aToZTap: () {
|
aToZTap: () {
|
||||||
context
|
context.read<UserTableBloc>().add(const DateNewestToOldestEvent());
|
||||||
.read<UserTableBloc>()
|
|
||||||
.add(const DateNewestToOldestEvent());
|
|
||||||
},
|
},
|
||||||
zToaTap: () {
|
zToaTap: () {
|
||||||
context
|
context.read<UserTableBloc>().add(const DateOldestToNewestEvent());
|
||||||
.read<UserTableBloc>()
|
|
||||||
.add(const DateOldestToNewestEvent());
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -425,23 +406,17 @@ class UsersPage extends StatelessWidget {
|
|||||||
Text(user.createdTime ?? ''),
|
Text(user.createdTime ?? ''),
|
||||||
Text(user.invitedBy),
|
Text(user.invitedBy),
|
||||||
status(
|
status(
|
||||||
status: user.isEnabled == false
|
status: user.isEnabled == false ? 'disabled' : user.status,
|
||||||
? 'disabled'
|
|
||||||
: user.status,
|
|
||||||
),
|
),
|
||||||
changeIconStatus(
|
changeIconStatus(
|
||||||
status: user.isEnabled == false
|
status: user.isEnabled == false ? 'disabled' : user.status,
|
||||||
? 'disabled'
|
|
||||||
: user.status,
|
|
||||||
userId: user.uuid,
|
userId: user.uuid,
|
||||||
onTap: user.status != "invited"
|
onTap: user.status != "invited"
|
||||||
? () {
|
? () {
|
||||||
context.read<UserTableBloc>().add(
|
context.read<UserTableBloc>().add(ChangeUserStatus(
|
||||||
ChangeUserStatus(
|
|
||||||
userId: user.uuid,
|
userId: user.uuid,
|
||||||
newStatus: user.isEnabled == false
|
newStatus:
|
||||||
? 'disabled'
|
user.isEnabled == false ? 'disabled' : user.status));
|
||||||
: user.status));
|
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
@ -452,12 +427,12 @@ class UsersPage extends StatelessWidget {
|
|||||||
isActive: true,
|
isActive: true,
|
||||||
title: "Edit",
|
title: "Edit",
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
context.read<SpaceTreeBloc>().add(ClearCachedData());
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return EditUserDialog(
|
return EditUserDialog(userId: user.uuid);
|
||||||
userId: user.uuid);
|
|
||||||
},
|
},
|
||||||
).then((v) {
|
).then((v) {
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
@ -478,13 +453,10 @@ class UsersPage extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return DeleteUserDialog(
|
return DeleteUserDialog(onTapDelete: () async {
|
||||||
onTapDelete: () async {
|
|
||||||
try {
|
try {
|
||||||
_blocRole.add(DeleteUserEvent(
|
_blocRole.add(DeleteUserEvent(user.uuid, context));
|
||||||
user.uuid, context));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
await Future.delayed(
|
|
||||||
const Duration(seconds: 2));
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
@ -514,20 +486,14 @@ class UsersPage extends StatelessWidget {
|
|||||||
visiblePagesCount: 4,
|
visiblePagesCount: 4,
|
||||||
buttonRadius: 10,
|
buttonRadius: 10,
|
||||||
selectedButtonColor: ColorsManager.secondaryColor,
|
selectedButtonColor: ColorsManager.secondaryColor,
|
||||||
buttonUnSelectedBorderColor:
|
buttonUnSelectedBorderColor: ColorsManager.grayBorder,
|
||||||
ColorsManager.grayBorder,
|
lastPageIcon: const Icon(Icons.keyboard_double_arrow_right),
|
||||||
lastPageIcon:
|
firstPageIcon: const Icon(Icons.keyboard_double_arrow_left),
|
||||||
const Icon(Icons.keyboard_double_arrow_right),
|
totalPages:
|
||||||
firstPageIcon:
|
(_blocRole.totalUsersCount.length / _blocRole.itemsPerPage).ceil(),
|
||||||
const Icon(Icons.keyboard_double_arrow_left),
|
|
||||||
totalPages: (_blocRole.totalUsersCount.length /
|
|
||||||
_blocRole.itemsPerPage)
|
|
||||||
.ceil(),
|
|
||||||
currentPage: _blocRole.currentPage,
|
currentPage: _blocRole.currentPage,
|
||||||
onPageChanged: (int pageNumber) {
|
onPageChanged: (int pageNumber) {
|
||||||
context
|
context.read<UserTableBloc>().add(ChangePage(pageNumber));
|
||||||
.read<UserTableBloc>()
|
|
||||||
.add(ChangePage(pageNumber));
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -9,6 +9,7 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/bl
|
|||||||
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/users_page.dart';
|
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/users_page.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
|
|
||||||
class RolesAndPermissionPage extends StatelessWidget {
|
class RolesAndPermissionPage extends StatelessWidget {
|
||||||
@ -27,11 +28,10 @@ class RolesAndPermissionPage extends StatelessWidget {
|
|||||||
? const Center(child: CircularProgressIndicator())
|
? const Center(child: CircularProgressIndicator())
|
||||||
: WebScaffold(
|
: WebScaffold(
|
||||||
enableMenuSidebar: false,
|
enableMenuSidebar: false,
|
||||||
appBarTitle: FittedBox(
|
appBarTitle: Text(
|
||||||
child: Text(
|
|
||||||
'Roles & Permissions',
|
'Roles & Permissions',
|
||||||
style: Theme.of(context).textTheme.headlineLarge,
|
style:
|
||||||
),
|
ResponsiveTextTheme.of(context).deviceManagementTitle,
|
||||||
),
|
),
|
||||||
rightBody: const NavigateHomeGridView(),
|
rightBody: const NavigateHomeGridView(),
|
||||||
centerBody: Row(
|
centerBody: Row(
|
||||||
|
@ -7,7 +7,6 @@ import 'package:syncrow_web/pages/routines/widgets/main_routine_view/routine_vie
|
|||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
|
||||||
|
|
||||||
class RoutinesView extends StatefulWidget {
|
class RoutinesView extends StatefulWidget {
|
||||||
const RoutinesView({super.key});
|
const RoutinesView({super.key});
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
@ -6,18 +5,8 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||||
import 'package:syncrow_web/utils/constants/strings_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
|
||||||
import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart';
|
|
||||||
|
|
||||||
class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
||||||
// String selectedCommunityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
|
|
||||||
// String selectedSpaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
|
||||||
final TextEditingController textController = TextEditingController();
|
|
||||||
|
|
||||||
// String selectedCommunityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
|
|
||||||
// String selectedSpaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
|
||||||
|
|
||||||
SpaceTreeBloc() : super(const SpaceTreeState()) {
|
SpaceTreeBloc() : super(const SpaceTreeState()) {
|
||||||
on<InitialEvent>(_fetchSpaces);
|
on<InitialEvent>(_fetchSpaces);
|
||||||
on<OnCommunityExpanded>(_onCommunityExpanded);
|
on<OnCommunityExpanded>(_onCommunityExpanded);
|
||||||
@ -25,6 +14,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
on<OnCommunitySelected>(_onCommunitySelected);
|
on<OnCommunitySelected>(_onCommunitySelected);
|
||||||
on<OnSpaceSelected>(_onSpaceSelected);
|
on<OnSpaceSelected>(_onSpaceSelected);
|
||||||
on<SearchQueryEvent>(_onSearch);
|
on<SearchQueryEvent>(_onSearch);
|
||||||
|
on<ClearAllData>(_clearAllData);
|
||||||
|
on<ClearCachedData>(_clearCachedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchSpaces(InitialEvent event, Emitter<SpaceTreeState> emit) async {
|
_fetchSpaces(InitialEvent event, Emitter<SpaceTreeState> emit) async {
|
||||||
@ -37,8 +28,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
List<CommunityModel> updatedCommunities = await Future.wait(
|
List<CommunityModel> updatedCommunities = await Future.wait(
|
||||||
communities.map((community) async {
|
communities.map((community) async {
|
||||||
List<SpaceModel> spaces = await CommunitySpaceManagementApi()
|
List<SpaceModel> spaces =
|
||||||
.getSpaceHierarchy(community.uuid, projectUuid);
|
await CommunitySpaceManagementApi().getSpaceHierarchy(community.uuid, projectUuid);
|
||||||
|
|
||||||
return CommunityModel(
|
return CommunityModel(
|
||||||
uuid: community.uuid,
|
uuid: community.uuid,
|
||||||
@ -53,19 +44,15 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
communitiesList: updatedCommunities,
|
communitiesList: updatedCommunities, expandedCommunity: [], expandedSpaces: []));
|
||||||
expandedCommunity: [],
|
|
||||||
expandedSpaces: []));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCommunityExpanded(
|
_onCommunityExpanded(OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
|
||||||
OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
|
|
||||||
try {
|
try {
|
||||||
List<String> updatedExpandedCommunityList =
|
List<String> updatedExpandedCommunityList = List.from(state.expandedCommunities);
|
||||||
List.from(state.expandedCommunities);
|
|
||||||
|
|
||||||
if (updatedExpandedCommunityList.contains(event.communityId)) {
|
if (updatedExpandedCommunityList.contains(event.communityId)) {
|
||||||
updatedExpandedCommunityList.remove(event.communityId);
|
updatedExpandedCommunityList.remove(event.communityId);
|
||||||
@ -97,17 +84,14 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCommunitySelected(
|
_onCommunitySelected(OnCommunitySelected event, Emitter<SpaceTreeState> emit) async {
|
||||||
OnCommunitySelected event, Emitter<SpaceTreeState> emit) async {
|
|
||||||
try {
|
try {
|
||||||
List<String> updatedSelectedCommunities =
|
List<String> updatedSelectedCommunities =
|
||||||
List.from(state.selectedCommunities.toSet().toList());
|
List.from(state.selectedCommunities.toSet().toList());
|
||||||
List<String> updatedSelectedSpaces =
|
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
||||||
List.from(state.selectedSpaces.toSet().toList());
|
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
||||||
List<String> updatedSoldChecks =
|
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
|
||||||
List.from(state.soldCheck.toSet().toList());
|
List<String> selectedSpacesInCommunity = communityAndSpaces[event.communityId] ?? [];
|
||||||
Map<String, List<String>> communityAndSpaces =
|
|
||||||
Map.from(state.selectedCommunityAndSpaces);
|
|
||||||
|
|
||||||
List<String> childrenIds = _getAllChildIds(event.children);
|
List<String> childrenIds = _getAllChildIds(event.children);
|
||||||
|
|
||||||
@ -115,14 +99,16 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
// Select the community and all its children
|
// Select the community and all its children
|
||||||
updatedSelectedCommunities.add(event.communityId);
|
updatedSelectedCommunities.add(event.communityId);
|
||||||
updatedSelectedSpaces.addAll(childrenIds);
|
updatedSelectedSpaces.addAll(childrenIds);
|
||||||
|
selectedSpacesInCommunity.addAll(childrenIds);
|
||||||
} else {
|
} else {
|
||||||
// Unselect the community and all its children
|
// Unselect the community and all its children
|
||||||
updatedSelectedCommunities.remove(event.communityId);
|
updatedSelectedCommunities.remove(event.communityId);
|
||||||
updatedSelectedSpaces.removeWhere(childrenIds.contains);
|
updatedSelectedSpaces.removeWhere(childrenIds.contains);
|
||||||
updatedSoldChecks.removeWhere(childrenIds.contains);
|
updatedSoldChecks.removeWhere(childrenIds.contains);
|
||||||
|
selectedSpacesInCommunity.removeWhere(childrenIds.contains);
|
||||||
}
|
}
|
||||||
|
|
||||||
communityAndSpaces[event.communityId] = updatedSelectedSpaces;
|
communityAndSpaces[event.communityId] = selectedSpacesInCommunity;
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
selectedCommunities: updatedSelectedCommunities,
|
selectedCommunities: updatedSelectedCommunities,
|
||||||
@ -138,12 +124,11 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
try {
|
try {
|
||||||
List<String> updatedSelectedCommunities =
|
List<String> updatedSelectedCommunities =
|
||||||
List.from(state.selectedCommunities.toSet().toList());
|
List.from(state.selectedCommunities.toSet().toList());
|
||||||
List<String> updatedSelectedSpaces =
|
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
||||||
List.from(state.selectedSpaces.toSet().toList());
|
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
||||||
List<String> updatedSoldChecks =
|
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
|
||||||
List.from(state.soldCheck.toSet().toList());
|
|
||||||
Map<String, List<String>> communityAndSpaces =
|
List<String> selectedSpacesInCommunity = communityAndSpaces[event.communityModel.uuid] ?? [];
|
||||||
Map.from(state.selectedCommunityAndSpaces);
|
|
||||||
|
|
||||||
List<String> childrenIds = _getAllChildIds(event.children);
|
List<String> childrenIds = _getAllChildIds(event.children);
|
||||||
bool isChildSelected = false;
|
bool isChildSelected = false;
|
||||||
@ -158,16 +143,17 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
!updatedSoldChecks.contains(event.spaceId)) {
|
!updatedSoldChecks.contains(event.spaceId)) {
|
||||||
// First click: Select the space and all its children
|
// First click: Select the space and all its children
|
||||||
updatedSelectedSpaces.add(event.spaceId);
|
updatedSelectedSpaces.add(event.spaceId);
|
||||||
updatedSelectedCommunities.add(event.communityId);
|
updatedSelectedCommunities.add(event.communityModel.uuid);
|
||||||
|
selectedSpacesInCommunity.add(event.spaceId);
|
||||||
|
|
||||||
if (childrenIds.isNotEmpty) {
|
if (childrenIds.isNotEmpty) {
|
||||||
updatedSelectedSpaces.addAll(childrenIds);
|
updatedSelectedSpaces.addAll(childrenIds);
|
||||||
|
selectedSpacesInCommunity.addAll(childrenIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> spaces =
|
List<String> spaces = _getThePathToChild(event.communityModel.uuid, event.spaceId);
|
||||||
_getThePathToChild(event.communityId, event.spaceId);
|
|
||||||
for (String space in spaces) {
|
for (String space in spaces) {
|
||||||
if (!updatedSelectedSpaces.contains(space) &&
|
if (!updatedSelectedSpaces.contains(space) && !updatedSoldChecks.contains(space)) {
|
||||||
!updatedSoldChecks.contains(space)) {
|
|
||||||
updatedSoldChecks.add(space);
|
updatedSoldChecks.add(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,29 +161,42 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
childrenIds.isNotEmpty &&
|
childrenIds.isNotEmpty &&
|
||||||
isChildSelected) {
|
isChildSelected) {
|
||||||
// Second click: Unselect space but keep children
|
// Second click: Unselect space but keep children
|
||||||
|
selectedSpacesInCommunity.remove(event.spaceId);
|
||||||
updatedSelectedSpaces.remove(event.spaceId);
|
updatedSelectedSpaces.remove(event.spaceId);
|
||||||
updatedSoldChecks.add(event.spaceId);
|
updatedSoldChecks.add(event.spaceId);
|
||||||
} else {
|
} else {
|
||||||
// Third click: Unselect space and all its children
|
// Third click: Unselect space and all its children
|
||||||
|
selectedSpacesInCommunity.remove(event.spaceId);
|
||||||
updatedSelectedSpaces.remove(event.spaceId);
|
updatedSelectedSpaces.remove(event.spaceId);
|
||||||
if (childrenIds.isNotEmpty) {
|
if (childrenIds.isNotEmpty) {
|
||||||
updatedSelectedSpaces.removeWhere(childrenIds.contains);
|
updatedSelectedSpaces.removeWhere(childrenIds.contains);
|
||||||
updatedSoldChecks.removeWhere(childrenIds.contains);
|
updatedSoldChecks.removeWhere(childrenIds.contains);
|
||||||
|
selectedSpacesInCommunity.removeWhere(childrenIds.contains);
|
||||||
}
|
}
|
||||||
updatedSoldChecks.remove(event.spaceId);
|
updatedSoldChecks.remove(event.spaceId);
|
||||||
|
|
||||||
List<String> parents =
|
List<String> parents =
|
||||||
_getThePathToChild(event.communityId, event.spaceId);
|
_getThePathToChild(event.communityModel.uuid, event.spaceId).toSet().toList();
|
||||||
if (!_parentSelected(parents, updatedSelectedSpaces)) {
|
|
||||||
|
if (updatedSelectedSpaces.isEmpty) {
|
||||||
updatedSoldChecks.removeWhere(parents.contains);
|
updatedSoldChecks.removeWhere(parents.contains);
|
||||||
}
|
updatedSelectedCommunities.remove(event.communityModel.uuid);
|
||||||
if (!_anySpacesSelectedInCommunity(
|
} else {
|
||||||
event.communityId, updatedSelectedSpaces, updatedSoldChecks)) {
|
// Check if any parent has selected children
|
||||||
updatedSelectedCommunities.remove(event.communityId);
|
for (String space in parents) {
|
||||||
|
if (!_noChildrenSelected(event.communityModel, space, updatedSelectedSpaces, parents)) {
|
||||||
|
updatedSoldChecks.remove(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
communityAndSpaces[event.communityId] = updatedSelectedSpaces;
|
if (!_anySpacesSelectedInCommunity(
|
||||||
|
event.communityModel, updatedSelectedSpaces, updatedSoldChecks)) {
|
||||||
|
updatedSelectedCommunities.remove(event.communityModel.uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
communityAndSpaces[event.communityModel.uuid] = selectedSpacesInCommunity;
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
selectedCommunities: updatedSelectedCommunities.toSet().toList(),
|
selectedCommunities: updatedSelectedCommunities.toSet().toList(),
|
||||||
@ -210,12 +209,24 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_parentSelected(List<String> parents, List<String> selectedSpaces) {
|
_noChildrenSelected(
|
||||||
for (String space in parents) {
|
CommunityModel community, String spaceId, List<String> selectedSpaces, List<String> parents) {
|
||||||
if (selectedSpaces.contains(space)) {
|
if (selectedSpaces.contains(spaceId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SpaceModel> children = _getAllChildSpaces(community.spaces);
|
||||||
|
for (var child in children) {
|
||||||
|
if (spaceId == child.uuid) {
|
||||||
|
List<String> ids = _getAllChildIds(child.children);
|
||||||
|
for (var id in ids) {
|
||||||
|
if (selectedSpaces.contains(id)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,11 +237,10 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
// Filter communities and expand only those that match the query
|
// Filter communities and expand only those that match the query
|
||||||
filteredCommunity = communities.where((community) {
|
filteredCommunity = communities.where((community) {
|
||||||
final containsQueryInCommunity = community.name
|
final containsQueryInCommunity =
|
||||||
.toLowerCase()
|
community.name.toLowerCase().contains(event.searchQuery.toLowerCase());
|
||||||
.contains(event.searchQuery.toLowerCase());
|
final containsQueryInSpaces =
|
||||||
final containsQueryInSpaces = community.spaces.any(
|
community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase()));
|
||||||
(space) => _containsQuery(space, event.searchQuery.toLowerCase()));
|
|
||||||
|
|
||||||
return containsQueryInCommunity || containsQueryInSpaces;
|
return containsQueryInCommunity || containsQueryInSpaces;
|
||||||
}).toList();
|
}).toList();
|
||||||
@ -244,11 +254,47 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_clearAllData(ClearAllData event, Emitter<SpaceTreeState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(state.copyWith(
|
||||||
|
communitiesList: [],
|
||||||
|
filteredCommunity: [],
|
||||||
|
isSearching: false,
|
||||||
|
soldCheck: [],
|
||||||
|
selectedSpaces: [],
|
||||||
|
selectedCommunities: [],
|
||||||
|
selectedCommunityAndSpaces: {},
|
||||||
|
searchQuery: '',
|
||||||
|
expandedSpaces: [],
|
||||||
|
expandedCommunity: []));
|
||||||
|
} catch (e) {
|
||||||
|
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearCachedData(ClearCachedData event, Emitter<SpaceTreeState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(state.copyWith(
|
||||||
|
communitiesList: state.communityList,
|
||||||
|
filteredCommunity: [],
|
||||||
|
isSearching: false,
|
||||||
|
soldCheck: [],
|
||||||
|
selectedSpaces: [],
|
||||||
|
selectedCommunities: [],
|
||||||
|
selectedCommunityAndSpaces: {},
|
||||||
|
searchQuery: '',
|
||||||
|
expandedSpaces: [],
|
||||||
|
expandedCommunity: []));
|
||||||
|
} catch (e) {
|
||||||
|
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to determine if any space or its children match the search query
|
// Helper function to determine if any space or its children match the search query
|
||||||
bool _containsQuery(SpaceModel space, String query) {
|
bool _containsQuery(SpaceModel space, String query) {
|
||||||
final matchesSpace = space.name.toLowerCase().contains(query);
|
final matchesSpace = space.name.toLowerCase().contains(query);
|
||||||
final matchesChildren = space.children.any((child) =>
|
final matchesChildren =
|
||||||
_containsQuery(child, query)); // Recursive check for children
|
space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
||||||
|
|
||||||
return matchesSpace || matchesChildren;
|
return matchesSpace || matchesChildren;
|
||||||
}
|
}
|
||||||
@ -259,24 +305,28 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
ids.add(child.uuid!);
|
ids.add(child.uuid!);
|
||||||
ids.addAll(_getAllChildIds(child.children));
|
ids.addAll(_getAllChildIds(child.children));
|
||||||
}
|
}
|
||||||
return ids;
|
return ids.toSet().toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _anySpacesSelectedInCommunity(String communityId,
|
List<SpaceModel> _getAllChildSpaces(List<SpaceModel> spaces) {
|
||||||
List<String> selectedSpaces, List<String> partialCheckedList) {
|
List<SpaceModel> children = [];
|
||||||
|
for (var child in spaces) {
|
||||||
|
children.add(child);
|
||||||
|
children.addAll(_getAllChildSpaces(child.children));
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _anySpacesSelectedInCommunity(
|
||||||
|
CommunityModel community, List<String> selectedSpaces, List<String> partialCheckedList) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
for (var community in state.communityList) {
|
|
||||||
if (community.uuid == communityId) {
|
|
||||||
List<String> ids = _getAllChildIds(community.spaces);
|
List<String> ids = _getAllChildIds(community.spaces);
|
||||||
for (var id in ids) {
|
for (var id in ids) {
|
||||||
result =
|
result = selectedSpaces.contains(id) || partialCheckedList.contains(id);
|
||||||
selectedSpaces.contains(id) || partialCheckedList.contains(id);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,8 +347,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> _getAllParentsIds(
|
List<String> _getAllParentsIds(SpaceModel child, String spaceId, List<String> listIds) {
|
||||||
SpaceModel child, String spaceId, List<String> listIds) {
|
|
||||||
List<String> ids = listIds;
|
List<String> ids = listIds;
|
||||||
|
|
||||||
ids.add(child.uuid ?? '');
|
ids.add(child.uuid ?? '');
|
||||||
@ -322,7 +371,6 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
textController.dispose();
|
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
|
|
||||||
class SpaceTreeEvent extends Equatable {
|
class SpaceTreeEvent extends Equatable {
|
||||||
@ -49,14 +50,14 @@ class OnSpaceExpanded extends SpaceTreeEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class OnSpaceSelected extends SpaceTreeEvent {
|
class OnSpaceSelected extends SpaceTreeEvent {
|
||||||
final String communityId;
|
|
||||||
final String spaceId;
|
final String spaceId;
|
||||||
final List<SpaceModel> children;
|
final List<SpaceModel> children;
|
||||||
|
final CommunityModel communityModel;
|
||||||
|
|
||||||
const OnSpaceSelected(this.communityId, this.spaceId, this.children);
|
const OnSpaceSelected(this.communityModel, this.spaceId, this.children);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [communityId, spaceId, children];
|
List<Object> get props => [communityModel, spaceId, children];
|
||||||
}
|
}
|
||||||
|
|
||||||
class SearchQueryEvent extends SpaceTreeEvent {
|
class SearchQueryEvent extends SpaceTreeEvent {
|
||||||
@ -67,3 +68,7 @@ class SearchQueryEvent extends SpaceTreeEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [searchQuery];
|
List<Object> get props => [searchQuery];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClearAllData extends SpaceTreeEvent {}
|
||||||
|
|
||||||
|
class ClearCachedData extends SpaceTreeEvent {}
|
||||||
|
@ -172,11 +172,8 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
.expandedSpaces
|
.expandedSpaces
|
||||||
.contains(space.uuid),
|
.contains(space.uuid),
|
||||||
onItemSelected: () {
|
onItemSelected: () {
|
||||||
context
|
context.read<SpaceTreeBloc>().add(
|
||||||
.read<SpaceTreeBloc>()
|
OnSpaceSelected(community, space.uuid ?? '',
|
||||||
.add(OnSpaceSelected(
|
|
||||||
community.uuid,
|
|
||||||
space.uuid ?? '',
|
|
||||||
space.children));
|
space.children));
|
||||||
widget.onSelect();
|
widget.onSelect();
|
||||||
},
|
},
|
||||||
@ -196,10 +193,7 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
isSoldCheck: state.soldCheck
|
isSoldCheck: state.soldCheck
|
||||||
.contains(space.uuid),
|
.contains(space.uuid),
|
||||||
children: _buildNestedSpaces(
|
children: _buildNestedSpaces(
|
||||||
context,
|
context, state, space, community),
|
||||||
state,
|
|
||||||
space,
|
|
||||||
community.uuid),
|
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
@ -281,8 +275,8 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _buildNestedSpaces(BuildContext context, SpaceTreeState state,
|
List<Widget> _buildNestedSpaces(
|
||||||
SpaceModel space, String communityId) {
|
BuildContext context, SpaceTreeState state, SpaceModel space, CommunityModel community) {
|
||||||
return space.children.map((child) {
|
return space.children.map((child) {
|
||||||
return CustomExpansionTileSpaceTree(
|
return CustomExpansionTileSpaceTree(
|
||||||
isSelected: state.selectedSpaces.contains(child.uuid) ||
|
isSelected: state.selectedSpaces.contains(child.uuid) ||
|
||||||
@ -291,16 +285,15 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
title: child.name,
|
title: child.name,
|
||||||
isExpanded: state.expandedSpaces.contains(child.uuid),
|
isExpanded: state.expandedSpaces.contains(child.uuid),
|
||||||
onItemSelected: () {
|
onItemSelected: () {
|
||||||
context.read<SpaceTreeBloc>().add(
|
context
|
||||||
OnSpaceSelected(communityId, child.uuid ?? '', child.children));
|
.read<SpaceTreeBloc>()
|
||||||
|
.add(OnSpaceSelected(community, child.uuid ?? '', child.children));
|
||||||
widget.onSelect();
|
widget.onSelect();
|
||||||
},
|
},
|
||||||
onExpansionChanged: () {
|
onExpansionChanged: () {
|
||||||
context
|
context.read<SpaceTreeBloc>().add(OnSpaceExpanded(community.uuid, child.uuid ?? ''));
|
||||||
.read<SpaceTreeBloc>()
|
|
||||||
.add(OnSpaceExpanded(communityId, child.uuid ?? ''));
|
|
||||||
},
|
},
|
||||||
children: _buildNestedSpaces(context, state, child, communityId),
|
children: _buildNestedSpaces(context, state, child, community),
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/spaces_management/structure_selector/view/cent
|
|||||||
import 'package:syncrow_web/services/product_api.dart';
|
import 'package:syncrow_web/services/product_api.dart';
|
||||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||||
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
||||||
|
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
|
|
||||||
class SpaceManagementPage extends StatefulWidget {
|
class SpaceManagementPage extends StatefulWidget {
|
||||||
@ -39,8 +40,10 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: WebScaffold(
|
child: WebScaffold(
|
||||||
appBarTitle: Text('Space Management',
|
appBarTitle: Text(
|
||||||
style: Theme.of(context).textTheme.headlineLarge),
|
'Space Management',
|
||||||
|
style: ResponsiveTextTheme.of(context).deviceManagementTitle,
|
||||||
|
),
|
||||||
enableMenuSidebar: false,
|
enableMenuSidebar: false,
|
||||||
centerBody: CenterBodyWidget(),
|
centerBody: CenterBodyWidget(),
|
||||||
rightBody: const NavigateHomeGridView(),
|
rightBody: const NavigateHomeGridView(),
|
||||||
|
@ -4,9 +4,6 @@ import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model
|
|||||||
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_state.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
||||||
import 'package:syncrow_web/utils/constants/strings_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
|
||||||
import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart';
|
|
||||||
|
|
||||||
class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
||||||
final SpaceModelManagementApi api;
|
final SpaceModelManagementApi api;
|
||||||
@ -17,6 +14,7 @@ class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
|||||||
}) : super(SpaceModelLoaded(spaceModels: initialSpaceModels)) {
|
}) : super(SpaceModelLoaded(spaceModels: initialSpaceModels)) {
|
||||||
on<CreateSpaceModel>(_onCreateSpaceModel);
|
on<CreateSpaceModel>(_onCreateSpaceModel);
|
||||||
on<UpdateSpaceModel>(_onUpdateSpaceModel);
|
on<UpdateSpaceModel>(_onUpdateSpaceModel);
|
||||||
|
on<DeleteSpaceModel>(_onDeleteSpaceModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onCreateSpaceModel(
|
Future<void> _onCreateSpaceModel(
|
||||||
@ -50,7 +48,7 @@ class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
|||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
final newSpaceModel =
|
final newSpaceModel =
|
||||||
await api.getSpaceModel(event.spaceModelUuid ?? '', projectUuid);
|
await api.getSpaceModel(event.spaceModelUuid, projectUuid);
|
||||||
if (newSpaceModel != null) {
|
if (newSpaceModel != null) {
|
||||||
final updatedSpaceModels = currentState.spaceModels.map((model) {
|
final updatedSpaceModels = currentState.spaceModels.map((model) {
|
||||||
return model.uuid == event.spaceModelUuid ? newSpaceModel : model;
|
return model.uuid == event.spaceModelUuid ? newSpaceModel : model;
|
||||||
@ -62,4 +60,28 @@ class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _onDeleteSpaceModel(
|
||||||
|
DeleteSpaceModel event, Emitter<SpaceModelState> emit) async {
|
||||||
|
final currentState = state;
|
||||||
|
|
||||||
|
if (currentState is SpaceModelLoaded) {
|
||||||
|
try {
|
||||||
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
|
final deletedSuccessfully =
|
||||||
|
await api.deleteSpaceModel(event.spaceModelUuid, projectUuid);
|
||||||
|
|
||||||
|
if (deletedSuccessfully) {
|
||||||
|
final updatedSpaceModels = currentState.spaceModels
|
||||||
|
.where((model) => model.uuid != event.spaceModelUuid)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
emit(SpaceModelLoaded(spaceModels: updatedSpaceModels));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(SpaceModelError(message: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,3 +34,12 @@ class UpdateSpaceModel extends SpaceModelEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object?> get props => [spaceModelUuid];
|
List<Object?> get props => [spaceModelUuid];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeleteSpaceModel extends SpaceModelEvent {
|
||||||
|
final String spaceModelUuid;
|
||||||
|
|
||||||
|
DeleteSpaceModel({required this.spaceModelUuid});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [spaceModelUuid];
|
||||||
|
}
|
||||||
|
@ -90,7 +90,11 @@ class SpaceModelPage extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.all(8.0),
|
margin: const EdgeInsets.all(8.0),
|
||||||
child: SpaceModelCardWidget(model: model),
|
child: SpaceModelCardWidget(
|
||||||
|
model: model,
|
||||||
|
pageContext: context,
|
||||||
|
topActionsDisabled: false,
|
||||||
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
class DeleteSpaceModelDialog extends StatelessWidget {
|
||||||
|
final VoidCallback onConfirmDelete;
|
||||||
|
|
||||||
|
const DeleteSpaceModelDialog({Key? key, required this.onConfirmDelete})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return AlertDialog(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
backgroundColor: ColorsManager.whiteColors,
|
||||||
|
title: Center(
|
||||||
|
child: Text(
|
||||||
|
"Delete Space Model",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headlineLarge
|
||||||
|
?.copyWith(color: ColorsManager.blackColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
content: SizedBox(
|
||||||
|
width: screenWidth * 0.4,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Are you sure you want to delete?",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
Text(
|
||||||
|
"The existing sub-spaces, devices, and routines will remain associated with the spaces, but the connection will be removed.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium
|
||||||
|
?.copyWith(color: ColorsManager.lightGrayColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 200,
|
||||||
|
child: CancelButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(); // Close dialog
|
||||||
|
},
|
||||||
|
label: "Cancel",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
SizedBox(
|
||||||
|
width: 200,
|
||||||
|
child: DefaultButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(); // Close dialog
|
||||||
|
onConfirmDelete(); // Execute delete action
|
||||||
|
},
|
||||||
|
backgroundColor: ColorsManager.semiTransparentRed,
|
||||||
|
borderRadius: 10,
|
||||||
|
foregroundColor: ColorsManager.whiteColors,
|
||||||
|
child: const Text('Delete'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,9 @@ import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/l
|
|||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
@ -17,8 +20,15 @@ import 'package:syncrow_web/utils/constants/assets.dart';
|
|||||||
|
|
||||||
class SpaceModelCardWidget extends StatelessWidget {
|
class SpaceModelCardWidget extends StatelessWidget {
|
||||||
final SpaceTemplateModel model;
|
final SpaceTemplateModel model;
|
||||||
|
final BuildContext? pageContext;
|
||||||
|
final bool topActionsDisabled;
|
||||||
|
|
||||||
const SpaceModelCardWidget({Key? key, required this.model}) : super(key: key);
|
const SpaceModelCardWidget({
|
||||||
|
Key? key,
|
||||||
|
required this.model,
|
||||||
|
this.pageContext,
|
||||||
|
this.topActionsDisabled = true,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -193,7 +203,48 @@ class SpaceModelCardWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
model.modelName,
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!topActionsDisabled)
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => _showDeleteDialog(context),
|
||||||
|
child: Container(
|
||||||
|
width: 36, // Adjust size as needed
|
||||||
|
height: 36,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withOpacity(0.1),
|
||||||
|
spreadRadius: 2,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.deleteSpaceModel, // Your actual SVG path
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
colorFilter: const ColorFilter.mode(
|
||||||
|
Colors.grey, BlendMode.srcIn),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (!showOnlyName) ...[
|
if (!showOnlyName) ...[
|
||||||
@ -253,4 +304,22 @@ class SpaceModelCardWidget extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showDeleteDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: true,
|
||||||
|
builder: (BuildContext dialogContext) {
|
||||||
|
return DeleteSpaceModelDialog(
|
||||||
|
onConfirmDelete: () {
|
||||||
|
if (pageContext != null) {
|
||||||
|
pageContext!.read<SpaceModelBloc>().add(
|
||||||
|
DeleteSpaceModel(spaceModelUuid: model.uuid ?? ''),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,12 +86,23 @@ class SpaceModelManagementApi {
|
|||||||
|
|
||||||
Future validateSpaceModel(String projectId, List<String> spaceUuids) async {
|
Future validateSpaceModel(String projectId, List<String> spaceUuids) async {
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path:
|
path: ApiEndpoints.validateSpaceModel
|
||||||
ApiEndpoints.validateSpaceModel.replaceAll('{projectId}', projectId),
|
.replaceAll('{projectId}', projectId),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
body: {"spacesUuids": spaceUuids},
|
body: {"spacesUuids": spaceUuids},
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> deleteSpaceModel(String spaceModelUuid, String projectId) async {
|
||||||
|
final response = await HTTPService().delete(
|
||||||
|
path: ApiEndpoints.getSpaceModel
|
||||||
|
.replaceAll('{projectId}', projectId)
|
||||||
|
.replaceAll('{spaceModelUuid}', spaceModelUuid),
|
||||||
|
showServerMessage: true,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json['success'] ?? false;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
|
@ -14,7 +14,7 @@ class UserPermissionApi {
|
|||||||
Future<List<RolesUserModel>> fetchUsers(String projectId) async {
|
Future<List<RolesUserModel>> fetchUsers(String projectId) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getUsers.replaceAll('{projectUuid}', projectId),
|
path: ApiEndpoints.getUsers.replaceAll('{projectId}', projectId),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
debugPrint('fetchUsers Response: $json');
|
debugPrint('fetchUsers Response: $json');
|
||||||
|
@ -71,4 +71,5 @@ abstract class ColorsManager {
|
|||||||
static const Color lightGrayBorderColor = Color(0xB2D5D5D5);
|
static const Color lightGrayBorderColor = Color(0xB2D5D5D5);
|
||||||
//background: #F8F8F8;
|
//background: #F8F8F8;
|
||||||
static const Color vividBlue = Color(0xFF023DFE);
|
static const Color vividBlue = Color(0xFF023DFE);
|
||||||
|
static const Color semiTransparentRed = Color(0x99FF0000);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ abstract class ApiEndpoints {
|
|||||||
|
|
||||||
////// Devices Management ////////////////
|
////// Devices Management ////////////////
|
||||||
|
|
||||||
static const String getAllDevices = '/projects/{projectId}/device';
|
static const String getAllDevices = '/projects/{projectId}/devices';
|
||||||
static const String getSpaceDevices =
|
static const String getSpaceDevices =
|
||||||
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
||||||
static const String getDeviceStatus = '/device/{uuid}/functions/status';
|
static const String getDeviceStatus = '/device/{uuid}/functions/status';
|
||||||
@ -120,8 +120,8 @@ abstract class ApiEndpoints {
|
|||||||
static const String inviteUser = '/invite-user';
|
static const String inviteUser = '/invite-user';
|
||||||
|
|
||||||
static const String checkEmail = '/invite-user/check-email';
|
static const String checkEmail = '/invite-user/check-email';
|
||||||
static const String getUsers = '/projects/{projectUuid}/user';
|
static const String getUsers = '/projects/{projectId}/user';
|
||||||
static const String getUserById = '/projects/{projectUuid}/user/{userUuid}';
|
static const String getUserById = '/projects/{projectId}/user/{userUuid}';
|
||||||
static const String editUser = '/invite-user/{inviteUserUuid}';
|
static const String editUser = '/invite-user/{inviteUserUuid}';
|
||||||
static const String deleteUser = '/invite-user/{inviteUserUuid}';
|
static const String deleteUser = '/invite-user/{inviteUserUuid}';
|
||||||
static const String changeUserStatus =
|
static const String changeUserStatus =
|
||||||
|
@ -258,6 +258,7 @@ class Assets {
|
|||||||
static const String doorSensor = 'assets/icons/door_sensor.svg';
|
static const String doorSensor = 'assets/icons/door_sensor.svg';
|
||||||
|
|
||||||
static const String delete = 'assets/icons/delete.svg';
|
static const String delete = 'assets/icons/delete.svg';
|
||||||
|
static const String deleteSpaceModel = 'assets/icons/delete_space_model.svg';
|
||||||
static const String edit = 'assets/icons/edit.svg';
|
static const String edit = 'assets/icons/edit.svg';
|
||||||
static const String editSpace = 'assets/icons/edit_space.svg';
|
static const String editSpace = 'assets/icons/edit_space.svg';
|
||||||
//assets/icons/routine/tab_to_run.svg
|
//assets/icons/routine/tab_to_run.svg
|
||||||
|
@ -1,18 +1,37 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ResponsiveLayout extends StatelessWidget {
|
class ResponsiveLayout extends StatelessWidget {
|
||||||
final Widget desktopBody;
|
|
||||||
final Widget mobileBody;
|
final Widget mobileBody;
|
||||||
const ResponsiveLayout(
|
final Widget? tablet;
|
||||||
{super.key, required this.desktopBody, required this.mobileBody});
|
final Widget desktopBody;
|
||||||
|
|
||||||
|
const ResponsiveLayout({
|
||||||
|
super.key,
|
||||||
|
required this.mobileBody,
|
||||||
|
this.tablet,
|
||||||
|
required this.desktopBody,
|
||||||
|
});
|
||||||
|
|
||||||
|
static bool isMobile(BuildContext context) =>
|
||||||
|
MediaQuery.of(context).size.width < 650;
|
||||||
|
|
||||||
|
static bool isTablet(BuildContext context) =>
|
||||||
|
MediaQuery.of(context).size.width < 1100 &&
|
||||||
|
MediaQuery.of(context).size.width >= 650;
|
||||||
|
|
||||||
|
static bool isDesktop(BuildContext context) =>
|
||||||
|
MediaQuery.of(context).size.width >= 1100;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
if (constraints.maxWidth < 600) {
|
if (constraints.maxWidth >= 1100) {
|
||||||
return mobileBody;
|
|
||||||
} else {
|
|
||||||
return desktopBody;
|
return desktopBody;
|
||||||
|
} else if (constraints.maxWidth >= 650) {
|
||||||
|
return tablet!;
|
||||||
|
} else {
|
||||||
|
return mobileBody;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
30
lib/utils/theme/responsive_text_theme.dart
Normal file
30
lib/utils/theme/responsive_text_theme.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/responsive_layout.dart';
|
||||||
|
|
||||||
|
class ResponsiveTextTheme extends ThemeExtension<ResponsiveTextTheme> {
|
||||||
|
final TextStyle deviceManagementTitle;
|
||||||
|
|
||||||
|
ResponsiveTextTheme({
|
||||||
|
required this.deviceManagementTitle,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
ThemeExtension<ResponsiveTextTheme> copyWith() => this;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ThemeExtension<ResponsiveTextTheme> lerp(
|
||||||
|
ThemeExtension<ResponsiveTextTheme>? other, double t) =>
|
||||||
|
this;
|
||||||
|
|
||||||
|
static ResponsiveTextTheme of(BuildContext context) {
|
||||||
|
final isMobile = ResponsiveLayout.isMobile(context);
|
||||||
|
return Theme.of(context).extension<ResponsiveTextTheme>() ??
|
||||||
|
ResponsiveTextTheme(
|
||||||
|
deviceManagementTitle: TextStyle(
|
||||||
|
fontSize: isMobile ? 20 : 30,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: ColorsManager.whiteColors),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -5,10 +5,10 @@ import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/responsive_layout.dart';
|
||||||
import 'package:syncrow_web/utils/user_drop_down_menu.dart';
|
import 'package:syncrow_web/utils/user_drop_down_menu.dart';
|
||||||
|
|
||||||
class WebAppBar extends StatefulWidget {
|
class WebAppBar extends StatelessWidget {
|
||||||
final Widget? title;
|
final Widget? title;
|
||||||
final Widget? centerBody;
|
final Widget? centerBody;
|
||||||
final Widget? rightBody;
|
final Widget? rightBody;
|
||||||
@ -16,178 +16,234 @@ class WebAppBar extends StatefulWidget {
|
|||||||
const WebAppBar({super.key, this.title, this.centerBody, this.rightBody});
|
const WebAppBar({super.key, this.title, this.centerBody, this.rightBody});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<WebAppBar> createState() => _WebAppBarState();
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<HomeBloc, HomeState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final user = context.read<HomeBloc>().user;
|
||||||
|
return ResponsiveLayout(
|
||||||
|
mobileBody: MobileAppBar(
|
||||||
|
title: title,
|
||||||
|
centerBody: centerBody,
|
||||||
|
rightBody: rightBody,
|
||||||
|
user: user,
|
||||||
|
),
|
||||||
|
tablet: TabletAppBar(
|
||||||
|
title: title,
|
||||||
|
centerBody: centerBody,
|
||||||
|
rightBody: rightBody,
|
||||||
|
user: user,
|
||||||
|
),
|
||||||
|
desktopBody: DesktopAppBar(
|
||||||
|
title: title,
|
||||||
|
centerBody: centerBody,
|
||||||
|
rightBody: rightBody,
|
||||||
|
user: user,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WebAppBarState extends State<WebAppBar> with HelperResponsiveLayout {
|
class DesktopAppBar extends StatelessWidget {
|
||||||
@override
|
final Widget? title;
|
||||||
void initState() {
|
final Widget? centerBody;
|
||||||
super.initState();
|
final Widget? rightBody;
|
||||||
}
|
final dynamic user;
|
||||||
|
|
||||||
|
const DesktopAppBar({
|
||||||
|
super.key,
|
||||||
|
this.title,
|
||||||
|
this.centerBody,
|
||||||
|
this.rightBody,
|
||||||
|
required this.user,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool isSmallScreen = isSmallScreenSize(context);
|
|
||||||
bool isHalfMediumScreen = isHafMediumScreenSize(context);
|
|
||||||
return BlocBuilder<HomeBloc, HomeState>(builder: (context, state) {
|
|
||||||
final user = context.read<HomeBloc>().user;
|
|
||||||
return Container(
|
return Container(
|
||||||
height: (isSmallScreen || isHalfMediumScreen) ? 130 : 100,
|
height: 100,
|
||||||
decoration: const BoxDecoration(color: ColorsManager.secondaryColor),
|
decoration: const BoxDecoration(color: ColorsManager.secondaryColor),
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||||
child: isSmallScreen || isHalfMediumScreen
|
child: Row(
|
||||||
? Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
if (widget.title != null)
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: widget.title!,
|
|
||||||
),
|
|
||||||
if (widget.centerBody != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
|
||||||
child: widget.centerBody,
|
|
||||||
),
|
|
||||||
if (widget.rightBody != null || user != null)
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
|
||||||
if (widget.rightBody != null) widget.rightBody!,
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
SizedBox.square(
|
|
||||||
dimension: 40,
|
|
||||||
child: CircleAvatar(
|
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
|
||||||
child: SizedBox.square(
|
|
||||||
dimension: 35,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.logoGrey,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
if (user != null)
|
|
||||||
Text(
|
|
||||||
'${user.firstName} ${user.lastName}',
|
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
widget.title!,
|
if (title != null) title!,
|
||||||
if (widget.centerBody != null)
|
if (centerBody != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 80),
|
padding: const EdgeInsets.only(left: 80),
|
||||||
child: widget.centerBody!,
|
child: centerBody!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Row(
|
_buildUserSection(context),
|
||||||
mainAxisSize: MainAxisSize.min,
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildUserSection(BuildContext context) {
|
||||||
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
if (widget.rightBody != null)
|
if (rightBody != null) rightBody!,
|
||||||
Align(
|
const SizedBox(width: 24),
|
||||||
alignment: Alignment.centerRight,
|
_UserAvatar(),
|
||||||
child: widget.rightBody,
|
const SizedBox(width: 12),
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
SizedBox.square(
|
|
||||||
dimension: 40,
|
|
||||||
child: CircleAvatar(
|
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
|
||||||
child: SizedBox.square(
|
|
||||||
dimension: 35,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.logoGrey,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
Text(
|
Text(
|
||||||
'${user.firstName} ${user.lastName}',
|
'${user.firstName} ${user.lastName}',
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(width: 12),
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
UserDropdownMenu(user: user),
|
UserDropdownMenu(user: user),
|
||||||
// GestureDetector(
|
],
|
||||||
// onTap: () {
|
);
|
||||||
// showCustomDialog(
|
}
|
||||||
// context: context,
|
}
|
||||||
// barrierDismissible: true,
|
|
||||||
// title: 'Logout',
|
class TabletAppBar extends StatelessWidget {
|
||||||
// message: 'Are you sure you want to logout?',
|
final Widget? title;
|
||||||
// actions: [
|
final Widget? centerBody;
|
||||||
// GestureDetector(
|
final Widget? rightBody;
|
||||||
// onTap: () {
|
final dynamic user;
|
||||||
// AuthBloc.logout();
|
|
||||||
// context.go(RoutesConst.auth);
|
const TabletAppBar({
|
||||||
// },
|
super.key,
|
||||||
// child: DefaultButton(
|
this.title,
|
||||||
// child: Text(
|
this.centerBody,
|
||||||
// 'Ok',
|
this.rightBody,
|
||||||
// style: Theme.of(context)
|
required this.user,
|
||||||
// .textTheme
|
});
|
||||||
// .bodyMedium!
|
|
||||||
// .copyWith(fontSize: 12, color: Colors.white),
|
@override
|
||||||
// ),
|
Widget build(BuildContext context) {
|
||||||
// ),
|
return Container(
|
||||||
// ),
|
height: 100,
|
||||||
// const SizedBox(
|
decoration: const BoxDecoration(color: ColorsManager.secondaryColor),
|
||||||
// height: 10,
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||||
// ),
|
child: Column(
|
||||||
// GestureDetector(
|
children: [
|
||||||
// onTap: () {
|
Row(
|
||||||
// context.pop();
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
// },
|
children: [
|
||||||
// child: DefaultButton(
|
if (title != null) Expanded(child: title!),
|
||||||
// child: Text(
|
_buildUserSection(context),
|
||||||
// 'Cancel',
|
],
|
||||||
// style: Theme.of(context)
|
),
|
||||||
// .textTheme
|
if (centerBody != null) Expanded(child: centerBody!),
|
||||||
// .bodyMedium!
|
],
|
||||||
// .copyWith(fontSize: 12, color: Colors.white),
|
),
|
||||||
// ),
|
);
|
||||||
// ),
|
}
|
||||||
// ),
|
|
||||||
// ],
|
Widget _buildUserSection(BuildContext context) {
|
||||||
// );
|
return Row(
|
||||||
// },
|
children: [
|
||||||
// child: const Icon(
|
if (rightBody != null) rightBody!,
|
||||||
// Icons.logout,
|
const SizedBox(width: 16),
|
||||||
// color: ColorsManager.whiteColors,
|
_UserAvatar(),
|
||||||
// ),
|
if (user != null) ...[
|
||||||
// )
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'${user.firstName} ${user.lastName}',
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: 14),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
UserDropdownMenu(user: user),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MobileAppBar extends StatelessWidget {
|
||||||
|
final Widget? title;
|
||||||
|
final Widget? centerBody;
|
||||||
|
final Widget? rightBody;
|
||||||
|
final dynamic user;
|
||||||
|
|
||||||
|
const MobileAppBar({
|
||||||
|
super.key,
|
||||||
|
this.title,
|
||||||
|
this.centerBody,
|
||||||
|
this.rightBody,
|
||||||
|
required this.user,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: 135,
|
||||||
|
decoration: const BoxDecoration(color: ColorsManager.secondaryColor),
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
if (title != null) title!,
|
||||||
|
_buildUserSection(context),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
if (centerBody != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8),
|
||||||
|
child: centerBody!,
|
||||||
|
),
|
||||||
|
if (rightBody != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8),
|
||||||
|
child: rightBody!,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
Widget _buildUserSection(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
_UserAvatar(),
|
||||||
|
if (user != null) ...[
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'${user.firstName} ${user.lastName}',
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: 14),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
UserDropdownMenu(user: user),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UserAvatar extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox.square(
|
||||||
|
dimension: 40,
|
||||||
|
child: CircleAvatar(
|
||||||
|
backgroundColor: ColorsManager.whiteColors,
|
||||||
|
child: SizedBox.square(
|
||||||
|
dimension: 35,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.logoGrey,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,20 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import firebase_analytics
|
||||||
|
import firebase_core
|
||||||
|
import firebase_crashlytics
|
||||||
|
import firebase_database
|
||||||
import flutter_secure_storage_macos
|
import flutter_secure_storage_macos
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin"))
|
||||||
|
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||||
|
FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin"))
|
||||||
|
FLTFirebaseDatabasePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseDatabasePlugin"))
|
||||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
108157F896CD9F637B06D7C0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DAF1C60594A51D692304366 /* Pods_Runner.framework */; };
|
108157F896CD9F637B06D7C0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DAF1C60594A51D692304366 /* Pods_Runner.framework */; };
|
||||||
|
2901225E5FAB0C696EE79F77 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */; };
|
||||||
2D0F1F294F673EF0DB5E4CA1 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */; };
|
2D0F1F294F673EF0DB5E4CA1 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */; };
|
||||||
331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
|
331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
|
||||||
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
|
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
|
||||||
@ -84,6 +85,7 @@
|
|||||||
81F2F315AC5109F6F5D27BE6 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
81F2F315AC5109F6F5D27BE6 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
96C46007EE0A4E9E1D6D74CE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
96C46007EE0A4E9E1D6D74CE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
|
996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
A604E311B663FBF4B7C54DC5 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
A604E311B663FBF4B7C54DC5 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
AB949539E0D0A8E2BDAB9ADF /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
AB949539E0D0A8E2BDAB9ADF /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@ -138,6 +140,7 @@
|
|||||||
33CC10EE2044A3C60003C045 /* Products */,
|
33CC10EE2044A3C60003C045 /* Products */,
|
||||||
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
||||||
75DCDFECC7757C5159E8F0C5 /* Pods */,
|
75DCDFECC7757C5159E8F0C5 /* Pods */,
|
||||||
|
996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@ -241,6 +244,7 @@
|
|||||||
33CC110E2044A8840003C045 /* Bundle Framework */,
|
33CC110E2044A8840003C045 /* Bundle Framework */,
|
||||||
3399D490228B24CF009A79C7 /* ShellScript */,
|
3399D490228B24CF009A79C7 /* ShellScript */,
|
||||||
92D754792F50A5D35F6D5AEE /* [CP] Embed Pods Frameworks */,
|
92D754792F50A5D35F6D5AEE /* [CP] Embed Pods Frameworks */,
|
||||||
|
7E188D2155D07A3E9E027C0F /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -317,6 +321,7 @@
|
|||||||
files = (
|
files = (
|
||||||
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
|
||||||
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
|
||||||
|
2901225E5FAB0C696EE79F77 /* GoogleService-Info.plist in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -361,6 +366,24 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
||||||
};
|
};
|
||||||
|
7E188D2155D07A3E9E027C0F /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\"\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --platform=macos --apple-project-path=\"${SRCROOT}\" --env-platform-name=\"${PLATFORM_NAME}\" --env-configuration=\"${CONFIGURATION}\" --env-project-dir=\"${PROJECT_DIR}\" --env-built-products-dir=\"${BUILT_PRODUCTS_DIR}\" --env-dwarf-dsym-folder-path=\"${DWARF_DSYM_FOLDER_PATH}\" --env-dwarf-dsym-file-name=\"${DWARF_DSYM_FILE_NAME}\" --env-infoplist-path=\"${INFOPLIST_PATH}\" --default-config=default\n";
|
||||||
|
};
|
||||||
8ECFD939A4D371A145DBA191 /* [CP] Check Pods Manifest.lock */ = {
|
8ECFD939A4D371A145DBA191 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
32
macos/Runner/GoogleService-Info.plist
Normal file
32
macos/Runner/GoogleService-Info.plist
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>427332280600</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>com.example.syncrowWeb</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>test2-8a3d2</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>test2-8a3d2.firebasestorage.app</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:427332280600:ios:14346b200780dc760c7e6d</string>
|
||||||
|
<key>DATABASE_URL</key>
|
||||||
|
<string>https://test2-8a3d2-default-rtdb.firebaseio.com</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
104
pubspec.lock
104
pubspec.lock
@ -1,6 +1,14 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
_flutterfire_internals:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: _flutterfire_internals
|
||||||
|
sha256: e051259913915ea5bc8fe18664596bea08592fd123930605d562969cd7315fcd
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.51"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -153,6 +161,94 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
|
firebase_analytics:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: firebase_analytics
|
||||||
|
sha256: "47428047a0778f72af53a3c7cb5d556e1cb25e2327cc8aa40d544971dc6245b2"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.4.2"
|
||||||
|
firebase_analytics_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_analytics_platform_interface
|
||||||
|
sha256: "1076f4b041f76143e14878c70f0758f17fe5910c0cd992db9e93bd3c3584512b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.2"
|
||||||
|
firebase_analytics_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_analytics_web
|
||||||
|
sha256: "8f6dd64ea6d28b7f5b9e739d183a9e1c7f17027794a3e9aba1879621d42426ef"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.10+8"
|
||||||
|
firebase_core:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: firebase_core
|
||||||
|
sha256: "93dc4dd12f9b02c5767f235307f609e61ed9211047132d07f9e02c668f0bfc33"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.11.0"
|
||||||
|
firebase_core_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_core_platform_interface
|
||||||
|
sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.4.0"
|
||||||
|
firebase_core_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_core_web
|
||||||
|
sha256: "0e13c80f0de8acaa5d0519cbe23c8b4cc138a2d5d508b5755c861bdfc9762678"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.20.0"
|
||||||
|
firebase_crashlytics:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: firebase_crashlytics
|
||||||
|
sha256: "6273ed71bcd8a6fb4d0ca13d3abddbb3301796807efaad8782b5f90156f26f03"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.2"
|
||||||
|
firebase_crashlytics_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_crashlytics_platform_interface
|
||||||
|
sha256: "94f3986e1a10e5a883f2ad5e3d719aef98a8a0f9a49357f6e45b7d3696ea6a97"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.8.2"
|
||||||
|
firebase_database:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: firebase_database
|
||||||
|
sha256: cd2354dfef68e52c0713b5efbb7f4e10dfc2aff2f945c7bc8db34d1934170627
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.3.2"
|
||||||
|
firebase_database_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_database_platform_interface
|
||||||
|
sha256: d430983f4d877c9f72f88b3d715cca9a50021dd7ccd8e3ae6fb79603853317de
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.6+2"
|
||||||
|
firebase_database_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_database_web
|
||||||
|
sha256: f64edae62c5beaa08e9e611a0736d64ab11a812983a0aa132695d2d191311ea7
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.6+8"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -572,10 +668,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: "3a293170d4d9403c3254ee05b84e62e8a9b3c5808ebd17de6a33fe9ea6457936"
|
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.2"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -777,10 +873,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "1.1.0"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -56,6 +56,11 @@ dependencies:
|
|||||||
number_pagination: ^1.1.6
|
number_pagination: ^1.1.6
|
||||||
url_launcher: ^6.2.5
|
url_launcher: ^6.2.5
|
||||||
flutter_html: ^3.0.0-beta.2
|
flutter_html: ^3.0.0-beta.2
|
||||||
|
firebase_analytics: ^11.4.0
|
||||||
|
firebase_core: ^3.11.0
|
||||||
|
firebase_crashlytics: ^4.3.2
|
||||||
|
firebase_database: ^11.3.2
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
<script src="flutter.js" defer></script>
|
<script src="flutter.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('load', function(ev) {
|
window.addEventListener('load', function(ev) {
|
||||||
// Download main.dart.js
|
// Download main.dart.js
|
||||||
@ -54,6 +56,20 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var firebaseConfig = {
|
||||||
|
apiKey: "AIzaSyCVEvKsJYzhWDFM-9Od68FE0nPpP933st0",
|
||||||
|
authDomain: "test2-8a3d2.firebaseapp.com",
|
||||||
|
databaseURL: "https://test2-8a3d2-default-rtdb.firebaseio.com",
|
||||||
|
projectId: "test2-8a3d2",
|
||||||
|
storageBucket: "test2-8a3d2.firebasestorage.app",
|
||||||
|
messagingSenderId: "427332280600",
|
||||||
|
appId: "1:427332280600:web:ad50516a87a35a1a0c7e6d",
|
||||||
|
measurementId: "G-Z1RTTTV5H9"
|
||||||
|
};
|
||||||
|
firebase.initializeApp(firebaseConfig);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||||
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
|
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
|
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
firebase_core
|
||||||
flutter_secure_storage_windows
|
flutter_secure_storage_windows
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user