Compare commits

..

4 Commits

90 changed files with 1075 additions and 2179 deletions

View File

@ -1,9 +1,5 @@
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"
} }

View File

@ -1,68 +0,0 @@
{
"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"
}

View File

@ -20,10 +20,6 @@ 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
} }

View File

@ -1 +0,0 @@
{"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"}}}}}}

View File

@ -15,7 +15,6 @@
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 */
@ -65,7 +64,6 @@
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 */
@ -140,7 +138,6 @@
331C8082294A63A400263BE5 /* RunnerTests */, 331C8082294A63A400263BE5 /* RunnerTests */,
1454C118FFCECEEDF59152D2 /* Pods */, 1454C118FFCECEEDF59152D2 /* Pods */,
20A3C64D2B1CFED5A81C3251 /* Frameworks */, 20A3C64D2B1CFED5A81C3251 /* Frameworks */,
B14AB50E8716720E10D074BD /* GoogleService-Info.plist */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -202,7 +199,6 @@
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 = (
); );
@ -268,7 +264,6 @@
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;
}; };
@ -308,24 +303,6 @@
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;

View File

@ -1,32 +0,0 @@
<?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>

View File

@ -1,93 +0,0 @@
// 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',
);
}

View File

@ -1,77 +0,0 @@
// 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',
);
}

View File

@ -1,12 +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:flutter_secure_storage/flutter_secure_storage.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/common/bloc/project_cubit.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';
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
@ -21,21 +20,20 @@ import 'package:syncrow_web/utils/theme/theme.dart';
Future<void> main() async { Future<void> main() async {
try { try {
const environment = const environment =
String.fromEnvironment('FLAVOR', defaultValue: 'production'); String.fromEnvironment('FLAVOR', defaultValue: 'development');
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()); final storage = FlutterSecureStorage();
final projectCubit = ProjectCubit(storage);
runApp(MyApp(projectCubit: projectCubit));
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
MyApp({ final ProjectCubit projectCubit;
super.key,
}); MyApp({super.key, required this.projectCubit});
final GoRouter _router = GoRouter( final GoRouter _router = GoRouter(
initialLocation: RoutesConst.auth, initialLocation: RoutesConst.auth,
@ -56,16 +54,17 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiBlocProvider( return MultiBlocProvider(
providers: [ providers: [
BlocProvider(create: (context) => projectCubit),
BlocProvider( BlocProvider(
create: (context) => HomeBloc()..add(const FetchUserInfo())), create: (context) => HomeBloc(projectCubit)..add(const FetchUserInfo())),
BlocProvider<VisitorPasswordBloc>( BlocProvider<VisitorPasswordBloc>(
create: (context) => VisitorPasswordBloc(), create: (context) => VisitorPasswordBloc(projectCubit),
), ),
BlocProvider<RoutineBloc>( BlocProvider<RoutineBloc>(
create: (context) => RoutineBloc(), create: (context) => RoutineBloc(projectCubit),
), ),
BlocProvider<SpaceTreeBloc>( BlocProvider<SpaceTreeBloc>(
create: (context) => SpaceTreeBloc()..add(InitialEvent()), create: (context) => SpaceTreeBloc(projectCubit)..add(InitialEvent()),
), ),
], ],
child: MaterialApp.router( child: MaterialApp.router(

View File

@ -1,84 +0,0 @@
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,
));
}
}

View File

@ -3,14 +3,18 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/access_management/bloc/access_event.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_event.dart';
import 'package:syncrow_web/pages/access_management/bloc/access_state.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_state.dart';
import 'package:syncrow_web/pages/access_management/model/password_model.dart'; import 'package:syncrow_web/pages/access_management/model/password_model.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/common/hour_picker_dialog.dart'; import 'package:syncrow_web/pages/common/hour_picker_dialog.dart';
import 'package:syncrow_web/services/access_mang_api.dart'; import 'package:syncrow_web/services/access_mang_api.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/app_enum.dart'; import 'package:syncrow_web/utils/constants/app_enum.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
import 'package:syncrow_web/utils/snack_bar.dart'; import 'package:syncrow_web/utils/snack_bar.dart';
class AccessBloc extends Bloc<AccessEvent, AccessState> { class AccessBloc extends Bloc<AccessEvent, AccessState> {
AccessBloc() : super((AccessInitial())) { final ProjectCubit projectCubit;
AccessBloc(this.projectCubit) : super((AccessInitial())) {
on<FetchTableData>(_onFetchTableData); on<FetchTableData>(_onFetchTableData);
on<SelectTime>(selectTime); on<SelectTime>(selectTime);
on<FilterDataEvent>(_filterData); on<FilterDataEvent>(_filterData);
@ -30,8 +34,10 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
Future<void> _onFetchTableData( Future<void> _onFetchTableData(
FetchTableData event, Emitter<AccessState> emit) async { FetchTableData event, Emitter<AccessState> emit) async {
try { try {
final projectUuid = projectCubit.state;
emit(AccessLoaded()); emit(AccessLoaded());
data = await AccessMangApi().fetchVisitorPassword(); data = await AccessMangApi()
.fetchVisitorPassword(projectUuid ?? TempConst.projectId);
filteredData = data; filteredData = data;
updateTabsCount(); updateTabsCount();
emit(TableLoaded(data)); emit(TableLoaded(data));
@ -88,8 +94,8 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
return Theme( return Theme(
data: ThemeData.light().copyWith( data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light( colorScheme: ColorScheme.light(
primary: ColorsManager.blackColor, primary: ColorsManager.blackColor,
onPrimary: Colors.white, onPrimary: Colors.white,
onSurface: ColorsManager.grayColor, onSurface: ColorsManager.grayColor,
), ),
textButtonTheme: TextButtonThemeData( textButtonTheme: TextButtonThemeData(

View File

@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/access_management/bloc/access_bloc.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_bloc.dart';
import 'package:syncrow_web/pages/access_management/bloc/access_event.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_event.dart';
import 'package:syncrow_web/pages/access_management/bloc/access_state.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_state.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/common/buttons/search_reset_buttons.dart'; import 'package:syncrow_web/pages/common/buttons/search_reset_buttons.dart';
import 'package:syncrow_web/pages/common/custom_table.dart'; import 'package:syncrow_web/pages/common/custom_table.dart';
@ -17,7 +18,6 @@ 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 {
@ -28,19 +28,19 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
final isLargeScreen = isLargeScreenSize(context); final isLargeScreen = isLargeScreenSize(context);
final isSmallScreen = isSmallScreenSize(context); final isSmallScreen = isSmallScreenSize(context);
final isHalfMediumScreen = isHafMediumScreenSize(context); final isHalfMediumScreen = isHafMediumScreenSize(context);
final padding = final padding = isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15);
isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15);
return WebScaffold( return WebScaffold(
enableMenuSidebar: false, enableMenuSidebar: false,
appBarTitle: Text( appBarTitle: FittedBox(
'Access Management', child: Text(
style: ResponsiveTextTheme.of(context).deviceManagementTitle, 'Access Management',
style: Theme.of(context).textTheme.headlineLarge,
),
), ),
rightBody: const NavigateHomeGridView(), rightBody: const NavigateHomeGridView(),
scaffoldBody: BlocProvider( scaffoldBody: BlocProvider(
create: (BuildContext context) => create: (BuildContext context) => AccessBloc(context.read<ProjectCubit>())..add(FetchTableData()),
AccessBloc()..add(FetchTableData()),
child: BlocConsumer<AccessBloc, AccessState>( child: BlocConsumer<AccessBloc, AccessState>(
listener: (context, state) {}, listener: (context, state) {},
builder: (context, state) { builder: (context, state) {
@ -94,14 +94,11 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
return [ return [
item.passwordName, item.passwordName,
item.passwordType.value, item.passwordType.value,
accessBloc accessBloc.timestampToDate(item.effectiveTime),
.timestampToDate(item.effectiveTime), accessBloc.timestampToDate(item.invalidTime),
accessBloc
.timestampToDate(item.invalidTime),
item.deviceName.toString(), item.deviceName.toString(),
item.authorizerEmail.toString(), item.authorizerEmail.toString(),
accessBloc accessBloc.timestampToDate(item.invalidTime),
.timestampToDate(item.invalidTime),
item.passwordStatus.value, item.passwordStatus.value,
]; ];
}).toList(), }).toList(),
@ -112,8 +109,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
}))); })));
} }
Wrap _buildVisitorAdminPasswords( Wrap _buildVisitorAdminPasswords(BuildContext context, AccessBloc accessBloc) {
BuildContext context, AccessBloc accessBloc) {
return Wrap( return Wrap(
spacing: 10, spacing: 10,
runSpacing: 10, runSpacing: 10,
@ -139,8 +135,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
borderRadius: 8, borderRadius: 8,
child: Text( child: Text(
'Create Visitor Password ', 'Create Visitor Password ',
style: context.textTheme.titleSmall! style: context.textTheme.titleSmall!.copyWith(color: Colors.white, fontSize: 12),
.copyWith(color: Colors.white, fontSize: 12),
)), )),
), ),
// Container( // Container(
@ -178,10 +173,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
description: '', description: '',
onSubmitted: (value) { onSubmitted: (value) {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
accessBloc.emailAuthorizer.text.toLowerCase(), selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -199,10 +192,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
description: '', description: '',
onSubmitted: (value) { onSubmitted: (value) {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
accessBloc.emailAuthorizer.text.toLowerCase(), selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -231,8 +222,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
onSearch: () { onSearch: () {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex: selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -260,10 +250,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
description: '', description: '',
onSubmitted: (value) { onSubmitted: (value) {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
accessBloc.emailAuthorizer.text.toLowerCase(), selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -287,8 +275,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
onSearch: () { onSearch: () {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex: selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));

View File

@ -9,6 +9,7 @@ import 'package:syncrow_web/pages/auth/model/login_with_email_model.dart';
import 'package:syncrow_web/pages/auth/model/region_model.dart'; 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_cubit.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';
@ -180,7 +181,6 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
return; return;
} }
if (token.accessTokenIsNotEmpty) { if (token.accessTokenIsNotEmpty) {
FlutterSecureStorage storage = const FlutterSecureStorage(); FlutterSecureStorage storage = const FlutterSecureStorage();
await storage.write( await storage.write(
@ -442,8 +442,13 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
emit(LoginInitial()); emit(LoginInitial());
} }
static logout() { static Future<void> logout(
const storage = FlutterSecureStorage(); BuildContext context, ProjectCubit projectCubit) async {
final storage = FlutterSecureStorage();
await storage.delete(key: ProjectCubit.projectKey);
projectCubit.clearProjectUUID();
storage.deleteAll(); storage.deleteAll();
} }
} }

View File

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

View File

@ -1,3 +1,4 @@
import 'package:syncrow_web/pages/auth/model/project_model.dart';
import 'package:syncrow_web/pages/auth/model/token.dart'; import 'package:syncrow_web/pages/auth/model/token.dart';
class UserModel { class UserModel {
@ -13,6 +14,7 @@ class UserModel {
final bool? hasAcceptedWebAgreement; final bool? hasAcceptedWebAgreement;
final DateTime? webAgreementAcceptedAt; final DateTime? webAgreementAcceptedAt;
final UserRole? role; final UserRole? role;
final Project? project;
UserModel({ UserModel({
required this.uuid, required this.uuid,
@ -26,6 +28,7 @@ class UserModel {
required this.hasAcceptedWebAgreement, required this.hasAcceptedWebAgreement,
required this.webAgreementAcceptedAt, required this.webAgreementAcceptedAt,
required this.role, required this.role,
required this.project,
}); });
factory UserModel.fromJson(Map<String, dynamic> json) { factory UserModel.fromJson(Map<String, dynamic> json) {
@ -43,6 +46,8 @@ class UserModel {
? DateTime.parse(json['webAgreementAcceptedAt']) ? DateTime.parse(json['webAgreementAcceptedAt'])
: null, : null,
role: json['role'] != null ? UserRole.fromJson(json['role']) : null, role: json['role'] != null ? UserRole.fromJson(json['role']) : null,
project:
json['project'] != null ? Project.fromJson(json['project']) : null,
); );
} }
@ -64,6 +69,7 @@ class UserModel {
phoneNumber: null, phoneNumber: null,
isEmailVerified: null, isEmailVerified: null,
isAgreementAccepted: null, isAgreementAccepted: null,
project: null
); );
} }

View File

@ -8,8 +8,6 @@ class ForgetPasswordPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const ResponsiveLayout( return const ResponsiveLayout(
tablet: ForgetPasswordWebPage(), desktopBody: ForgetPasswordWebPage(), mobileBody: ForgetPasswordWebPage());
desktopBody: ForgetPasswordWebPage(),
mobileBody: ForgetPasswordWebPage());
} }
} }

View File

@ -9,8 +9,6 @@ class LoginPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const ResponsiveLayout( return const ResponsiveLayout(
tablet: LoginWebPage(), desktopBody: LoginWebPage(), mobileBody: LoginWebPage());
desktopBody: LoginWebPage(),
mobileBody: LoginWebPage());
} }
} }

View File

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

View File

@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/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';
@ -20,7 +19,6 @@ 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(
@ -30,64 +28,12 @@ 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);

View File

@ -1,5 +1,4 @@
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 {
@ -8,7 +7,6 @@ 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;
@ -18,10 +16,7 @@ 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;

View File

@ -24,8 +24,7 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
final isLarge = isLargeScreenSize(context); final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context); final isMedium = isMediumScreenSize(context);
return BlocProvider( return BlocProvider(
create: (context) => AcBloc(deviceId: device.uuid!) create: (context) => AcBloc(deviceId: device.uuid!)..add(AcFetchDeviceStatusEvent(device.uuid!)),
..add(AcFetchDeviceStatusEvent(device.uuid!)),
child: BlocBuilder<AcBloc, AcsState>( child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) { builder: (context, state) {
if (state is ACStatusLoaded) { if (state is ACStatusLoaded) {
@ -99,8 +98,7 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
), ),
Text( Text(
'h', 'h',
style: context.textTheme.bodySmall! style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
.copyWith(color: ColorsManager.blackColor),
), ),
Text( Text(
'30', '30',
@ -109,9 +107,7 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
Text('m', Text('m', style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor)),
style: context.textTheme.bodySmall!
.copyWith(color: ColorsManager.blackColor)),
IconButton( IconButton(
padding: const EdgeInsets.all(0), padding: const EdgeInsets.all(0),
onPressed: () {}, onPressed: () {},

View File

@ -1,14 +1,17 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.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/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
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/services/devices_mang_api.dart'; import 'package:syncrow_web/services/devices_mang_api.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
part 'device_managment_event.dart'; part 'device_managment_event.dart';
part 'device_managment_state.dart'; part 'device_managment_state.dart';
class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementState> { class DeviceManagementBloc
extends Bloc<DeviceManagementEvent, DeviceManagementState> {
int _selectedIndex = 0; int _selectedIndex = 0;
List<AllDevicesModel> _devices = []; List<AllDevicesModel> _devices = [];
int _onlineCount = 0; int _onlineCount = 0;
@ -19,8 +22,9 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
String currentProductName = ''; String currentProductName = '';
String? currentCommunity; String? currentCommunity;
String? currentUnitName; String? currentUnitName;
final ProjectCubit projectCubit;
DeviceManagementBloc() : super(DeviceManagementInitial()) { DeviceManagementBloc(this.projectCubit) : super(DeviceManagementInitial()) {
on<FetchDevices>(_onFetchDevices); on<FetchDevices>(_onFetchDevices);
on<FilterDevices>(_onFilterDevices); on<FilterDevices>(_onFilterDevices);
on<SelectedFilterChanged>(_onSelectedFilterChanged); on<SelectedFilterChanged>(_onSelectedFilterChanged);
@ -31,19 +35,25 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
on<UpdateSelection>(_onUpdateSelection); on<UpdateSelection>(_onUpdateSelection);
} }
Future<void> _onFetchDevices(FetchDevices event, Emitter<DeviceManagementState> emit) async { Future<void> _onFetchDevices(
FetchDevices event, Emitter<DeviceManagementState> emit) async {
emit(DeviceManagementLoading()); emit(DeviceManagementLoading());
try { try {
List<AllDevicesModel> devices = []; List<AllDevicesModel> devices = [];
_devices.clear(); _devices.clear();
var spaceBloc = event.context.read<SpaceTreeBloc>(); var spaceBloc = event.context.read<SpaceTreeBloc>();
final projectUuid = projectCubit.state;
if (spaceBloc.state.selectedCommunities.isEmpty) { if (spaceBloc.state.selectedCommunities.isEmpty) {
devices = await DevicesManagementApi().fetchDevices('', ''); devices = await DevicesManagementApi()
.fetchDevices('', '', projectUuid ?? TempConst.projectId);
} else { } else {
for (var community in spaceBloc.state.selectedCommunities) { for (var community in spaceBloc.state.selectedCommunities) {
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[community] ?? []; List<String> spacesList =
spaceBloc.state.selectedCommunityAndSpaces[community] ?? [];
for (var space in spacesList) { for (var space in spacesList) {
devices.addAll(await DevicesManagementApi().fetchDevices(community, space)); devices.addAll(await DevicesManagementApi().fetchDevices(
community, space, projectUuid ?? TempConst.projectId));
} }
} }
} }
@ -66,7 +76,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
} }
} }
void _onFilterDevices(FilterDevices event, Emitter<DeviceManagementState> emit) async { void _onFilterDevices(
FilterDevices event, Emitter<DeviceManagementState> emit) async {
if (_devices.isNotEmpty) { if (_devices.isNotEmpty) {
_filteredDevices = List.from(_devices.where((device) { _filteredDevices = List.from(_devices.where((device) {
switch (event.filter) { switch (event.filter) {
@ -97,7 +108,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
} }
} }
Future<void> _onResetFilters(ResetFilters event, Emitter<DeviceManagementState> emit) async { Future<void> _onResetFilters(
ResetFilters event, Emitter<DeviceManagementState> emit) async {
currentProductName = ''; currentProductName = '';
_selectedDevices.clear(); _selectedDevices.clear();
_filteredDevices = List.from(_devices); _filteredDevices = List.from(_devices);
@ -113,7 +125,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
)); ));
} }
void _onResetSelectedDevices(ResetSelectedDevices event, Emitter<DeviceManagementState> emit) { void _onResetSelectedDevices(
ResetSelectedDevices event, Emitter<DeviceManagementState> emit) {
_selectedDevices.clear(); _selectedDevices.clear();
if (state is DeviceManagementLoaded) { if (state is DeviceManagementLoaded) {
@ -139,12 +152,14 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
} }
} }
void _onSelectedFilterChanged(SelectedFilterChanged event, Emitter<DeviceManagementState> emit) { void _onSelectedFilterChanged(
SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
_selectedIndex = event.selectedIndex; _selectedIndex = event.selectedIndex;
add(FilterDevices(_getFilterFromIndex(_selectedIndex))); add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
} }
void _onSelectDevice(SelectDevice event, Emitter<DeviceManagementState> emit) { void _onSelectDevice(
SelectDevice event, Emitter<DeviceManagementState> emit) {
final selectedUuid = event.selectedDevice.uuid; final selectedUuid = event.selectedDevice.uuid;
if (_selectedDevices.any((device) => device.uuid == selectedUuid)) { if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
@ -155,7 +170,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
List<AllDevicesModel> clonedSelectedDevices = List.from(_selectedDevices); List<AllDevicesModel> clonedSelectedDevices = List.from(_selectedDevices);
bool isControlButtonEnabled = _checkIfControlButtonEnabled(clonedSelectedDevices); bool isControlButtonEnabled =
_checkIfControlButtonEnabled(clonedSelectedDevices);
if (state is DeviceManagementLoaded) { if (state is DeviceManagementLoaded) {
emit(DeviceManagementLoaded( emit(DeviceManagementLoaded(
@ -164,7 +180,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
onlineCount: _onlineCount, onlineCount: _onlineCount,
offlineCount: _offlineCount, offlineCount: _offlineCount,
lowBatteryCount: _lowBatteryCount, lowBatteryCount: _lowBatteryCount,
selectedDevice: clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null, selectedDevice:
clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null,
isControlButtonEnabled: isControlButtonEnabled, isControlButtonEnabled: isControlButtonEnabled,
)); ));
} else if (state is DeviceManagementFiltered) { } else if (state is DeviceManagementFiltered) {
@ -174,13 +191,15 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
onlineCount: _onlineCount, onlineCount: _onlineCount,
offlineCount: _offlineCount, offlineCount: _offlineCount,
lowBatteryCount: _lowBatteryCount, lowBatteryCount: _lowBatteryCount,
selectedDevice: clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null, selectedDevice:
clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null,
isControlButtonEnabled: isControlButtonEnabled, isControlButtonEnabled: isControlButtonEnabled,
)); ));
} }
} }
void _onUpdateSelection(UpdateSelection event, Emitter<DeviceManagementState> emit) { void _onUpdateSelection(
UpdateSelection event, Emitter<DeviceManagementState> emit) {
List<AllDevicesModel> selectedDevices = []; List<AllDevicesModel> selectedDevices = [];
List<AllDevicesModel> devicesToSelectFrom = []; List<AllDevicesModel> devicesToSelectFrom = [];
@ -223,7 +242,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
bool _checkIfControlButtonEnabled(List<AllDevicesModel> selectedDevices) { bool _checkIfControlButtonEnabled(List<AllDevicesModel> selectedDevices) {
if (selectedDevices.length > 1) { if (selectedDevices.length > 1) {
final productTypes = selectedDevices.map((device) => device.productType).toSet(); final productTypes =
selectedDevices.map((device) => device.productType).toSet();
return productTypes.length == 1; return productTypes.length == 1;
} else if (selectedDevices.length == 1) { } else if (selectedDevices.length == 1) {
return true; return true;
@ -234,8 +254,10 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
void _calculateDeviceCounts() { void _calculateDeviceCounts() {
_onlineCount = _devices.where((device) => device.online == true).length; _onlineCount = _devices.where((device) => device.online == true).length;
_offlineCount = _devices.where((device) => device.online == false).length; _offlineCount = _devices.where((device) => device.online == false).length;
_lowBatteryCount = _lowBatteryCount = _devices
_devices.where((device) => device.batteryLevel != null && device.batteryLevel! < 20).length; .where((device) =>
device.batteryLevel != null && device.batteryLevel! < 20)
.length;
} }
String _getFilterFromIndex(int index) { String _getFilterFromIndex(int index) {
@ -251,7 +273,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
} }
} }
void _onSearchDevices(SearchDevices event, Emitter<DeviceManagementState> emit) { void _onSearchDevices(
SearchDevices event, Emitter<DeviceManagementState> emit) {
if ((event.community == null || event.community!.isEmpty) && if ((event.community == null || event.community!.isEmpty) &&
(event.unitName == null || event.unitName!.isEmpty) && (event.unitName == null || event.unitName!.isEmpty) &&
(event.productName == null || event.productName!.isEmpty)) { (event.productName == null || event.productName!.isEmpty)) {
@ -280,22 +303,33 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
final filteredDevices = devicesToSearch.where((device) { final filteredDevices = devicesToSearch.where((device) {
final matchesCommunity = event.community == null || final matchesCommunity = event.community == null ||
event.community!.isEmpty || event.community!.isEmpty ||
(device.community?.name?.toLowerCase().contains(event.community!.toLowerCase()) ?? (device.community?.name
?.toLowerCase()
.contains(event.community!.toLowerCase()) ??
false); false);
final matchesUnit = event.unitName == null || final matchesUnit = event.unitName == null ||
event.unitName!.isEmpty || event.unitName!.isEmpty ||
(device.spaces != null && (device.spaces != null &&
device.spaces!.isNotEmpty && device.spaces!.isNotEmpty &&
device.spaces![0].spaceName!.toLowerCase().contains(event.unitName!.toLowerCase())); device.spaces![0].spaceName!
.toLowerCase()
.contains(event.unitName!.toLowerCase()));
final matchesProductName = event.productName == null || final matchesProductName = event.productName == null ||
event.productName!.isEmpty || event.productName!.isEmpty ||
(device.name?.toLowerCase().contains(event.productName!.toLowerCase()) ?? false); (device.name
?.toLowerCase()
.contains(event.productName!.toLowerCase()) ??
false);
final matchesDeviceName = event.productName == null || final matchesDeviceName = event.productName == null ||
event.productName!.isEmpty || event.productName!.isEmpty ||
(device.categoryName?.toLowerCase().contains(event.productName!.toLowerCase()) ?? (device.categoryName
?.toLowerCase()
.contains(event.productName!.toLowerCase()) ??
false); false);
return matchesCommunity && matchesUnit && (matchesProductName || matchesDeviceName); return matchesCommunity &&
matchesUnit &&
(matchesProductName || matchesDeviceName);
}).toList(); }).toList();
emit(DeviceManagementFiltered( emit(DeviceManagementFiltered(

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_managment_body.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_managment_body.dart';
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
@ -9,7 +10,6 @@ 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 {
@ -20,17 +20,17 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
return MultiBlocProvider( return MultiBlocProvider(
providers: [ providers: [
BlocProvider( BlocProvider(
create: (context) => create: (context) => DeviceManagementBloc(context.read<ProjectCubit>())..add(FetchDevices(context)),
DeviceManagementBloc()..add(FetchDevices(context)),
), ),
], ],
child: WebScaffold( child: WebScaffold(
appBarTitle: Text( appBarTitle: FittedBox(
'Device Management', child: Text(
style: ResponsiveTextTheme.of(context).deviceManagementTitle, 'Device Management',
style: Theme.of(context).textTheme.headlineLarge,
),
), ),
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: [
@ -46,11 +46,8 @@ 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 color: !state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor,
? ColorsManager.whiteColors fontWeight: !state.routineTab ? FontWeight.w700 : FontWeight.w400,
: ColorsManager.grayColor,
fontWeight:
!state.routineTab ? FontWeight.w700 : FontWeight.w400,
), ),
), ),
), ),
@ -59,18 +56,13 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
backgroundColor: null, backgroundColor: null,
), ),
onPressed: () { onPressed: () {
context context.read<RoutineBloc>().add(const TriggerSwitchTabsEvent(isRoutineTab: true));
.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 color: state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor,
? ColorsManager.whiteColors fontWeight: state.routineTab ? FontWeight.w700 : FontWeight.w400,
: ColorsManager.grayColor,
fontWeight:
state.routineTab ? FontWeight.w700 : FontWeight.w400,
), ),
), ),
), ),
@ -78,8 +70,7 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
); );
}), }),
rightBody: const NavigateHomeGridView(), rightBody: const NavigateHomeGridView(),
scaffoldBody: scaffoldBody: BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
if (state.routineTab) { if (state.routineTab) {
return const RoutinesView(); return const RoutinesView();
} }
@ -94,8 +85,7 @@ 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( return DeviceManagementBody(devices: deviceState.filteredDevices);
devices: deviceState.filteredDevices);
} else { } else {
return const Center(child: Text('Error fetching Devices')); return const Center(child: Text('Error fetching Devices'));
} }

View File

@ -8,6 +8,7 @@ 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';
@ -94,7 +95,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(

View File

@ -1,6 +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/ceiling_sensor/bloc/ceiling_event.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart';
@ -23,55 +22,42 @@ 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 = var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = CeilingSensorModel.fromJson(response.status); deviceStatus = CeilingSensorModel.fromJson(response.status);
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
_listenToChanges(event.deviceId); // _listenToChanges();
} catch (e) { } catch (e) {
emit(CeilingFailedState(error: e.toString())); emit(CeilingFailedState(error: e.toString()));
return; return;
} }
} }
_listenToChanges(deviceId) { // _listenToChanges() {
try { // try {
DatabaseReference ref = // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
FirebaseDatabase.instance.ref('device-status/$deviceId'); // Stream<DatabaseEvent> stream = ref.onValue;
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) { // stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap = // Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
event.snapshot.value as Map<dynamic, dynamic>; // List<StatusModel> statusList = [];
List<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 = CeilingSensorModel.fromJson(statusList); // deviceStatus = WallSensorModel.fromJson(statusList);
if (!isClosed) { // add(WallSensorUpdatedEvent());
add(StatusUpdated(deviceStatus)); // });
} // } catch (_) {}
}); // }
} catch (_) {}
}
void _onStatusUpdated(StatusUpdated event, Emitter<CeilingSensorState> emit) { void _changeValue(CeilingChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
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;
@ -136,8 +122,7 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
try { try {
late bool response; late bool response;
if (isBatch) { if (isBatch) {
response = await DevicesManagementApi() response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
.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));
@ -158,8 +143,8 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
}); });
} }
FutureOr<void> _getDeviceReports(GetCeilingDeviceReportsEvent event, FutureOr<void> _getDeviceReports(
Emitter<CeilingSensorState> emit) async { GetCeilingDeviceReportsEvent event, Emitter<CeilingSensorState> emit) async {
if (event.code.isEmpty) { if (event.code.isEmpty) {
emit(ShowCeilingDescriptionState(description: reportString)); emit(ShowCeilingDescriptionState(description: reportString));
return; return;
@ -170,8 +155,7 @@ 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) await DevicesManagementApi.getDeviceReports(deviceId, event.code).then((value) {
.then((value) {
emit(CeilingReportsState(deviceReport: value)); emit(CeilingReportsState(deviceReport: value));
}); });
} catch (e) { } catch (e) {
@ -181,23 +165,19 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
} }
} }
void _showDescription( void _showDescription(ShowCeilingDescriptionEvent event, Emitter<CeilingSensorState> emit) {
ShowCeilingDescriptionEvent event, Emitter<CeilingSensorState> emit) {
emit(ShowCeilingDescriptionState(description: event.description)); emit(ShowCeilingDescriptionState(description: event.description));
} }
void _backToGridView( void _backToGridView(BackToCeilingGridViewEvent event, Emitter<CeilingSensorState> emit) {
BackToCeilingGridViewEvent event, Emitter<CeilingSensorState> emit) {
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
} }
FutureOr<void> _fetchCeilingSensorBatchControl( FutureOr<void> _fetchCeilingSensorBatchControl(
CeilingFetchDeviceStatusEvent event, CeilingFetchDeviceStatusEvent event, Emitter<CeilingSensorState> emit) async {
Emitter<CeilingSensorState> emit) async {
emit(CeilingLoadingInitialState()); emit(CeilingLoadingInitialState());
try { try {
var response = var response = await DevicesManagementApi().getBatchStatus(event.devicesIds);
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) {

View File

@ -1,6 +1,5 @@
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();
@ -84,12 +83,3 @@ 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];
}

View File

@ -1,5 +1,4 @@
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';
@ -17,7 +16,6 @@ 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(
@ -26,7 +24,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));
@ -35,48 +33,6 @@ 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;

View File

@ -60,7 +60,3 @@ 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);
}

View File

@ -1,7 +1,6 @@
// 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';
@ -19,39 +18,6 @@ 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(
@ -62,8 +28,6 @@ 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()));

View File

@ -1,6 +1,5 @@
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();
@ -52,10 +51,3 @@ 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];
}

View File

@ -1,7 +1,6 @@
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';
@ -40,68 +39,31 @@ 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 _onStatusUpdated(StatusUpdated event, Emitter<GarageDoorState> emit) { void _fetchGarageDoorStatus(GarageDoorInitialEvent event, Emitter<GarageDoorState> emit) async {
deviceStatus = event.deviceStatus;
emit(GarageDoorLoadedState(status: deviceStatus));
}
void _fetchGarageDoorStatus(
GarageDoorInitialEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState()); emit(GarageDoorLoadingState());
try { try {
var response = var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
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, Future<void> _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, Emitter<GarageDoorState> emit) async {
Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState()); emit(GarageDoorLoadingState());
try { try {
final status = final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
await DevicesManagementApi().getBatchStatus(event.deviceIds); deviceStatus = GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status);
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( Future<void> _addSchedule(AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try { try {
ScheduleEntry newSchedule = ScheduleEntry( ScheduleEntry newSchedule = ScheduleEntry(
category: event.category, category: event.category,
@ -109,11 +71,9 @@ 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 = bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
if (success) { if (success) {
add(FetchGarageDoorSchedulesEvent( add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
deviceId: deviceId, category: 'switch_1'));
} else { } else {
emit(GarageDoorLoadedState(status: deviceStatus)); emit(GarageDoorLoadedState(status: deviceStatus));
} }
@ -122,19 +82,16 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
void _onUpdateCountdownAlarm( void _onUpdateCountdownAlarm(UpdateCountdownAlarmEvent event, Emitter<GarageDoorState> emit) {
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: status: currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
)); ));
} }
} }
void _onUpdateTrTimeCon( void _onUpdateTrTimeCon(UpdateTrTimeConEvent event, Emitter<GarageDoorState> emit) {
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(
@ -143,8 +100,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event, Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
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) {
@ -171,15 +127,12 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event, Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
Emitter<GarageDoorState> emit) async {
try { try {
bool success = await DevicesManagementApi() bool success = await DevicesManagementApi().deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
.deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
if (success) { if (success) {
final updatedSchedules = deviceStatus.schedules final updatedSchedules =
?.where((schedule) => schedule.scheduleId != event.scheduleId) deviceStatus.schedules?.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
.toList();
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules); deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
emit(GarageDoorLoadedState(status: deviceStatus)); emit(GarageDoorLoadedState(status: deviceStatus));
} else { } else {
@ -190,12 +143,11 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event, Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event, Emitter<GarageDoorState> emit) async {
Emitter<GarageDoorState> emit) async {
emit(ScheduleGarageLoadingState()); emit(ScheduleGarageLoadingState());
try { try {
List<ScheduleModel> schedules = await DevicesManagementApi() List<ScheduleModel> schedules =
.getDeviceSchedules(deviceStatus.uuid, event.category); await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
deviceStatus = deviceStatus.copyWith(schedules: schedules); deviceStatus = deviceStatus.copyWith(schedules: schedules);
emit( emit(
GarageDoorLoadedState( GarageDoorLoadedState(
@ -213,37 +165,30 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
Future<void> _updateSelectedTime( Future<void> _updateSelectedTime(UpdateSelectedTimeEvent event, Emitter<GarageDoorState> emit) async {
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( Future<void> _updateSelectedDay(UpdateSelectedDayEvent event, Emitter<GarageDoorState> emit) async {
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( emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
selectedDays: updatedDays, selectedTime: currentState.selectedTime));
} }
} }
Future<void> _updateFunctionOn( Future<void> _updateFunctionOn(UpdateFunctionOnEvent event, Emitter<GarageDoorState> emit) async {
UpdateFunctionOnEvent 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(functionOn: event.functionOn, selectedTime: currentState.selectedTime));
functionOn: event.functionOn,
selectedTime: currentState.selectedTime));
} }
} }
Future<void> _initializeAddSchedule( Future<void> _initializeAddSchedule(InitializeAddScheduleEvent event, Emitter<GarageDoorState> emit) async {
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(
@ -255,25 +200,20 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
Future<void> _fetchRecords( Future<void> _fetchRecords(FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorReportsLoadingState()); emit(GarageDoorReportsLoadingState());
try { try {
final from = DateTime.now() final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
.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( await DevicesManagementApi.getDeviceReportsByDate(event.deviceId, 'switch_1', from.toString(), to.toString());
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( Future<void> _onBatchControl(GarageDoorBatchControlEvent event, Emitter<GarageDoorState> emit) async {
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);
@ -293,13 +233,11 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
void _backToGridView( void _backToGridView(BackToGarageDoorGridViewEvent event, Emitter<GarageDoorState> emit) {
BackToGarageDoorGridViewEvent event, Emitter<GarageDoorState> emit) {
emit(GarageDoorLoadedState(status: deviceStatus)); emit(GarageDoorLoadedState(status: deviceStatus));
} }
void _handleUpdate( void _handleUpdate(GarageDoorUpdatedEvent event, Emitter<GarageDoorState> emit) {
GarageDoorUpdatedEvent event, Emitter<GarageDoorState> emit) {
emit(GarageDoorLoadedState(status: deviceStatus)); emit(GarageDoorLoadedState(status: deviceStatus));
} }
@ -315,11 +253,9 @@ 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() status = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
.deviceBatchControl(deviceId, code, value);
} else { } else {
status = await DevicesManagementApi() status = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
.deviceControl(deviceId, Status(code: code, value: value));
} }
if (!status) { if (!status) {
@ -334,12 +270,10 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
Future<void> _onFactoryReset( Future<void> _onFactoryReset(GarageDoorFactoryResetEvent event, Emitter<GarageDoorState> emit) async {
GarageDoorFactoryResetEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState()); emit(GarageDoorLoadingState());
try { try {
final response = await DevicesManagementApi() final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
.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 {
@ -350,47 +284,34 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
void _increaseDelay( void _increaseDelay(IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
// if (deviceStatus.countdown1 != 0) { // if (deviceStatus.countdown1 != 0) {
try { try {
deviceStatus = deviceStatus.copyWith( deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay + Duration(minutes: 10));
delay: deviceStatus.delay + Duration(minutes: 10));
emit(GarageDoorLoadedState(status: deviceStatus)); emit(GarageDoorLoadedState(status: deviceStatus));
add(GarageDoorControlEvent( add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
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( void _decreaseDelay(DecreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
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( deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay - Duration(minutes: 10));
delay: deviceStatus.delay - Duration(minutes: 10));
} }
emit(GarageDoorLoadedState(status: deviceStatus)); emit(GarageDoorLoadedState(status: deviceStatus));
add(GarageDoorControlEvent( add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
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( void _garageDoorControlEvent(GarageDoorControlEvent event, Emitter<GarageDoorState> emit) async {
GarageDoorControlEvent event, Emitter<GarageDoorState> emit) async { final oldValue = event.code == 'countdown_1' ? deviceStatus.countdown1 : deviceStatus.switch1;
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(
@ -406,8 +327,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
} }
} }
void _revertValue( void _revertValue(String code, dynamic oldValue, Emitter<GarageDoorState> emit) {
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) {
@ -416,8 +336,7 @@ 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( deviceStatus = deviceStatus.copyWith(countdown1: oldValue, delay: Duration(seconds: oldValue));
countdown1: oldValue, delay: Duration(seconds: oldValue));
} }
break; break;
// Add other cases if needed // Add other cases if needed
@ -439,8 +358,7 @@ 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( deviceStatus = deviceStatus.copyWith(countdown1: value, delay: Duration(seconds: value));
countdown1: value, delay: Duration(seconds: value));
} }
break; break;
case 'countdown_alarm': case 'countdown_alarm':
@ -483,8 +401,7 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
return super.close(); return super.close();
} }
FutureOr<void> _onEditSchedule( FutureOr<void> _onEditSchedule(EditGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
EditGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try { try {
ScheduleEntry newSchedule = ScheduleEntry( ScheduleEntry newSchedule = ScheduleEntry(
scheduleId: event.scheduleId, scheduleId: event.scheduleId,
@ -493,11 +410,9 @@ 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() bool success = await DevicesManagementApi().editScheduleRecord(deviceId, newSchedule);
.editScheduleRecord(deviceId, newSchedule);
if (success) { if (success) {
add(FetchGarageDoorSchedulesEvent( add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
deviceId: deviceId, category: 'switch_1'));
} else { } else {
emit(GarageDoorLoadedState(status: deviceStatus)); emit(GarageDoorLoadedState(status: deviceStatus));
} }

View File

@ -3,7 +3,6 @@
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();
@ -26,8 +25,7 @@ class GarageDoorControlEvent extends GarageDoorEvent {
final dynamic value; final dynamic value;
final String code; final String code;
const GarageDoorControlEvent( const GarageDoorControlEvent({required this.deviceId, required this.value, required this.code});
{required this.deviceId, required this.value, required this.code});
@override @override
List<Object?> get props => [deviceId, value]; List<Object?> get props => [deviceId, value];
@ -123,8 +121,7 @@ class FetchGarageDoorRecordsEvent extends GarageDoorEvent {
final String deviceId; final String deviceId;
final String code; final String code;
const FetchGarageDoorRecordsEvent( const FetchGarageDoorRecordsEvent({required this.deviceId, required this.code});
{required this.deviceId, required this.code});
@override @override
List<Object?> get props => [deviceId, code]; List<Object?> get props => [deviceId, code];
@ -235,10 +232,3 @@ 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];
}

View File

@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/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';
@ -17,7 +16,6 @@ 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;
@ -30,7 +28,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) {
@ -158,35 +156,4 @@ 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));
}
} }

View File

@ -1,5 +1,4 @@
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';
@ -72,10 +71,3 @@ 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];
}

View File

@ -1,7 +1,6 @@
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';
@ -11,71 +10,33 @@ 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 class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
OneGangGlassStatusModel deviceStatus; OneGangGlassStatusModel deviceStatus;
Timer? _timer; Timer? _timer;
OneGangGlassSwitchBloc({required String deviceId}) OneGangGlassSwitchBloc({required String deviceId})
: deviceStatus = OneGangGlassStatusModel( : deviceStatus = OneGangGlassStatusModel(uuid: deviceId, switch1: false, countDown: 0),
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(OneGangGlassSwitchFetchDeviceEvent event, Future<void> _onFetchDeviceStatus(
Emitter<OneGangGlassSwitchState> emit) async { OneGangGlassSwitchFetchDeviceEvent event, Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading()); emit(OneGangGlassSwitchLoading());
try { try {
final status = final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
_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()));
} }
} }
_listenToChanges(deviceId) { Future<void> _onControl(OneGangGlassSwitchControl event, Emitter<OneGangGlassSwitchState> emit) async {
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);
@ -91,12 +52,10 @@ class OneGangGlassSwitchBloc
); );
} }
Future<void> _onFactoryReset(OneGangGlassFactoryResetEvent event, Future<void> _onFactoryReset(OneGangGlassFactoryResetEvent event, Emitter<OneGangGlassSwitchState> emit) async {
Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading()); emit(OneGangGlassSwitchLoading());
try { try {
final response = await DevicesManagementApi() final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
.factoryReset(event.factoryReset, event.deviceId);
if (!response) { if (!response) {
emit(OneGangGlassSwitchError('Failed to reset device')); emit(OneGangGlassSwitchError('Failed to reset device'));
} else { } else {
@ -107,8 +66,7 @@ class OneGangGlassSwitchBloc
} }
} }
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event, Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event, Emitter<OneGangGlassSwitchState> emit) async {
Emitter<OneGangGlassSwitchState> emit) async {
final oldValue = _getValueByCode(event.code); final oldValue = _getValueByCode(event.code);
_updateLocalValue(event.code, event.value); _updateLocalValue(event.code, event.value);
@ -125,14 +83,11 @@ class OneGangGlassSwitchBloc
} }
Future<void> _onFetchBatchStatus( Future<void> _onFetchBatchStatus(
OneGangGlassSwitchFetchBatchStatusEvent event, OneGangGlassSwitchFetchBatchStatusEvent event, Emitter<OneGangGlassSwitchState> emit) async {
Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading()); emit(OneGangGlassSwitchLoading());
try { try {
final status = final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
await DevicesManagementApi().getBatchStatus(event.deviceIds); deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
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()));
@ -162,11 +117,9 @@ class OneGangGlassSwitchBloc
try { try {
late bool response; late bool response;
if (isBatch) { if (isBatch) {
response = await DevicesManagementApi() response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
.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));
} }
if (!response) { if (!response) {
@ -178,8 +131,7 @@ class OneGangGlassSwitchBloc
}); });
} }
void _revertValueAndEmit(String deviceId, String code, bool oldValue, void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<OneGangGlassSwitchState> emit) {
Emitter<OneGangGlassSwitchState> emit) {
_updateLocalValue(code, oldValue); _updateLocalValue(code, oldValue);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
} }

View File

@ -39,11 +39,6 @@ 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;

View File

@ -1,6 +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/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';
@ -17,7 +16,6 @@ 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;
@ -33,44 +31,12 @@ 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);

View File

@ -1,6 +1,5 @@
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
@ -58,10 +57,3 @@ 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];
}

View File

@ -1,7 +1,6 @@
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';
@ -11,8 +10,7 @@ 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 class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGangGlassSwitchState> {
extends Bloc<ThreeGangGlassSwitchEvent, ThreeGangGlassSwitchState> {
ThreeGangGlassStatusModel deviceStatus; ThreeGangGlassStatusModel deviceStatus;
Timer? _timer; Timer? _timer;
@ -31,57 +29,21 @@ class ThreeGangGlassSwitchBloc
on<ThreeGangGlassSwitchBatchControl>(_onBatchControl); on<ThreeGangGlassSwitchBatchControl>(_onBatchControl);
on<ThreeGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus); on<ThreeGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
on<ThreeGangGlassFactoryReset>(_onFactoryReset); on<ThreeGangGlassFactoryReset>(_onFactoryReset);
on<StatusUpdated>(_onStatusUpdated);
} }
Future<void> _onFetchDeviceStatus(ThreeGangGlassSwitchFetchDeviceEvent event, Future<void> _onFetchDeviceStatus(
Emitter<ThreeGangGlassSwitchState> emit) async { ThreeGangGlassSwitchFetchDeviceEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
emit(ThreeGangGlassSwitchLoading()); emit(ThreeGangGlassSwitchLoading());
try { try {
final status = final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status);
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()));
} }
} }
_listenToChanges(deviceId) { Future<void> _onControl(ThreeGangGlassSwitchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
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);
@ -97,8 +59,7 @@ class ThreeGangGlassSwitchBloc
); );
} }
Future<void> _onBatchControl(ThreeGangGlassSwitchBatchControl event, Future<void> _onBatchControl(ThreeGangGlassSwitchBatchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
Emitter<ThreeGangGlassSwitchState> emit) async {
final oldValue = _getValueByCode(event.code); final oldValue = _getValueByCode(event.code);
_updateLocalValue(event.code, event.value); _updateLocalValue(event.code, event.value);
@ -115,26 +76,21 @@ class ThreeGangGlassSwitchBloc
} }
Future<void> _onFetchBatchStatus( Future<void> _onFetchBatchStatus(
ThreeGangGlassSwitchFetchBatchStatusEvent event, ThreeGangGlassSwitchFetchBatchStatusEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
Emitter<ThreeGangGlassSwitchState> emit) async {
emit(ThreeGangGlassSwitchLoading()); emit(ThreeGangGlassSwitchLoading());
try { try {
final status = final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
await DevicesManagementApi().getBatchStatus(event.deviceIds); deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
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, Future<void> _onFactoryReset(ThreeGangGlassFactoryReset event, Emitter<ThreeGangGlassSwitchState> emit) async {
Emitter<ThreeGangGlassSwitchState> emit) async {
emit(ThreeGangGlassSwitchLoading()); emit(ThreeGangGlassSwitchLoading());
try { try {
final response = await DevicesManagementApi() final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
.factoryReset(event.factoryReset, event.deviceId);
if (!response) { if (!response) {
emit(ThreeGangGlassSwitchError('Failed')); emit(ThreeGangGlassSwitchError('Failed'));
} else { } else {
@ -168,11 +124,9 @@ class ThreeGangGlassSwitchBloc
try { try {
late bool response; late bool response;
if (isBatch) { if (isBatch) {
response = await DevicesManagementApi() response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
.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));
} }
if (!response) { if (!response) {
@ -184,8 +138,7 @@ class ThreeGangGlassSwitchBloc
}); });
} }
void _revertValueAndEmit(String deviceId, String code, bool oldValue, void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<ThreeGangGlassSwitchState> emit) {
Emitter<ThreeGangGlassSwitchState> emit) {
_updateLocalValue(code, oldValue); _updateLocalValue(code, oldValue);
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus)); emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
} }

View File

@ -49,10 +49,3 @@ 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];
}

View File

@ -3,7 +3,6 @@
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';
@ -23,7 +22,6 @@ 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,
@ -34,7 +32,6 @@ 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()));
@ -147,9 +144,6 @@ 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()));
@ -191,34 +185,4 @@ 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));
}
} }

View File

@ -58,10 +58,3 @@ 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];
}

View File

@ -1,11 +1,12 @@
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';
@ -13,6 +14,7 @@ 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,
@ -26,7 +28,6 @@ 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,
@ -37,44 +38,12 @@ 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);
@ -209,37 +178,4 @@ 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));
}
} }

View File

@ -48,11 +48,3 @@ 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];
}

View File

@ -6,8 +6,7 @@ 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 class TwoGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
final String deviceId; final String deviceId;
const TwoGangGlassSwitchControlView({required this.deviceId, super.key}); const TwoGangGlassSwitchControlView({required this.deviceId, super.key});
@ -15,25 +14,25 @@ class TwoGangGlassSwitchControlView extends StatelessWidget
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => TwoGangGlassSwitchBloc(deviceId: deviceId) create: (context) =>
..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)), TwoGangGlassSwitchBloc(deviceId: 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) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} 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 Center(child: Text(state.message)); return const Center(child: Text('Error fetching status'));
} else { } else {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} }
}, },
)); ),
);
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) {
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);

View File

@ -1,6 +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/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';
@ -15,7 +14,6 @@ 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;
@ -28,8 +26,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()));
@ -176,34 +174,4 @@ 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));
}
} }

View File

@ -1,6 +1,5 @@
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
@ -58,10 +57,3 @@ 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];
}

View File

@ -1,5 +1,4 @@
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';
@ -30,7 +29,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(emit); // _listenToChanges();
} catch (e) { } catch (e) {
emit(WallSensorFailedState(error: e.toString())); emit(WallSensorFailedState(error: e.toString()));
return; return;
@ -39,12 +38,10 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
// Fetch batch status // Fetch batch status
FutureOr<void> _fetchWallSensorBatchControl( FutureOr<void> _fetchWallSensorBatchControl(
WallSensorFetchBatchStatusEvent event, WallSensorFetchBatchStatusEvent event, Emitter<WallSensorState> emit) async {
Emitter<WallSensorState> emit) async {
emit(WallSensorLoadingInitialState()); emit(WallSensorLoadingInitialState());
try { try {
var response = var response = await DevicesManagementApi().getBatchStatus(event.devicesIds);
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) {
@ -52,30 +49,26 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
} }
} }
_listenToChanges(Emitter<WallSensorState> emit) { // _listenToChanges() {
try { // try {
DatabaseReference ref = // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
FirebaseDatabase.instance.ref('device-status/$deviceId'); // Stream<DatabaseEvent> stream = ref.onValue;
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) { // stream.listen((DatabaseEvent event) {
Map<dynamic, dynamic> usersMap = // Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
event.snapshot.value as Map<dynamic, dynamic>; // List<StatusModel> statusList = [];
List<Status> statusList = [];
usersMap['status'].forEach((element) { // usersMap['status'].forEach((element) {
statusList // statusList.add(StatusModel(code: element['code'], value: element['value']));
.add(Status(code: element['code'], value: element['value'])); // });
});
deviceStatus = WallSensorModel.fromJson(statusList); // deviceStatus = WallSensorModel.fromJson(statusList);
emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus)); // add(WallSensorUpdatedEvent());
}); // });
} catch (_) {} // } catch (_) {}
} // }
void _changeValue( void _changeValue(WallSensorChangeValueEvent event, Emitter<WallSensorState> emit) async {
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;
@ -132,8 +125,7 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
try { try {
late bool response; late bool response;
if (isBatch) { if (isBatch) {
response = await DevicesManagementApi() response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
.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));
@ -158,8 +150,7 @@ 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) await DevicesManagementApi.getDeviceReports(deviceId, event.code).then((value) {
.then((value) {
emit(DeviceReportsState(deviceReport: value, code: event.code)); emit(DeviceReportsState(deviceReport: value, code: event.code));
}); });
} catch (e) { } catch (e) {
@ -168,13 +159,11 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
} }
} }
void _showDescription( void _showDescription(ShowDescriptionEvent event, Emitter<WallSensorState> emit) {
ShowDescriptionEvent event, Emitter<WallSensorState> emit) {
emit(WallSensorShowDescriptionState(description: event.description)); emit(WallSensorShowDescriptionState(description: event.description));
} }
void _backToGridView( void _backToGridView(BackToGridViewEvent event, Emitter<WallSensorState> emit) {
BackToGridViewEvent event, Emitter<WallSensorState> emit) {
emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); emit(WallSensorUpdateState(wallSensorModel: deviceStatus));
} }

View File

@ -4,7 +4,6 @@ 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';
@ -35,7 +34,6 @@ 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;
@ -80,8 +78,7 @@ 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( emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
selectedDays: updatedDays, selectedTime: currentState.selectedTime));
} }
FutureOr<void> _updateFunctionOn( FutureOr<void> _updateFunctionOn(
@ -89,8 +86,7 @@ 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( emit(currentState.copyWith(functionOn: event.isOn, selectedTime: currentState.selectedTime));
functionOn: event.isOn, selectedTime: currentState.selectedTime));
} }
FutureOr<void> _updateScheduleEvent( FutureOr<void> _updateScheduleEvent(
@ -105,8 +101,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
)); ));
} }
if (event.scheduleMode == ScheduleModes.countdown) { if (event.scheduleMode == ScheduleModes.countdown) {
final countdownRemaining = final countdownRemaining = Duration(hours: event.hours, minutes: event.minutes);
Duration(hours: event.hours, minutes: event.minutes);
emit(currentState.copyWith( emit(currentState.copyWith(
scheduleMode: ScheduleModes.countdown, scheduleMode: ScheduleModes.countdown,
@ -116,13 +111,11 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
countdownRemaining: countdownRemaining, countdownRemaining: countdownRemaining,
)); ));
if (!currentState.isCountdownActive! && if (!currentState.isCountdownActive! && countdownRemaining > Duration.zero) {
countdownRemaining > Duration.zero) {
_startCountdownTimer(emit, countdownRemaining); _startCountdownTimer(emit, countdownRemaining);
} }
} else if (event.scheduleMode == ScheduleModes.inching) { } else if (event.scheduleMode == ScheduleModes.inching) {
final inchingDuration = final inchingDuration = Duration(hours: event.hours, minutes: event.minutes);
Duration(hours: event.hours, minutes: event.minutes);
emit(currentState.copyWith( emit(currentState.copyWith(
scheduleMode: ScheduleModes.inching, scheduleMode: ScheduleModes.inching,
@ -224,8 +217,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
try { try {
final status = await DevicesManagementApi().deviceControl( final status = await DevicesManagementApi().deviceControl(
event.deviceId, event.deviceId,
Status( Status(code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0),
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.'));
@ -243,10 +235,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
emit(WaterHeaterLoadingState()); emit(WaterHeaterLoadingState());
try { try {
final status = final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
deviceStatus =
WaterHeaterStatusModel.fromJson(event.deviceId, status.status);
if (deviceStatus.scheduleMode == ScheduleModes.countdown) { if (deviceStatus.scheduleMode == ScheduleModes.countdown) {
final countdownRemaining = Duration( final countdownRemaining = Duration(
@ -310,42 +300,11 @@ 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,
@ -375,10 +334,8 @@ 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 && if (currentState.countdownRemaining != null && currentState.countdownRemaining! > Duration.zero) {
currentState.countdownRemaining! > Duration.zero) { final newRemaining = currentState.countdownRemaining! - const Duration(minutes: 1);
final newRemaining =
currentState.countdownRemaining! - const Duration(minutes: 1);
if (newRemaining <= Duration.zero) { if (newRemaining <= Duration.zero) {
_countdownTimer?.cancel(); _countdownTimer?.cancel();
@ -473,8 +430,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
} }
} }
void _revertValue(String code, dynamic oldValue, void _revertValue(String code, dynamic oldValue, void Function(WaterHeaterState state) emit) {
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;
@ -521,13 +477,12 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
return super.close(); return super.close();
} }
FutureOr<void> _getSchedule( FutureOr<void> _getSchedule(GetSchedulesEvent event, Emitter<WaterHeaterState> emit) async {
GetSchedulesEvent event, Emitter<WaterHeaterState> emit) async {
emit(ScheduleLoadingState()); emit(ScheduleLoadingState());
try { try {
List<ScheduleModel> schedules = await DevicesManagementApi() List<ScheduleModel> schedules =
.getDeviceSchedules(deviceStatus.uuid, event.category); await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
emit(WaterHeaterDeviceStatusLoaded( emit(WaterHeaterDeviceStatusLoaded(
deviceStatus, deviceStatus,
@ -559,8 +514,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
// emit(ScheduleLoadingState()); // emit(ScheduleLoadingState());
bool success = await DevicesManagementApi() bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, currentState.status.uuid);
.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));
@ -571,8 +525,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
} }
} }
FutureOr<void> _onEditSchedule(EditWaterHeaterScheduleEvent event, FutureOr<void> _onEditSchedule(EditWaterHeaterScheduleEvent event, Emitter<WaterHeaterState> emit) async {
Emitter<WaterHeaterState> emit) async {
if (state is WaterHeaterDeviceStatusLoaded) { if (state is WaterHeaterDeviceStatusLoaded) {
final currentState = state as WaterHeaterDeviceStatusLoaded; final currentState = state as WaterHeaterDeviceStatusLoaded;
@ -641,13 +594,11 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
// emit(ScheduleLoadingState()); // emit(ScheduleLoadingState());
bool success = await DevicesManagementApi() bool success = await DevicesManagementApi().deleteScheduleRecord(currentState.status.uuid, event.scheduleId);
.deleteScheduleRecord(currentState.status.uuid, event.scheduleId);
if (success) { if (success) {
final updatedSchedules = currentState.schedules final updatedSchedules =
.where((schedule) => schedule.scheduleId != event.scheduleId) currentState.schedules.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
.toList();
emit(currentState.copyWith(schedules: updatedSchedules)); emit(currentState.copyWith(schedules: updatedSchedules));
} else { } else {
@ -657,15 +608,12 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
} }
} }
FutureOr<void> _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, FutureOr<void> _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, Emitter<WaterHeaterState> emit) async {
Emitter<WaterHeaterState> emit) async {
emit(WaterHeaterLoadingState()); emit(WaterHeaterLoadingState());
try { try {
final status = final status = await DevicesManagementApi().getBatchStatus(event.devicesUuid);
await DevicesManagementApi().getBatchStatus(event.devicesUuid); deviceStatus = WaterHeaterStatusModel.fromJson(event.devicesUuid.first, status.status);
deviceStatus = WaterHeaterStatusModel.fromJson(
event.devicesUuid.first, status.status);
emit(WaterHeaterDeviceStatusLoaded(deviceStatus)); emit(WaterHeaterDeviceStatusLoaded(deviceStatus));
} catch (e) { } catch (e) {
@ -673,8 +621,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
} }
} }
FutureOr<void> _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, FutureOr<void> _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, Emitter<WaterHeaterState> emit) async {
Emitter<WaterHeaterState> emit) async {
if (state is WaterHeaterDeviceStatusLoaded) { if (state is WaterHeaterDeviceStatusLoaded) {
final currentState = state as WaterHeaterDeviceStatusLoaded; final currentState = state as WaterHeaterDeviceStatusLoaded;

View File

@ -54,15 +54,6 @@ 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;

View File

@ -1,5 +1,4 @@
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';
@ -22,7 +21,6 @@ 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(
@ -32,43 +30,12 @@ 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;

View File

@ -1,6 +1,5 @@
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();
@ -18,13 +17,6 @@ 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;

View File

@ -4,6 +4,7 @@ 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:graphview/GraphView.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_cubit.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';
@ -21,8 +22,9 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
UserModel? user; UserModel? user;
String terms = ''; String terms = '';
String policy = ''; String policy = '';
final ProjectCubit projectCubit;
HomeBloc() : super((HomeInitial())) { HomeBloc(this.projectCubit) : super((HomeInitial())) {
// on<CreateNewNode>(_createNode); // on<CreateNewNode>(_createNode);
on<FetchUserInfo>(_fetchUserInfo); on<FetchUserInfo>(_fetchUserInfo);
on<FetchTermEvent>(_fetchTerms); on<FetchTermEvent>(_fetchTerms);
@ -51,6 +53,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
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) {
projectCubit.setProjectUUID(user!.project!.uuid);
}
add(FetchTermEvent()); add(FetchTermEvent());
add(FetchPolicyEvent()); add(FetchPolicyEvent());
@ -65,6 +71,8 @@ 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;
} }
@ -74,6 +82,8 @@ 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");
@ -106,7 +116,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
List<HomeItemModel> homeItems = [ List<HomeItemModel> homeItems = [
HomeItemModel( HomeItemModel(
title: 'Access Management', title: 'Access',
icon: Assets.accessIcon, icon: Assets.accessIcon,
active: true, active: true,
onPress: (context) { onPress: (context) {
@ -124,7 +134,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
color: ColorsManager.primaryColor, color: ColorsManager.primaryColor,
), ),
HomeItemModel( HomeItemModel(
title: 'Devices Management', title: 'Devices',
icon: Assets.devicesIcon, icon: Assets.devicesIcon,
active: true, active: true,
onPress: (context) { onPress: (context) {
@ -134,7 +144,6 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
}, },
color: ColorsManager.primaryColor, color: ColorsManager.primaryColor,
), ),
// HomeItemModel( // HomeItemModel(
// title: 'Move in', // title: 'Move in',
// icon: Assets.moveinIcon, // icon: Assets.moveinIcon,

View File

@ -1,7 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_html/flutter_html.dart'; import 'package:flutter_html/flutter_html.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.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/common/bloc/project_cubit.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/routes_const.dart'; import 'package:syncrow_web/utils/constants/routes_const.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -162,7 +164,8 @@ class _AgreementAndPrivacyDialogState extends State<AgreementAndPrivacyDialog> {
children: [ children: [
InkWell( InkWell(
onTap: () { onTap: () {
AuthBloc.logout(); final projectCubit = BlocProvider.of<ProjectCubit>(context);
AuthBloc.logout(context, projectCubit);
context.go(RoutesConst.auth); context.go(RoutesConst.auth);
}, },
child: const Text("Cancel"), child: const Text("Cancel"),

View File

@ -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:syncrow_web/pages/common/bloc/project_cubit.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';
import 'package:syncrow_web/pages/roles_and_permission/model/role_type_model.dart'; import 'package:syncrow_web/pages/roles_and_permission/model/role_type_model.dart';
@ -12,9 +13,12 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model
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/temp_const.dart';
class UsersBloc extends Bloc<UsersEvent, UsersState> { class UsersBloc extends Bloc<UsersEvent, UsersState> {
UsersBloc() : super(UsersInitial()) { final ProjectCubit projectCubit;
UsersBloc(this.projectCubit) : super(UsersInitial()) {
on<CheckStepStatus>(isCompleteBasicsFun); on<CheckStepStatus>(isCompleteBasicsFun);
on<LoadCommunityAndSpacesEvent>(_onLoadCommunityAndSpaces); on<LoadCommunityAndSpacesEvent>(_onLoadCommunityAndSpaces);
on<SearchAnode>(searchTreeNode); on<SearchAnode>(searchTreeNode);
@ -74,7 +78,10 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
Future<List<SpaceModel>> _fetchSpacesForCommunity( Future<List<SpaceModel>> _fetchSpacesForCommunity(
String communityUuid) async { String communityUuid) async {
return await CommunitySpaceManagementApi().getSpaceHierarchy(communityUuid); final projectUuid = projectCubit.state;
return await CommunitySpaceManagementApi()
.getSpaceHierarchy(communityUuid, projectUuid ?? TempConst.projectId);
} }
List<TreeNode> updatedCommunities = []; List<TreeNode> updatedCommunities = [];
@ -84,8 +91,9 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
LoadCommunityAndSpacesEvent event, Emitter<UsersState> emit) async { LoadCommunityAndSpacesEvent event, Emitter<UsersState> emit) async {
try { try {
emit(UsersLoadingState()); emit(UsersLoadingState());
List<CommunityModel> communities = final projectUuid = projectCubit.state;
await CommunitySpaceManagementApi().fetchCommunities(); List<CommunityModel> communities = await CommunitySpaceManagementApi()
.fetchCommunities(projectUuid ?? TempConst.projectId);
communityIds = communities.map((community) => community.uuid).toList(); communityIds = communities.map((community) => community.uuid).toList();
updatedCommunities = await Future.wait( updatedCommunities = await Future.wait(
communities.map((community) async { communities.map((community) async {
@ -328,20 +336,22 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
void _sendInvitUser(SendInviteUsers event, Emitter<UsersState> emit) async { void _sendInvitUser(SendInviteUsers event, Emitter<UsersState> emit) async {
try { try {
final projectUuid = projectCubit.state;
emit(UsersLoadingState()); emit(UsersLoadingState());
List<String> selectedIds = getSelectedIds(updatedCommunities) List<String> selectedIds = getSelectedIds(updatedCommunities)
.where((id) => !communityIds.contains(id)) .where((id) => !communityIds.contains(id))
.toList(); .toList();
bool res = await UserPermissionApi().sendInviteUser( bool res = await UserPermissionApi().sendInviteUser(
email: emailController.text, email: emailController.text,
firstName: firstNameController.text, firstName: firstNameController.text,
jobTitle: jobTitleController.text, jobTitle: jobTitleController.text,
lastName: lastNameController.text, lastName: lastNameController.text,
phoneNumber: phoneController.text, phoneNumber: phoneController.text,
roleUuid: roleSelected, roleUuid: roleSelected,
spaceUuids: selectedIds, spaceUuids: selectedIds,
); projectUuid: projectUuid ?? TempConst.projectId);
if (res) { if (res) {
showCustomDialog( showCustomDialog(
@ -376,16 +386,17 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
List<String> selectedIds = getSelectedIds(updatedCommunities) List<String> selectedIds = getSelectedIds(updatedCommunities)
.where((id) => !communityIds.contains(id)) .where((id) => !communityIds.contains(id))
.toList(); .toList();
final projectUuid = projectCubit.state;
bool res = await UserPermissionApi().editInviteUser( bool res = await UserPermissionApi().editInviteUser(
userId: event.userId, userId: event.userId,
firstName: firstNameController.text, firstName: firstNameController.text,
jobTitle: jobTitleController.text, jobTitle: jobTitleController.text,
lastName: lastNameController.text, lastName: lastNameController.text,
phoneNumber: phoneController.text, phoneNumber: phoneController.text,
roleUuid: roleSelected, roleUuid: roleSelected,
spaceUuids: selectedIds, spaceUuids: selectedIds,
); projectUuid: projectUuid ?? TempConst.projectId);
if (res == true) { if (res == true) {
showCustomDialog( showCustomDialog(
barrierDismissible: false, barrierDismissible: false,
@ -490,8 +501,11 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
emit(UsersLoadingState()); emit(UsersLoadingState());
try { try {
final projectUuid = projectCubit.state;
if (event.uuid?.isNotEmpty ?? false) { if (event.uuid?.isNotEmpty ?? false) {
final res = await UserPermissionApi().fetchUserById(event.uuid); final res = await UserPermissionApi()
.fetchUserById(event.uuid, projectUuid ?? TempConst.projectId);
if (res != null) { if (res != null) {
// Populate the text controllers // Populate the text controllers

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.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';
@ -23,7 +24,7 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (BuildContext context) => UsersBloc() create: (BuildContext context) => UsersBloc(context.read<ProjectCubit>())
..add(const LoadCommunityAndSpacesEvent()) ..add(const LoadCommunityAndSpacesEvent())
..add(const RoleEvent()), ..add(const RoleEvent()),
child: BlocConsumer<UsersBloc, UsersState>( child: BlocConsumer<UsersBloc, UsersState>(

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.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';
@ -21,7 +22,7 @@ class TreeView extends StatelessWidget {
final _blocRole = BlocProvider.of<UsersBloc>(context); final _blocRole = BlocProvider.of<UsersBloc>(context);
debugPrint('TreeView constructed with userId = $userId'); debugPrint('TreeView constructed with userId = $userId');
return BlocProvider( return BlocProvider(
create: (_) => UsersBloc(), create: (_) => UsersBloc(context.read<ProjectCubit>()),
// ..add(const LoadCommunityAndSpacesEvent()), // ..add(const LoadCommunityAndSpacesEvent()),
child: BlocConsumer<UsersBloc, UsersState>( child: BlocConsumer<UsersBloc, UsersState>(
listener: (context, state) { listener: (context, state) {

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.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';
@ -24,7 +25,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (BuildContext context) => UsersBloc() create: (BuildContext context) => UsersBloc(context.read<ProjectCubit>())
..add(const LoadCommunityAndSpacesEvent()) ..add(const LoadCommunityAndSpacesEvent())
..add(const RoleEvent()) ..add(const RoleEvent())
..add(GetUserByIdEvent(uuid: widget.userId)), ..add(GetUserByIdEvent(uuid: widget.userId)),

View File

@ -1,13 +1,17 @@
import 'dart:async'; import 'dart:async';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/roles_and_permission/model/roles_user_model.dart'; import 'package:syncrow_web/pages/roles_and_permission/model/roles_user_model.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart';
import 'package:syncrow_web/services/user_permission.dart'; import 'package:syncrow_web/services/user_permission.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
class UserTableBloc extends Bloc<UserTableEvent, UserTableState> { class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
UserTableBloc() : super(TableInitial()) { final ProjectCubit _projectCubit;
UserTableBloc(this._projectCubit) : super(TableInitial()) {
on<GetUsers>(_getUsers); on<GetUsers>(_getUsers);
on<ChangeUserStatus>(_changeUserStatus); on<ChangeUserStatus>(_changeUserStatus);
on<SortUsersByNameAsc>(_toggleSortUsersByNameAsc); on<SortUsersByNameAsc>(_toggleSortUsersByNameAsc);
@ -46,10 +50,13 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
Future<void> _getUsers(GetUsers event, Emitter<UserTableState> emit) async { Future<void> _getUsers(GetUsers event, Emitter<UserTableState> emit) async {
emit(UsersLoadingState()); emit(UsersLoadingState());
try { try {
final projectUuid = _projectCubit.state;
roleTypes.clear(); roleTypes.clear();
jobTitle.clear(); jobTitle.clear();
createdBy.clear(); createdBy.clear();
users = await UserPermissionApi().fetchUsers(); users = await UserPermissionApi()
.fetchUsers(projectUuid ?? TempConst.projectId);
users.sort((a, b) { users.sort((a, b) {
final dateA = _parseDateTime(a.createdDate); final dateA = _parseDateTime(a.createdDate);
final dateB = _parseDateTime(b.createdDate); final dateB = _parseDateTime(b.createdDate);
@ -96,9 +103,13 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
Future<void> _changeUserStatus( Future<void> _changeUserStatus(
ChangeUserStatus event, Emitter<UserTableState> emit) async { ChangeUserStatus event, Emitter<UserTableState> emit) async {
try { try {
final projectUuid = _projectCubit.state;
emit(UsersLoadingState()); emit(UsersLoadingState());
bool res = await UserPermissionApi().changeUserStatusById( bool res = await UserPermissionApi().changeUserStatusById(
event.userId, event.newStatus == "disabled" ? false : true); event.userId,
event.newStatus == "disabled" ? false : true,
projectUuid ?? TempConst.projectId);
if (res == true) { if (res == true) {
add(const GetUsers()); add(const GetUsers());
} }

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
import 'package:syncrow_web/pages/roles_and_permission/bloc/roles_permission_bloc.dart'; import 'package:syncrow_web/pages/roles_and_permission/bloc/roles_permission_bloc.dart';
import 'package:syncrow_web/pages/roles_and_permission/bloc/roles_permission_state.dart'; import 'package:syncrow_web/pages/roles_and_permission/bloc/roles_permission_state.dart';
@ -8,7 +9,6 @@ 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,10 +27,11 @@ class RolesAndPermissionPage extends StatelessWidget {
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: WebScaffold( : WebScaffold(
enableMenuSidebar: false, enableMenuSidebar: false,
appBarTitle: Text( appBarTitle: FittedBox(
'Roles & Permissions', child: Text(
style: 'Roles & Permissions',
ResponsiveTextTheme.of(context).deviceManagementTitle, style: Theme.of(context).textTheme.headlineLarge,
),
), ),
rightBody: const NavigateHomeGridView(), rightBody: const NavigateHomeGridView(),
centerBody: Row( centerBody: Row(
@ -76,7 +77,7 @@ class RolesAndPermissionPage extends StatelessWidget {
], ],
), ),
scaffoldBody: BlocProvider<UserTableBloc>( scaffoldBody: BlocProvider<UserTableBloc>(
create: (context) => UserTableBloc()..add(const GetUsers()), create: (context) => UserTableBloc(context.read<ProjectCubit>())..add(const GetUsers()),
child: UsersPage(), child: UsersPage(),
) )
// _blocRole.tapSelect == false // _blocRole.tapSelect == false

View File

@ -3,6 +3,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:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart'; import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart'; import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart';
@ -13,6 +14,7 @@ import 'package:syncrow_web/pages/routines/models/routine_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart'; import 'package:syncrow_web/services/devices_mang_api.dart';
import 'package:syncrow_web/services/routines_api.dart'; import 'package:syncrow_web/services/routines_api.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
import 'package:syncrow_web/utils/snack_bar.dart'; import 'package:syncrow_web/utils/snack_bar.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -23,7 +25,9 @@ String spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
String communityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9'; String communityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> { class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
RoutineBloc() : super(const RoutineState()) { final ProjectCubit projectCubit;
RoutineBloc(this.projectCubit) : super(const RoutineState()) {
on<AddToIfContainer>(_onAddToIfContainer); on<AddToIfContainer>(_onAddToIfContainer);
on<AddToThenContainer>(_onAddToThenContainer); on<AddToThenContainer>(_onAddToThenContainer);
on<LoadScenes>(_onLoadScenes); on<LoadScenes>(_onLoadScenes);
@ -54,7 +58,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
TriggerSwitchTabsEvent event, TriggerSwitchTabsEvent event,
Emitter<RoutineState> emit, Emitter<RoutineState> emit,
) { ) {
emit(state.copyWith(routineTab: event.isRoutineTab, createRoutineView: false)); emit(state.copyWith(
routineTab: event.isRoutineTab, createRoutineView: false));
add(ResetRoutineState()); add(ResetRoutineState());
if (event.isRoutineTab) { if (event.isRoutineTab) {
add(LoadScenes(spaceId, communityId)); add(LoadScenes(spaceId, communityId));
@ -80,8 +85,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems); final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems);
// Find the index of the item in teh current itemsList // Find the index of the item in teh current itemsList
int index = int index = updatedIfItems.indexWhere(
updatedIfItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
// Replace the map if the index is valid // Replace the map if the index is valid
if (index != -1) { if (index != -1) {
updatedIfItems[index] = event.item; updatedIfItems[index] = event.item;
@ -90,18 +95,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
if (event.isTabToRun) { if (event.isTabToRun) {
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: true, isAutomation: false)); emit(state.copyWith(
ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
} else { } else {
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: false, isAutomation: true)); emit(state.copyWith(
ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
} }
} }
void _onAddToThenContainer(AddToThenContainer event, Emitter<RoutineState> emit) { void _onAddToThenContainer(
AddToThenContainer event, Emitter<RoutineState> emit) {
final currentItems = List<Map<String, dynamic>>.from(state.thenItems); final currentItems = List<Map<String, dynamic>>.from(state.thenItems);
// Find the index of the item in teh current itemsList // Find the index of the item in teh current itemsList
int index = int index = currentItems.indexWhere(
currentItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
// Replace the map if the index is valid // Replace the map if the index is valid
if (index != -1) { if (index != -1) {
currentItems[index] = event.item; currentItems[index] = event.item;
@ -112,22 +120,26 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
emit(state.copyWith(thenItems: currentItems)); emit(state.copyWith(thenItems: currentItems));
} }
void _onAddFunctionsToRoutine(AddFunctionToRoutine event, Emitter<RoutineState> emit) { void _onAddFunctionsToRoutine(
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
try { try {
if (event.functions.isEmpty) return; if (event.functions.isEmpty) return;
List<DeviceFunctionData> selectedFunction = List<DeviceFunctionData>.from(event.functions); List<DeviceFunctionData> selectedFunction =
List<DeviceFunctionData>.from(event.functions);
Map<String, List<DeviceFunctionData>> currentSelectedFunctions = Map<String, List<DeviceFunctionData>> currentSelectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions); Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) { if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
List<DeviceFunctionData> currentFunctions = List<DeviceFunctionData> currentFunctions =
List<DeviceFunctionData>.from(currentSelectedFunctions[event.uniqueCustomId] ?? []); List<DeviceFunctionData>.from(
currentSelectedFunctions[event.uniqueCustomId] ?? []);
List<String> functionCode = []; List<String> functionCode = [];
for (int i = 0; i < selectedFunction.length; i++) { for (int i = 0; i < selectedFunction.length; i++) {
for (int j = 0; j < currentFunctions.length; j++) { for (int j = 0; j < currentFunctions.length; j++) {
if (selectedFunction[i].functionCode == currentFunctions[j].functionCode) { if (selectedFunction[i].functionCode ==
currentFunctions[j].functionCode) {
currentFunctions[j] = selectedFunction[i]; currentFunctions[j] = selectedFunction[i];
if (!functionCode.contains(currentFunctions[j].functionCode)) { if (!functionCode.contains(currentFunctions[j].functionCode)) {
functionCode.add(currentFunctions[j].functionCode); functionCode.add(currentFunctions[j].functionCode);
@ -137,13 +149,15 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
for (int i = 0; i < functionCode.length; i++) { for (int i = 0; i < functionCode.length; i++) {
selectedFunction.removeWhere((code) => code.functionCode == functionCode[i]); selectedFunction
.removeWhere((code) => code.functionCode == functionCode[i]);
} }
currentSelectedFunctions[event.uniqueCustomId] = List.from(currentFunctions) currentSelectedFunctions[event.uniqueCustomId] =
..addAll(selectedFunction); List.from(currentFunctions)..addAll(selectedFunction);
} else { } else {
currentSelectedFunctions[event.uniqueCustomId] = List.from(event.functions); currentSelectedFunctions[event.uniqueCustomId] =
List.from(event.functions);
} }
emit(state.copyWith(selectedFunctions: currentSelectedFunctions)); emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
@ -152,17 +166,20 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
Future<void> _onLoadScenes(LoadScenes event, Emitter<RoutineState> emit) async { Future<void> _onLoadScenes(
LoadScenes event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null)); emit(state.copyWith(isLoading: true, errorMessage: null));
try { try {
final projectUuid = projectCubit.state;
spaceId = event.spaceId; spaceId = event.spaceId;
communityId = event.communityId; communityId = event.communityId;
List<ScenesModel> scenes = []; List<ScenesModel> scenes = [];
if (communityId.isNotEmpty && spaceId.isNotEmpty) { if (communityId.isNotEmpty && spaceId.isNotEmpty) {
scenes = await SceneApi.getScenes(event.spaceId, event.communityId); scenes = await SceneApi.getScenes(event.spaceId, event.communityId, projectUuid ?? TempConst.projectId);
} }
emit(state.copyWith( emit(state.copyWith(
scenes: scenes, scenes: scenes,
@ -178,7 +195,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<RoutineState> emit) async { Future<void> _onLoadAutomation(
LoadAutomation event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null)); emit(state.copyWith(isLoading: true, errorMessage: null));
try { try {
@ -201,14 +219,16 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onSearchRoutines(SearchRoutines event, Emitter<RoutineState> emit) async { FutureOr<void> _onSearchRoutines(
SearchRoutines event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null)); emit(state.copyWith(isLoading: true, errorMessage: null));
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(state.copyWith(isLoading: false, errorMessage: null)); emit(state.copyWith(isLoading: false, errorMessage: null));
emit(state.copyWith(searchText: event.query)); emit(state.copyWith(searchText: event.query));
} }
FutureOr<void> _onAddSelectedIcon(AddSelectedIcon event, Emitter<RoutineState> emit) { FutureOr<void> _onAddSelectedIcon(
AddSelectedIcon event, Emitter<RoutineState> emit) {
emit(state.copyWith(selectedIcon: event.icon)); emit(state.copyWith(selectedIcon: event.icon));
} }
@ -222,7 +242,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
return actions.last['deviceId'] == 'delay'; return actions.last['deviceId'] == 'delay';
} }
Future<void> _onCreateScene(CreateSceneEvent event, Emitter<RoutineState> emit) async { Future<void> _onCreateScene(
CreateSceneEvent event, Emitter<RoutineState> emit) async {
try { try {
// Check if first action is delay // Check if first action is delay
// if (_isFirstActionDelay(state.thenItems)) { // if (_isFirstActionDelay(state.thenItems)) {
@ -235,7 +256,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (_isLastActionDelay(state.thenItems)) { if (_isLastActionDelay(state.thenItems)) {
emit(state.copyWith( emit(state.copyWith(
errorMessage: 'A delay condition cannot be the only or the last action', errorMessage:
'A delay condition cannot be the only or the last action',
isLoading: false, isLoading: false,
)); ));
return; return;
@ -308,7 +330,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
Future<void> _onCreateAutomation(CreateAutomationEvent event, Emitter<RoutineState> emit) async { Future<void> _onCreateAutomation(
CreateAutomationEvent event, Emitter<RoutineState> emit) async {
try { try {
if (state.routineName == null || state.routineName!.isEmpty) { if (state.routineName == null || state.routineName!.isEmpty) {
emit(state.copyWith( emit(state.copyWith(
@ -329,7 +352,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (_isLastActionDelay(state.thenItems)) { if (_isLastActionDelay(state.thenItems)) {
emit(state.copyWith( emit(state.copyWith(
errorMessage: 'A delay condition cannot be the only or the last action', errorMessage:
'A delay condition cannot be the only or the last action',
isLoading: false, isLoading: false,
)); ));
CustomSnackBar.redSnackBar('Cannot have delay as the last action'); CustomSnackBar.redSnackBar('Cannot have delay as the last action');
@ -439,17 +463,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onRemoveDragCard(RemoveDragCard event, Emitter<RoutineState> emit) { FutureOr<void> _onRemoveDragCard(
RemoveDragCard event, Emitter<RoutineState> emit) {
if (event.isFromThen) { if (event.isFromThen) {
final thenItems = List<Map<String, dynamic>>.from(state.thenItems); final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions); final selectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
thenItems.removeAt(event.index); thenItems.removeAt(event.index);
selectedFunctions.remove(event.key); selectedFunctions.remove(event.key);
emit(state.copyWith(thenItems: thenItems, selectedFunctions: selectedFunctions)); emit(state.copyWith(
thenItems: thenItems, selectedFunctions: selectedFunctions));
} else { } else {
final ifItems = List<Map<String, dynamic>>.from(state.ifItems); final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions); final selectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
ifItems.removeAt(event.index); ifItems.removeAt(event.index);
selectedFunctions.remove(event.key); selectedFunctions.remove(event.key);
@ -460,7 +488,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
isAutomation: false, isAutomation: false,
isTabToRun: false)); isTabToRun: false));
} else { } else {
emit(state.copyWith(ifItems: ifItems, selectedFunctions: selectedFunctions)); emit(state.copyWith(
ifItems: ifItems, selectedFunctions: selectedFunctions));
} }
} }
} }
@ -472,18 +501,23 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
)); ));
} }
FutureOr<void> _onEffectiveTimeEvent(EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) { FutureOr<void> _onEffectiveTimeEvent(
EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
emit(state.copyWith(effectiveTime: event.effectiveTime)); emit(state.copyWith(effectiveTime: event.effectiveTime));
} }
FutureOr<void> _onSetRoutineName(SetRoutineName event, Emitter<RoutineState> emit) { FutureOr<void> _onSetRoutineName(
SetRoutineName event, Emitter<RoutineState> emit) {
emit(state.copyWith( emit(state.copyWith(
routineName: event.name, routineName: event.name,
)); ));
} }
(List<Map<String, dynamic>>, List<Map<String, dynamic>>, Map<String, List<DeviceFunctionData>>) (
_createCardData( List<Map<String, dynamic>>,
List<Map<String, dynamic>>,
Map<String, List<DeviceFunctionData>>
) _createCardData(
List<RoutineAction> actions, List<RoutineAction> actions,
List<RoutineCondition>? conditions, List<RoutineCondition>? conditions,
Map<String, List<DeviceFunctionData>> currentFunctions, Map<String, List<DeviceFunctionData>> currentFunctions,
@ -516,7 +550,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
'deviceId': condition.entityId, 'deviceId': condition.entityId,
'title': matchingDevice.name ?? condition.entityId, 'title': matchingDevice.name ?? condition.entityId,
'productType': condition.entityType, 'productType': condition.entityType,
'imagePath': matchingDevice.getDefaultIcon(condition.entityType), 'imagePath':
matchingDevice.getDefaultIcon(condition.entityType),
}; };
final functions = matchingDevice.functions; final functions = matchingDevice.functions;
@ -552,8 +587,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final cardData = { final cardData = {
'entityId': action.entityId, 'entityId': action.entityId,
'uniqueCustomId': const Uuid().v4(), 'uniqueCustomId': const Uuid().v4(),
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId, 'deviceId':
'title': action.actionExecutor == 'delay' ? 'Delay' : (matchingDevice.name ?? 'Device'), action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'title': action.actionExecutor == 'delay'
? 'Delay'
: (matchingDevice.name ?? 'Device'),
'productType': action.productType, 'productType': action.productType,
'imagePath': matchingDevice.getDefaultIcon(action.productType), 'imagePath': matchingDevice.getDefaultIcon(action.productType),
}; };
@ -596,7 +634,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
return (thenItems, ifItems, currentFunctions); return (thenItems, ifItems, currentFunctions);
} }
Future<void> _onGetSceneDetails(GetSceneDetails event, Emitter<RoutineState> emit) async { Future<void> _onGetSceneDetails(
GetSceneDetails event, Emitter<RoutineState> emit) async {
try { try {
emit(state.copyWith( emit(state.copyWith(
isLoading: true, isLoading: true,
@ -644,10 +683,12 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (!deviceCards.containsKey(deviceId)) { if (!deviceCards.containsKey(deviceId)) {
deviceCards[deviceId] = { deviceCards[deviceId] = {
'entityId': action.entityId, 'entityId': action.entityId,
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId, 'deviceId':
'uniqueCustomId': action.type == 'automation' || action.actionExecutor == 'delay' action.actionExecutor == 'delay' ? 'delay' : action.entityId,
? const Uuid().v4() 'uniqueCustomId':
: action.entityId, action.type == 'automation' || action.actionExecutor == 'delay'
? const Uuid().v4()
: action.entityId,
'title': action.actionExecutor == 'delay' 'title': action.actionExecutor == 'delay'
? 'Delay' ? 'Delay'
: action.type == 'automation' : action.type == 'automation'
@ -682,7 +723,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
), ),
); );
// emit(state.copyWith(automationActionExecutor: action.actionExecutor)); // emit(state.copyWith(automationActionExecutor: action.actionExecutor));
} else if (action.executorProperty != null && action.actionExecutor != 'delay') { } else if (action.executorProperty != null &&
action.actionExecutor != 'delay') {
if (!updatedFunctions.containsKey(uniqueCustomId)) { if (!updatedFunctions.containsKey(uniqueCustomId)) {
updatedFunctions[uniqueCustomId] = []; updatedFunctions[uniqueCustomId] = [];
} }
@ -754,7 +796,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onResetRoutineState(ResetRoutineState event, Emitter<RoutineState> emit) { FutureOr<void> _onResetRoutineState(
ResetRoutineState event, Emitter<RoutineState> emit) {
emit(state.copyWith( emit(state.copyWith(
ifItems: [], ifItems: [],
thenItems: [], thenItems: [],
@ -784,7 +827,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (state.isTabToRun) { if (state.isTabToRun) {
SceneApi.deleteScene(unitUuid: spaceId, sceneId: state.sceneId ?? ''); SceneApi.deleteScene(unitUuid: spaceId, sceneId: state.sceneId ?? '');
} else { } else {
SceneApi.deleteAutomation(unitUuid: spaceId, automationId: state.automationId ?? ''); SceneApi.deleteAutomation(
unitUuid: spaceId, automationId: state.automationId ?? '');
} }
add(LoadScenes(spaceId, communityId)); add(LoadScenes(spaceId, communityId));
@ -813,10 +857,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
// } // }
// } // }
FutureOr<void> _fetchDevices(FetchDevicesInRoutine event, Emitter<RoutineState> emit) async { FutureOr<void> _fetchDevices(
FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true)); emit(state.copyWith(isLoading: true));
try { try {
final devices = await DevicesManagementApi().fetchDevices('', ''); final projectUuid = projectCubit.state;
final devices = await DevicesManagementApi()
.fetchDevices('', '', projectUuid ?? TempConst.projectId);
emit(state.copyWith(isLoading: false, devices: devices)); emit(state.copyWith(isLoading: false, devices: devices));
} catch (e) { } catch (e) {
@ -824,7 +871,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onUpdateScene(UpdateScene event, Emitter<RoutineState> emit) async { FutureOr<void> _onUpdateScene(
UpdateScene event, Emitter<RoutineState> emit) async {
try { try {
// Check if first action is delay // Check if first action is delay
// if (_isFirstActionDelay(state.thenItems)) { // if (_isFirstActionDelay(state.thenItems)) {
@ -838,7 +886,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (_isLastActionDelay(state.thenItems)) { if (_isLastActionDelay(state.thenItems)) {
emit(state.copyWith( emit(state.copyWith(
errorMessage: 'A delay condition cannot be the only or the last action', errorMessage:
'A delay condition cannot be the only or the last action',
isLoading: false, isLoading: false,
)); ));
return; return;
@ -891,7 +940,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
actions: actions, actions: actions,
); );
final result = await SceneApi.updateScene(createSceneModel, state.sceneId ?? ''); final result =
await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
if (result['success']) { if (result['success']) {
add(ResetRoutineState()); add(ResetRoutineState());
add(LoadScenes(spaceId, communityId)); add(LoadScenes(spaceId, communityId));
@ -910,7 +960,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onUpdateAutomation(UpdateAutomation event, Emitter<RoutineState> emit) async { FutureOr<void> _onUpdateAutomation(
UpdateAutomation event, Emitter<RoutineState> emit) async {
try { try {
if (state.routineName == null || state.routineName!.isEmpty) { if (state.routineName == null || state.routineName!.isEmpty) {
emit(state.copyWith( emit(state.copyWith(
@ -1018,8 +1069,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
actions: actions, actions: actions,
); );
final result = final result = await SceneApi.updateAutomation(
await SceneApi.updateAutomation(createAutomationModel, state.automationId ?? ''); createAutomationModel, state.automationId ?? '');
if (result['success']) { if (result['success']) {
add(ResetRoutineState()); add(ResetRoutineState());
@ -1052,7 +1103,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
thenItems: [], thenItems: [],
)); ));
final automationDetails = await SceneApi.getAutomationDetails(event.automationId); final automationDetails =
await SceneApi.getAutomationDetails(event.automationId);
final Map<String, Map<String, dynamic>> deviceIfCards = {}; final Map<String, Map<String, dynamic>> deviceIfCards = {};
final Map<String, Map<String, dynamic>> deviceThenCards = {}; final Map<String, Map<String, dynamic>> deviceThenCards = {};
@ -1120,13 +1172,15 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
), ),
); );
final deviceId = final deviceId = action.actionExecutor == 'delay'
action.actionExecutor == 'delay' ? '${action.entityId}_delay' : action.entityId; ? '${action.entityId}_delay'
: action.entityId;
if (!deviceThenCards.containsKey(deviceId)) { if (!deviceThenCards.containsKey(deviceId)) {
deviceThenCards[deviceId] = { deviceThenCards[deviceId] = {
'entityId': action.entityId, 'entityId': action.entityId,
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId, 'deviceId':
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'uniqueCustomId': const Uuid().v4(), 'uniqueCustomId': const Uuid().v4(),
'title': action.actionExecutor == 'delay' 'title': action.actionExecutor == 'delay'
? 'Delay' ? 'Delay'
@ -1157,7 +1211,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
updatedFunctions[uniqueCustomId] = []; updatedFunctions[uniqueCustomId] = [];
} }
if (action.executorProperty != null && action.actionExecutor != 'delay') { if (action.executorProperty != null &&
action.actionExecutor != 'delay') {
final functions = matchingDevice.functions; final functions = matchingDevice.functions;
final functionCode = action.executorProperty!.functionCode; final functionCode = action.executorProperty!.functionCode;
for (var function in functions) { for (var function in functions) {
@ -1199,10 +1254,14 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
final ifItems = deviceIfCards.values.where((card) => card['type'] == 'condition').toList(); final ifItems = deviceIfCards.values
.where((card) => card['type'] == 'condition')
.toList();
final thenItems = deviceThenCards.values final thenItems = deviceThenCards.values
.where((card) => .where((card) =>
card['type'] == 'action' || card['type'] == 'automation' || card['type'] == 'scene') card['type'] == 'action' ||
card['type'] == 'automation' ||
card['type'] == 'scene')
.toList(); .toList();
emit(state.copyWith( emit(state.copyWith(

View File

@ -1,15 +1,18 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.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';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart'; 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/temp_const.dart';
class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> { class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
String selectedCommunityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9'; String selectedCommunityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
String selectedSpaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6'; String selectedSpaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
final ProjectCubit projectCubit;
SpaceTreeBloc() : super(const SpaceTreeState()) { SpaceTreeBloc(this.projectCubit) : super(const SpaceTreeState()) {
on<InitialEvent>(_fetchSpaces); on<InitialEvent>(_fetchSpaces);
on<OnCommunityExpanded>(_onCommunityExpanded); on<OnCommunityExpanded>(_onCommunityExpanded);
on<OnSpaceExpanded>(_onSpaceExpanded); on<OnSpaceExpanded>(_onSpaceExpanded);
@ -21,12 +24,16 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
_fetchSpaces(InitialEvent event, Emitter<SpaceTreeState> emit) async { _fetchSpaces(InitialEvent event, Emitter<SpaceTreeState> emit) async {
emit(SpaceTreeLoadingState()); emit(SpaceTreeLoadingState());
try { try {
List<CommunityModel> communities = await CommunitySpaceManagementApi().fetchCommunities(); final projectUuid = projectCubit.state;
List<CommunityModel> communities = await CommunitySpaceManagementApi()
.fetchCommunities(projectUuid ?? TempConst.projectId);
List<CommunityModel> updatedCommunities = await Future.wait( List<CommunityModel> updatedCommunities = await Future.wait(
communities.map((community) async { communities.map((community) async {
List<SpaceModel> spaces = List<SpaceModel> spaces = await CommunitySpaceManagementApi()
await CommunitySpaceManagementApi().getSpaceHierarchy(community.uuid); .getSpaceHierarchy(
community.uuid, projectUuid ?? TempConst.projectId);
return CommunityModel( return CommunityModel(
uuid: community.uuid, uuid: community.uuid,
@ -41,15 +48,19 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
); );
emit(state.copyWith( emit(state.copyWith(
communitiesList: updatedCommunities, expandedCommunity: [], expandedSpaces: [])); communitiesList: updatedCommunities,
expandedCommunity: [],
expandedSpaces: []));
} catch (e) { } catch (e) {
emit(SpaceTreeErrorState('Error loading communities and spaces: $e')); emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
} }
} }
_onCommunityExpanded(OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async { _onCommunityExpanded(
OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
try { try {
List<String> updatedExpandedCommunityList = List.from(state.expandedCommunities); List<String> updatedExpandedCommunityList =
List.from(state.expandedCommunities);
if (updatedExpandedCommunityList.contains(event.communityId)) { if (updatedExpandedCommunityList.contains(event.communityId)) {
updatedExpandedCommunityList.remove(event.communityId); updatedExpandedCommunityList.remove(event.communityId);
@ -81,13 +92,17 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
} }
} }
_onCommunitySelected(OnCommunitySelected event, Emitter<SpaceTreeState> emit) async { _onCommunitySelected(
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.from(state.selectedSpaces.toSet().toList()); List<String> updatedSelectedSpaces =
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); List.from(state.selectedSpaces.toSet().toList());
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces); List<String> updatedSoldChecks =
List.from(state.soldCheck.toSet().toList());
Map<String, List<String>> communityAndSpaces =
Map.from(state.selectedCommunityAndSpaces);
List<String> childrenIds = _getAllChildIds(event.children); List<String> childrenIds = _getAllChildIds(event.children);
@ -118,9 +133,12 @@ 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.from(state.selectedSpaces.toSet().toList()); List<String> updatedSelectedSpaces =
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); List.from(state.selectedSpaces.toSet().toList());
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces); List<String> updatedSoldChecks =
List.from(state.soldCheck.toSet().toList());
Map<String, List<String>> communityAndSpaces =
Map.from(state.selectedCommunityAndSpaces);
List<String> childrenIds = _getAllChildIds(event.children); List<String> childrenIds = _getAllChildIds(event.children);
bool isChildSelected = false; bool isChildSelected = false;
@ -140,9 +158,11 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
updatedSelectedSpaces.addAll(childrenIds); updatedSelectedSpaces.addAll(childrenIds);
} }
List<String> spaces = _getThePathToChild(event.communityId, event.spaceId); List<String> spaces =
_getThePathToChild(event.communityId, event.spaceId);
for (String space in spaces) { for (String space in spaces) {
if (!updatedSelectedSpaces.contains(space) && !updatedSoldChecks.contains(space)) { if (!updatedSelectedSpaces.contains(space) &&
!updatedSoldChecks.contains(space)) {
updatedSoldChecks.add(space); updatedSoldChecks.add(space);
} }
} }
@ -161,7 +181,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
} }
updatedSoldChecks.remove(event.spaceId); updatedSoldChecks.remove(event.spaceId);
List<String> parents = _getThePathToChild(event.communityId, event.spaceId); List<String> parents =
_getThePathToChild(event.communityId, event.spaceId);
if (!_parentSelected(parents, updatedSelectedSpaces)) { if (!_parentSelected(parents, updatedSelectedSpaces)) {
updatedSoldChecks.removeWhere(parents.contains); updatedSoldChecks.removeWhere(parents.contains);
} }
@ -200,16 +221,18 @@ 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 = final containsQueryInCommunity = community.name
community.name.toLowerCase().contains(event.searchQuery.toLowerCase()); .toLowerCase()
final containsQueryInSpaces = .contains(event.searchQuery.toLowerCase());
community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase())); final containsQueryInSpaces = community.spaces.any(
(space) => _containsQuery(space, event.searchQuery.toLowerCase()));
return containsQueryInCommunity || containsQueryInSpaces; return containsQueryInCommunity || containsQueryInSpaces;
}).toList(); }).toList();
emit(state.copyWith( emit(state.copyWith(
filteredCommunity: filteredCommunity, isSearching: event.searchQuery.isNotEmpty)); filteredCommunity: filteredCommunity,
isSearching: event.searchQuery.isNotEmpty));
} catch (e) { } catch (e) {
emit(const SpaceTreeErrorState('Something went wrong')); emit(const SpaceTreeErrorState('Something went wrong'));
} }
@ -218,8 +241,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
// 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 = final matchesChildren = space.children.any((child) =>
space.children.any((child) => _containsQuery(child, query)); // Recursive check for children _containsQuery(child, query)); // Recursive check for children
return matchesSpace || matchesChildren; return matchesSpace || matchesChildren;
} }
@ -233,14 +256,15 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
return ids; return ids;
} }
bool _anySpacesSelectedInCommunity( bool _anySpacesSelectedInCommunity(String communityId,
String communityId, List<String> selectedSpaces, List<String> partialCheckedList) { List<String> selectedSpaces, List<String> partialCheckedList) {
bool result = false; bool result = false;
for (var community in state.communityList) { for (var community in state.communityList) {
if (community.uuid == communityId) { 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 = selectedSpaces.contains(id) || partialCheckedList.contains(id); result =
selectedSpaces.contains(id) || partialCheckedList.contains(id);
if (result) { if (result) {
return result; return result;
} }
@ -267,7 +291,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
return ids; return ids;
} }
List<String> _getAllParentsIds(SpaceModel child, String spaceId, List<String> listIds) { List<String> _getAllParentsIds(
SpaceModel child, String spaceId, List<String> listIds) {
List<String> ids = listIds; List<String> ids = listIds;
ids.add(child.uuid ?? ''); ids.add(child.uuid ?? '');

View File

@ -1,4 +1,5 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.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/create_subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_model.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
@ -14,16 +15,19 @@ 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/constants/action_enum.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
class SpaceManagementBloc class SpaceManagementBloc
extends Bloc<SpaceManagementEvent, SpaceManagementState> { extends Bloc<SpaceManagementEvent, SpaceManagementState> {
final CommunitySpaceManagementApi _api; final CommunitySpaceManagementApi _api;
final ProductApi _productApi; final ProductApi _productApi;
final SpaceModelManagementApi _spaceModelApi; final SpaceModelManagementApi _spaceModelApi;
final ProjectCubit projectCubit;
List<ProductModel>? _cachedProducts; List<ProductModel>? _cachedProducts;
SpaceManagementBloc(this._api, this._productApi, this._spaceModelApi) SpaceManagementBloc(
this._api, this._productApi, this._spaceModelApi, this.projectCubit)
: super(SpaceManagementInitial()) { : super(SpaceManagementInitial()) {
on<LoadCommunityAndSpacesEvent>(_onLoadCommunityAndSpaces); on<LoadCommunityAndSpacesEvent>(_onLoadCommunityAndSpaces);
on<UpdateSpacePositionEvent>(_onUpdateSpacePosition); on<UpdateSpacePositionEvent>(_onUpdateSpacePosition);
@ -45,9 +49,11 @@ class SpaceManagementBloc
) async { ) async {
final previousState = state; final previousState = state;
try { try {
final projectUuid = projectCubit.state;
emit(SpaceManagementLoading()); emit(SpaceManagementLoading());
final success = final success = await _api.updateCommunity(
await _api.updateCommunity(event.communityUuid, event.name); event.communityUuid, event.name, projectUuid ?? TempConst.projectId);
if (success) { if (success) {
if (previousState is SpaceManagementLoaded) { if (previousState is SpaceManagementLoaded) {
final updatedCommunities = final updatedCommunities =
@ -79,6 +85,8 @@ class SpaceManagementBloc
Future<List<SpaceTemplateModel>> fetchSpaceModels( Future<List<SpaceTemplateModel>> fetchSpaceModels(
SpaceManagementState previousState) async { SpaceManagementState previousState) async {
try { try {
final projectUuid = projectCubit.state;
List<SpaceTemplateModel> allSpaces = []; List<SpaceTemplateModel> allSpaces = [];
List<SpaceTemplateModel> prevSpaceModels = []; List<SpaceTemplateModel> prevSpaceModels = [];
@ -95,7 +103,8 @@ class SpaceManagementBloc
int page = 1; int page = 1;
while (hasNext) { while (hasNext) {
final spaces = await _spaceModelApi.listSpaceModels(page: page); final spaces = await _spaceModelApi.listSpaceModels(
page: page, projectId: projectUuid ?? TempConst.projectId);
if (spaces.isNotEmpty) { if (spaces.isNotEmpty) {
allSpaces.addAll(spaces); allSpaces.addAll(spaces);
page++; page++;
@ -103,7 +112,8 @@ class SpaceManagementBloc
hasNext = false; hasNext = false;
} }
} }
prevSpaceModels = await _spaceModelApi.listSpaceModels(page: 1); prevSpaceModels = await _spaceModelApi.listSpaceModels(
page: 1, projectId: projectUuid ?? TempConst.projectId);
} }
return allSpaces; return allSpaces;
@ -132,7 +142,10 @@ class SpaceManagementBloc
Future<List<SpaceModel>> _fetchSpacesForCommunity( Future<List<SpaceModel>> _fetchSpacesForCommunity(
String communityUuid) async { String communityUuid) async {
return await _api.getSpaceHierarchy(communityUuid); final projectUuid = projectCubit.state;
return await _api.getSpaceHierarchy(
communityUuid, projectUuid ?? TempConst.projectId);
} }
Future<void> _onNewCommunity( Future<void> _onNewCommunity(
@ -163,6 +176,8 @@ class SpaceManagementBloc
BlankStateEvent event, Emitter<SpaceManagementState> emit) async { BlankStateEvent event, Emitter<SpaceManagementState> emit) async {
try { try {
final previousState = state; final previousState = state;
final projectUuid = projectCubit.state;
var prevSpaceModels = await fetchSpaceModels(previousState); var prevSpaceModels = await fetchSpaceModels(previousState);
if (previousState is SpaceManagementLoaded || if (previousState is SpaceManagementLoaded ||
@ -176,7 +191,8 @@ class SpaceManagementBloc
return; return;
} }
final communities = await _api.fetchCommunities(); final communities =
await _api.fetchCommunities(projectUuid ?? TempConst.projectId);
final updatedCommunities = final updatedCommunities =
await Future.wait(communities.map((community) async { await Future.wait(communities.map((community) async {
final spaces = await _fetchSpacesForCommunity(community.uuid); final spaces = await _fetchSpacesForCommunity(community.uuid);
@ -209,8 +225,11 @@ class SpaceManagementBloc
var prevState = state; var prevState = state;
emit(SpaceManagementLoading()); emit(SpaceManagementLoading());
try { try {
final projectUuid = projectCubit.state;
_onloadProducts(); _onloadProducts();
List<CommunityModel> communities = await _api.fetchCommunities(); List<CommunityModel> communities =
await _api.fetchCommunities(projectUuid ?? TempConst.projectId);
List<CommunityModel> updatedCommunities = await Future.wait( List<CommunityModel> updatedCommunities = await Future.wait(
communities.map((community) async { communities.map((community) async {
@ -244,8 +263,10 @@ class SpaceManagementBloc
) async { ) async {
try { try {
emit(SpaceManagementLoading()); emit(SpaceManagementLoading());
final projectUuid = projectCubit.state;
final success = await _api.deleteCommunity(event.communityUuid); final success = await _api.deleteCommunity(
event.communityUuid, projectUuid ?? TempConst.projectId);
if (success) { if (success) {
add(LoadCommunityAndSpacesEvent()); add(LoadCommunityAndSpacesEvent());
} else { } else {
@ -270,8 +291,9 @@ class SpaceManagementBloc
emit(SpaceManagementLoading()); emit(SpaceManagementLoading());
try { try {
CommunityModel? newCommunity = final projectUuid = projectCubit.state;
await _api.createCommunity(event.name, event.description); CommunityModel? newCommunity = await _api.createCommunity(
event.name, event.description, projectUuid ?? TempConst.projectId);
var prevSpaceModels = await fetchSpaceModels(previousState); var prevSpaceModels = await fetchSpaceModels(previousState);
if (newCommunity != null) { if (newCommunity != null) {
@ -414,6 +436,7 @@ class SpaceManagementBloc
Future<List<SpaceModel>> saveSpacesHierarchically( Future<List<SpaceModel>> saveSpacesHierarchically(
List<SpaceModel> spaces, String communityUuid) async { List<SpaceModel> spaces, String communityUuid) async {
final orderedSpaces = flattenHierarchy(spaces); final orderedSpaces = flattenHierarchy(spaces);
final projectUuid = projectCubit.state;
final parentsToDelete = orderedSpaces.where((space) => final parentsToDelete = orderedSpaces.where((space) =>
space.status == SpaceStatus.deleted && space.status == SpaceStatus.deleted &&
@ -422,7 +445,8 @@ class SpaceManagementBloc
for (var parent in parentsToDelete) { for (var parent in parentsToDelete) {
try { try {
if (parent.uuid != null) { if (parent.uuid != null) {
await _api.deleteSpace(communityUuid, parent.uuid!); await _api.deleteSpace(
communityUuid, parent.uuid!, projectUuid ?? TempConst.projectId);
} }
} catch (e) { } catch (e) {
rethrow; rethrow;
@ -435,7 +459,8 @@ class SpaceManagementBloc
if (space.uuid != null && space.uuid!.isNotEmpty) { if (space.uuid != null && space.uuid!.isNotEmpty) {
List<TagModelUpdate> tagUpdates = []; List<TagModelUpdate> tagUpdates = [];
final prevSpace = await _api.getSpace(communityUuid, space.uuid!); final prevSpace = await _api.getSpace(
communityUuid, space.uuid!, projectUuid ?? TempConst.projectId);
final List<UpdateSubspaceTemplateModel> subspaceUpdates = []; final List<UpdateSubspaceTemplateModel> subspaceUpdates = [];
final List<SubspaceModel>? prevSubspaces = prevSpace?.subspaces; final List<SubspaceModel>? prevSubspaces = prevSpace?.subspaces;
final List<SubspaceModel>? newSubspaces = space.subspaces; final List<SubspaceModel>? newSubspaces = space.subspaces;
@ -504,17 +529,17 @@ class SpaceManagementBloc
} }
final response = await _api.updateSpace( final response = await _api.updateSpace(
communityId: communityUuid, communityId: communityUuid,
spaceId: space.uuid!, spaceId: space.uuid!,
name: space.name, name: space.name,
parentId: space.parent?.uuid, parentId: space.parent?.uuid,
isPrivate: space.isPrivate, isPrivate: space.isPrivate,
position: space.position, position: space.position,
icon: space.icon, icon: space.icon,
subspaces: subspaceUpdates, subspaces: subspaceUpdates,
tags: tagUpdates, tags: tagUpdates,
direction: space.incomingConnection?.direction, direction: space.incomingConnection?.direction,
); projectId: projectUuid ?? TempConst.projectId);
} else { } else {
// Call create if the space does not have a UUID // Call create if the space does not have a UUID
final List<CreateTagBodyModel> tagBodyModels = space.tags != null final List<CreateTagBodyModel> tagBodyModels = space.tags != null
@ -533,17 +558,17 @@ class SpaceManagementBloc
[]; [];
final response = await _api.createSpace( final response = await _api.createSpace(
communityId: communityUuid, communityId: communityUuid,
name: space.name, name: space.name,
parentId: space.parent?.uuid, parentId: space.parent?.uuid,
isPrivate: space.isPrivate, isPrivate: space.isPrivate,
position: space.position, position: space.position,
icon: space.icon, icon: space.icon,
direction: space.incomingConnection?.direction, direction: space.incomingConnection?.direction,
spaceModelUuid: space.spaceModel?.uuid, spaceModelUuid: space.spaceModel?.uuid,
tags: tagBodyModels, tags: tagBodyModels,
subspaces: createSubspaceBodyModels, subspaces: createSubspaceBodyModels,
); projectId: projectUuid ?? TempConst.projectId);
space.uuid = response?.uuid; space.uuid = response?.uuid;
} }
} catch (e) { } catch (e) {
@ -583,8 +608,10 @@ class SpaceManagementBloc
emit(SpaceManagementLoading()); emit(SpaceManagementLoading());
try { try {
var prevState = state; var prevState = state;
final projectUuid = projectCubit.state;
List<CommunityModel> communities = await _api.fetchCommunities(); List<CommunityModel> communities =
await _api.fetchCommunities(projectUuid ?? TempConst.projectId);
List<CommunityModel> updatedCommunities = await Future.wait( List<CommunityModel> updatedCommunities = await Future.wait(
communities.map((community) async { communities.map((community) async {

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
@ -10,7 +11,6 @@ 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 {
@ -29,18 +29,20 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
return MultiBlocProvider( return MultiBlocProvider(
providers: [ providers: [
BlocProvider( BlocProvider(
create: (_) => SpaceManagementBloc(_api, _productApi, _spaceModelApi) create: (_) => SpaceManagementBloc(
..add(LoadCommunityAndSpacesEvent()), _api,
_productApi,
_spaceModelApi,
context.read<ProjectCubit>(),
)..add(LoadCommunityAndSpacesEvent()),
), ),
BlocProvider( BlocProvider(
create: (_) => CenterBodyBloc(), create: (_) => CenterBodyBloc(),
), ),
], ],
child: WebScaffold( child: WebScaffold(
appBarTitle: Text( appBarTitle: Text('Space Management',
'Space Management', style: Theme.of(context).textTheme.headlineLarge),
style: ResponsiveTextTheme.of(context).deviceManagementTitle,
),
enableMenuSidebar: false, enableMenuSidebar: false,
centerBody: CenterBodyWidget(), centerBody: CenterBodyWidget(),
rightBody: const NavigateHomeGridView(), rightBody: const NavigateHomeGridView(),

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.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/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_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';
@ -87,6 +88,7 @@ class _LoadedSpaceViewState extends State<LoadedSpaceView> {
child: BlocProvider( child: BlocProvider(
create: (context) => SpaceModelBloc( create: (context) => SpaceModelBloc(
api: SpaceModelManagementApi(), api: SpaceModelManagementApi(),
projectCubit: context.read<ProjectCubit>(),
initialSpaceModels: _spaceModels, initialSpaceModels: _spaceModels,
), ),
child: SpaceModelPage( child: SpaceModelPage(

View File

@ -1,4 +1,5 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_event.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_state.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_state.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/create_space_template_body_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/create_space_template_body_model.dart';
@ -8,16 +9,20 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_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/action_enum.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
class CreateSpaceModelBloc class CreateSpaceModelBloc
extends Bloc<CreateSpaceModelEvent, CreateSpaceModelState> { extends Bloc<CreateSpaceModelEvent, CreateSpaceModelState> {
SpaceTemplateModel? _space; SpaceTemplateModel? _space;
final SpaceModelManagementApi _api; final SpaceModelManagementApi _api;
final ProjectCubit _projectCubit;
CreateSpaceModelBloc(this._api) : super(CreateSpaceModelInitial()) { CreateSpaceModelBloc(this._api, this._projectCubit)
: super(CreateSpaceModelInitial()) {
on<CreateSpaceTemplate>((event, emit) async { on<CreateSpaceTemplate>((event, emit) async {
try { try {
final projectUuid = _projectCubit.state;
late SpaceTemplateModel spaceTemplate = event.spaceTemplate; late SpaceTemplateModel spaceTemplate = event.spaceTemplate;
final tagBodyModels = final tagBodyModels =
@ -40,7 +45,8 @@ class CreateSpaceModelBloc
tags: tagBodyModels, tags: tagBodyModels,
subspaceModels: subspaceTemplateBodyModels); subspaceModels: subspaceTemplateBodyModels);
final newSpaceTemplate = await _api.createSpaceModel(spaceModelBody); final newSpaceTemplate = await _api.createSpaceModel(
spaceModelBody, projectUuid ?? TempConst.projectId);
spaceTemplate.uuid = newSpaceTemplate?.uuid ?? ''; spaceTemplate.uuid = newSpaceTemplate?.uuid ?? '';
if (newSpaceTemplate != null) { if (newSpaceTemplate != null) {
@ -201,9 +207,12 @@ class CreateSpaceModelBloc
on<ModifySpaceTemplate>((event, emit) async { on<ModifySpaceTemplate>((event, emit) async {
try { try {
final projectUuid = _projectCubit.state;
if (event.spaceTemplate.uuid != null) { if (event.spaceTemplate.uuid != null) {
final prevSpaceModel = final prevSpaceModel = await _api.getSpaceModel(
await _api.getSpaceModel(event.spaceTemplate.uuid ?? ''); event.spaceTemplate.uuid ?? '',
projectUuid ?? TempConst.projectId);
final newSpaceModel = event.updatedSpaceTemplate; final newSpaceModel = event.updatedSpaceTemplate;
String? spaceModelName; String? spaceModelName;
@ -286,8 +295,8 @@ class CreateSpaceModelBloc
tags: tagUpdates, tags: tagUpdates,
subspaceModels: subspaceUpdates); subspaceModels: subspaceUpdates);
final res = await _api.updateSpaceModel( final res = await _api.updateSpaceModel(spaceModelBody,
spaceModelBody, prevSpaceModel?.uuid ?? ''); prevSpaceModel?.uuid ?? '', projectUuid ?? TempConst.projectId);
if (res != null) { if (res != null) {
emit(CreateSpaceModelLoaded(newSpaceModel)); emit(CreateSpaceModelLoaded(newSpaceModel));

View File

@ -1,14 +1,18 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart';
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/temp_const.dart';
class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> { class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
final SpaceModelManagementApi api; final SpaceModelManagementApi api;
final ProjectCubit projectCubit;
SpaceModelBloc({ SpaceModelBloc({
required this.api, required this.api,
required this.projectCubit,
required List<SpaceTemplateModel> initialSpaceModels, required List<SpaceTemplateModel> initialSpaceModels,
}) : super(SpaceModelLoaded(spaceModels: initialSpaceModels)) { }) : super(SpaceModelLoaded(spaceModels: initialSpaceModels)) {
on<CreateSpaceModel>(_onCreateSpaceModel); on<CreateSpaceModel>(_onCreateSpaceModel);
@ -18,10 +22,12 @@ class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
Future<void> _onCreateSpaceModel( Future<void> _onCreateSpaceModel(
CreateSpaceModel event, Emitter<SpaceModelState> emit) async { CreateSpaceModel event, Emitter<SpaceModelState> emit) async {
final currentState = state; final currentState = state;
if (currentState is SpaceModelLoaded) { if (currentState is SpaceModelLoaded) {
try { try {
final newSpaceModel = final projectUuid = projectCubit.state;
await api.getSpaceModel(event.newSpaceModel.uuid ?? ''); final newSpaceModel = await api.getSpaceModel(
event.newSpaceModel.uuid ?? '', projectUuid ?? TempConst.projectId);
if (newSpaceModel != null) { if (newSpaceModel != null) {
final updatedSpaceModels = final updatedSpaceModels =
@ -40,8 +46,10 @@ class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
final currentState = state; final currentState = state;
if (currentState is SpaceModelLoaded) { if (currentState is SpaceModelLoaded) {
try { try {
final newSpaceModel = final projectUuid = projectCubit.state;
await api.getSpaceModel(event.spaceModelUuid ?? '');
final newSpaceModel = await api.getSpaceModel(
event.spaceModelUuid ?? '', projectUuid ?? TempConst.projectId);
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;

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/common/buttons/cancel_button.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/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
@ -50,7 +51,10 @@ class CreateSpaceModelDialog extends StatelessWidget {
width: screenWidth * 0.3, width: screenWidth * 0.3,
child: BlocProvider( child: BlocProvider(
create: (_) { create: (_) {
final bloc = CreateSpaceModelBloc(_spaceModelApi); final bloc = CreateSpaceModelBloc(
_spaceModelApi,
context.read<ProjectCubit>(),
);
if (spaceModel != null) { if (spaceModel != null) {
bloc.add(UpdateSpaceTemplate(spaceModel!, otherSpaceModels)); bloc.add(UpdateSpaceTemplate(spaceModel!, otherSpaceModels));
} else { } else {

View File

@ -3,6 +3,7 @@ import 'package:dio/dio.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:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/common/custom_dialog.dart'; import 'package:syncrow_web/pages/common/custom_dialog.dart';
import 'package:syncrow_web/pages/common/hour_picker_dialog.dart'; import 'package:syncrow_web/pages/common/hour_picker_dialog.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
@ -13,10 +14,14 @@ import 'package:syncrow_web/pages/visitor_password/model/schedule_model.dart';
import 'package:syncrow_web/services/access_mang_api.dart'; import 'package:syncrow_web/services/access_mang_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/temp_const.dart';
import 'package:syncrow_web/utils/snack_bar.dart'; import 'package:syncrow_web/utils/snack_bar.dart';
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> { class VisitorPasswordBloc
VisitorPasswordBloc() : super(VisitorPasswordInitial()) { extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
final ProjectCubit projectCubit;
VisitorPasswordBloc(this.projectCubit) : super(VisitorPasswordInitial()) {
on<SelectUsageFrequency>(selectUsageFrequency); on<SelectUsageFrequency>(selectUsageFrequency);
on<FetchDevice>(_onFetchDevice); on<FetchDevice>(_onFetchDevice);
on<SelectPasswordType>(selectAccessType); on<SelectPasswordType>(selectAccessType);
@ -38,7 +43,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
final TextEditingController deviceNameController = TextEditingController(); final TextEditingController deviceNameController = TextEditingController();
final TextEditingController deviceIdController = TextEditingController(); final TextEditingController deviceIdController = TextEditingController();
final TextEditingController unitNameController = TextEditingController(); final TextEditingController unitNameController = TextEditingController();
final TextEditingController virtualAddressController = TextEditingController(); final TextEditingController virtualAddressController =
TextEditingController();
List<String> selectedDevices = []; List<String> selectedDevices = [];
List<DeviceModel> data = []; List<DeviceModel> data = [];
@ -64,12 +70,14 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
String startTimeAccess = 'Start Time'; String startTimeAccess = 'Start Time';
String endTimeAccess = 'End Time'; String endTimeAccess = 'End Time';
PasswordStatus? passwordStatus; PasswordStatus? passwordStatus;
selectAccessType(SelectPasswordType event, Emitter<VisitorPasswordState> emit) { selectAccessType(
SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
accessTypeSelected = event.type; accessTypeSelected = event.type;
emit(PasswordTypeSelected(event.type)); emit(PasswordTypeSelected(event.type));
} }
selectUsageFrequency(SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) { selectUsageFrequency(
SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
usageFrequencySelected = event.usageType; usageFrequencySelected = event.usageType;
emit(UsageFrequencySelected(event.usageType)); emit(UsageFrequencySelected(event.usageType));
} }
@ -116,10 +124,12 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
timePicked.minute, timePicked.minute,
); );
final selectedTimestamp = selectedDateTime.millisecondsSinceEpoch ~/ 1000; final selectedTimestamp =
selectedDateTime.millisecondsSinceEpoch ~/ 1000;
if (event.isStart) { if (event.isStart) {
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) { if (expirationTimeTimeStamp != null &&
selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar( CustomSnackBar.displaySnackBar(
'Effective Time cannot be later than Expiration Time.', 'Effective Time cannot be later than Expiration Time.',
); );
@ -128,7 +138,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
effectiveTimeTimeStamp = selectedTimestamp; effectiveTimeTimeStamp = selectedTimestamp;
startTimeAccess = selectedDateTime.toString().split('.').first; startTimeAccess = selectedDateTime.toString().split('.').first;
} else { } else {
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) { if (effectiveTimeTimeStamp != null &&
selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar( CustomSnackBar.displaySnackBar(
'Expiration Time cannot be earlier than Effective Time.', 'Expiration Time cannot be earlier than Effective Time.',
); );
@ -143,7 +154,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
} }
} }
bool toggleRepeat(ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) { bool toggleRepeat(
ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
emit(LoadingInitialState()); emit(LoadingInitialState());
repeat = !repeat; repeat = !repeat;
emit(IsRepeatState(repeat: repeat)); emit(IsRepeatState(repeat: repeat));
@ -175,10 +187,14 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
emit(ChangeTimeState()); emit(ChangeTimeState());
} }
Future<void> _onFetchDevice(FetchDevice event, Emitter<VisitorPasswordState> emit) async { Future<void> _onFetchDevice(
FetchDevice event, Emitter<VisitorPasswordState> emit) async {
try { try {
emit(DeviceLoaded()); emit(DeviceLoaded());
data = await AccessMangApi().fetchDevices(); final projectUuid = projectCubit.state;
data = await AccessMangApi()
.fetchDevices(projectUuid ?? TempConst.projectId);
emit(TableLoaded(data)); emit(TableLoaded(data));
} catch (e) { } catch (e) {
emit(FailedState(e.toString())); emit(FailedState(e.toString()));
@ -186,8 +202,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
} }
//online password //online password
Future<void> postOnlineOneTimePassword( Future<void> postOnlineOneTimePassword(OnlineOneTimePasswordEvent event,
OnlineOneTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async { Emitter<VisitorPasswordState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
generate7DigitNumber(); generate7DigitNumber();
@ -211,7 +227,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
} }
Future<void> postOnlineMultipleTimePassword( Future<void> postOnlineMultipleTimePassword(
OnlineMultipleTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async { OnlineMultipleTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
@ -221,7 +238,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
if (repeat) if (repeat)
Schedule( Schedule(
effectiveTime: getTimeFromDateTimeString(effectiveTime), effectiveTime: getTimeFromDateTimeString(effectiveTime),
invalidTime: getTimeFromDateTimeString(expirationTime).toString(), invalidTime:
getTimeFromDateTimeString(expirationTime).toString(),
workingDay: selectedDays, workingDay: selectedDays,
), ),
], ],
@ -244,13 +262,15 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
} }
//offline password //offline password
Future<void> postOfflineOneTimePassword( Future<void> postOfflineOneTimePassword(OfflineOneTimePasswordEvent event,
OfflineOneTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async { Emitter<VisitorPasswordState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
await generate7DigitNumber(); await generate7DigitNumber();
var res = await AccessMangApi().postOffLineOneTime( var res = await AccessMangApi().postOffLineOneTime(
email: event.email, devicesUuid: selectedDevices, passwordName: event.passwordName); email: event.email,
devicesUuid: selectedDevices,
passwordName: event.passwordName);
if (res['statusCode'] == 201) { if (res['statusCode'] == 201) {
passwordStatus = PasswordStatus.fromJson(res['data']); passwordStatus = PasswordStatus.fromJson(res['data']);
emit(SuccessState()); emit(SuccessState());
@ -264,7 +284,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
} }
Future<void> postOfflineMultipleTimePassword( Future<void> postOfflineMultipleTimePassword(
OfflineMultipleTimePasswordEvent event, Emitter<VisitorPasswordState> emit) async { OfflineMultipleTimePasswordEvent event,
Emitter<VisitorPasswordState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
await generate7DigitNumber(); await generate7DigitNumber();
@ -287,7 +308,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
} }
} }
void selectDevice(SelectDeviceEvent event, Emitter<VisitorPasswordState> emit) { void selectDevice(
SelectDeviceEvent event, Emitter<VisitorPasswordState> emit) {
if (selectedDeviceIds.contains(event.deviceId)) { if (selectedDeviceIds.contains(event.deviceId)) {
selectedDeviceIds.remove(event.deviceId); selectedDeviceIds.remove(event.deviceId);
} else { } else {
@ -329,7 +351,8 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
add(UpdateFilteredDevicesEvent(filteredData)); add(UpdateFilteredDevicesEvent(filteredData));
} }
Stream<VisitorPasswordState> mapEventToState(VisitorPasswordEvent event) async* { Stream<VisitorPasswordState> mapEventToState(
VisitorPasswordEvent event) async* {
if (event is FetchDevice) { if (event is FetchDevice) {
} else if (event is UpdateFilteredDevicesEvent) { } else if (event is UpdateFilteredDevicesEvent) {
yield TableLoaded(event.filteredData); yield TableLoaded(event.filteredData);
@ -378,16 +401,20 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
).millisecondsSinceEpoch ~/ ).millisecondsSinceEpoch ~/
1000; // Divide by 1000 to remove milliseconds 1000; // Divide by 1000 to remove milliseconds
if (event.isEffective) { if (event.isEffective) {
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) { if (expirationTimeTimeStamp != null &&
accessPeriodValidate = "Effective Time cannot be later than Expiration Time."; selectedTimestamp > expirationTimeTimeStamp!) {
accessPeriodValidate =
"Effective Time cannot be later than Expiration Time.";
} else { } else {
accessPeriodValidate = ''; accessPeriodValidate = '';
effectiveTime = selectedDateTime.toString().split('.').first; effectiveTime = selectedDateTime.toString().split('.').first;
effectiveTimeTimeStamp = selectedTimestamp; effectiveTimeTimeStamp = selectedTimestamp;
} }
} else { } else {
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) { if (effectiveTimeTimeStamp != null &&
accessPeriodValidate = 'Expiration Time cannot be earlier than Effective Time.'; selectedTimestamp < effectiveTimeTimeStamp!) {
accessPeriodValidate =
'Expiration Time cannot be earlier than Effective Time.';
} else { } else {
accessPeriodValidate = ''; accessPeriodValidate = '';
expirationTime = selectedDateTime.toString().split('.').first; expirationTime = selectedDateTime.toString().split('.').first;

View File

@ -2,6 +2,7 @@ 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/access_device_table.dart'; import 'package:syncrow_web/pages/common/access_device_table.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart'; import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
@ -19,7 +20,7 @@ class AddDeviceDialog extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;
return BlocProvider( return BlocProvider(
create: (context) => VisitorPasswordBloc()..add(FetchDevice()), create: (context) => VisitorPasswordBloc(context.read<ProjectCubit>())..add(FetchDevice()),
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>( child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
builder: (BuildContext context, VisitorPasswordState state) { builder: (BuildContext context, VisitorPasswordState state) {
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context); final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);

View File

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.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_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/common/date_time_widget.dart'; import 'package:syncrow_web/pages/common/date_time_widget.dart';
import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart'; import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart';
@ -22,7 +23,7 @@ class VisitorPasswordDialog extends StatelessWidget {
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;
var text = Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black, fontSize: 13); var text = Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black, fontSize: 13);
return BlocProvider( return BlocProvider(
create: (context) => VisitorPasswordBloc(), create: (context) => VisitorPasswordBloc(context.read<ProjectCubit>()),
child: BlocListener<VisitorPasswordBloc, VisitorPasswordState>( child: BlocListener<VisitorPasswordBloc, VisitorPasswordState>(
listener: (context, state) { listener: (context, state) {
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context); final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);

View File

@ -6,10 +6,10 @@ import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/constants/api_const.dart';
class AccessMangApi { class AccessMangApi {
Future<List<PasswordModel>> fetchVisitorPassword() async { Future<List<PasswordModel>> fetchVisitorPassword(String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.visitorPassword, path: ApiEndpoints.visitorPassword.replaceAll('{projectId}', projectId),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = json; List<dynamic> jsonData = json;
@ -25,10 +25,10 @@ class AccessMangApi {
} }
} }
Future fetchDevices() async { Future fetchDevices(String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getDevices, path: ApiEndpoints.getDevices.replaceAll('{projectId}', projectId),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = json; List<dynamic> jsonData = json;
@ -86,7 +86,8 @@ class AccessMangApi {
"invalidTime": invalidTime, "invalidTime": invalidTime,
}; };
if (scheduleList != null) { if (scheduleList != null) {
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList(); body["scheduleList"] =
scheduleList.map((schedule) => schedule.toJson()).toList();
} }
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.sendOnlineMultipleTime, path: ApiEndpoints.sendOnlineMultipleTime,
@ -105,7 +106,11 @@ class AccessMangApi {
{String? email, String? passwordName, List<String>? devicesUuid}) async { {String? email, String? passwordName, List<String>? devicesUuid}) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.sendOffLineOneTime, path: ApiEndpoints.sendOffLineOneTime,
body: jsonEncode({"email": email, "passwordName": passwordName, "devicesUuid": devicesUuid}), body: jsonEncode({
"email": email,
"passwordName": passwordName,
"devicesUuid": devicesUuid
}),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json; return json;

View File

@ -12,15 +12,15 @@ import 'package:syncrow_web/utils/constants/api_const.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart'; import 'package:syncrow_web/utils/constants/temp_const.dart';
class DevicesManagementApi { class DevicesManagementApi {
Future<List<AllDevicesModel>> fetchDevices(String communityId, String spaceId) async { Future<List<AllDevicesModel>> fetchDevices(String communityId, String spaceId, String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: communityId.isNotEmpty && spaceId.isNotEmpty path: communityId.isNotEmpty && spaceId.isNotEmpty
? ApiEndpoints.getSpaceDevices ? ApiEndpoints.getSpaceDevices
.replaceAll('{spaceUuid}', spaceId) .replaceAll('{spaceUuid}', spaceId)
.replaceAll('{communityUuid}', communityId) .replaceAll('{communityUuid}', communityId)
.replaceAll('{projectId}', TempConst.projectId) .replaceAll('{projectId}', projectId)
: ApiEndpoints.getAllDevices, : ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = List<dynamic> jsonData =

View File

@ -12,7 +12,8 @@ class SceneApi {
static final HTTPService _httpService = HTTPService(); static final HTTPService _httpService = HTTPService();
// //create scene // //create scene
static Future<Map<String, dynamic>> createScene(CreateSceneModel createSceneModel) async { static Future<Map<String, dynamic>> createScene(
CreateSceneModel createSceneModel) async {
try { try {
debugPrint('create scene model: ${createSceneModel.toMap()}'); debugPrint('create scene model: ${createSceneModel.toMap()}');
final response = await _httpService.post( final response = await _httpService.post(
@ -69,14 +70,15 @@ class SceneApi {
//get scenes by community id and space id //get scenes by community id and space id
static Future<List<ScenesModel>> getScenes(String spaceId, String communityId, static Future<List<ScenesModel>> getScenes(
String spaceId, String communityId, String projectId,
{showInDevice = false}) async { {showInDevice = false}) async {
try { try {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getUnitScenes path: ApiEndpoints.getUnitScenes
.replaceAll('{spaceUuid}', spaceId) .replaceAll('{spaceUuid}', spaceId)
.replaceAll('{communityUuid}', communityId) .replaceAll('{communityUuid}', communityId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
queryParameters: {'showInHomePage': showInDevice}, queryParameters: {'showInHomePage': showInDevice},
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
@ -100,7 +102,8 @@ class SceneApi {
static Future<List<ScenesModel>> getAutomation(String spaceId) async { static Future<List<ScenesModel>> getAutomation(String spaceId) async {
try { try {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getSpaceAutomation.replaceAll('{spaceUuid}', spaceId), path:
ApiEndpoints.getSpaceAutomation.replaceAll('{spaceUuid}', spaceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<ScenesModel> scenes = []; List<ScenesModel> scenes = [];
@ -130,10 +133,12 @@ class SceneApi {
// } // }
//automation details //automation details
static Future<RoutineDetailsModel> getAutomationDetails(String automationId) async { static Future<RoutineDetailsModel> getAutomationDetails(
String automationId) async {
try { try {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getAutomationDetails.replaceAll('{automationId}', automationId), path: ApiEndpoints.getAutomationDetails
.replaceAll('{automationId}', automationId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json), expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json),
); );
@ -148,7 +153,8 @@ class SceneApi {
try { try {
final response = await _httpService.put( final response = await _httpService.put(
path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId), path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
body: createSceneModel.toJson(sceneId.isNotEmpty == true ? sceneId : null), body: createSceneModel
.toJson(sceneId.isNotEmpty == true ? sceneId : null),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json; return json;
}, },
@ -160,11 +166,14 @@ class SceneApi {
} }
//update automation //update automation
static updateAutomation(CreateAutomationModel createAutomationModel, String automationId) async { static updateAutomation(
CreateAutomationModel createAutomationModel, String automationId) async {
try { try {
final response = await _httpService.put( final response = await _httpService.put(
path: ApiEndpoints.updateAutomation.replaceAll('{automationId}', automationId), path: ApiEndpoints.updateAutomation
body: createAutomationModel.toJson(automationId.isNotEmpty == true ? automationId : null), .replaceAll('{automationId}', automationId),
body: createAutomationModel
.toJson(automationId.isNotEmpty == true ? automationId : null),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json; return json;
}, },
@ -181,7 +190,8 @@ class SceneApi {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId), path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json['data']), expectedResponseModel: (json) =>
RoutineDetailsModel.fromMap(json['data']),
); );
return response; return response;
} catch (e) { } catch (e) {
@ -190,7 +200,8 @@ class SceneApi {
} }
//delete Scene //delete Scene
static Future<bool> deleteScene({required String unitUuid, required String sceneId}) async { static Future<bool> deleteScene(
{required String unitUuid, required String sceneId}) async {
try { try {
final response = await _httpService.delete( final response = await _httpService.delete(
path: ApiEndpoints.deleteScene path: ApiEndpoints.deleteScene

View File

@ -13,7 +13,8 @@ import 'package:syncrow_web/utils/constants/temp_const.dart';
class CommunitySpaceManagementApi { class CommunitySpaceManagementApi {
// Community Management APIs // Community Management APIs
Future<List<CommunityModel>> fetchCommunities({int page = 1}) async { Future<List<CommunityModel>> fetchCommunities(String projectId,
{int page = 1}) async {
try { try {
List<CommunityModel> allCommunities = []; List<CommunityModel> allCommunities = [];
bool hasNext = true; bool hasNext = true;
@ -21,7 +22,7 @@ class CommunitySpaceManagementApi {
while (hasNext) { while (hasNext) {
await HTTPService().get( await HTTPService().get(
path: ApiEndpoints.getCommunityList path: ApiEndpoints.getCommunityList
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
queryParameters: {'page': page}, queryParameters: {'page': page},
expectedResponseModel: (json) { expectedResponseModel: (json) {
try { try {
@ -65,11 +66,10 @@ class CommunitySpaceManagementApi {
} }
Future<CommunityModel?> createCommunity( Future<CommunityModel?> createCommunity(
String name, String description) async { String name, String description, String projectId) async {
try { try {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.createCommunity path: ApiEndpoints.createCommunity.replaceAll('{projectId}', projectId),
.replaceAll('{projectId}', TempConst.projectId),
body: { body: {
'name': name, 'name': name,
'description': description, 'description': description,
@ -85,12 +85,13 @@ class CommunitySpaceManagementApi {
} }
} }
Future<bool> updateCommunity(String communityId, String name) async { Future<bool> updateCommunity(
String communityId, String name, String projectId) async {
try { try {
final response = await HTTPService().put( final response = await HTTPService().put(
path: ApiEndpoints.updateCommunity path: ApiEndpoints.updateCommunity
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
body: { body: {
'name': name, 'name': name,
}, },
@ -105,12 +106,12 @@ class CommunitySpaceManagementApi {
} }
} }
Future<bool> deleteCommunity(String communityId) async { Future<bool> deleteCommunity(String communityId, String projectId) async {
try { try {
final response = await HTTPService().delete( final response = await HTTPService().delete(
path: ApiEndpoints.deleteCommunity path: ApiEndpoints.deleteCommunity
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['success'] ?? false; return json['success'] ?? false;
}, },
@ -122,12 +123,13 @@ class CommunitySpaceManagementApi {
} }
} }
Future<SpacesResponse> fetchSpaces(String communityId) async { Future<SpacesResponse> fetchSpaces(
String communityId, String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.listSpaces path: ApiEndpoints.listSpaces
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return SpacesResponse.fromJson(json); return SpacesResponse.fromJson(json);
}, },
@ -148,13 +150,14 @@ class CommunitySpaceManagementApi {
} }
} }
Future<SpaceModel?> getSpace(String communityId, String spaceId) async { Future<SpaceModel?> getSpace(
String communityId, String spaceId, String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getSpace path: ApiEndpoints.getSpace
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{spaceId}', spaceId) .replaceAll('{spaceId}', spaceId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return SpaceModel.fromJson(json['data']); return SpaceModel.fromJson(json['data']);
}, },
@ -176,7 +179,8 @@ class CommunitySpaceManagementApi {
String? spaceModelUuid, String? spaceModelUuid,
String? icon, String? icon,
List<CreateTagBodyModel>? tags, List<CreateTagBodyModel>? tags,
List<CreateSubspaceModel>? subspaces}) async { List<CreateSubspaceModel>? subspaces,
required String projectId}) async {
try { try {
final body = { final body = {
'spaceName': name, 'spaceName': name,
@ -199,7 +203,7 @@ class CommunitySpaceManagementApi {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.createSpace path: ApiEndpoints.createSpace
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
body: body, body: body,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return SpaceModel.fromJson(json['data']); return SpaceModel.fromJson(json['data']);
@ -212,18 +216,18 @@ class CommunitySpaceManagementApi {
} }
} }
Future<bool> updateSpace({ Future<bool> updateSpace(
required String communityId, {required String communityId,
required spaceId, required spaceId,
required String name, required String name,
String? parentId, String? parentId,
String? icon, String? icon,
String? direction, String? direction,
bool isPrivate = false, bool isPrivate = false,
required Offset position, required Offset position,
List<TagModelUpdate>? tags, List<TagModelUpdate>? tags,
List<UpdateSubspaceTemplateModel>? subspaces, List<UpdateSubspaceTemplateModel>? subspaces,
}) async { required String projectId}) async {
try { try {
final body = { final body = {
'spaceName': name, 'spaceName': name,
@ -243,7 +247,7 @@ class CommunitySpaceManagementApi {
path: ApiEndpoints.updateSpace path: ApiEndpoints.updateSpace
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{spaceId}', spaceId) .replaceAll('{spaceId}', spaceId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
body: body, body: body,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['success'] ?? false; return json['success'] ?? false;
@ -256,13 +260,14 @@ class CommunitySpaceManagementApi {
} }
} }
Future<bool> deleteSpace(String communityId, String spaceId) async { Future<bool> deleteSpace(
String communityId, String spaceId, String projectId) async {
try { try {
final response = await HTTPService().delete( final response = await HTTPService().delete(
path: ApiEndpoints.deleteSpace path: ApiEndpoints.deleteSpace
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{spaceId}', spaceId) .replaceAll('{spaceId}', spaceId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['success'] ?? false; return json['success'] ?? false;
}, },
@ -274,12 +279,13 @@ class CommunitySpaceManagementApi {
} }
} }
Future<List<SpaceModel>> getSpaceHierarchy(String communityId) async { Future<List<SpaceModel>> getSpaceHierarchy(
String communityId, String projectId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getSpaceHierarchy path: ApiEndpoints.getSpaceHierarchy
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId), .replaceAll('{projectId}', projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
final spaceModels = (json['data'] as List) final spaceModels = (json['data'] as List)
.map((spaceJson) => SpaceModel.fromJson(spaceJson)) .map((spaceJson) => SpaceModel.fromJson(spaceJson))

View File

@ -5,10 +5,10 @@ import 'package:syncrow_web/utils/constants/api_const.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart'; import 'package:syncrow_web/utils/constants/temp_const.dart';
class SpaceModelManagementApi { class SpaceModelManagementApi {
Future<List<SpaceTemplateModel>> listSpaceModels({int page = 1}) async { Future<List<SpaceTemplateModel>> listSpaceModels(
{required String projectId, int page = 1}) async {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.listSpaceModels path: ApiEndpoints.listSpaceModels.replaceAll('{projectId}', projectId),
.replaceAll('{projectId}', TempConst.projectId),
queryParameters: {'page': page}, queryParameters: {'page': page},
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = json['data']; List<dynamic> jsonData = json['data'];
@ -21,10 +21,9 @@ class SpaceModelManagementApi {
} }
Future<SpaceTemplateModel?> createSpaceModel( Future<SpaceTemplateModel?> createSpaceModel(
CreateSpaceTemplateBodyModel spaceModel) async { CreateSpaceTemplateBodyModel spaceModel, String projectId) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.createSpaceModel path: ApiEndpoints.createSpaceModel.replaceAll('{projectId}', projectId),
.replaceAll('{projectId}', TempConst.projectId),
showServerMessage: true, showServerMessage: true,
body: spaceModel.toJson(), body: spaceModel.toJson(),
expectedResponseModel: (json) { expectedResponseModel: (json) {
@ -34,12 +33,12 @@ class SpaceModelManagementApi {
return response; return response;
} }
Future<String?> updateSpaceModel(CreateSpaceTemplateBodyModel spaceModel,
Future<String?> updateSpaceModel( String spaceModelUuid, String projectId) async {
CreateSpaceTemplateBodyModel spaceModel, String spaceModelUuid) async {
final response = await HTTPService().put( final response = await HTTPService().put(
path: ApiEndpoints.updateSpaceModel path: ApiEndpoints.updateSpaceModel
.replaceAll('{projectId}', TempConst.projectId).replaceAll('{spaceModelUuid}', spaceModelUuid), .replaceAll('{projectId}', projectId)
.replaceAll('{spaceModelUuid}', spaceModelUuid),
body: spaceModel.toJson(), body: spaceModel.toJson(),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['message']; return json['message'];
@ -48,10 +47,11 @@ class SpaceModelManagementApi {
return response; return response;
} }
Future<SpaceTemplateModel?> getSpaceModel(String spaceModelUuid) async { Future<SpaceTemplateModel?> getSpaceModel(
String spaceModelUuid, String projectId) async {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getSpaceModel path: ApiEndpoints.getSpaceModel
.replaceAll('{projectId}', TempConst.projectId) .replaceAll('{projectId}', projectId)
.replaceAll('{spaceModelUuid}', spaceModelUuid), .replaceAll('{spaceModelUuid}', spaceModelUuid),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {

View File

@ -11,10 +11,10 @@ import 'package:syncrow_web/utils/constants/api_const.dart';
class UserPermissionApi { class UserPermissionApi {
static final HTTPService _httpService = HTTPService(); static final HTTPService _httpService = HTTPService();
Future<List<RolesUserModel>> fetchUsers() async { Future<List<RolesUserModel>> fetchUsers(String projectId) async {
try { try {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getUsers, path: ApiEndpoints.getUsers.replaceAll('{projectUuid}', projectId),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
debugPrint('fetchUsers Response: $json'); debugPrint('fetchUsers Response: $json');
@ -34,8 +34,9 @@ class UserPermissionApi {
path: ApiEndpoints.roleTypes, path: ApiEndpoints.roleTypes,
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
final List<RoleTypeModel> fetchedRoles = final List<RoleTypeModel> fetchedRoles = (json['data'] as List)
(json['data'] as List).map((item) => RoleTypeModel.fromJson(item)).toList(); .map((item) => RoleTypeModel.fromJson(item))
.toList();
return fetchedRoles; return fetchedRoles;
}, },
); );
@ -47,7 +48,9 @@ class UserPermissionApi {
path: ApiEndpoints.permission.replaceAll("roleUuid", roleUuid), path: ApiEndpoints.permission.replaceAll("roleUuid", roleUuid),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return (json as List).map((data) => PermissionOption.fromJson(data)).toList(); return (json as List)
.map((data) => PermissionOption.fromJson(data))
.toList();
}, },
); );
return response ?? []; return response ?? [];
@ -61,6 +64,7 @@ class UserPermissionApi {
String? phoneNumber, String? phoneNumber,
String? roleUuid, String? roleUuid,
List<String>? spaceUuids, List<String>? spaceUuids,
required String projectUuid,
}) async { }) async {
try { try {
final body = <String, dynamic>{ final body = <String, dynamic>{
@ -70,7 +74,7 @@ class UserPermissionApi {
"jobTitle": jobTitle != '' ? jobTitle : null, "jobTitle": jobTitle != '' ? jobTitle : null,
"phoneNumber": phoneNumber != '' ? phoneNumber : null, "phoneNumber": phoneNumber != '' ? phoneNumber : null,
"roleUuid": roleUuid, "roleUuid": roleUuid,
"projectUuid": "0e62577c-06fa-41b9-8a92-99a21fbaf51c", "projectUuid": projectUuid,
"spaceUuids": spaceUuids, "spaceUuids": spaceUuids,
}; };
final response = await _httpService.post( final response = await _httpService.post(
@ -121,9 +125,11 @@ class UserPermissionApi {
} }
} }
Future<EditUserModel?> fetchUserById(userUuid) async { Future<EditUserModel?> fetchUserById(userUuid, String projectId) async {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getUserById.replaceAll("{userUuid}", userUuid), path: ApiEndpoints.getUserById
.replaceAll("{userUuid}", userUuid)
.replaceAll("{projectId}", projectId),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
EditUserModel res = EditUserModel.fromJson(json['data']); EditUserModel res = EditUserModel.fromJson(json['data']);
@ -141,6 +147,7 @@ class UserPermissionApi {
String? phoneNumber, String? phoneNumber,
String? roleUuid, String? roleUuid,
List<String>? spaceUuids, List<String>? spaceUuids,
required String projectUuid,
}) async { }) async {
try { try {
final body = <String, dynamic>{ final body = <String, dynamic>{
@ -149,7 +156,7 @@ class UserPermissionApi {
"jobTitle": jobTitle != '' ? jobTitle : " ", "jobTitle": jobTitle != '' ? jobTitle : " ",
"phoneNumber": phoneNumber != '' ? phoneNumber : " ", "phoneNumber": phoneNumber != '' ? phoneNumber : " ",
"roleUuid": roleUuid, "roleUuid": roleUuid,
"projectUuid": "0e62577c-06fa-41b9-8a92-99a21fbaf51c", "projectUuid": projectUuid,
"spaceUuids": spaceUuids, "spaceUuids": spaceUuids,
}; };
final response = await _httpService.put( final response = await _httpService.put(
@ -186,15 +193,16 @@ class UserPermissionApi {
} }
} }
Future<bool> changeUserStatusById(userUuid, status) async { Future<bool> changeUserStatusById(userUuid, status, String projectUuid) async {
try { try {
Map<String, dynamic> bodya = { Map<String, dynamic> bodya = {
"disable": status, "disable": status,
"projectUuid": "0e62577c-06fa-41b9-8a92-99a21fbaf51c" "projectUuid": projectUuid
}; };
final response = await _httpService.put( final response = await _httpService.put(
path: ApiEndpoints.changeUserStatus.replaceAll("{invitedUserUuid}", userUuid), path: ApiEndpoints.changeUserStatus
.replaceAll("{invitedUserUuid}", userUuid),
body: bodya, body: bodya,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['success']; return json['success'];

View File

@ -9,8 +9,8 @@ abstract class ApiEndpoints {
static const String sendOtp = '/authentication/user/send-otp'; static const String sendOtp = '/authentication/user/send-otp';
static const String verifyOtp = '/authentication/user/verify-otp'; static const String verifyOtp = '/authentication/user/verify-otp';
static const String getRegion = '/region'; static const String getRegion = '/region';
static const String visitorPassword = '/visitor-password'; static const String visitorPassword = '/projects/{projectId}/visitor-password';
static const String getDevices = '/visitor-password/devices'; static const String getDevices = '/projects/{projectId}/visitor-password/devices';
static const String sendOnlineOneTime = '/visitor-password/temporary-password/online/one-time'; static const String sendOnlineOneTime = '/visitor-password/temporary-password/online/one-time';
static const String sendOnlineMultipleTime = static const String sendOnlineMultipleTime =
@ -25,7 +25,7 @@ abstract class ApiEndpoints {
////// Devices Management //////////////// ////// Devices Management ////////////////
static const String getAllDevices = '/device'; static const String getAllDevices = '/projects/{projectId}/device';
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';
@ -95,8 +95,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/{projectUuid}/user';
static const String getUserById = '/projects/${projectUuid}/user/{userUuid}'; static const String getUserById = '/projects/{projectUuid}/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 = '/invite-user/{invitedUserUuid}/disable'; static const String changeUserStatus = '/invite-user/{invitedUserUuid}/disable';

View File

@ -1,37 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ResponsiveLayout extends StatelessWidget { class ResponsiveLayout extends StatelessWidget {
final Widget mobileBody;
final Widget? tablet;
final Widget desktopBody; final Widget desktopBody;
final Widget mobileBody;
const ResponsiveLayout({ const ResponsiveLayout(
super.key, {super.key, required this.desktopBody, required this.mobileBody});
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 >= 1100) { if (constraints.maxWidth < 600) {
return desktopBody;
} else if (constraints.maxWidth >= 650) {
return tablet!;
} else {
return mobileBody; return mobileBody;
} else {
return desktopBody;
} }
}, },
); );

View File

@ -1,30 +0,0 @@
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),
);
}
}

View File

@ -1,8 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.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/auth/model/user_model.dart'; import 'package:syncrow_web/pages/auth/model/user_model.dart';
import 'package:syncrow_web/pages/common/bloc/project_cubit.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.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';
@ -218,7 +220,10 @@ class _UserDropdownMenuState extends State<UserDropdownMenu> {
), ),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
AuthBloc.logout(); final projectCubit =
BlocProvider.of<ProjectCubit>(context);
AuthBloc.logout(context, projectCubit);
context.go(RoutesConst.auth); context.go(RoutesConst.auth);
}, },
child: SizedBox( child: SizedBox(

View File

@ -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/responsive_layout.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
import 'package:syncrow_web/utils/user_drop_down_menu.dart'; import 'package:syncrow_web/utils/user_drop_down_menu.dart';
class WebAppBar extends StatelessWidget { class WebAppBar extends StatefulWidget {
final Widget? title; final Widget? title;
final Widget? centerBody; final Widget? centerBody;
final Widget? rightBody; final Widget? rightBody;
@ -16,234 +16,178 @@ class WebAppBar extends StatelessWidget {
const WebAppBar({super.key, this.title, this.centerBody, this.rightBody}); const WebAppBar({super.key, this.title, this.centerBody, this.rightBody});
@override @override
Widget build(BuildContext context) { State<WebAppBar> createState() => _WebAppBarState();
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 DesktopAppBar extends StatelessWidget { class _WebAppBarState extends State<WebAppBar> with HelperResponsiveLayout {
final Widget? title; @override
final Widget? centerBody; void initState() {
final Widget? rightBody; super.initState();
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) {
return Container( bool isSmallScreen = isSmallScreenSize(context);
height: 100, bool isHalfMediumScreen = isHafMediumScreenSize(context);
decoration: const BoxDecoration(color: ColorsManager.secondaryColor), return BlocBuilder<HomeBloc, HomeState>(builder: (context, state) {
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10), final user = context.read<HomeBloc>().user;
child: Row( return Container(
mainAxisAlignment: MainAxisAlignment.spaceBetween, height: (isSmallScreen || isHalfMediumScreen) ? 130 : 100,
children: [ decoration: const BoxDecoration(color: ColorsManager.secondaryColor),
Expanded( padding: const EdgeInsets.all(10),
child: Row( child: isSmallScreen || isHalfMediumScreen
children: [ ? Column(
if (title != null) title!, crossAxisAlignment: CrossAxisAlignment.start,
if (centerBody != null) children: [
Padding( if (widget.title != null)
padding: const EdgeInsets.only(left: 80), Align(
child: centerBody!, 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,
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: [
Expanded(
child: Row(
children: [
widget.title!,
if (widget.centerBody != null)
Padding(
padding: const EdgeInsets.only(left: 80),
child: widget.centerBody!,
),
],
),
), ),
], Row(
), mainAxisSize: MainAxisSize.min,
), children: [
_buildUserSection(context), if (widget.rightBody != null)
], Align(
), alignment: Alignment.centerRight,
); child: widget.rightBody,
} ),
const SizedBox(
Widget _buildUserSection(BuildContext context) { width: 10,
return Row( ),
children: [ SizedBox.square(
if (rightBody != null) rightBody!, dimension: 40,
const SizedBox(width: 24), child: CircleAvatar(
_UserAvatar(), backgroundColor: ColorsManager.whiteColors,
const SizedBox(width: 12), child: SizedBox.square(
if (user != null) dimension: 35,
Text( child: SvgPicture.asset(
'${user.firstName} ${user.lastName}', Assets.logoGrey,
style: Theme.of(context).textTheme.bodyLarge, fit: BoxFit.cover,
), ),
const SizedBox(width: 12), ),
UserDropdownMenu(user: user), ),
], ),
); const SizedBox(
} width: 10,
} ),
if (user != null)
class TabletAppBar extends StatelessWidget { Text(
final Widget? title; '${user.firstName} ${user.lastName}',
final Widget? centerBody; style: Theme.of(context).textTheme.bodyLarge,
final Widget? rightBody; ),
final dynamic user; const SizedBox(
width: 10,
const TabletAppBar({ ),
super.key, UserDropdownMenu(user: user),
this.title, // GestureDetector(
this.centerBody, // onTap: () {
this.rightBody, // showCustomDialog(
required this.user, // context: context,
}); // barrierDismissible: true,
// title: 'Logout',
@override // message: 'Are you sure you want to logout?',
Widget build(BuildContext context) { // actions: [
return Container( // GestureDetector(
height: 100, // onTap: () {
decoration: const BoxDecoration(color: ColorsManager.secondaryColor), // AuthBloc.logout();
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), // context.go(RoutesConst.auth);
child: Column( // },
children: [ // child: DefaultButton(
Row( // child: Text(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // 'Ok',
children: [ // style: Theme.of(context)
if (title != null) Expanded(child: title!), // .textTheme
_buildUserSection(context), // .bodyMedium!
], // .copyWith(fontSize: 12, color: Colors.white),
), // ),
if (centerBody != null) Expanded(child: centerBody!), // ),
], // ),
), // const SizedBox(
); // height: 10,
} // ),
// GestureDetector(
Widget _buildUserSection(BuildContext context) { // onTap: () {
return Row( // context.pop();
children: [ // },
if (rightBody != null) rightBody!, // child: DefaultButton(
const SizedBox(width: 16), // child: Text(
_UserAvatar(), // 'Cancel',
if (user != null) ...[ // style: Theme.of(context)
const SizedBox(width: 8), // .textTheme
Text( // .bodyMedium!
'${user.firstName} ${user.lastName}', // .copyWith(fontSize: 12, color: Colors.white),
style: // ),
Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: 14), // ),
), // ),
], // ],
UserDropdownMenu(user: user), // );
], // },
); // child: const Icon(
} // Icons.logout,
} // color: ColorsManager.whiteColors,
// ),
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,
),
),
),
);
} }
} }

View File

@ -5,20 +5,12 @@
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"))

View File

@ -22,7 +22,6 @@
/* 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 */; };
@ -85,7 +84,6 @@
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; };
@ -140,7 +138,6 @@
33CC10EE2044A3C60003C045 /* Products */, 33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */, D73912EC22F37F3D000D13A0 /* Frameworks */,
75DCDFECC7757C5159E8F0C5 /* Pods */, 75DCDFECC7757C5159E8F0C5 /* Pods */,
996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -244,7 +241,6 @@
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 = (
); );
@ -321,7 +317,6 @@
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;
}; };
@ -366,24 +361,6 @@
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;

View File

@ -1,32 +0,0 @@
<?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>

View File

@ -1,14 +1,6 @@
# 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:
@ -161,94 +153,6 @@ 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:
@ -668,10 +572,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_web name: shared_preferences_web
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e sha256: "3a293170d4d9403c3254ee05b84e62e8a9b3c5808ebd17de6a33fe9ea6457936"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.2" version: "2.4.0"
shared_preferences_windows: shared_preferences_windows:
dependency: transitive dependency: transitive
description: description:
@ -873,10 +777,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: web name: web
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "0.5.1"
win32: win32:
dependency: transitive dependency: transitive
description: description:

View File

@ -56,11 +56,6 @@ 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:

View File

@ -40,8 +40,6 @@
<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
@ -56,20 +54,6 @@
} }
}); });
}); });
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>

View File

@ -6,13 +6,10 @@
#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(

View File

@ -3,7 +3,6 @@
# #
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
) )