From b593e75c6741b4fdee9e579294309414619e36fe Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Fri, 23 May 2025 02:17:23 -0500 Subject: [PATCH 01/82] build main structure and build data layer and space managment bloc --- lib/core/network/custom_exceptions.dart | 16 +++ lib/core/network/dio.dart | 36 ++++++ lib/core/network/end_points.dart | 3 + lib/core/network/enums.dart | 50 ++++++++ lib/core/network/request.dart | 121 ++++++++++++++++++ .../communities_bloc/communities_bloc.dart | 37 ++++++ .../communities_bloc/communities_event.dart | 10 ++ .../communities_bloc/communities_state.dart | 30 +++++ .../refactor/data/models/community_model.dart | 21 +++ .../refactor/data/models/device_model.dart | 20 +++ .../refactor/data/models/space_model.dart | 27 ++++ .../refactor/data/models/sub_space_model.dart | 19 +++ .../space_managment_remote_source.dart | 17 +++ .../screens/space_mamagment_screen.dart | 0 14 files changed, 407 insertions(+) create mode 100644 lib/core/network/custom_exceptions.dart create mode 100644 lib/core/network/dio.dart create mode 100644 lib/core/network/end_points.dart create mode 100644 lib/core/network/enums.dart create mode 100644 lib/core/network/request.dart create mode 100644 lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart create mode 100644 lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart create mode 100644 lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart create mode 100644 lib/pages/spaces_management/refactor/data/models/community_model.dart create mode 100644 lib/pages/spaces_management/refactor/data/models/device_model.dart create mode 100644 lib/pages/spaces_management/refactor/data/models/space_model.dart create mode 100644 lib/pages/spaces_management/refactor/data/models/sub_space_model.dart create mode 100644 lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart create mode 100644 lib/pages/spaces_management/refactor/presentation/screens/space_mamagment_screen.dart diff --git a/lib/core/network/custom_exceptions.dart b/lib/core/network/custom_exceptions.dart new file mode 100644 index 00000000..23b81a8d --- /dev/null +++ b/lib/core/network/custom_exceptions.dart @@ -0,0 +1,16 @@ + +import 'enums.dart'; + +class GenericException implements Exception { + final ExceptionType type; + final String errorMessage; + const GenericException( + {required this.type, this.errorMessage = "Unknown Error"}); + + @override + String toString() { + return errorMessage; + } + + List get props => [type, errorMessage]; +} diff --git a/lib/core/network/dio.dart b/lib/core/network/dio.dart new file mode 100644 index 00000000..e01fef90 --- /dev/null +++ b/lib/core/network/dio.dart @@ -0,0 +1,36 @@ +import 'package:dio/dio.dart'; + +import '../../utils/constants/api_const.dart'; + +class DioInstance { + Dio? _dio; + + Dio get dio => _dio ?? _instantiate(); + + String? baseUrl; + + DioInstance({this.baseUrl}); + + Dio _instantiate() { + Dio dio = Dio( + BaseOptions( + baseUrl: baseUrl ?? '${ApiEndpoints.baseUrl}/', + receiveDataWhenStatusError: true, + headers: { + 'content_Type': 'application/json', + }, + ), + ); + + dio.interceptors.add( + LogInterceptor( + responseHeader: false, + requestHeader: false, + requestBody: true, + responseBody: true, + ), + ); + + return dio; + } +} diff --git a/lib/core/network/end_points.dart b/lib/core/network/end_points.dart new file mode 100644 index 00000000..3e2afd84 --- /dev/null +++ b/lib/core/network/end_points.dart @@ -0,0 +1,3 @@ +class EndPoints { + static const String fetchCommunities = 'projects/{projectUuid}/communities'; +} diff --git a/lib/core/network/enums.dart b/lib/core/network/enums.dart new file mode 100644 index 00000000..488d7cb9 --- /dev/null +++ b/lib/core/network/enums.dart @@ -0,0 +1,50 @@ +enum RequestType { + get, + post, + delete, + put, +} + +enum ExceptionType { + notAuthenticated, + connectionError, + // related to http status code exceptions + notAuthorized, + notFound, + internalServerException, + serviceUnavailableException, + pageGone, + + // related to bad request status code + // related to auth requests + invalidCredentials, + solutionAlreadySunmitted, + invalidValidation, + // other + other, +} + +enum ExceptionMessage { + NOT_AUTHENTICATED, + INVALID_CREDENTIALS, + The_password_field_must_be_at_least_8_characters, + SOLUTION_ALREADY_SUBMITTED, + you_are_not_authorized, + page_not_found, + page_gone, + INTERNAL_SERVER_ERROR, + service_unavailable, +} + +enum NotificationsType { + payment, + transporation, + product, + zero, +} + +enum ImagesType { + assets, + svg, + network, +} diff --git a/lib/core/network/request.dart b/lib/core/network/request.dart new file mode 100644 index 00000000..c242b8a6 --- /dev/null +++ b/lib/core/network/request.dart @@ -0,0 +1,121 @@ +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; + +import '../../pages/auth/model/token.dart'; +import 'custom_exceptions.dart'; +import 'dio.dart'; +import 'enums.dart'; + +class Request { + String endPoint; + bool? autherized; + bool? isFormData; + RequestType? method; + Map? headers; + final Map? queryParams; + Map? body; + Duration? receiveTimeout; + Request( + this.endPoint, { + this.autherized, + this.isFormData, + this.method, + this.headers, + this.queryParams, + this.body, + this.receiveTimeout, + }) { + headers = { + 'content_Type': 'application/json', + 'Accept': 'application/json', + }; + } + Future> sendRequest() async { + Response? response; + if (autherized != null && autherized!) { + final storage = const FlutterSecureStorage(); + final token = await storage.read(key: Token.loginAccessTokenKey); + if (token != null) { + headers!["authorization"] = "Bearer $token"; + } + } + try { + response = await DioInstance().dio.request( + endPoint, + queryParameters: queryParams, + data: isFormData != null && isFormData == true + ? FormData.fromMap(body!) + : body, + options: Options( + method: method!.name.toUpperCase(), + headers: headers, + contentType: 'application/json', + receiveTimeout: receiveTimeout, + ), + ); + if (response.statusCode! >= 200 && response.statusCode! < 300) { + return response.data; + } + } on DioException catch (error) { + if (error.type == DioExceptionType.badResponse) { + throw badRequestException[error.response!.data["error"]] ?? + const GenericException( + type: ExceptionType.other, + ); + } + if (error.type == DioExceptionType.connectionError || + error.type == DioExceptionType.connectionTimeout || + error.type == DioExceptionType.receiveTimeout || + error.type == DioExceptionType.sendTimeout || + error.type == DioExceptionType.unknown) { + throw const GenericException( + type: ExceptionType.connectionError, + errorMessage: 'no_internet_connection', + ); + } + } + return {}; + } + + Map toJson() => { + 'endPoint': endPoint, + 'method': method!.name.toUpperCase(), + 'body': json.encode(body), + 'headers': headers, + 'queryParams': queryParams, + 'autherized': autherized, + 'isFormData': isFormData, + }; + @override + String toString() { + return jsonEncode(toJson()); + } + + List get props => [ + endPoint, + autherized, + isFormData, + method, + headers, + queryParams, + body, + receiveTimeout, + ]; +} + +Map badRequestException = { + ExceptionMessage.INVALID_CREDENTIALS.name: const GenericException( + type: ExceptionType.invalidCredentials, + errorMessage: "Invalid credentials ...", + ), + "The password field must be at least 8 characters.": const GenericException( + type: ExceptionType.invalidValidation, + errorMessage: 'password must be 8 or more characters', + ), + ExceptionMessage.NOT_AUTHENTICATED.name: const GenericException( + type: ExceptionType.notAuthenticated, + errorMessage: "not authenticated", + ), +}; diff --git a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart new file mode 100644 index 00000000..286318d5 --- /dev/null +++ b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart @@ -0,0 +1,37 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; + +import '../../data/models/community_model.dart'; +import '../../data/sources/space_managment_remote_source.dart'; + +part 'communities_event.dart'; +part 'communities_state.dart'; + +class CommunitiesBloc extends Bloc { + SpaceManagementRemoteSource spaceManagementRemoteSource = + SpaceManagementRemoteSource(); + CommunitiesBloc() : super(CommunitiesInitial()) { + on((event, emit) { + if (event is FetchCommunitiesEvent) { + _fetchCommunities(emit); + } + }); + } + + Future _fetchCommunities(Emitter emit) async { + String? projectUuid = await ProjectManager.getProjectUUID(); + if (projectUuid == null) { + emit(const CommunitiesError("Project UUID is null")); + return; + } + emit(CommunitiesLoading()); + try { + final communities = + await spaceManagementRemoteSource.fetchCommunities(projectUuid); + emit(CommunitiesLoaded(communities)); + } catch (e) { + emit(CommunitiesError(e.toString())); + } + } +} diff --git a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart new file mode 100644 index 00000000..1d47af23 --- /dev/null +++ b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart @@ -0,0 +1,10 @@ +part of 'communities_bloc.dart'; + +sealed class CommunitiesEvent extends Equatable { + const CommunitiesEvent(); + + @override + List get props => []; +} + +class FetchCommunitiesEvent extends CommunitiesEvent {} \ No newline at end of file diff --git a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart new file mode 100644 index 00000000..747d8d82 --- /dev/null +++ b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart @@ -0,0 +1,30 @@ +part of 'communities_bloc.dart'; + +sealed class CommunitiesState extends Equatable { + const CommunitiesState(); + + @override + List get props => []; +} + +final class CommunitiesInitial extends CommunitiesState {} + +final class CommunitiesLoading extends CommunitiesState {} + +final class CommunitiesLoaded extends CommunitiesState { + final List communities; + + const CommunitiesLoaded(this.communities); + + @override + List get props => [communities]; +} + +final class CommunitiesError extends CommunitiesState { + final String message; + + const CommunitiesError(this.message); + + @override + List get props => [message]; +} diff --git a/lib/pages/spaces_management/refactor/data/models/community_model.dart b/lib/pages/spaces_management/refactor/data/models/community_model.dart new file mode 100644 index 00000000..88c62ad0 --- /dev/null +++ b/lib/pages/spaces_management/refactor/data/models/community_model.dart @@ -0,0 +1,21 @@ +import 'package:syncrow_web/pages/spaces_management/refactor/data/models/space_model.dart'; + +class CommunityModel { + String id, name; + List? spaces; + CommunityModel({ + required this.id, + required this.name, + this.spaces, + }); + + factory CommunityModel.fromJson(Map json) => CommunityModel( + id: json['id'], + name: json['name'], + spaces: SpaceModel.fromJsonList(json['spaces']), + ); + + static List fromJsonList(List jsonList) { + return jsonList.map((json) => CommunityModel.fromJson(json)).toList(); + } +} diff --git a/lib/pages/spaces_management/refactor/data/models/device_model.dart b/lib/pages/spaces_management/refactor/data/models/device_model.dart new file mode 100644 index 00000000..1d000a37 --- /dev/null +++ b/lib/pages/spaces_management/refactor/data/models/device_model.dart @@ -0,0 +1,20 @@ +class DeviceModel { + String id, name, tag; + String location; + DeviceModel({ + required this.id, + required this.name, + required this.tag, + required this.location, + }); + factory DeviceModel.fromJson(Map json) => DeviceModel( + id: json['id'], + name: json['name'], + tag: json['tag'], + location: json['location'], + ); + + static List fromJsonList(List jsonList) { + return jsonList.map((json) => DeviceModel.fromJson(json)).toList(); + } +} diff --git a/lib/pages/spaces_management/refactor/data/models/space_model.dart b/lib/pages/spaces_management/refactor/data/models/space_model.dart new file mode 100644 index 00000000..c2b6d73c --- /dev/null +++ b/lib/pages/spaces_management/refactor/data/models/space_model.dart @@ -0,0 +1,27 @@ +import 'device_model.dart'; + +class SpaceModel { + String id, parentId, name; + List? spaces; + List? devices; + + SpaceModel({ + required this.id, + required this.parentId, + required this.name, + this.spaces, + this.devices, + }); + + factory SpaceModel.fromJson(Map json) => SpaceModel( + id: json['id'], + parentId: json['parentId'], + name: json['name'], + spaces: SpaceModel.fromJsonList(json['spaces']), + devices: DeviceModel.fromJsonList(json['devices']), + ); + + static List fromJsonList(List jsonList) { + return jsonList.map((json) => SpaceModel.fromJson(json)).toList(); + } +} diff --git a/lib/pages/spaces_management/refactor/data/models/sub_space_model.dart b/lib/pages/spaces_management/refactor/data/models/sub_space_model.dart new file mode 100644 index 00000000..2893e0ed --- /dev/null +++ b/lib/pages/spaces_management/refactor/data/models/sub_space_model.dart @@ -0,0 +1,19 @@ +import 'device_model.dart'; + +class SubSpaceModel { + String id, name; + List? devices; + SubSpaceModel({ + required this.id, + required this.name, + this.devices, + }); + factory SubSpaceModel.fromJson(Map json) => SubSpaceModel( + id: json['id'], + name: json['name'], + devices: DeviceModel.fromJsonList(json['devices']), + ); + static List fromJsonList(List jsonList) { + return jsonList.map((json) => SubSpaceModel.fromJson(json)).toList(); + } +} diff --git a/lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart b/lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart new file mode 100644 index 00000000..189cabbf --- /dev/null +++ b/lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart @@ -0,0 +1,17 @@ +import 'package:syncrow_web/core/network/end_points.dart'; +import 'package:syncrow_web/core/network/enums.dart'; +import 'package:syncrow_web/core/network/request.dart'; + +import '../models/community_model.dart'; + +class SpaceManagementRemoteSource { + Future> fetchCommunities(String projectUuid) async { + Request request = Request( + EndPoints.fetchCommunities.replaceFirst('{projectUuid}', projectUuid), + method: RequestType.get, + autherized: true, + ); + final response = await request.sendRequest(); + return CommunityModel.fromJsonList((response['data'])); + } +} diff --git a/lib/pages/spaces_management/refactor/presentation/screens/space_mamagment_screen.dart b/lib/pages/spaces_management/refactor/presentation/screens/space_mamagment_screen.dart new file mode 100644 index 00000000..e69de29b From 9e8ebf37683a499f4aeb085ee2a357439766a0c5 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Fri, 23 May 2025 07:52:21 -0500 Subject: [PATCH 02/82] no need for models and blocs for now --- .../communities_bloc/communities_bloc.dart | 37 ------------------- .../communities_bloc/communities_event.dart | 10 ----- .../communities_bloc/communities_state.dart | 30 --------------- .../refactor/data/models/community_model.dart | 21 ----------- .../refactor/data/models/device_model.dart | 20 ---------- .../refactor/data/models/space_model.dart | 27 -------------- .../refactor/data/models/sub_space_model.dart | 19 ---------- .../space_managment_remote_source.dart | 17 --------- .../screens/space_mamagment_screen.dart | 0 9 files changed, 181 deletions(-) delete mode 100644 lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart delete mode 100644 lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart delete mode 100644 lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart delete mode 100644 lib/pages/spaces_management/refactor/data/models/community_model.dart delete mode 100644 lib/pages/spaces_management/refactor/data/models/device_model.dart delete mode 100644 lib/pages/spaces_management/refactor/data/models/space_model.dart delete mode 100644 lib/pages/spaces_management/refactor/data/models/sub_space_model.dart delete mode 100644 lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart delete mode 100644 lib/pages/spaces_management/refactor/presentation/screens/space_mamagment_screen.dart diff --git a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart deleted file mode 100644 index 286318d5..00000000 --- a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_bloc.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:bloc/bloc.dart'; -import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; - -import '../../data/models/community_model.dart'; -import '../../data/sources/space_managment_remote_source.dart'; - -part 'communities_event.dart'; -part 'communities_state.dart'; - -class CommunitiesBloc extends Bloc { - SpaceManagementRemoteSource spaceManagementRemoteSource = - SpaceManagementRemoteSource(); - CommunitiesBloc() : super(CommunitiesInitial()) { - on((event, emit) { - if (event is FetchCommunitiesEvent) { - _fetchCommunities(emit); - } - }); - } - - Future _fetchCommunities(Emitter emit) async { - String? projectUuid = await ProjectManager.getProjectUUID(); - if (projectUuid == null) { - emit(const CommunitiesError("Project UUID is null")); - return; - } - emit(CommunitiesLoading()); - try { - final communities = - await spaceManagementRemoteSource.fetchCommunities(projectUuid); - emit(CommunitiesLoaded(communities)); - } catch (e) { - emit(CommunitiesError(e.toString())); - } - } -} diff --git a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart deleted file mode 100644 index 1d47af23..00000000 --- a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_event.dart +++ /dev/null @@ -1,10 +0,0 @@ -part of 'communities_bloc.dart'; - -sealed class CommunitiesEvent extends Equatable { - const CommunitiesEvent(); - - @override - List get props => []; -} - -class FetchCommunitiesEvent extends CommunitiesEvent {} \ No newline at end of file diff --git a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart b/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart deleted file mode 100644 index 747d8d82..00000000 --- a/lib/pages/spaces_management/refactor/business_logic/communities_bloc/communities_state.dart +++ /dev/null @@ -1,30 +0,0 @@ -part of 'communities_bloc.dart'; - -sealed class CommunitiesState extends Equatable { - const CommunitiesState(); - - @override - List get props => []; -} - -final class CommunitiesInitial extends CommunitiesState {} - -final class CommunitiesLoading extends CommunitiesState {} - -final class CommunitiesLoaded extends CommunitiesState { - final List communities; - - const CommunitiesLoaded(this.communities); - - @override - List get props => [communities]; -} - -final class CommunitiesError extends CommunitiesState { - final String message; - - const CommunitiesError(this.message); - - @override - List get props => [message]; -} diff --git a/lib/pages/spaces_management/refactor/data/models/community_model.dart b/lib/pages/spaces_management/refactor/data/models/community_model.dart deleted file mode 100644 index 88c62ad0..00000000 --- a/lib/pages/spaces_management/refactor/data/models/community_model.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:syncrow_web/pages/spaces_management/refactor/data/models/space_model.dart'; - -class CommunityModel { - String id, name; - List? spaces; - CommunityModel({ - required this.id, - required this.name, - this.spaces, - }); - - factory CommunityModel.fromJson(Map json) => CommunityModel( - id: json['id'], - name: json['name'], - spaces: SpaceModel.fromJsonList(json['spaces']), - ); - - static List fromJsonList(List jsonList) { - return jsonList.map((json) => CommunityModel.fromJson(json)).toList(); - } -} diff --git a/lib/pages/spaces_management/refactor/data/models/device_model.dart b/lib/pages/spaces_management/refactor/data/models/device_model.dart deleted file mode 100644 index 1d000a37..00000000 --- a/lib/pages/spaces_management/refactor/data/models/device_model.dart +++ /dev/null @@ -1,20 +0,0 @@ -class DeviceModel { - String id, name, tag; - String location; - DeviceModel({ - required this.id, - required this.name, - required this.tag, - required this.location, - }); - factory DeviceModel.fromJson(Map json) => DeviceModel( - id: json['id'], - name: json['name'], - tag: json['tag'], - location: json['location'], - ); - - static List fromJsonList(List jsonList) { - return jsonList.map((json) => DeviceModel.fromJson(json)).toList(); - } -} diff --git a/lib/pages/spaces_management/refactor/data/models/space_model.dart b/lib/pages/spaces_management/refactor/data/models/space_model.dart deleted file mode 100644 index c2b6d73c..00000000 --- a/lib/pages/spaces_management/refactor/data/models/space_model.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'device_model.dart'; - -class SpaceModel { - String id, parentId, name; - List? spaces; - List? devices; - - SpaceModel({ - required this.id, - required this.parentId, - required this.name, - this.spaces, - this.devices, - }); - - factory SpaceModel.fromJson(Map json) => SpaceModel( - id: json['id'], - parentId: json['parentId'], - name: json['name'], - spaces: SpaceModel.fromJsonList(json['spaces']), - devices: DeviceModel.fromJsonList(json['devices']), - ); - - static List fromJsonList(List jsonList) { - return jsonList.map((json) => SpaceModel.fromJson(json)).toList(); - } -} diff --git a/lib/pages/spaces_management/refactor/data/models/sub_space_model.dart b/lib/pages/spaces_management/refactor/data/models/sub_space_model.dart deleted file mode 100644 index 2893e0ed..00000000 --- a/lib/pages/spaces_management/refactor/data/models/sub_space_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'device_model.dart'; - -class SubSpaceModel { - String id, name; - List? devices; - SubSpaceModel({ - required this.id, - required this.name, - this.devices, - }); - factory SubSpaceModel.fromJson(Map json) => SubSpaceModel( - id: json['id'], - name: json['name'], - devices: DeviceModel.fromJsonList(json['devices']), - ); - static List fromJsonList(List jsonList) { - return jsonList.map((json) => SubSpaceModel.fromJson(json)).toList(); - } -} diff --git a/lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart b/lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart deleted file mode 100644 index 189cabbf..00000000 --- a/lib/pages/spaces_management/refactor/data/sources/space_managment_remote_source.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:syncrow_web/core/network/end_points.dart'; -import 'package:syncrow_web/core/network/enums.dart'; -import 'package:syncrow_web/core/network/request.dart'; - -import '../models/community_model.dart'; - -class SpaceManagementRemoteSource { - Future> fetchCommunities(String projectUuid) async { - Request request = Request( - EndPoints.fetchCommunities.replaceFirst('{projectUuid}', projectUuid), - method: RequestType.get, - autherized: true, - ); - final response = await request.sendRequest(); - return CommunityModel.fromJsonList((response['data'])); - } -} diff --git a/lib/pages/spaces_management/refactor/presentation/screens/space_mamagment_screen.dart b/lib/pages/spaces_management/refactor/presentation/screens/space_mamagment_screen.dart deleted file mode 100644 index e69de29b..00000000 From e0951aa13ded4900049b30ccfc7c6eb37fac8850 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Fri, 23 May 2025 08:52:53 -0500 Subject: [PATCH 03/82] add interceptor to print request and response --- lib/services/api/http_service.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/services/api/http_service.dart b/lib/services/api/http_service.dart index b75f05cf..af5b60fe 100644 --- a/lib/services/api/http_service.dart +++ b/lib/services/api/http_service.dart @@ -22,6 +22,18 @@ class HTTPService { ); client.interceptors.add(serviceLocator.get()); + // Add this interceptor for logging requests and responses + client.interceptors.add( + LogInterceptor( + request: true, + requestHeader: true, + requestBody: true, + responseHeader: false, + responseBody: true, + error: true, + logPrint: (object) => print(object), + ), + ); return client; } From 0b65c589476a6c4618743f6f171e72fcf6ec07e2 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Mon, 26 May 2025 02:45:58 -0500 Subject: [PATCH 04/82] fix add subspace bugs and plusButton widget --- .../widgets/community_structure_widget.dart | 75 ++++++--- .../widgets/dialogs/create_space_dialog.dart | 147 ++++++++++++------ .../widgets/plus_button_widget.dart | 55 ++++--- .../all_spaces/widgets/space_card_widget.dart | 51 +++--- .../views/create_subspace_model_dialog.dart | 50 +++++- 5 files changed, 242 insertions(+), 136 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index a93679d0..16ecae36 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -67,7 +67,8 @@ class _CommunityStructureAreaState extends State { void initState() { super.initState(); spaces = widget.spaces.isNotEmpty ? flattenSpaces(widget.spaces) : []; - connections = widget.spaces.isNotEmpty ? createConnections(widget.spaces) : []; + connections = + widget.spaces.isNotEmpty ? createConnections(widget.spaces) : []; _adjustCanvasSizeForSpaces(); _nameController = TextEditingController( text: widget.selectedCommunity?.name ?? '', @@ -96,13 +97,15 @@ class _CommunityStructureAreaState extends State { if (oldWidget.spaces != widget.spaces) { setState(() { spaces = widget.spaces.isNotEmpty ? flattenSpaces(widget.spaces) : []; - connections = widget.spaces.isNotEmpty ? createConnections(widget.spaces) : []; + connections = + widget.spaces.isNotEmpty ? createConnections(widget.spaces) : []; _adjustCanvasSizeForSpaces(); realignTree(); }); } - if (widget.selectedSpace != oldWidget.selectedSpace && widget.selectedSpace != null) { + if (widget.selectedSpace != oldWidget.selectedSpace && + widget.selectedSpace != null) { WidgetsBinding.instance.addPostFrameCallback((_) { _moveToSpace(widget.selectedSpace!); }); @@ -185,7 +188,8 @@ class _CommunityStructureAreaState extends State { connection, widget.selectedSpace) ? 1.0 : 0.3, // Adjust opacity - child: CustomPaint(painter: CurvedLinePainter([connection])), + child: CustomPaint( + painter: CurvedLinePainter([connection])), ), for (var entry in spaces.asMap().entries) if (entry.value.status != SpaceStatus.deleted && @@ -195,9 +199,11 @@ class _CommunityStructureAreaState extends State { top: entry.value.position.dy, child: SpaceCardWidget( index: entry.key, - onButtonTap: (int index, Offset newPosition, String direction) { + onButtonTap: (int index, Offset newPosition, + String direction) { _showCreateSpaceDialog(screenSize, - position: spaces[index].position + newPosition, + position: + spaces[index].position + newPosition, parentIndex: index, direction: direction, projectTags: widget.projectTags); @@ -210,8 +216,9 @@ class _CommunityStructureAreaState extends State { _updateNodePosition(entry.value, newPosition); }, buildSpaceContainer: (int index) { - final bool isHighlighted = SpaceHelper.isHighlightedSpace( - spaces[index], widget.selectedSpace); + final bool isHighlighted = + SpaceHelper.isHighlightedSpace( + spaces[index], widget.selectedSpace); return Opacity( opacity: isHighlighted ? 1.0 : 0.3, @@ -299,19 +306,25 @@ class _CommunityStructureAreaState extends State { return CreateSpaceDialog( products: widget.products, spaceModels: widget.spaceModels, - allTags: TagHelper.getAllTagValues(widget.communities, widget.spaceModels), + allTags: + TagHelper.getAllTagValues(widget.communities, widget.spaceModels), parentSpace: parentIndex != null ? spaces[parentIndex] : null, projectTags: projectTags, - onCreateSpace: (String name, String icon, List selectedProducts, - SpaceTemplateModel? spaceModel, List? subspaces, List? tags) { + onCreateSpace: (String name, + String icon, + List selectedProducts, + SpaceTemplateModel? spaceModel, + List? subspaces, + List? tags) { setState(() { // Set the first space in the center or use passed position Offset newPosition; if (parentIndex != null) { - newPosition = - getBalancedChildPosition(spaces[parentIndex]); // Ensure balanced position + newPosition = getBalancedChildPosition( + spaces[parentIndex]); // Ensure balanced position } else { - newPosition = position ?? ConnectionHelper.getCenterPosition(screenSize); + newPosition = + position ?? ConnectionHelper.getCenterPosition(screenSize); } SpaceModel newSpace = SpaceModel( @@ -360,16 +373,21 @@ class _CommunityStructureAreaState extends State { name: widget.selectedSpace!.name, icon: widget.selectedSpace!.icon, projectTags: widget.projectTags, - parentSpace: - SpaceHelper.findSpaceByInternalId(widget.selectedSpace?.parent?.internalId, spaces), + parentSpace: SpaceHelper.findSpaceByInternalId( + widget.selectedSpace?.parent?.internalId, spaces), editSpace: widget.selectedSpace, currentSpaceModel: widget.selectedSpace?.spaceModel, tags: widget.selectedSpace?.tags, subspaces: widget.selectedSpace?.subspaces, isEdit: true, - allTags: TagHelper.getAllTagValues(widget.communities, widget.spaceModels), - onCreateSpace: (String name, String icon, List selectedProducts, - SpaceTemplateModel? spaceModel, List? subspaces, List? tags) { + allTags: TagHelper.getAllTagValues( + widget.communities, widget.spaceModels), + onCreateSpace: (String name, + String icon, + List selectedProducts, + SpaceTemplateModel? spaceModel, + List? subspaces, + List? tags) { setState(() { // Update the space's properties widget.selectedSpace!.name = name; @@ -379,7 +397,8 @@ class _CommunityStructureAreaState extends State { widget.selectedSpace!.tags = tags; if (widget.selectedSpace!.status != SpaceStatus.newSpace) { - widget.selectedSpace!.status = SpaceStatus.modified; // Mark as modified + widget.selectedSpace!.status = + SpaceStatus.modified; // Mark as modified } for (var space in spaces) { @@ -410,7 +429,8 @@ class _CommunityStructureAreaState extends State { Map idToSpace = {}; void flatten(SpaceModel space) { - if (space.status == SpaceStatus.deleted || space.status == SpaceStatus.parentDeleted) { + if (space.status == SpaceStatus.deleted || + space.status == SpaceStatus.parentDeleted) { return; } result.add(space); @@ -532,13 +552,16 @@ class _CommunityStructureAreaState extends State { void _selectSpace(BuildContext context, SpaceModel space) { context.read().add( - SelectSpaceEvent(selectedCommunity: widget.selectedCommunity, selectedSpace: space), + SelectSpaceEvent( + selectedCommunity: widget.selectedCommunity, + selectedSpace: space), ); } void _deselectSpace(BuildContext context) { context.read().add( - SelectSpaceEvent(selectedCommunity: widget.selectedCommunity, selectedSpace: null), + SelectSpaceEvent( + selectedCommunity: widget.selectedCommunity, selectedSpace: null), ); } @@ -708,7 +731,8 @@ class _CommunityStructureAreaState extends State { SpaceModel duplicated = _deepCloneSpaceTree(space, parent: parent); - duplicated.position = Offset(space.position.dx + 300, space.position.dy + 100); + duplicated.position = + Offset(space.position.dx + 300, space.position.dy + 100); List duplicatedSubtree = []; void collectSubtree(SpaceModel node) { duplicatedSubtree.add(node); @@ -739,7 +763,8 @@ class _CommunityStructureAreaState extends State { } SpaceModel _deepCloneSpaceTree(SpaceModel original, {SpaceModel? parent}) { - final duplicatedName = SpaceHelper.generateUniqueSpaceName(original.name, spaces); + final duplicatedName = + SpaceHelper.generateUniqueSpaceName(original.name, spaces); final newSpace = SpaceModel( name: duplicatedName, diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index e9dde6f8..b3d1e358 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -82,8 +82,10 @@ class CreateSpaceDialogState extends State { super.initState(); selectedIcon = widget.icon ?? Assets.location; nameController = TextEditingController(text: widget.name ?? ''); - selectedProducts = widget.selectedProducts.isNotEmpty ? widget.selectedProducts : []; - isOkButtonEnabled = enteredName.isNotEmpty || nameController.text.isNotEmpty; + selectedProducts = + widget.selectedProducts.isNotEmpty ? widget.selectedProducts : []; + isOkButtonEnabled = + enteredName.isNotEmpty || nameController.text.isNotEmpty; if (widget.currentSpaceModel != null) { subspaces = []; tags = []; @@ -96,13 +98,15 @@ class CreateSpaceDialogState extends State { @override Widget build(BuildContext context) { - bool isSpaceModelDisabled = - (tags != null && tags!.isNotEmpty || subspaces != null && subspaces!.isNotEmpty); + bool isSpaceModelDisabled = (tags != null && tags!.isNotEmpty || + subspaces != null && subspaces!.isNotEmpty); bool isTagsAndSubspaceModelDisabled = (selectedSpaceModel != null); final screenWidth = MediaQuery.of(context).size.width; return AlertDialog( - title: widget.isEdit ? const Text('Edit Space') : const Text('Create New Space'), + title: widget.isEdit + ? const Text('Edit Space') + : const Text('Create New Space'), backgroundColor: ColorsManager.whiteColors, content: SizedBox( width: screenWidth * 0.5, @@ -176,8 +180,8 @@ class CreateSpaceDialogState extends State { isNameFieldInvalid = value.isEmpty; if (!isNameFieldInvalid) { - if (SpaceHelper.isNameConflict( - value, widget.parentSpace, widget.editSpace)) { + if (SpaceHelper.isNameConflict(value, + widget.parentSpace, widget.editSpace)) { isNameFieldExist = true; isOkButtonEnabled = false; } else { @@ -244,7 +248,9 @@ class CreateSpaceDialogState extends State { padding: EdgeInsets.zero, ), onPressed: () { - isSpaceModelDisabled ? null : _showLinkSpaceModelDialog(context); + isSpaceModelDisabled + ? null + : _showLinkSpaceModelDialog(context); }, child: ButtonContentWidget( svgAssets: Assets.link, @@ -254,7 +260,8 @@ class CreateSpaceDialogState extends State { ) : Container( width: screenWidth * 0.25, - padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0), + padding: const EdgeInsets.symmetric( + vertical: 10.0, horizontal: 16.0), decoration: BoxDecoration( color: ColorsManager.boxColor, borderRadius: BorderRadius.circular(10), @@ -269,7 +276,8 @@ class CreateSpaceDialogState extends State { style: Theme.of(context) .textTheme .bodyMedium! - .copyWith(color: ColorsManager.spaceColor), + .copyWith( + color: ColorsManager.spaceColor), ), backgroundColor: ColorsManager.whiteColors, shape: RoundedRectangleBorder( @@ -340,12 +348,12 @@ class CreateSpaceDialogState extends State { onPressed: () async { isTagsAndSubspaceModelDisabled ? null - : _showSubSpaceDialog( - context, enteredName, [], false, widget.products, subspaces); + : _showSubSpaceDialog(context, enteredName, + [], false, widget.products, subspaces); }, child: ButtonContentWidget( icon: Icons.add, - label: 'Create Sub Space', + label: 'Create Sub Spaces', disabled: isTagsAndSubspaceModelDisabled, ), ) @@ -368,16 +376,22 @@ class CreateSpaceDialogState extends State { if (subspaces != null) ...subspaces!.map((subspace) { return Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ SubspaceNameDisplayWidget( text: subspace.subspaceName, validateName: (updatedName) { - bool nameExists = subspaces!.any((s) { - bool isSameId = s.internalId == subspace.internalId; - bool isSameName = - s.subspaceName.trim().toLowerCase() == - updatedName.trim().toLowerCase(); + bool nameExists = + subspaces!.any((s) { + bool isSameId = s.internalId == + subspace.internalId; + bool isSameName = s.subspaceName + .trim() + .toLowerCase() == + updatedName + .trim() + .toLowerCase(); return !isSameId && isSameName; }); @@ -386,7 +400,8 @@ class CreateSpaceDialogState extends State { }, onNameChanged: (updatedName) { setState(() { - subspace.subspaceName = updatedName; + subspace.subspaceName = + updatedName; }); }, ), @@ -395,8 +410,8 @@ class CreateSpaceDialogState extends State { }), EditChip( onTap: () async { - _showSubSpaceDialog(context, enteredName, [], true, - widget.products, subspaces); + _showSubSpaceDialog(context, enteredName, + [], true, widget.products, subspaces); }, ) ], @@ -405,7 +420,9 @@ class CreateSpaceDialogState extends State { ), const SizedBox(height: 10), (tags?.isNotEmpty == true || - subspaces?.any((subspace) => subspace.tags?.isNotEmpty == true) == true) + subspaces?.any((subspace) => + subspace.tags?.isNotEmpty == true) == + true) ? SizedBox( width: screenWidth * 0.25, child: Container( @@ -425,14 +442,16 @@ class CreateSpaceDialogState extends State { // Combine tags from spaceModel and subspaces ...TagHelper.groupTags([ ...?tags, - ...?subspaces?.expand((subspace) => subspace.tags ?? []) + ...?subspaces?.expand( + (subspace) => subspace.tags ?? []) ]).entries.map( (entry) => Chip( avatar: SizedBox( width: 24, height: 24, child: SvgPicture.asset( - entry.key.icon ?? 'assets/icons/gateway.svg', + entry.key.icon ?? + 'assets/icons/gateway.svg', fit: BoxFit.contain, ), ), @@ -441,11 +460,15 @@ class CreateSpaceDialogState extends State { style: Theme.of(context) .textTheme .bodySmall - ?.copyWith(color: ColorsManager.spaceColor), + ?.copyWith( + color: ColorsManager + .spaceColor), ), - backgroundColor: ColorsManager.whiteColors, + backgroundColor: + ColorsManager.whiteColors, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), + borderRadius: + BorderRadius.circular(16), side: const BorderSide( color: ColorsManager.spaceColor, ), @@ -460,15 +483,18 @@ class CreateSpaceDialogState extends State { products: widget.products, subspaces: subspaces, allTags: widget.allTags, - addedProducts: - TagHelper.createInitialSelectedProductsForTags( + addedProducts: TagHelper + .createInitialSelectedProductsForTags( tags ?? [], subspaces), title: 'Edit Device', - initialTags: TagHelper.generateInitialForTags( - spaceTags: tags, subspaces: subspaces), + initialTags: + TagHelper.generateInitialForTags( + spaceTags: tags, + subspaces: subspaces), spaceName: widget.name ?? '', projectTags: widget.projectTags, - onSave: (updatedTags, updatedSubspaces) { + onSave: + (updatedTags, updatedSubspaces) { setState(() { tags = updatedTags; subspaces = updatedSubspaces; @@ -529,17 +555,25 @@ class CreateSpaceDialogState extends State { } else if (isNameFieldExist) { return; } else { - String newName = enteredName.isNotEmpty ? enteredName : (widget.name ?? ''); + String newName = enteredName.isNotEmpty + ? enteredName + : (widget.name ?? ''); if (newName.isNotEmpty) { - widget.onCreateSpace(newName, selectedIcon, selectedProducts, - selectedSpaceModel, subspaces, tags); + widget.onCreateSpace( + newName, + selectedIcon, + selectedProducts, + selectedSpaceModel, + subspaces, + tags); Navigator.of(context).pop(); } } }, borderRadius: 10, - backgroundColor: - isOkButtonEnabled ? ColorsManager.secondaryColor : ColorsManager.grayColor, + backgroundColor: isOkButtonEnabled + ? ColorsManager.secondaryColor + : ColorsManager.grayColor, foregroundColor: ColorsManager.whiteColors, child: const Text('OK'), ), @@ -586,24 +620,31 @@ class CreateSpaceDialogState extends State { ); } - void _showSubSpaceDialog(BuildContext context, String name, final List? spaceTags, - bool isEdit, List? products, final List? existingSubSpaces) { + void _showSubSpaceDialog( + BuildContext context, + String name, + final List? spaceTags, + bool isEdit, + List? products, + final List? existingSubSpaces) { showDialog( context: context, builder: (BuildContext context) { return CreateSubSpaceDialog( spaceName: name, - dialogTitle: isEdit ? 'Edit Sub-space' : 'Create Sub-space', + dialogTitle: isEdit ? 'Edit Sub-spaces' : 'Create Sub-spaces', products: products, existingSubSpaces: existingSubSpaces, onSave: (slectedSubspaces) { final List tagsToAppendToSpace = []; - if (slectedSubspaces != null) { - final updatedIds = slectedSubspaces.map((s) => s.internalId).toSet(); + if (slectedSubspaces != null && slectedSubspaces.isNotEmpty) { + final updatedIds = + slectedSubspaces.map((s) => s.internalId).toSet(); if (existingSubSpaces != null) { - final deletedSubspaces = - existingSubSpaces.where((s) => !updatedIds.contains(s.internalId)).toList(); + final deletedSubspaces = existingSubSpaces + .where((s) => !updatedIds.contains(s.internalId)) + .toList(); for (var s in deletedSubspaces) { if (s.tags != null) { tagsToAppendToSpace.addAll(s.tags!); @@ -623,15 +664,16 @@ class CreateSpaceDialogState extends State { ); } - void _showTagCreateDialog( - BuildContext context, String name, bool isEdit, List? products) { + void _showTagCreateDialog(BuildContext context, String name, bool isEdit, + List? products) { isEdit ? showDialog( context: context, builder: (BuildContext context) { return AssignTagDialog( title: 'Edit Device', - addedProducts: TagHelper.createInitialSelectedProductsForTags(tags, subspaces), + addedProducts: TagHelper.createInitialSelectedProductsForTags( + tags, subspaces), spaceName: name, products: products, subspaces: subspaces, @@ -646,7 +688,8 @@ class CreateSpaceDialogState extends State { if (subspaces != null) { for (final subspace in subspaces!) { for (final selectedSubspace in selectedSubspaces) { - if (subspace.subspaceName == selectedSubspace.subspaceName) { + if (subspace.subspaceName == + selectedSubspace.subspaceName) { subspace.tags = selectedSubspace.tags; } } @@ -670,7 +713,8 @@ class CreateSpaceDialogState extends State { allTags: widget.allTags, projectTags: widget.projectTags, initialSelectedProducts: - TagHelper.createInitialSelectedProductsForTags(tags, subspaces), + TagHelper.createInitialSelectedProductsForTags( + tags, subspaces), onSave: (selectedSpaceTags, selectedSubspaces) { setState(() { tags = selectedSpaceTags; @@ -680,7 +724,8 @@ class CreateSpaceDialogState extends State { if (subspaces != null) { for (final subspace in subspaces!) { for (final selectedSubspace in selectedSubspaces) { - if (subspace.subspaceName == selectedSubspace.subspaceName) { + if (subspace.subspaceName == + selectedSubspace.subspaceName) { subspace.tags = selectedSubspace.tags; } } diff --git a/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart index 40be7284..280816a0 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart @@ -17,36 +17,33 @@ class PlusButtonWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Positioned( - left: offset.dx, - top: offset.dy, - child: GestureDetector( - onTap: () { - Offset newPosition; - switch (direction) { - case 'left': - newPosition = const Offset(-200, 0); - break; - case 'right': - newPosition = const Offset(200, 0); - break; - case 'down': - newPosition = const Offset(0, 150); - break; - default: - newPosition = Offset.zero; - } - onButtonTap(index, newPosition, direction); - }, - child: Container( - width: 30, - height: 30, - decoration: const BoxDecoration( - color: ColorsManager.spaceColor, - shape: BoxShape.circle, - ), - child: const Icon(Icons.add, color: ColorsManager.whiteColors, size: 20), + return GestureDetector( + onTap: () { + Offset newPosition; + switch (direction) { + case 'left': + newPosition = const Offset(-200, 0); + break; + case 'right': + newPosition = const Offset(200, 0); + break; + case 'down': + newPosition = const Offset(0, 150); + break; + default: + newPosition = Offset.zero; + } + onButtonTap(index, newPosition, direction); + }, + child: Container( + width: 30, + height: 30, + decoration: const BoxDecoration( + color: ColorsManager.spaceColor, + shape: BoxShape.circle, ), + child: + const Icon(Icons.add, color: ColorsManager.whiteColors, size: 20), ), ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart index f3a476b2..49df9daa 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart @@ -25,35 +25,34 @@ class SpaceCardWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onPanUpdate: (details) { - // Call the provided callback to update the position - final newPosition = position + details.delta; - onPositionChanged(newPosition); - }, - child: MouseRegion( - onEnter: (_) { - // Call the provided callback to handle hover state - onHoverChanged(index, true); - }, - onExit: (_) { - // Call the provided callback to handle hover state - onHoverChanged(index, false); - }, + return MouseRegion( + onEnter: (_) => onHoverChanged(index, true), + onExit: (_) => onHoverChanged(index, false), + child: SizedBox( + width: 140, // Make sure this covers both card and plus button + height: 90, child: Stack( - clipBehavior: Clip - .none, // Allow hovering elements to be displayed outside the boundary + clipBehavior: Clip.none, children: [ - buildSpaceContainer(index), // Build the space container - if (isHovered) ...[ - PlusButtonWidget( - index: index, - direction: 'down', - offset: const Offset(63, 50), - onButtonTap: onButtonTap, + // Main card + Container( + width: 140, + height: 80, + alignment: Alignment.center, + color: Colors.transparent, + child: buildSpaceContainer(index), + ), + // Plus button (NO inner Positioned!) + if (isHovered) + Align( + alignment: Alignment.bottomCenter, + child: PlusButtonWidget( + index: index, + direction: 'down', + offset: Offset.zero, + onButtonTap: onButtonTap, + ), ), - ], ], ), ), diff --git a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart index 948028ed..483382af 100644 --- a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart +++ b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart @@ -79,6 +79,22 @@ class _CreateSubSpaceDialogState extends State { color: ColorsManager.blackColor, ), ), + Row( + children: [ + Text( + 'press Enter to Save', + style: context.textTheme.headlineLarge?.copyWith( + fontWeight: FontWeight.w500, + fontSize: 10, + color: ColorsManager.grayColor, + ), + ), + const SizedBox( + width: 5, + ), + const Icon(Icons.save_as_sharp, size: 10), + ], + ), const SizedBox(height: 16), Container( width: context.screenWidth * 0.35, @@ -101,13 +117,15 @@ class _CreateSubSpaceDialogState extends State { final index = entry.key; final subSpace = entry.value; - final lowerName = subSpace.subspaceName.toLowerCase(); + final lowerName = + subSpace.subspaceName.toLowerCase(); final duplicateIndices = state.subSpaces .asMap() .entries .where((e) => - e.value.subspaceName.toLowerCase() == lowerName) + e.value.subspaceName.toLowerCase() == + lowerName) .map((e) => e.key) .toList(); final isDuplicate = duplicateIndices.length > 1 && @@ -182,10 +200,32 @@ class _CreateSubSpaceDialogState extends State { Expanded( child: DefaultButton( onPressed: state.errorMessage.isEmpty - ? () { - final subSpacesBloc = context.read(); - final subSpaces = subSpacesBloc.state.subSpaces; + ? () async { + final trimmedValue = + _subspaceNameController.text.trim(); + + final subSpacesBloc = + context.read(); + if (trimmedValue.isNotEmpty) { + subSpacesBloc.add( + AddSubSpace( + SubspaceModel( + subspaceName: trimmedValue, + disabled: false, + ), + ), + ); + _subspaceNameController.clear(); + } + + await Future.delayed( + const Duration(milliseconds: 10)); + final subSpaces = + subSpacesBloc.state.subSpaces; + // if (subSpaces.isNotEmpty) { widget.onSave?.call(subSpaces); + // } + Navigator.of(context).pop(); } : null, From c97dd40b058b15330d57aeb82ee18602376c6e56 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Mon, 26 May 2025 06:11:06 -0500 Subject: [PATCH 05/82] add toSelected function to convert from product to selectedProduct --- .../all_spaces/model/product_model.dart | 11 +++++++++++ .../tag_model/widgets/device_type_tile_widget.dart | 8 ++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/model/product_model.dart b/lib/pages/spaces_management/all_spaces/model/product_model.dart index a4ebd550..8f905032 100644 --- a/lib/pages/spaces_management/all_spaces/model/product_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/product_model.dart @@ -1,5 +1,7 @@ import 'package:syncrow_web/utils/constants/assets.dart'; +import 'selected_product_model.dart'; + class ProductModel { final String uuid; final String catName; @@ -38,6 +40,15 @@ class ProductModel { }; } + SelectedProduct toSelectedProduct(int count) { + return SelectedProduct( + productId: uuid, + count: count, + productName: name!, + product: this, + ); + } + static String _mapIconToProduct(String prodType) { const iconMapping = { '1G': Assets.Gang1SwitchIcon, diff --git a/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart b/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart index 7d103cdb..3d645d7c 100644 --- a/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart +++ b/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart @@ -54,10 +54,10 @@ class DeviceTypeTileWidget extends StatelessWidget { onCountChanged: (newCount) { context.read().add( UpdateProductCountEvent( - productId: product.uuid, - count: newCount, - productName: product.catName, - product: product), + selectedProduct: product.toSelectedProduct( + newCount, + ), + ), ); }, ), From 766a39f161c5f5cbc50041bd2c1b312acf867d86 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Mon, 26 May 2025 06:11:48 -0500 Subject: [PATCH 06/82] use selected model in add device event --- lib/common/tag_dialog_textfield_dropdown.dart | 23 +++++++++++---- .../tag_model/bloc/add_device_model_bloc.dart | 29 +++++-------------- .../bloc/add_device_type_model_event.dart | 11 ++----- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/lib/common/tag_dialog_textfield_dropdown.dart b/lib/common/tag_dialog_textfield_dropdown.dart index 219e03ce..6bc22fc0 100644 --- a/lib/common/tag_dialog_textfield_dropdown.dart +++ b/lib/common/tag_dialog_textfield_dropdown.dart @@ -17,7 +17,8 @@ class TagDialogTextfieldDropdown extends StatefulWidget { }) : super(key: key); @override - _DialogTextfieldDropdownState createState() => _DialogTextfieldDropdownState(); + _DialogTextfieldDropdownState createState() => + _DialogTextfieldDropdownState(); } class _DialogTextfieldDropdownState extends State { @@ -36,6 +37,12 @@ class _DialogTextfieldDropdownState extends State { _focusNode.addListener(() { if (!_focusNode.hasFocus) { + // Call onSelected when focus is lost + final selectedTag = _filteredItems.firstWhere( + (tag) => tag.tag == _controller.text, + orElse: () => Tag(tag: _controller.text), + ); + widget.onSelected(selectedTag); _closeDropdown(); } }); @@ -43,7 +50,9 @@ class _DialogTextfieldDropdownState extends State { void _filterItems() { setState(() { - _filteredItems = widget.items.where((tag) => tag.product?.uuid == widget.product).toList(); + _filteredItems = widget.items + .where((tag) => tag.product?.uuid == widget.product) + .toList(); }); } @@ -112,7 +121,9 @@ class _DialogTextfieldDropdownState extends State { style: Theme.of(context) .textTheme .bodyMedium - ?.copyWith(color: ColorsManager.textPrimaryColor)), + ?.copyWith( + color: ColorsManager + .textPrimaryColor)), onTap: () { _controller.text = tag.tag ?? ''; widget.onSelected(tag); @@ -156,13 +167,15 @@ class _DialogTextfieldDropdownState extends State { controller: _controller, focusNode: _focusNode, onFieldSubmitted: (value) { - final selectedTag = _filteredItems.firstWhere((tag) => tag.tag == value, + final selectedTag = _filteredItems.firstWhere( + (tag) => tag.tag == value, orElse: () => Tag(tag: value)); widget.onSelected(selectedTag); _closeDropdown(); }, onTapOutside: (event) { - widget.onSelected(_filteredItems.firstWhere((tag) => tag.tag == _controller.text, + widget.onSelected(_filteredItems.firstWhere( + (tag) => tag.tag == _controller.text, orElse: () => Tag(tag: _controller.text))); _closeDropdown(); }, diff --git a/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart b/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart index 9c617a12..a0081c22 100644 --- a/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart +++ b/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart @@ -24,37 +24,22 @@ class AddDeviceTypeModelBloc if (currentState is AddDeviceModelLoaded) { final existingProduct = currentState.selectedProducts.firstWhere( - (p) => p.productId == event.productId, - orElse: () => SelectedProduct( - productId: event.productId, - count: 0, - productName: event.productName, - product: event.product, - ), + (p) => p.productId == event.selectedProduct.productId, + orElse: () => event.selectedProduct, ); List updatedProducts; - if (event.count > 0) { + if (event.selectedProduct.count > 0) { if (!currentState.selectedProducts.contains(existingProduct)) { updatedProducts = [ ...currentState.selectedProducts, - SelectedProduct( - productId: event.productId, - count: event.count, - productName: event.productName, - product: event.product, - ), + event.selectedProduct, ]; } else { updatedProducts = currentState.selectedProducts.map((p) { - if (p.productId == event.productId) { - return SelectedProduct( - productId: p.productId, - count: event.count, - productName: p.productName, - product: p.product, - ); + if (p.productId == event.selectedProduct.productId) { + return event.selectedProduct; } return p; }).toList(); @@ -62,7 +47,7 @@ class AddDeviceTypeModelBloc } else { // Remove the product if the count is 0 updatedProducts = currentState.selectedProducts - .where((p) => p.productId != event.productId) + .where((p) => p.productId != event.selectedProduct.productId) .toList(); } diff --git a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart index b9018b2b..27f183a6 100644 --- a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart +++ b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart @@ -10,20 +10,15 @@ abstract class AddDeviceTypeModelEvent extends Equatable { List get props => []; } - class UpdateProductCountEvent extends AddDeviceTypeModelEvent { - final String productId; - final int count; - final String productName; - final ProductModel product; + final SelectedProduct selectedProduct; - UpdateProductCountEvent({required this.productId, required this.count, required this.productName, required this.product}); + UpdateProductCountEvent({required this.selectedProduct}); @override - List get props => [productId, count]; + List get props => [selectedProduct]; } - class InitializeDeviceTypeModel extends AddDeviceTypeModelEvent { final List initialTags; final List addedProducts; From 644fe56478d79c2159a54d2a3dfa27eb48d7274e Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Mon, 26 May 2025 06:12:24 -0500 Subject: [PATCH 07/82] seperaate UI into widgets --- .../views/assign_tag_models_dialog.dart | 257 ++---------------- .../views/widgets/RowOfCancelSaveWidget.dart | 152 +++++++++++ .../widgets/assign_tags_tables_widget.dart | 172 ++++++++++++ 3 files changed, 344 insertions(+), 237 deletions(-) create mode 100644 lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart create mode 100644 lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart diff --git a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart index 85be3bf3..873c7dd6 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart @@ -1,9 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/common/dialog_dropdown.dart'; -import 'package:syncrow_web/common/tag_dialog_textfield_dropdown.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/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; @@ -12,11 +8,9 @@ import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assig import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_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/subspace_template_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart'; -import 'package:syncrow_web/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; -import 'package:uuid/uuid.dart'; + +import 'widgets/assign_tags_tables_widget.dart'; class AssignTagModelsDialog extends StatelessWidget { final List? products; @@ -53,8 +47,10 @@ class AssignTagModelsDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final List locations = - (subspaces ?? []).map((subspace) => subspace.subspaceName).toList()..add('Main Space'); + final List locations = (subspaces ?? []) + .map((subspace) => subspace.subspaceName) + .toList() + ..add('Main Space'); return BlocProvider( create: (_) => AssignTagModelBloc(projectTags) @@ -78,137 +74,9 @@ class AssignTagModelsDialog extends StatelessWidget { content: SingleChildScrollView( child: Column( children: [ - ClipRRect( - borderRadius: BorderRadius.circular(20), - child: DataTable( - headingRowColor: WidgetStateProperty.all(ColorsManager.dataHeaderGrey), - key: ValueKey(state.tags.length), - border: TableBorder.all( - color: ColorsManager.dataHeaderGrey, - width: 1, - borderRadius: BorderRadius.circular(20), - ), - columns: [ - DataColumn( - label: Text('#', style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: Text('Device', - style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - numeric: false, - label: - Text('Tag', style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: Text('Location', - style: Theme.of(context).textTheme.bodyMedium)), - ], - rows: state.tags.isEmpty - ? [ - DataRow(cells: [ - DataCell( - Center( - child: Text('No Devices Available', - style: - Theme.of(context).textTheme.bodyMedium?.copyWith( - color: ColorsManager.lightGrayColor, - )), - ), - ), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - ]) - ] - : List.generate(state.tags.length, (index) { - final tag = state.tags[index]; - final controller = controllers[index]; - - return DataRow( - cells: [ - DataCell(Text((index + 1).toString())), - DataCell( - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - tag.product?.name ?? 'Unknown', - overflow: TextOverflow.ellipsis, - )), - const SizedBox(width: 10), - Container( - width: 20.0, - height: 20.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.lightGrayColor, - width: 1.0, - ), - ), - child: IconButton( - icon: const Icon( - Icons.close, - color: ColorsManager.lightGreyColor, - size: 16, - ), - onPressed: () { - context.read().add( - DeleteTagModel( - tagToDelete: tag, tags: state.tags)); - controllers.removeAt(index); - }, - tooltip: 'Delete Tag', - padding: EdgeInsets.zero, - constraints: const BoxConstraints(), - ), - ), - ], - ), - ), - DataCell( - Container( - alignment: Alignment - .centerLeft, // Align cell content to the left - child: SizedBox( - width: double.infinity, - child: TagDialogTextfieldDropdown( - key: ValueKey( - 'dropdown_${const Uuid().v4()}_$index'), - product: tag.product?.uuid ?? 'Unknown', - items: state.updatedTags, - initialValue: tag, - onSelected: (value) { - controller.text = value.tag ?? ''; - context.read().add(UpdateTag( - index: index, - tag: value, - )); - }, - ), - ), - ), - ), - DataCell( - SizedBox( - width: double.infinity, - child: DialogDropdown( - items: locations, - selectedValue: tag.location ?? 'Main Space', - onSelected: (value) { - context - .read() - .add(UpdateLocation( - index: index, - location: value, - )); - }, - )), - ), - ], - ); - }), - ), + AssignTagsTable( + controllers: controllers, + locations: locations, ), if (state.errorMessage != null) Text(state.errorMessage!, @@ -220,102 +88,17 @@ class AssignTagModelsDialog extends StatelessWidget { ), ), actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - const SizedBox(width: 10), - Expanded( - child: Builder( - builder: (buttonContext) => CancelButton( - label: 'Add New Device', - onPressed: () async { - final updatedTags = List.from(state.tags); - final result = - TagHelper.updateSubspaceTagModels(updatedTags, subspaces); - - final processedTags = result['updatedTags'] as List; - final processedSubspaces = List.from( - result['subspaces'] as List); - - if (context.mounted) { - Navigator.of(context).pop(); - - await showDialog( - barrierDismissible: false, - context: context, - builder: (dialogContext) => AddDeviceTypeModelWidget( - products: products, - subspaces: processedSubspaces, - isCreate: false, - initialSelectedProducts: - TagHelper.createInitialSelectedProducts( - processedTags, processedSubspaces), - allTags: allTags, - spaceName: spaceName, - otherSpaceModels: otherSpaceModels, - spaceTagModels: processedTags, - pageContext: pageContext, - projectTags: projectTags, - spaceModel: SpaceTemplateModel( - modelName: spaceName, - tags: updatedTags, - uuid: spaceModel?.uuid, - internalId: spaceModel?.internalId, - subspaceModels: processedSubspaces)), - ); - } - }, - ), - ), - ), - const SizedBox(width: 10), - Expanded( - child: DefaultButton( - borderRadius: 10, - backgroundColor: ColorsManager.secondaryColor, - foregroundColor: state.isSaveEnabled - ? ColorsManager.whiteColors - : ColorsManager.whiteColorsWithOpacity, - onPressed: state.isSaveEnabled - ? () async { - final updatedTags = List.from(state.tags); - - final result = - TagHelper.updateSubspaceTagModels(updatedTags, subspaces); - - final processedTags = result['updatedTags'] as List; - final processedSubspaces = List.from( - result['subspaces'] as List); - - Navigator.of(context).popUntil((route) => route.isFirst); - - await showDialog( - context: context, - builder: (BuildContext dialogContext) { - return CreateSpaceModelDialog( - products: products, - allSpaceModels: allSpaceModels, - allTags: allTags, - projectTags: projectTags, - pageContext: pageContext, - otherSpaceModels: otherSpaceModels, - spaceModel: SpaceTemplateModel( - modelName: spaceName, - tags: processedTags, - uuid: spaceModel?.uuid, - internalId: spaceModel?.internalId, - subspaceModels: processedSubspaces), - ); - }, - ); - } - : null, - child: const Text('Save'), - ), - ), - const SizedBox(width: 10), - ], - ), + // RowOfNextCancelWidget( + // subspaces: subspaces, + // products: products, + // allTags: allTags, + // spaceName: spaceName, + // otherSpaceModels: otherSpaceModels, + // pageContext: pageContext, + // projectTags: projectTags, + // spaceModel: spaceModel, + // allSpaceModels: allSpaceModels, + // ), ], ); } else if (state is AssignTagModelLoading) { diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart new file mode 100644 index 00000000..9b2a1367 --- /dev/null +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart @@ -0,0 +1,152 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../../utils/color_manager.dart'; +import '../../../../common/buttons/cancel_button.dart'; +import '../../../../common/buttons/default_button.dart'; +import '../../../all_spaces/model/product_model.dart'; +import '../../../all_spaces/model/tag.dart'; +import '../../../helper/tag_helper.dart'; +import '../../../space_model/models/space_template_model.dart'; +import '../../../space_model/models/subspace_template_model.dart'; +import '../../../space_model/widgets/dialog/create_space_model_dialog.dart'; +import '../../../tag_model/views/add_device_type_model_widget.dart'; +import '../../bloc/assign_tag_model_bloc.dart'; +import '../../bloc/assign_tag_model_state.dart'; + +class RowOfSaveCancelWidget extends StatelessWidget { + const RowOfSaveCancelWidget({ + super.key, + required this.subspaces, + required this.products, + required this.allTags, + required this.spaceName, + required this.otherSpaceModels, + required this.pageContext, + required this.projectTags, + required this.spaceModel, + required this.allSpaceModels, + }); + + final List? subspaces; + final List? products; + final List? allTags; + final String spaceName; + final List? otherSpaceModels; + final BuildContext? pageContext; + final List projectTags; + final SpaceTemplateModel? spaceModel; + final List? allSpaceModels; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is AssignTagModelLoaded) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + const SizedBox(width: 10), + Expanded( + child: Builder( + builder: (buttonContext) => CancelButton( + label: 'Add New Device', + onPressed: () async { + final updatedTags = List.from(state.tags); + final result = TagHelper.updateSubspaceTagModels( + updatedTags, subspaces); + + final processedTags = result['updatedTags'] as List; + final processedSubspaces = + List.from( + result['subspaces'] as List); + + if (context.mounted) { + Navigator.of(context).pop(); + + await showDialog( + barrierDismissible: false, + context: context, + builder: (dialogContext) => AddDeviceTypeModelWidget( + products: products, + subspaces: processedSubspaces, + isCreate: false, + initialSelectedProducts: + TagHelper.createInitialSelectedProducts( + processedTags, processedSubspaces), + allTags: allTags, + spaceName: spaceName, + otherSpaceModels: otherSpaceModels, + spaceTagModels: processedTags, + pageContext: pageContext, + projectTags: projectTags, + spaceModel: SpaceTemplateModel( + modelName: spaceName, + tags: updatedTags, + uuid: spaceModel?.uuid, + internalId: spaceModel?.internalId, + subspaceModels: processedSubspaces)), + ); + } + }, + ), + ), + ), + const SizedBox(width: 10), + Expanded( + child: DefaultButton( + borderRadius: 10, + backgroundColor: ColorsManager.secondaryColor, + foregroundColor: state.isSaveEnabled + ? ColorsManager.whiteColors + : ColorsManager.whiteColorsWithOpacity, + onPressed: state.isSaveEnabled + ? () async { + final updatedTags = List.from(state.tags); + + final result = TagHelper.updateSubspaceTagModels( + updatedTags, subspaces); + + final processedTags = + result['updatedTags'] as List; + final processedSubspaces = + List.from( + result['subspaces'] as List); + + Navigator.of(context) + .popUntil((route) => route.isFirst); + + await showDialog( + context: context, + builder: (BuildContext dialogContext) { + return CreateSpaceModelDialog( + products: products, + allSpaceModels: allSpaceModels, + allTags: allTags, + projectTags: projectTags, + pageContext: pageContext, + otherSpaceModels: otherSpaceModels, + spaceModel: SpaceTemplateModel( + modelName: spaceName, + tags: processedTags, + uuid: spaceModel?.uuid, + internalId: spaceModel?.internalId, + subspaceModels: processedSubspaces), + ); + }, + ); + } + : null, + child: const Text('Save'), + ), + ), + const SizedBox(width: 10), + ], + ); + } else { + return const SizedBox(); + } + }, + ); + } +} diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart new file mode 100644 index 00000000..eaddc26c --- /dev/null +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart @@ -0,0 +1,172 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:uuid/uuid.dart'; + +import '../../../../../common/dialog_dropdown.dart'; +import '../../../../../common/tag_dialog_textfield_dropdown.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../bloc/assign_tag_model_bloc.dart'; +import '../../bloc/assign_tag_model_event.dart'; +import '../../bloc/assign_tag_model_state.dart'; + +class AssignTagsTable extends StatelessWidget { + const AssignTagsTable({ + super.key, + required this.controllers, + required this.locations, + }); + + final List controllers; + final List locations; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is AssignTagModelLoaded) { + return ClipRRect( + borderRadius: BorderRadius.circular(20), + child: DataTable( + headingRowColor: + WidgetStateProperty.all(ColorsManager.dataHeaderGrey), + key: ValueKey(state.tags.length), + border: TableBorder.all( + color: ColorsManager.dataHeaderGrey, + width: 1, + borderRadius: BorderRadius.circular(20), + ), + columns: [ + DataColumn( + label: Text('#', + style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + label: Text('Device', + style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + numeric: false, + label: Text('Tag', + style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + label: Text('Location', + style: Theme.of(context).textTheme.bodyMedium)), + ], + rows: state.tags.isEmpty + ? [ + DataRow(cells: [ + DataCell( + Center( + child: Text('No Devices Available', + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith( + color: ColorsManager.lightGrayColor, + )), + ), + ), + const DataCell(SizedBox()), + const DataCell(SizedBox()), + const DataCell(SizedBox()), + ]) + ] + : List.generate(state.tags.length, (index) { + final tag = state.tags[index]; + final controller = controllers[index]; + + return DataRow( + cells: [ + DataCell(Text((index + 1).toString())), + DataCell( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + tag.product?.name ?? 'Unknown', + overflow: TextOverflow.ellipsis, + )), + const SizedBox(width: 10), + Container( + width: 20.0, + height: 20.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: ColorsManager.lightGrayColor, + width: 1.0, + ), + ), + child: IconButton( + icon: const Icon( + Icons.close, + color: ColorsManager.lightGreyColor, + size: 16, + ), + onPressed: () { + context.read().add( + DeleteTagModel( + tagToDelete: tag, + tags: state.tags)); + controllers.removeAt(index); + }, + tooltip: 'Delete Tag', + padding: EdgeInsets.zero, + constraints: const BoxConstraints(), + ), + ), + ], + ), + ), + DataCell( + Container( + alignment: Alignment + .centerLeft, // Align cell content to the left + child: SizedBox( + width: double.infinity, + child: TagDialogTextfieldDropdown( + key: ValueKey( + 'dropdown_${const Uuid().v4()}_$index'), + product: tag.product?.uuid ?? 'Unknown', + items: state.updatedTags, + initialValue: tag, + onSelected: (value) { + controller.text = value.tag ?? ''; + context + .read() + .add(UpdateTag( + index: index, + tag: value, + )); + }, + ), + ), + ), + ), + DataCell( + SizedBox( + width: double.infinity, + child: DialogDropdown( + items: locations, + selectedValue: tag.location ?? 'Main Space', + onSelected: (value) { + context + .read() + .add(UpdateLocation( + index: index, + location: value, + )); + }, + )), + ), + ], + ); + }), + ), + ); + } else { + return const SizedBox(); + } + }, + ); + } +} From d69d867120f297988a7a13d6d30a0f28df6bf336 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Mon, 26 May 2025 06:27:48 -0500 Subject: [PATCH 08/82] use assign_tag_dialog_widgetwidget --- .../views/assign_tag_models_dialog.dart | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart index 873c7dd6..6343782c 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart @@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/space_tem import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'widgets/RowOfCancelSaveWidget.dart'; import 'widgets/assign_tags_tables_widget.dart'; class AssignTagModelsDialog extends StatelessWidget { @@ -88,17 +89,17 @@ class AssignTagModelsDialog extends StatelessWidget { ), ), actions: [ - // RowOfNextCancelWidget( - // subspaces: subspaces, - // products: products, - // allTags: allTags, - // spaceName: spaceName, - // otherSpaceModels: otherSpaceModels, - // pageContext: pageContext, - // projectTags: projectTags, - // spaceModel: spaceModel, - // allSpaceModels: allSpaceModels, - // ), + RowOfSaveCancelWidget( + subspaces: subspaces, + products: products, + allTags: allTags, + spaceName: spaceName, + otherSpaceModels: otherSpaceModels, + pageContext: pageContext, + projectTags: projectTags, + spaceModel: spaceModel, + allSpaceModels: allSpaceModels, + ), ], ); } else if (state is AssignTagModelLoading) { From 056e7372e08ff3777ead092f27ba0cac5255f4ae Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Tue, 27 May 2025 01:15:30 -0500 Subject: [PATCH 09/82] use assign table as widget --- .../assign_tag/views/assign_tag_dialog.dart | 178 +++--------- .../views/assign_tag_models_dialog.dart | 29 ++ .../widgets/assign_tags_tables_widget.dart | 275 ++++++++---------- 3 files changed, 201 insertions(+), 281 deletions(-) diff --git a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart index fd1454e5..a244d235 100644 --- a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart +++ b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart @@ -12,6 +12,7 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart'; +import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart'; import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:uuid/uuid.dart'; @@ -44,8 +45,10 @@ class AssignTagDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final List locations = - (subspaces ?? []).map((subspace) => subspace.subspaceName).toList()..add('Main Space'); + final List locations = (subspaces ?? []) + .map((subspace) => subspace.subspaceName) + .toList() + ..add('Main Space'); return BlocProvider( create: (_) => AssignTagBloc(projectTags) @@ -67,131 +70,31 @@ class AssignTagDialog extends StatelessWidget { content: SingleChildScrollView( child: Column( children: [ - ClipRRect( - borderRadius: BorderRadius.circular(20), - child: DataTable( - headingRowColor: WidgetStateProperty.all(ColorsManager.dataHeaderGrey), - key: ValueKey(state.tags.length), - border: TableBorder.all( - color: ColorsManager.dataHeaderGrey, - width: 1, - borderRadius: BorderRadius.circular(20), - ), - columns: [ - DataColumn( - label: Text('#', style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: Text('Device', style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - numeric: false, - label: Text('Tag', style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: - Text('Location', style: Theme.of(context).textTheme.bodyMedium)), - ], - rows: state.tags.isEmpty - ? [ - DataRow(cells: [ - DataCell( - Center( - child: Text('No Data Available', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: ColorsManager.lightGrayColor, - )), - ), - ), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - ]) - ] - : List.generate(state.tags.length, (index) { - final tag = state.tags[index]; - final controller = controllers[index]; + AssignTagsTable( + controllers: controllers, + locations: locations, + tags: state.tags, + updatedTags: state.updatedTags, + onDeleteDevice: ({required index, required tag}) { + context + .read() + .add(DeleteTag(tagToDelete: tag, tags: state.tags)); - return DataRow( - cells: [ - DataCell(Text((index + 1).toString())), - DataCell( - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - tag.product?.name ?? 'Unknown', - overflow: TextOverflow.ellipsis, - )), - const SizedBox(width: 10), - Container( - width: 20.0, - height: 20.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.lightGrayColor, - width: 1.0, - ), - ), - child: IconButton( - icon: const Icon( - Icons.close, - color: ColorsManager.lightGreyColor, - size: 16, - ), - onPressed: () { - context.read().add( - DeleteTag(tagToDelete: tag, tags: state.tags)); - - controllers.removeAt(index); - }, - tooltip: 'Delete Tag', - padding: EdgeInsets.zero, - constraints: const BoxConstraints(), - ), - ), - ], - ), - ), - DataCell( - Container( - alignment: - Alignment.centerLeft, // Align cell content to the left - child: SizedBox( - width: double.infinity, - child: TagDialogTextfieldDropdown( - key: ValueKey('dropdown_${const Uuid().v4()}_$index'), - items: state.updatedTags, - product: tag.product?.uuid ?? 'Unknown', - initialValue: tag, - onSelected: (value) { - controller.text = value.tag ?? ''; - context.read().add(UpdateTagEvent( - index: index, - tag: value, - )); - }, - ), - ), - ), - ), - DataCell( - SizedBox( - width: double.infinity, - child: DialogDropdown( - items: locations, - selectedValue: tag.location ?? 'Main Space', - onSelected: (value) { - context.read().add(UpdateLocation( - index: index, - location: value, - )); - }, - )), - ), - ], - ); - }), - ), + controllers.removeAt(index); + }, + onTagDropDownSelected: ({required index, required tag}) { + context.read().add(UpdateTagEvent( + index: index, + tag: tag, + )); + }, + onLocationDropDownSelected: ( + {required index, required location}) { + context.read().add(UpdateLocation( + index: index, + location: location, + )); + }, ), if (state.errorMessage != null) Text(state.errorMessage!, @@ -213,11 +116,13 @@ class AssignTagDialog extends StatelessWidget { label: 'Add New Device', onPressed: () async { final updatedTags = List.from(state.tags); - final result = TagHelper.processTags(updatedTags, subspaces); + final result = + TagHelper.processTags(updatedTags, subspaces); - final processedTags = result['updatedTags'] as List; - final processedSubspaces = - List.from(result['subspaces'] as List); + final processedTags = + result['updatedTags'] as List; + final processedSubspaces = List.from( + result['subspaces'] as List); Navigator.of(context).pop(); @@ -227,8 +132,8 @@ class AssignTagDialog extends StatelessWidget { products: products, subspaces: processedSubspaces, projectTags: projectTags, - initialSelectedProducts: - TagHelper.createInitialSelectedProductsForTags( + initialSelectedProducts: TagHelper + .createInitialSelectedProductsForTags( processedTags, processedSubspaces), spaceName: spaceName, spaceTags: processedTags, @@ -252,11 +157,14 @@ class AssignTagDialog extends StatelessWidget { onPressed: state.isSaveEnabled ? () async { final updatedTags = List.from(state.tags); - final result = TagHelper.processTags(updatedTags, subspaces); + final result = TagHelper.processTags( + updatedTags, subspaces); - final processedTags = result['updatedTags'] as List; + final processedTags = + result['updatedTags'] as List; final processedSubspaces = - List.from(result['subspaces'] as List); + List.from( + result['subspaces'] as List); onSave?.call(processedTags, processedSubspaces); Navigator.of(context).pop(); } diff --git a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart index 6343782c..57ed93df 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart @@ -78,6 +78,35 @@ class AssignTagModelsDialog extends StatelessWidget { AssignTagsTable( controllers: controllers, locations: locations, + tags: state.tags, + updatedTags: state.updatedTags, + onDeleteDevice: ({required index, required tag}) { + context + .read() + .add(DeleteTagModel( + tagToDelete: tag, + tags: state.tags, + )); + controllers.removeAt(index); + }, + onTagDropDownSelected: ( + {required index, required tag}) { + context.read().add( + UpdateTag( + index: index, + tag: tag, + ), + ); + }, + onLocationDropDownSelected: ( + {required index, required location}) { + context.read().add( + UpdateLocation( + index: index, + location: location, + ), + ); + }, ), if (state.errorMessage != null) Text(state.errorMessage!, diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart index eaddc26c..0e17a0d7 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart @@ -1,172 +1,155 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:uuid/uuid.dart'; import '../../../../../common/dialog_dropdown.dart'; import '../../../../../common/tag_dialog_textfield_dropdown.dart'; import '../../../../../utils/color_manager.dart'; -import '../../bloc/assign_tag_model_bloc.dart'; -import '../../bloc/assign_tag_model_event.dart'; -import '../../bloc/assign_tag_model_state.dart'; class AssignTagsTable extends StatelessWidget { const AssignTagsTable({ super.key, required this.controllers, required this.locations, + required this.tags, + required this.updatedTags, + required this.onDeleteDevice, + required this.onLocationDropDownSelected, + required this.onTagDropDownSelected, }); - + final void Function({required Tag tag, required int index}) + onTagDropDownSelected; + final void Function({required String location, required int index}) + onLocationDropDownSelected; + final void Function({required Tag tag, required int index}) onDeleteDevice; + final List tags; + final List updatedTags; final List controllers; final List locations; @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state is AssignTagModelLoaded) { - return ClipRRect( - borderRadius: BorderRadius.circular(20), - child: DataTable( - headingRowColor: - WidgetStateProperty.all(ColorsManager.dataHeaderGrey), - key: ValueKey(state.tags.length), - border: TableBorder.all( - color: ColorsManager.dataHeaderGrey, - width: 1, - borderRadius: BorderRadius.circular(20), - ), - columns: [ - DataColumn( - label: Text('#', - style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: Text('Device', - style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - numeric: false, - label: Text('Tag', - style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: Text('Location', - style: Theme.of(context).textTheme.bodyMedium)), - ], - rows: state.tags.isEmpty - ? [ - DataRow(cells: [ - DataCell( - Center( - child: Text('No Devices Available', - style: Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith( - color: ColorsManager.lightGrayColor, - )), - ), - ), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - ]) - ] - : List.generate(state.tags.length, (index) { - final tag = state.tags[index]; - final controller = controllers[index]; + return ClipRRect( + borderRadius: BorderRadius.circular(20), + child: DataTable( + headingRowColor: WidgetStateProperty.all(ColorsManager.dataHeaderGrey), + key: ValueKey(tags.length), + border: TableBorder.all( + color: ColorsManager.dataHeaderGrey, + width: 1, + borderRadius: BorderRadius.circular(20), + ), + columns: [ + DataColumn( + label: Text('#', style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + label: Text('Device', + style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + numeric: false, + label: + Text('Tag', style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + label: Text('Location', + style: Theme.of(context).textTheme.bodyMedium)), + ], + rows: tags.isEmpty + ? [ + DataRow(cells: [ + DataCell( + Center( + child: Text('No Devices Available', + style: + Theme.of(context).textTheme.bodyMedium?.copyWith( + color: ColorsManager.lightGrayColor, + )), + ), + ), + const DataCell(SizedBox()), + const DataCell(SizedBox()), + const DataCell(SizedBox()), + ]) + ] + : List.generate(tags.length, (index) { + final tag = tags[index]; + final controller = controllers[index]; - return DataRow( - cells: [ - DataCell(Text((index + 1).toString())), - DataCell( - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - tag.product?.name ?? 'Unknown', - overflow: TextOverflow.ellipsis, - )), - const SizedBox(width: 10), - Container( - width: 20.0, - height: 20.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.lightGrayColor, - width: 1.0, - ), - ), - child: IconButton( - icon: const Icon( - Icons.close, - color: ColorsManager.lightGreyColor, - size: 16, - ), - onPressed: () { - context.read().add( - DeleteTagModel( - tagToDelete: tag, - tags: state.tags)); - controllers.removeAt(index); - }, - tooltip: 'Delete Tag', - padding: EdgeInsets.zero, - constraints: const BoxConstraints(), - ), - ), - ], - ), - ), - DataCell( - Container( - alignment: Alignment - .centerLeft, // Align cell content to the left - child: SizedBox( - width: double.infinity, - child: TagDialogTextfieldDropdown( - key: ValueKey( - 'dropdown_${const Uuid().v4()}_$index'), - product: tag.product?.uuid ?? 'Unknown', - items: state.updatedTags, - initialValue: tag, - onSelected: (value) { - controller.text = value.tag ?? ''; - context - .read() - .add(UpdateTag( - index: index, - tag: value, - )); - }, - ), + return DataRow( + cells: [ + DataCell(Text((index + 1).toString())), + DataCell( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + tag.product?.name ?? 'Unknown', + overflow: TextOverflow.ellipsis, + )), + const SizedBox(width: 10), + Container( + width: 20.0, + height: 20.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: ColorsManager.lightGrayColor, + width: 1.0, ), ), - ), - DataCell( - SizedBox( - width: double.infinity, - child: DialogDropdown( - items: locations, - selectedValue: tag.location ?? 'Main Space', - onSelected: (value) { - context - .read() - .add(UpdateLocation( - index: index, - location: value, - )); - }, - )), + child: IconButton( + icon: const Icon( + Icons.close, + color: ColorsManager.lightGreyColor, + size: 16, + ), + onPressed: () { + onDeleteDevice(tag: tag, index: index); + }, + tooltip: 'Delete Tag', + padding: EdgeInsets.zero, + constraints: const BoxConstraints(), + ), ), ], - ); - }), - ), - ); - } else { - return const SizedBox(); - } - }, + ), + ), + DataCell( + Container( + alignment: Alignment + .centerLeft, // Align cell content to the left + child: SizedBox( + width: double.infinity, + child: TagDialogTextfieldDropdown( + key: ValueKey( + 'dropdown_${const Uuid().v4()}_$index'), + product: tag.product?.uuid ?? 'Unknown', + items: updatedTags, + initialValue: tag, + onSelected: (value) { + controller.text = value.tag ?? ''; + onTagDropDownSelected(tag: value, index: index); + }, + ), + ), + ), + ), + DataCell( + SizedBox( + width: double.infinity, + child: DialogDropdown( + items: locations, + selectedValue: tag.location ?? 'Main Space', + onSelected: (value) { + onLocationDropDownSelected( + location: value, index: index); + }, + )), + ), + ], + ); + }), + ), ); } } From a87e79878b1e118a639c4374c2a03ee6f08a7bea Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Tue, 27 May 2025 05:32:42 -0500 Subject: [PATCH 10/82] add ok_candel row of buttons in seperated widget also text field widget --- .../views/create_subspace_model_dialog.dart | 149 ++---------------- .../widgets/ok_cancel_sub_space_widget.dart | 72 +++++++++ .../textfield_sub_space_dialog_widget.dart | 98 ++++++++++++ 3 files changed, 181 insertions(+), 138 deletions(-) create mode 100644 lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart create mode 100644 lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart diff --git a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart index 483382af..501ad5a1 100644 --- a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart +++ b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart @@ -12,6 +12,9 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import 'widgets/ok_cancel_sub_space_widget.dart'; +import 'widgets/textfield_sub_space_dialog_widget.dart'; + class CreateSubSpaceDialog extends StatefulWidget { final String dialogTitle; final List? existingSubSpaces; @@ -33,14 +36,7 @@ class CreateSubSpaceDialog extends StatefulWidget { } class _CreateSubSpaceDialogState extends State { - late final TextEditingController _subspaceNameController; - - @override - void initState() { - _subspaceNameController = TextEditingController(); - super.initState(); - } - + final TextEditingController _subspaceNameController = TextEditingController(); @override void dispose() { _subspaceNameController.dispose(); @@ -96,84 +92,9 @@ class _CreateSubSpaceDialogState extends State { ], ), const SizedBox(height: 16), - Container( - width: context.screenWidth * 0.35, - padding: const EdgeInsets.symmetric( - vertical: 10, - horizontal: 16, - ), - decoration: BoxDecoration( - color: ColorsManager.boxColor, - borderRadius: BorderRadius.circular(10), - ), - child: Wrap( - spacing: 8, - runSpacing: 8, - alignment: WrapAlignment.start, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - ...state.subSpaces.asMap().entries.map( - (entry) { - final index = entry.key; - final subSpace = entry.value; - - final lowerName = - subSpace.subspaceName.toLowerCase(); - - final duplicateIndices = state.subSpaces - .asMap() - .entries - .where((e) => - e.value.subspaceName.toLowerCase() == - lowerName) - .map((e) => e.key) - .toList(); - final isDuplicate = duplicateIndices.length > 1 && - duplicateIndices.indexOf(index) != 0; - return SubspaceChip( - subSpace: SubspaceTemplateModel( - subspaceName: entry.value.subspaceName, - disabled: entry.value.disabled, - ), - isDuplicate: isDuplicate, - onDeleted: () => context.read().add( - RemoveSubSpace(subSpace), - ), - ); - }, - ), - SizedBox( - width: 200, - child: TextField( - controller: _subspaceNameController, - decoration: InputDecoration( - border: InputBorder.none, - hintText: state.subSpaces.isEmpty - ? 'Please enter the name' - : null, - hintStyle: context.textTheme.bodySmall?.copyWith( - color: ColorsManager.lightGrayColor, - ), - ), - onSubmitted: (value) { - final trimmedValue = value.trim(); - if (trimmedValue.isNotEmpty) { - context.read().add( - AddSubSpace( - SubspaceModel( - subspaceName: trimmedValue, - disabled: false, - ), - ), - ); - _subspaceNameController.clear(); - } - }, - style: context.textTheme.bodyMedium, - ), - ), - ], - ), + TextFieldSubSpaceDialogWidget( + subspaceNameController: _subspaceNameController, + subSpaces: state.subSpaces, ), if (state.errorMessage.isNotEmpty) Padding( @@ -186,58 +107,10 @@ class _CreateSubSpaceDialogState extends State { ), ), const SizedBox(height: 16), - Row( - children: [ - Expanded( - child: CancelButton( - label: 'Cancel', - onPressed: () async { - Navigator.of(context).pop(); - }, - ), - ), - const SizedBox(width: 10), - Expanded( - child: DefaultButton( - onPressed: state.errorMessage.isEmpty - ? () async { - final trimmedValue = - _subspaceNameController.text.trim(); - - final subSpacesBloc = - context.read(); - if (trimmedValue.isNotEmpty) { - subSpacesBloc.add( - AddSubSpace( - SubspaceModel( - subspaceName: trimmedValue, - disabled: false, - ), - ), - ); - _subspaceNameController.clear(); - } - - await Future.delayed( - const Duration(milliseconds: 10)); - final subSpaces = - subSpacesBloc.state.subSpaces; - // if (subSpaces.isNotEmpty) { - widget.onSave?.call(subSpaces); - // } - - Navigator.of(context).pop(); - } - : null, - backgroundColor: ColorsManager.secondaryColor, - borderRadius: 10, - foregroundColor: state.errorMessage.isNotEmpty - ? ColorsManager.whiteColorsWithOpacity - : ColorsManager.whiteColors, - child: const Text('OK'), - ), - ), - ], + OkCancelSubSpaceWidget( + subspaceNameController: _subspaceNameController, + errorMessage: state.errorMessage, + onSave: widget.onSave, ), ], ), diff --git a/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart new file mode 100644 index 00000000..3c3db8f0 --- /dev/null +++ b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; + +import '../../bloc/subspace_bloc.dart'; +import '../../bloc/subspace_event.dart'; + +class OkCancelSubSpaceWidget extends StatelessWidget { + const OkCancelSubSpaceWidget({ + super.key, + required this.subspaceNameController, + required this.onSave, + required this.errorMessage, + }); + + final TextEditingController subspaceNameController; + final void Function(List?)? onSave; + final String errorMessage; + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: CancelButton( + label: 'Cancel', + onPressed: () async { + Navigator.of(context).pop(); + }, + ), + ), + const SizedBox(width: 10), + Expanded( + child: DefaultButton( + onPressed: errorMessage.isEmpty + ? () async { + final trimmedValue = subspaceNameController.text.trim(); + + final subSpacesBloc = context.read(); + if (trimmedValue.isNotEmpty) { + subSpacesBloc.add( + AddSubSpace( + SubspaceModel( + subspaceName: trimmedValue, + disabled: false, + ), + ), + ); + subspaceNameController.clear(); + } + + await Future.delayed(const Duration(milliseconds: 10)); + final subSpaces = subSpacesBloc.state.subSpaces; + onSave?.call(subSpaces); + + Navigator.of(context).pop(); + } + : null, + backgroundColor: ColorsManager.secondaryColor, + borderRadius: 10, + foregroundColor: errorMessage.isNotEmpty + ? ColorsManager.whiteColorsWithOpacity + : ColorsManager.whiteColors, + child: const Text('OK'), + ), + ), + ], + ); + } +} diff --git a/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart b/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart new file mode 100644 index 00000000..f655e178 --- /dev/null +++ b/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; + +import '../../../../../utils/color_manager.dart'; +import '../../../all_spaces/model/subspace_model.dart'; +import '../../../create_subspace_model/widgets/subspace_chip.dart'; +import '../../../space_model/models/subspace_template_model.dart'; +import '../../bloc/subspace_bloc.dart'; +import '../../bloc/subspace_event.dart'; + +class TextFieldSubSpaceDialogWidget extends StatelessWidget { + const TextFieldSubSpaceDialogWidget({ + super.key, + required TextEditingController subspaceNameController, + required this.subSpaces, + }) : _subspaceNameController = subspaceNameController; + + final TextEditingController _subspaceNameController; + final List subSpaces; + @override + Widget build(BuildContext context) { + return Container( + width: context.screenWidth * 0.35, + padding: const EdgeInsets.symmetric( + vertical: 10, + horizontal: 16, + ), + decoration: BoxDecoration( + color: ColorsManager.boxColor, + borderRadius: BorderRadius.circular(10), + ), + child: Wrap( + spacing: 8, + runSpacing: 8, + alignment: WrapAlignment.start, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + ...subSpaces.asMap().entries.map( + (entry) { + final index = entry.key; + final subSpace = entry.value; + + final lowerName = subSpace.subspaceName.toLowerCase(); + + final duplicateIndices = subSpaces + .asMap() + .entries + .where((e) => e.value.subspaceName.toLowerCase() == lowerName) + .map((e) => e.key) + .toList(); + final isDuplicate = duplicateIndices.length > 1 && + duplicateIndices.indexOf(index) != 0; + return SubspaceChip( + subSpace: SubspaceTemplateModel( + subspaceName: entry.value.subspaceName, + disabled: entry.value.disabled, + ), + isDuplicate: isDuplicate, + onDeleted: () => context.read().add( + RemoveSubSpace(subSpace), + ), + ); + }, + ), + SizedBox( + width: 200, + child: TextField( + controller: _subspaceNameController, + decoration: InputDecoration( + border: InputBorder.none, + hintText: subSpaces.isEmpty ? 'Please enter the name' : null, + hintStyle: context.textTheme.bodySmall?.copyWith( + color: ColorsManager.lightGrayColor, + ), + ), + onSubmitted: (value) { + final trimmedValue = value.trim(); + if (trimmedValue.isNotEmpty) { + context.read().add( + AddSubSpace( + SubspaceModel( + subspaceName: trimmedValue, + disabled: false, + ), + ), + ); + _subspaceNameController.clear(); + } + }, + style: context.textTheme.bodyMedium, + ), + ), + ], + ), + ); + } +} From 8967852ca85bd01bf2cabf5a11458684a211d769 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Tue, 27 May 2025 06:01:25 -0500 Subject: [PATCH 11/82] seperate assign tag dialog to widgets --- .../assign_tag/views/assign_tag_dialog.dart | 91 +++------------- .../widgets/save_add_device_row_widget.dart | 100 ++++++++++++++++++ 2 files changed, 113 insertions(+), 78 deletions(-) create mode 100644 lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart diff --git a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart index a244d235..21ba141c 100644 --- a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart +++ b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart @@ -1,10 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/common/dialog_dropdown.dart'; -import 'package:syncrow_web/common/tag_dialog_textfield_dropdown.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/spaces_management/add_device_type/views/add_device_type_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; @@ -13,9 +8,9 @@ import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_b import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:uuid/uuid.dart'; + +import 'widgets/save_add_device_row_widget.dart'; class AssignTagDialog extends StatelessWidget { final List? products; @@ -30,7 +25,7 @@ class AssignTagDialog extends StatelessWidget { final List projectTags; const AssignTagDialog( - {Key? key, + {super.key, required this.products, required this.subspaces, required this.addedProducts, @@ -40,8 +35,7 @@ class AssignTagDialog extends StatelessWidget { required this.spaceName, required this.title, this.onSave, - required this.projectTags}) - : super(key: key); + required this.projectTags}); @override Widget build(BuildContext context) { @@ -106,74 +100,15 @@ class AssignTagDialog extends StatelessWidget { ), ), actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - const SizedBox(width: 10), - Expanded( - child: Builder( - builder: (buttonContext) => CancelButton( - label: 'Add New Device', - onPressed: () async { - final updatedTags = List.from(state.tags); - final result = - TagHelper.processTags(updatedTags, subspaces); - - final processedTags = - result['updatedTags'] as List; - final processedSubspaces = List.from( - result['subspaces'] as List); - - Navigator.of(context).pop(); - - await showDialog( - context: context, - builder: (context) => AddDeviceTypeWidget( - products: products, - subspaces: processedSubspaces, - projectTags: projectTags, - initialSelectedProducts: TagHelper - .createInitialSelectedProductsForTags( - processedTags, processedSubspaces), - spaceName: spaceName, - spaceTags: processedTags, - isCreate: false, - onSave: onSave, - allTags: allTags, - ), - ); - }, - ), - ), - ), - const SizedBox(width: 10), - Expanded( - child: DefaultButton( - borderRadius: 10, - backgroundColor: ColorsManager.secondaryColor, - foregroundColor: state.isSaveEnabled - ? ColorsManager.whiteColors - : ColorsManager.whiteColorsWithOpacity, - onPressed: state.isSaveEnabled - ? () async { - final updatedTags = List.from(state.tags); - final result = TagHelper.processTags( - updatedTags, subspaces); - - final processedTags = - result['updatedTags'] as List; - final processedSubspaces = - List.from( - result['subspaces'] as List); - onSave?.call(processedTags, processedSubspaces); - Navigator.of(context).pop(); - } - : null, - child: const Text('Save'), - ), - ), - const SizedBox(width: 10), - ], + SaveAddDeviceRowWidget( + subspaces: subspaces, + products: products, + projectTags: projectTags, + spaceName: spaceName, + onSave: onSave, + allTags: allTags, + tags: state.tags, + isSaveEnabled: state.isSaveEnabled, ), ], ); diff --git a/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart b/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart new file mode 100644 index 00000000..a81b7ad0 --- /dev/null +++ b/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +import '../../../add_device_type/views/add_device_type_widget.dart'; +import '../../../helper/tag_helper.dart'; + +class SaveAddDeviceRowWidget extends StatelessWidget { + const SaveAddDeviceRowWidget({ + super.key, + required this.subspaces, + required this.products, + required this.projectTags, + required this.spaceName, + required this.onSave, + required this.allTags, + required this.tags, + required this.isSaveEnabled, + }); + final List tags; + final List? subspaces; + final List? products; + final List projectTags; + final String spaceName; + final Function(List p1, List? p2)? onSave; + final List? allTags; + final bool isSaveEnabled; + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + const SizedBox(width: 10), + Expanded( + child: Builder( + builder: (buttonContext) => CancelButton( + label: 'Add New Device', + onPressed: () async { + final updatedTags = List.from(tags); + final result = TagHelper.processTags(updatedTags, subspaces); + + final processedTags = result['updatedTags'] as List; + final processedSubspaces = List.from( + result['subspaces'] as List); + + Navigator.of(context).pop(); + + await showDialog( + context: context, + builder: (context) => AddDeviceTypeWidget( + products: products, + subspaces: processedSubspaces, + projectTags: projectTags, + initialSelectedProducts: + TagHelper.createInitialSelectedProductsForTags( + processedTags, processedSubspaces), + spaceName: spaceName, + spaceTags: processedTags, + isCreate: false, + onSave: onSave, + allTags: allTags, + ), + ); + }, + ), + ), + ), + const SizedBox(width: 10), + Expanded( + child: DefaultButton( + borderRadius: 10, + backgroundColor: ColorsManager.secondaryColor, + foregroundColor: isSaveEnabled + ? ColorsManager.whiteColors + : ColorsManager.whiteColorsWithOpacity, + onPressed: isSaveEnabled + ? () async { + final updatedTags = List.from(tags); + final result = + TagHelper.processTags(updatedTags, subspaces); + + final processedTags = result['updatedTags'] as List; + final processedSubspaces = List.from( + result['subspaces'] as List); + onSave?.call(processedTags, processedSubspaces); + Navigator.of(context).pop(); + } + : null, + child: const Text('Save'), + ), + ), + const SizedBox(width: 10), + ], + ); + } +} From fc81555be3182b558b6bcb4c815d12693e976184 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 00:40:34 -0500 Subject: [PATCH 12/82] seperate iconchoose widget in create space dialog --- .../icon_choose_part_widget.dart | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart new file mode 100644 index 00000000..59a100a3 --- /dev/null +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../../../../../utils/color_manager.dart'; +import '../../../../../utils/constants/assets.dart'; + +class IconChoosePartWidget extends StatelessWidget { + const IconChoosePartWidget({ + super.key, + required this.selectedIcon, + required this.showIconSelection, + required this.screenWidth, + }); + final double screenWidth; + final String selectedIcon; + final void Function() showIconSelection; + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 50), + Stack( + alignment: Alignment.center, + children: [ + Container( + width: screenWidth * 0.1, + height: screenWidth * 0.1, + decoration: const BoxDecoration( + color: ColorsManager.boxColor, + shape: BoxShape.circle, + ), + ), + SvgPicture.asset( + selectedIcon, + width: screenWidth * 0.04, + height: screenWidth * 0.04, + ), + Positioned( + top: 20, + right: 20, + child: InkWell( + onTap: showIconSelection, + child: Container( + width: 24, + height: 24, + decoration: const BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + child: SvgPicture.asset( + Assets.iconEdit, + width: 16, + height: 16, + ), + ), + ), + ), + ], + ), + ], + ); + } +} From 52046909d5598bebef85b9c1ea591d58b4a92d27 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 00:41:01 -0500 Subject: [PATCH 13/82] seperate textfield of the space name --- .../space_name_textfield_widget.dart | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart new file mode 100644 index 00000000..d9abbf7f --- /dev/null +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; + +import '../../../../../utils/color_manager.dart'; + +class SpaceNameTextfieldWidget extends StatelessWidget { + SpaceNameTextfieldWidget({ + super.key, + required this.isNameFieldExist, + required this.isNameFieldInvalid, + required this.onChange, + required this.screenWidth, + }); + TextEditingController nameController = TextEditingController(); + final void Function(String value) onChange; + final double screenWidth; + bool isNameFieldExist; + bool isNameFieldInvalid; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SizedBox( + width: screenWidth * 0.25, + child: TextField( + controller: nameController, + onChanged: onChange, + style: Theme.of(context).textTheme.bodyMedium, + decoration: InputDecoration( + hintText: 'Please enter the name', + hintStyle: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: ColorsManager.lightGrayColor), + filled: true, + fillColor: ColorsManager.boxColor, + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + color: isNameFieldInvalid || isNameFieldExist + ? ColorsManager.red + : ColorsManager.boxColor, + width: 1.5, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + color: ColorsManager.boxColor, + width: 1.5, + ), + ), + ), + ), + ), + if (isNameFieldInvalid) + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text( + '*Space name should not be empty.', + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: ColorsManager.red), + ), + ), + if (isNameFieldExist) + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text( + '*Name already exist', + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: ColorsManager.red), + ), + ), + ], + ); + } +} From 4feae9ad87920d7095222dfea01790d889b8589f Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 00:41:33 -0500 Subject: [PATCH 14/82] seperate spacemodel linking into widget --- .../space_model_linking_widget.dart | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart new file mode 100644 index 00000000..cd9ae470 --- /dev/null +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; + +import '../../../../../utils/color_manager.dart'; +import '../../../../../utils/constants/assets.dart'; +import '../../../space_model/models/space_template_model.dart'; +import '../../../space_model/widgets/button_content_widget.dart'; + +class SpaceModelLinkingWidget extends StatelessWidget { + const SpaceModelLinkingWidget({ + super.key, + required this.onDeleted, + required this.onPressed, + required this.screenWidth, + required this.selectedSpaceModel, + required this.isSpaceModelDisabled, + }); + final bool isSpaceModelDisabled; + final void Function()? onDeleted; + final void Function()? onPressed; + final double screenWidth; + final SpaceTemplateModel? selectedSpaceModel; + @override + Widget build(BuildContext context) { + return Column( + children: [ + selectedSpaceModel == null + ? TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + ), + onPressed: onPressed, + child: ButtonContentWidget( + svgAssets: Assets.link, + label: 'Link a space model', + disabled: isSpaceModelDisabled, + ), + ) + : Container( + width: screenWidth * 0.25, + padding: const EdgeInsets.symmetric( + vertical: 10.0, horizontal: 16.0), + decoration: BoxDecoration( + color: ColorsManager.boxColor, + borderRadius: BorderRadius.circular(10), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + Chip( + label: Text( + selectedSpaceModel?.modelName ?? '', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: ColorsManager.spaceColor), + ), + backgroundColor: ColorsManager.whiteColors, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: const BorderSide( + color: ColorsManager.transparentColor, + width: 0, + ), + ), + deleteIcon: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: ColorsManager.lightGrayColor, + width: 1.5, + ), + ), + child: const Icon( + Icons.close, + size: 16, + color: ColorsManager.lightGrayColor, + ), + ), + onDeleted: onDeleted), + ], + ), + ), + ], + ); + } +} From 6ec20e2d72afc382135e7e8b3335766d343a9047 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 00:41:53 -0500 Subject: [PATCH 15/82] seperate subspace part into widget --- .../sub_space_part_widget.dart | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart new file mode 100644 index 00000000..e518877a --- /dev/null +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; + +import '../../../../../common/edit_chip.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../../space_model/widgets/button_content_widget.dart'; +import '../../../space_model/widgets/subspace_name_label_widget.dart'; +import '../../model/subspace_model.dart'; + +class SubSpacePartWidget extends StatefulWidget { + SubSpacePartWidget({ + super.key, + required this.subspaces, + required this.onPressed, + required this.isTagsAndSubspaceModelDisabled, + required this.screenWidth, + required this.editChipOnTap, + }); + double screenWidth; + bool isTagsAndSubspaceModelDisabled; + final void Function() editChipOnTap; + List? subspaces; + final void Function() onPressed; + + @override + State createState() => _SubSpacePartWidgetState(); +} + +class _SubSpacePartWidgetState extends State { + @override + Widget build(BuildContext context) { + return Column( + children: [ + widget.subspaces == null || widget.subspaces!.isEmpty + ? TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + overlayColor: ColorsManager.transparentColor, + ), + onPressed: widget.onPressed, + child: ButtonContentWidget( + icon: Icons.add, + label: 'Create Sub Spaces', + disabled: widget.isTagsAndSubspaceModelDisabled, + ), + ) + : SizedBox( + width: widget.screenWidth * 0.25, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: ColorsManager.textFieldGreyColor, + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: ColorsManager.textFieldGreyColor, + width: 3.0, // Border width + ), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + if (widget.subspaces != null) + ...widget.subspaces!.map((subspace) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SubspaceNameDisplayWidget( + text: subspace.subspaceName, + validateName: (updatedName) { + bool nameExists = widget.subspaces!.any((s) { + bool isSameId = + s.internalId == subspace.internalId; + bool isSameName = + s.subspaceName.trim().toLowerCase() == + updatedName.trim().toLowerCase(); + + return !isSameId && isSameName; + }); + + return !nameExists; + }, + onNameChanged: (updatedName) { + setState(() { + subspace.subspaceName = updatedName; + }); + }, + ), + ], + ); + }), + EditChip( + onTap: widget.editChipOnTap, + ) + ], + ), + ), + ) + ], + ); + } +} From 2c73dd6c31557d4058348c40092f3d82e68d607d Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 00:42:05 -0500 Subject: [PATCH 16/82] call the new widgets --- .../widgets/dialogs/create_space_dialog.dart | 322 ++++-------------- 1 file changed, 60 insertions(+), 262 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index b3d1e358..5223a091 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -9,6 +9,10 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_pr import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart'; @@ -116,50 +120,10 @@ class CreateSpaceDialogState extends State { children: [ Expanded( flex: 1, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox(height: 50), - Stack( - alignment: Alignment.center, - children: [ - Container( - width: screenWidth * 0.1, - height: screenWidth * 0.1, - decoration: const BoxDecoration( - color: ColorsManager.boxColor, - shape: BoxShape.circle, - ), - ), - SvgPicture.asset( - selectedIcon, - width: screenWidth * 0.04, - height: screenWidth * 0.04, - ), - Positioned( - top: 20, - right: 20, - child: InkWell( - onTap: _showIconSelectionDialog, - child: Container( - width: 24, - height: 24, - decoration: const BoxDecoration( - color: Colors.white, - shape: BoxShape.circle, - ), - child: SvgPicture.asset( - Assets.iconEdit, - width: 16, - height: 16, - ), - ), - ), - ), - ], - ), - ], + child: IconChoosePartWidget( + selectedIcon: selectedIcon, + showIconSelection: _showIconSelectionDialog, + screenWidth: screenWidth, ), ), const SizedBox(width: 20), @@ -168,149 +132,46 @@ class CreateSpaceDialogState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - width: screenWidth * 0.25, - child: TextField( - controller: nameController, - onChanged: (value) { - enteredName = value.trim(); - setState(() { - isNameFieldExist = false; - isOkButtonEnabled = false; - isNameFieldInvalid = value.isEmpty; + SpaceNameTextfieldWidget( + isNameFieldExist: isNameFieldExist, + isNameFieldInvalid: isNameFieldInvalid, + screenWidth: screenWidth, + onChange: (value) { + enteredName = value.trim(); + setState(() { + isNameFieldExist = false; + isOkButtonEnabled = false; + isNameFieldInvalid = value.isEmpty; - if (!isNameFieldInvalid) { - if (SpaceHelper.isNameConflict(value, - widget.parentSpace, widget.editSpace)) { - isNameFieldExist = true; - isOkButtonEnabled = false; - } else { - isNameFieldExist = false; - isOkButtonEnabled = true; - } + if (!isNameFieldInvalid) { + if (SpaceHelper.isNameConflict( + value, widget.parentSpace, widget.editSpace)) { + isNameFieldExist = true; + isOkButtonEnabled = false; + } else { + isNameFieldExist = false; + isOkButtonEnabled = true; } - }); - }, - style: Theme.of(context).textTheme.bodyMedium, - decoration: InputDecoration( - hintText: 'Please enter the name', - hintStyle: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: ColorsManager.lightGrayColor), - filled: true, - fillColor: ColorsManager.boxColor, - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: isNameFieldInvalid || isNameFieldExist - ? ColorsManager.red - : ColorsManager.boxColor, - width: 1.5, - ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: const BorderSide( - color: ColorsManager.boxColor, - width: 1.5, - ), - ), - ), - ), + } + }); + }, ), - if (isNameFieldInvalid) - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Text( - '*Space name should not be empty.', - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(color: ColorsManager.red), - ), - ), - if (isNameFieldExist) - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Text( - '*Name already exist', - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(color: ColorsManager.red), - ), - ), const SizedBox(height: 10), - selectedSpaceModel == null - ? TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - ), - onPressed: () { - isSpaceModelDisabled - ? null - : _showLinkSpaceModelDialog(context); - }, - child: ButtonContentWidget( - svgAssets: Assets.link, - label: 'Link a space model', - disabled: isSpaceModelDisabled, - ), - ) - : Container( - width: screenWidth * 0.25, - padding: const EdgeInsets.symmetric( - vertical: 10.0, horizontal: 16.0), - decoration: BoxDecoration( - color: ColorsManager.boxColor, - borderRadius: BorderRadius.circular(10), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - Chip( - label: Text( - selectedSpaceModel?.modelName ?? '', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith( - color: ColorsManager.spaceColor), - ), - backgroundColor: ColorsManager.whiteColors, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - side: const BorderSide( - color: ColorsManager.transparentColor, - width: 0, - ), - ), - deleteIcon: Container( - width: 24, - height: 24, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.lightGrayColor, - width: 1.5, - ), - ), - child: const Icon( - Icons.close, - size: 16, - color: ColorsManager.lightGrayColor, - ), - ), - onDeleted: () => setState(() { - this.selectedSpaceModel = null; - subspaces = widget.subspaces ?? []; - tags = widget.tags ?? []; - })), - ], - ), - ), + SpaceModelLinkingWidget( + isSpaceModelDisabled: isSpaceModelDisabled, + onPressed: () { + isSpaceModelDisabled + ? null + : _showLinkSpaceModelDialog(context); + }, + onDeleted: () => setState(() { + selectedSpaceModel = null; + subspaces = widget.subspaces ?? []; + tags = widget.tags ?? []; + }), + screenWidth: screenWidth, + selectedSpaceModel: selectedSpaceModel, + ), const SizedBox(height: 25), Row( children: [ @@ -339,85 +200,22 @@ class CreateSpaceDialogState extends State { ], ), const SizedBox(height: 25), - subspaces == null || subspaces!.isEmpty - ? TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - overlayColor: ColorsManager.transparentColor, - ), - onPressed: () async { - isTagsAndSubspaceModelDisabled - ? null - : _showSubSpaceDialog(context, enteredName, - [], false, widget.products, subspaces); - }, - child: ButtonContentWidget( - icon: Icons.add, - label: 'Create Sub Spaces', - disabled: isTagsAndSubspaceModelDisabled, - ), - ) - : SizedBox( - width: screenWidth * 0.25, - child: Container( - padding: const EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: ColorsManager.textFieldGreyColor, - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: ColorsManager.textFieldGreyColor, - width: 3.0, // Border width - ), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - if (subspaces != null) - ...subspaces!.map((subspace) { - return Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SubspaceNameDisplayWidget( - text: subspace.subspaceName, - validateName: (updatedName) { - bool nameExists = - subspaces!.any((s) { - bool isSameId = s.internalId == - subspace.internalId; - bool isSameName = s.subspaceName - .trim() - .toLowerCase() == - updatedName - .trim() - .toLowerCase(); - - return !isSameId && isSameName; - }); - - return !nameExists; - }, - onNameChanged: (updatedName) { - setState(() { - subspace.subspaceName = - updatedName; - }); - }, - ), - ], - ); - }), - EditChip( - onTap: () async { - _showSubSpaceDialog(context, enteredName, - [], true, widget.products, subspaces); - }, - ) - ], - ), - ), - ), + SubSpacePartWidget( + subspaces: subspaces, + onPressed: () { + isTagsAndSubspaceModelDisabled + ? null + : _showSubSpaceDialog(context, enteredName, [], + false, widget.products, subspaces); + }, + isTagsAndSubspaceModelDisabled: + isTagsAndSubspaceModelDisabled, + screenWidth: screenWidth, + editChipOnTap: () async { + _showSubSpaceDialog(context, enteredName, [], true, + widget.products, subspaces); + }, + ), const SizedBox(height: 10), (tags?.isNotEmpty == true || subspaces?.any((subspace) => From cf9bafef4d84c12eebe31dd24c45ba63077d7c0b Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 01:20:31 -0500 Subject: [PATCH 17/82] add devices part widget --- .../devices_part_widget.dart | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart new file mode 100644 index 00000000..94896554 --- /dev/null +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../../../../../common/edit_chip.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../../helper/tag_helper.dart'; +import '../../../space_model/widgets/button_content_widget.dart'; +import '../../model/subspace_model.dart'; +import '../../model/tag.dart'; + +class DevicesPartWidget extends StatelessWidget { + const DevicesPartWidget({ + super.key, + required this.tags, + required this.subspaces, + required this.screenWidth, + required this.onEditChip, + required this.onTextButtonPressed, + required this.isTagsAndSubspaceModelDisabled, + }); + final bool isTagsAndSubspaceModelDisabled; + final void Function() onEditChip; + final void Function() onTextButtonPressed; + final double screenWidth; + final List? tags; + final List? subspaces; + @override + Widget build(BuildContext context) { + return Column( + children: [ + (tags?.isNotEmpty == true || + subspaces?.any( + (subspace) => subspace.tags?.isNotEmpty == true) == + true) + ? SizedBox( + width: screenWidth * 0.25, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: ColorsManager.textFieldGreyColor, + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: ColorsManager.textFieldGreyColor, + width: 3.0, // Border width + ), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + // Combine tags from spaceModel and subspaces + ...TagHelper.groupTags([ + ...?tags, + ...?subspaces?.expand((subspace) => subspace.tags ?? []) + ]).entries.map( + (entry) => Chip( + avatar: SizedBox( + width: 24, + height: 24, + child: SvgPicture.asset( + entry.key.icon ?? 'assets/icons/gateway.svg', + fit: BoxFit.contain, + ), + ), + label: Text( + 'x${entry.value}', // Show count + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: ColorsManager.spaceColor), + ), + backgroundColor: ColorsManager.whiteColors, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: const BorderSide( + color: ColorsManager.spaceColor, + ), + ), + ), + ), + + EditChip(onTap: onEditChip) + ], + ), + ), + ) + : TextButton( + onPressed: onTextButtonPressed, + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + ), + child: ButtonContentWidget( + icon: Icons.add, + label: 'Add Devices', + disabled: isTagsAndSubspaceModelDisabled, + ), + ) + ], + ); + } +} From 1db069e9a518a9343a2f9b3b61ae8b35f4967fa4 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 01:21:06 -0500 Subject: [PATCH 18/82] use devicePart in main widget --- .../widgets/dialogs/create_space_dialog.dart | 152 +++++------------- 1 file changed, 42 insertions(+), 110 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index 5223a091..0cbecfd8 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -1,6 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_web/common/edit_chip.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/spaces_management/add_device_type/views/add_device_type_widget.dart'; @@ -9,6 +7,7 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_pr import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart'; @@ -20,8 +19,6 @@ import 'package:syncrow_web/pages/spaces_management/helper/space_helper.dart'; import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; import 'package:syncrow_web/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/space_icon_const.dart'; @@ -217,113 +214,47 @@ class CreateSpaceDialogState extends State { }, ), const SizedBox(height: 10), - (tags?.isNotEmpty == true || - subspaces?.any((subspace) => - subspace.tags?.isNotEmpty == true) == - true) - ? SizedBox( - width: screenWidth * 0.25, - child: Container( - padding: const EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: ColorsManager.textFieldGreyColor, - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: ColorsManager.textFieldGreyColor, - width: 3.0, // Border width - ), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - // Combine tags from spaceModel and subspaces - ...TagHelper.groupTags([ - ...?tags, - ...?subspaces?.expand( - (subspace) => subspace.tags ?? []) - ]).entries.map( - (entry) => Chip( - avatar: SizedBox( - width: 24, - height: 24, - child: SvgPicture.asset( - entry.key.icon ?? - 'assets/icons/gateway.svg', - fit: BoxFit.contain, - ), - ), - label: Text( - 'x${entry.value}', // Show count - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith( - color: ColorsManager - .spaceColor), - ), - backgroundColor: - ColorsManager.whiteColors, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(16), - side: const BorderSide( - color: ColorsManager.spaceColor, - ), - ), - ), - ), - - EditChip(onTap: () async { - await showDialog( - context: context, - builder: (context) => AssignTagDialog( - products: widget.products, - subspaces: subspaces, - allTags: widget.allTags, - addedProducts: TagHelper - .createInitialSelectedProductsForTags( - tags ?? [], subspaces), - title: 'Edit Device', - initialTags: - TagHelper.generateInitialForTags( - spaceTags: tags, - subspaces: subspaces), - spaceName: widget.name ?? '', - projectTags: widget.projectTags, - onSave: - (updatedTags, updatedSubspaces) { - setState(() { - tags = updatedTags; - subspaces = updatedSubspaces; - }); - }, - ), - ); - }) - ], - ), - ), - ) - : TextButton( - onPressed: () { - isTagsAndSubspaceModelDisabled - ? null - : _showTagCreateDialog( - context, - enteredName, - widget.isEdit, - widget.products, - ); + DevicesPartWidget( + tags: tags, + subspaces: subspaces, + screenWidth: screenWidth, + isTagsAndSubspaceModelDisabled: + isTagsAndSubspaceModelDisabled, + onEditChip: () async { + await showDialog( + context: context, + builder: (context) => AssignTagDialog( + products: widget.products, + subspaces: subspaces, + allTags: widget.allTags, + addedProducts: + TagHelper.createInitialSelectedProductsForTags( + tags ?? [], subspaces), + title: 'Edit Device', + initialTags: TagHelper.generateInitialForTags( + spaceTags: tags, subspaces: subspaces), + spaceName: widget.name ?? '', + projectTags: widget.projectTags, + onSave: (updatedTags, updatedSubspaces) { + setState(() { + tags = updatedTags; + subspaces = updatedSubspaces; + }); }, - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - ), - child: ButtonContentWidget( - icon: Icons.add, - label: 'Add Devices', - disabled: isTagsAndSubspaceModelDisabled, - )) + ), + ); + }, + onTextButtonPressed: () { + isTagsAndSubspaceModelDisabled + ? null + : _showTagCreateDialog( + context, + enteredName, + widget.isEdit, + widget.products, + ); + }, + ) ], ), ), @@ -382,6 +313,7 @@ class CreateSpaceDialogState extends State { ); } +//dialooogggs void _showIconSelectionDialog() { showDialog( context: context, From ee244fa5ed5dc77eb941c3743e524984d7dc5c4a Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 01:48:37 -0500 Subject: [PATCH 19/82] use textfield controller from constructor --- .../create_space_widgets/space_name_textfield_widget.dart | 3 ++- .../all_spaces/widgets/dialogs/create_space_dialog.dart | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart index d9abbf7f..600cb8ad 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart @@ -9,8 +9,9 @@ class SpaceNameTextfieldWidget extends StatelessWidget { required this.isNameFieldInvalid, required this.onChange, required this.screenWidth, + required this.nameController, }); - TextEditingController nameController = TextEditingController(); + TextEditingController nameController; final void Function(String value) onChange; final double screenWidth; bool isNameFieldExist; diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index 0cbecfd8..eaadf671 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -132,6 +132,7 @@ class CreateSpaceDialogState extends State { SpaceNameTextfieldWidget( isNameFieldExist: isNameFieldExist, isNameFieldInvalid: isNameFieldInvalid, + nameController: nameController, screenWidth: screenWidth, onChange: (value) { enteredName = value.trim(); From 321df401fd4ede301d921d577c99bf43e65f8171 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 01:56:57 -0500 Subject: [PATCH 20/82] comment interceptor cuz it is crashing app --- lib/services/api/http_service.dart | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/services/api/http_service.dart b/lib/services/api/http_service.dart index af5b60fe..c76291bf 100644 --- a/lib/services/api/http_service.dart +++ b/lib/services/api/http_service.dart @@ -23,17 +23,17 @@ class HTTPService { client.interceptors.add(serviceLocator.get()); // Add this interceptor for logging requests and responses - client.interceptors.add( - LogInterceptor( - request: true, - requestHeader: true, - requestBody: true, - responseHeader: false, - responseBody: true, - error: true, - logPrint: (object) => print(object), - ), - ); + // client.interceptors.add( + // LogInterceptor( + // request: true, + // requestHeader: true, + // requestBody: true, + // responseHeader: false, + // responseBody: true, + // error: true, + // logPrint: (object) => print(object), + // ), + // ); return client; } From c99b32fb81e5c0ec5bec89b948b49c5b43f4f9a1 Mon Sep 17 00:00:00 2001 From: Rafeek Alkhoudare Date: Wed, 28 May 2025 06:50:04 -0500 Subject: [PATCH 21/82] cancel direction --- .../bloc/space_management_bloc.dart | 114 +++++++++++------- .../all_spaces/model/connection_model.dart | 17 +-- .../all_spaces/model/space_model.dart | 2 +- .../widgets/community_structure_widget.dart | 11 +- .../widgets/curved_line_painter.dart | 27 +---- .../widgets/plus_button_widget.dart | 25 ++-- .../all_spaces/widgets/space_card_widget.dart | 2 +- lib/services/space_mana_api.dart | 8 +- 8 files changed, 100 insertions(+), 106 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 759cea27..04087257 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -21,7 +21,8 @@ import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/space_model_mang_api.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart' as custom_action; -class SpaceManagementBloc extends Bloc { +class SpaceManagementBloc + extends Bloc { final CommunitySpaceManagementApi _api; final ProductApi _productApi; final SpaceModelManagementApi _spaceModelApi; @@ -62,7 +63,8 @@ class SpaceManagementBloc extends Bloc emit) async { + void _deleteSpaceModelFromCache(DeleteSpaceModelFromCache event, + Emitter emit) async { if (_cachedSpaceModels != null) { - _cachedSpaceModels = - _cachedSpaceModels!.where((model) => model.uuid != event.deletedUuid).toList(); + _cachedSpaceModels = _cachedSpaceModels! + .where((model) => model.uuid != event.deletedUuid) + .toList(); } else { _cachedSpaceModels = await fetchSpaceModels(); } await fetchTags(); emit(SpaceModelLoaded( - communities: - state is SpaceManagementLoaded ? (state as SpaceManagementLoaded).communities : [], + communities: state is SpaceManagementLoaded + ? (state as SpaceManagementLoaded).communities + : [], products: _cachedProducts ?? [], spaceModels: List.from(_cachedSpaceModels ?? []), allTags: _cachedTags ?? [])); @@ -122,8 +127,8 @@ class SpaceManagementBloc extends Bloc.from(previousState.communities); + final updatedCommunities = + List.from(previousState.communities); for (var community in updatedCommunities) { if (community.uuid == event.communityUuid) { community.name = event.name; @@ -212,7 +219,8 @@ class SpaceManagementBloc extends Bloc> _fetchSpacesForCommunity(String communityUuid) async { + Future> _fetchSpacesForCommunity( + String communityUuid) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; return await _api.getSpaceHierarchy(communityUuid, projectUuid); @@ -242,20 +250,23 @@ class SpaceManagementBloc extends Bloc _onBlankState(BlankStateEvent event, Emitter emit) async { + Future _onBlankState( + BlankStateEvent event, Emitter emit) async { try { final previousState = state; final projectUuid = await ProjectManager.getProjectUUID() ?? ''; var spaceBloc = event.context.read(); var spaceTreeState = event.context.read().state; - List communities = await _waitForCommunityList(spaceBloc, spaceTreeState); + List communities = + await _waitForCommunityList(spaceBloc, spaceTreeState); await fetchSpaceModels(); await fetchTags(); var prevSpaceModels = await fetchSpaceModels(); - if (previousState is SpaceManagementLoaded || previousState is BlankState) { + if (previousState is SpaceManagementLoaded || + previousState is BlankState) { final prevCommunities = (previousState as dynamic).communities ?? []; emit(BlankState( communities: List.from(prevCommunities), @@ -286,7 +297,8 @@ class SpaceManagementBloc extends Bloc communities = await _waitForCommunityList(spaceBloc, spaceTreeState); + List communities = + await _waitForCommunityList(spaceBloc, spaceTreeState); // Fetch space models after communities are available final prevSpaceModels = await fetchSpaceModels(); @@ -310,8 +322,9 @@ class SpaceManagementBloc extends Bloc>(); final subscription = spaceBloc.stream.listen((state) { if (!completer.isCompleted && state.communityList.isNotEmpty) { - completer - .complete(state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList); + completer.complete(state.searchQuery.isNotEmpty + ? state.filteredCommunity + : state.communityList); } }); try { @@ -339,7 +352,8 @@ class SpaceManagementBloc extends Bloc.from( (previousState as dynamic).communities, ); @@ -459,8 +474,8 @@ class SpaceManagementBloc extends Bloc().state; - final updatedSpaces = - await saveSpacesHierarchically(event.context, event.spaces, event.communityUuid); + final updatedSpaces = await saveSpacesHierarchically( + event.context, event.spaces, event.communityUuid); final allSpaces = await _fetchSpacesForCommunity(event.communityUuid); emit(SpaceCreationSuccess(spaces: updatedSpaces)); @@ -520,8 +535,8 @@ class SpaceManagementBloc extends Bloc> saveSpacesHierarchically( - BuildContext context, List spaces, String communityUuid) async { + Future> saveSpacesHierarchically(BuildContext context, + List spaces, String communityUuid) async { final orderedSpaces = flattenHierarchy(spaces); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -575,17 +590,19 @@ class SpaceManagementBloc extends Bloc subspace.uuid == prevSubspace.uuid); + final existsInNew = newSubspaces + .any((subspace) => subspace.uuid == prevSubspace.uuid); if (!existsInNew) { subspaceUpdates.add(UpdateSubspaceTemplateModel( - action: custom_action.Action.delete, uuid: prevSubspace.uuid)); + action: custom_action.Action.delete, + uuid: prevSubspace.uuid)); } } } else if (prevSubspaces != null && newSubspaces == null) { for (var prevSubspace in prevSubspaces) { subspaceUpdates.add(UpdateSubspaceTemplateModel( - action: custom_action.Action.delete, uuid: prevSubspace.uuid)); + action: custom_action.Action.delete, + uuid: prevSubspace.uuid)); } } @@ -613,7 +630,9 @@ class SpaceManagementBloc extends Bloc tag.toCreateTagBodyModel()).toList() ?? []; + final tagBodyModels = subspace.tags + ?.map((tag) => tag.toCreateTagBodyModel()) + .toList() ?? + []; return CreateSubspaceModel() ..subspaceName = subspace.subspaceName ..tags = tagBodyModels; @@ -671,7 +691,6 @@ class SpaceManagementBloc extends Bloc emit) async { + void _onLoadSpaceModel( + SpaceModelLoadEvent event, Emitter emit) async { emit(SpaceManagementLoading()); try { @@ -757,14 +777,17 @@ class SpaceManagementBloc extends Bloc newTag.uuid == prevTag.uuid); + final existsInNew = + newTags.any((newTag) => newTag.uuid == prevTag.uuid); if (!existsInNew) { - tagUpdates.add(TagModelUpdate(action: custom_action.Action.delete, uuid: prevTag.uuid)); + tagUpdates.add(TagModelUpdate( + action: custom_action.Action.delete, uuid: prevTag.uuid)); } } } else if (prevTags != null && newTags == null) { for (var prevTag in prevTags) { - tagUpdates.add(TagModelUpdate(action: custom_action.Action.delete, uuid: prevTag.uuid)); + tagUpdates.add(TagModelUpdate( + action: custom_action.Action.delete, uuid: prevTag.uuid)); } } @@ -807,15 +830,16 @@ class SpaceManagementBloc extends Bloc findMatchingSpaces(List spaces, String targetUuid) { + List findMatchingSpaces( + List spaces, String targetUuid) { List matched = []; for (var space in spaces) { if (space.uuid == targetUuid) { matched.add(space); } - matched - .addAll(findMatchingSpaces(space.children, targetUuid)); // Recursively search in children + matched.addAll(findMatchingSpaces( + space.children, targetUuid)); // Recursively search in children } return matched; diff --git a/lib/pages/spaces_management/all_spaces/model/connection_model.dart b/lib/pages/spaces_management/all_spaces/model/connection_model.dart index a774efe2..0799d81e 100644 --- a/lib/pages/spaces_management/all_spaces/model/connection_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/connection_model.dart @@ -3,23 +3,26 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model class Connection { final SpaceModel startSpace; final SpaceModel endSpace; - final String direction; - Connection({required this.startSpace, required this.endSpace, required this.direction}); + Connection({ + required this.startSpace, + required this.endSpace, + }); Map toMap() { return { - 'startUuid': startSpace.uuid ?? 'unsaved-start-space-${startSpace.name}', // Fallback for unsaved spaces - 'endUuid': endSpace.uuid ?? 'unsaved-end-space-${endSpace.name}', // Fallback for unsaved spaces - 'direction': direction, + 'startUuid': startSpace.uuid ?? + 'unsaved-start-space-${startSpace.name}', // Fallback for unsaved spaces + 'endUuid': endSpace.uuid ?? + 'unsaved-end-space-${endSpace.name}', // Fallback for unsaved spaces }; } - static Connection fromMap(Map map, Map spaces) { + static Connection fromMap( + Map map, Map spaces) { return Connection( startSpace: spaces[map['startUuid']]!, endSpace: spaces[map['endUuid']]!, - direction: map['direction'], ); } } diff --git a/lib/pages/spaces_management/all_spaces/model/space_model.dart b/lib/pages/spaces_management/all_spaces/model/space_model.dart index 6e744a29..6b570004 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_model.dart @@ -116,7 +116,7 @@ class SpaceModel { instance.incomingConnection = Connection( startSpace: instance.parent ?? instance, // Parent space endSpace: instance, // This space instance - direction: conn['direction'], + ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index 16ecae36..178f7659 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -199,13 +199,11 @@ class _CommunityStructureAreaState extends State { top: entry.value.position.dy, child: SpaceCardWidget( index: entry.key, - onButtonTap: (int index, Offset newPosition, - String direction) { + onButtonTap: (int index, Offset newPosition) { _showCreateSpaceDialog(screenSize, position: spaces[index].position + newPosition, parentIndex: index, - direction: direction, projectTags: widget.projectTags); }, position: entry.value.position, @@ -296,7 +294,6 @@ class _CommunityStructureAreaState extends State { void _showCreateSpaceDialog(Size screenSize, {Offset? position, int? parentIndex, - String? direction, double? canvasWidth, double? canvasHeight, required List projectTags}) { @@ -338,14 +335,13 @@ class _CommunityStructureAreaState extends State { subspaces: subspaces, tags: tags); - if (parentIndex != null && direction != null) { + if (parentIndex != null) { SpaceModel parentSpace = spaces[parentIndex]; parentSpace.internalId = spaces[parentIndex].internalId; newSpace.parent = parentSpace; final newConnection = Connection( startSpace: parentSpace, endSpace: newSpace, - direction: direction, ); connections.add(newConnection); newSpace.incomingConnection = newConnection; @@ -467,7 +463,6 @@ class _CommunityStructureAreaState extends State { Connection( startSpace: parent, endSpace: child, - direction: "down", ), ); @@ -750,7 +745,6 @@ class _CommunityStructureAreaState extends State { final newConnection = Connection( startSpace: parent, endSpace: duplicated, - direction: "down", ); connections.add(newConnection); duplicated.incomingConnection = newConnection; @@ -786,7 +780,6 @@ class _CommunityStructureAreaState extends State { final newConnection = Connection( startSpace: newSpace, endSpace: duplicatedChild, - direction: "down", ); connections.add(newConnection); diff --git a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart index 2b85acfd..d8291110 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart @@ -30,28 +30,13 @@ class CurvedLinePainter extends CustomPainter { Offset end = connection.endSpace.position + const Offset(75, 0); // Center top of end space - if (connection.direction == 'down') { - // Curved line for down connections - final controlPoint = Offset((start.dx + end.dx) / 2, start.dy + 50); - final path = Path() - ..moveTo(start.dx, start.dy) - ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, end.dx, end.dy); - canvas.drawPath(path, paint); - } else if (connection.direction == 'right') { - start = connection.startSpace.position + - const Offset(150, 30); // Right center - end = connection.endSpace.position + const Offset(0, 30); // Left center + // Curved line for down connections + final controlPoint = Offset((start.dx + end.dx) / 2, start.dy + 50); + final path = Path() + ..moveTo(start.dx, start.dy) + ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, end.dx, end.dy); + canvas.drawPath(path, paint); - canvas.drawLine(start, end, paint); - } else if (connection.direction == 'left') { - start = - connection.startSpace.position + const Offset(0, 30); // Left center - end = connection.endSpace.position + - const Offset(150, 30); // Right center - - canvas.drawLine(start, end, paint); - } - final dotPaint = Paint()..color = ColorsManager.blackColor; canvas.drawCircle(start, 5, dotPaint); // Start dot canvas.drawCircle(end, 5, dotPaint); // End dot diff --git a/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart index 280816a0..6c5babaf 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart @@ -5,7 +5,7 @@ class PlusButtonWidget extends StatelessWidget { final int index; final String direction; final Offset offset; - final Function(int index, Offset newPosition, String direction) onButtonTap; + final Function(int index, Offset newPosition) onButtonTap; const PlusButtonWidget({ super.key, @@ -19,21 +19,7 @@ class PlusButtonWidget extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector( onTap: () { - Offset newPosition; - switch (direction) { - case 'left': - newPosition = const Offset(-200, 0); - break; - case 'right': - newPosition = const Offset(200, 0); - break; - case 'down': - newPosition = const Offset(0, 150); - break; - default: - newPosition = Offset.zero; - } - onButtonTap(index, newPosition, direction); + onButtonTap(index, const Offset(0, 150)); }, child: Container( width: 30, @@ -42,8 +28,11 @@ class PlusButtonWidget extends StatelessWidget { color: ColorsManager.spaceColor, shape: BoxShape.circle, ), - child: - const Icon(Icons.add, color: ColorsManager.whiteColors, size: 20), + child: const Icon( + Icons.add, + color: ColorsManager.whiteColors, + size: 20, + ), ), ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart index 49df9daa..7e6e132f 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart @@ -7,7 +7,7 @@ class SpaceCardWidget extends StatelessWidget { final Offset position; final bool isHovered; final Function(int index, bool isHovered) onHoverChanged; - final Function(int index, Offset newPosition, String direction) onButtonTap; + final Function(int index, Offset newPosition) onButtonTap; final Widget Function(int index) buildSpaceContainer; final ValueChanged onPositionChanged; diff --git a/lib/services/space_mana_api.dart b/lib/services/space_mana_api.dart index 19e219b6..a1372618 100644 --- a/lib/services/space_mana_api.dart +++ b/lib/services/space_mana_api.dart @@ -199,7 +199,7 @@ class CommunitySpaceManagementApi { {required String communityId, required String name, String? parentId, - String? direction, + bool isPrivate = false, required Offset position, String? spaceModelUuid, @@ -213,7 +213,7 @@ class CommunitySpaceManagementApi { 'isPrivate': isPrivate, 'x': position.dx, 'y': position.dy, - 'direction': direction, + 'icon': icon, }; if (parentId != null) { @@ -248,7 +248,7 @@ class CommunitySpaceManagementApi { required String name, String? parentId, String? icon, - String? direction, + bool isPrivate = false, required Offset position, List? tags, @@ -261,7 +261,7 @@ class CommunitySpaceManagementApi { 'isPrivate': isPrivate, 'x': position.dx, 'y': position.dy, - 'direction': direction, + 'icon': icon, 'subspace': subspaces, 'tags': tags, From a1d7457065fa6a45287505b747868cf9db717590 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Thu, 29 May 2025 14:34:15 +0300 Subject: [PATCH 22/82] Test commit with updated user --- .../spaces_management/create_subspace/bloc/subspace_bloc.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart b/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart index b334a301..a2d44553 100644 --- a/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart +++ b/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart @@ -77,7 +77,7 @@ class SubSpaceBloc extends Bloc { emit(SubSpaceState( updatedSubSpaces, updatedSubspaceModels, - errorMessage, + errorMessage , updatedDuplicates, )); }); From 511acc186fd500c304e0d86ed27f5dc2c4bba5c7 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 29 May 2025 15:39:44 +0300 Subject: [PATCH 23/82] Created a param class for loading device location data. --- .../params/get_device_location_data_param.dart | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 lib/pages/analytics/params/get_device_location_data_param.dart diff --git a/lib/pages/analytics/params/get_device_location_data_param.dart b/lib/pages/analytics/params/get_device_location_data_param.dart new file mode 100644 index 00000000..c66af4d8 --- /dev/null +++ b/lib/pages/analytics/params/get_device_location_data_param.dart @@ -0,0 +1,16 @@ +class GetDeviceLocationDataParam { + const GetDeviceLocationDataParam({ + required this.latitude, + required this.longitude, + }); + + final double latitude; + final double longitude; + + Map toJson() { + return { + 'latitude': latitude, + 'longitude': longitude, + }; + } +} From e7476a084d866fb546c3ebe52b92a575c663bbae Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 29 May 2025 15:39:51 +0300 Subject: [PATCH 24/82] Created a model class for loading device location data. --- .../models/device_location_info.dart | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/pages/analytics/models/device_location_info.dart diff --git a/lib/pages/analytics/models/device_location_info.dart b/lib/pages/analytics/models/device_location_info.dart new file mode 100644 index 00000000..9b0095f7 --- /dev/null +++ b/lib/pages/analytics/models/device_location_info.dart @@ -0,0 +1,58 @@ +import 'package:equatable/equatable.dart'; + +class DeviceLocationInfo extends Equatable { + const DeviceLocationInfo({ + this.airQuality, + this.humidity, + this.city, + this.country, + this.address, + this.temperature, + }); + + final double? airQuality; + final double? humidity; + final String? city; + final String? country; + final String? address; + final double? temperature; + + factory DeviceLocationInfo.fromJson(Map json) { + return DeviceLocationInfo( + airQuality: json['airQuality'] as double?, + humidity: json['humidity'] as double?, + city: json['city'] as String?, + country: json['country'] as String?, + address: json['address'] as String?, + temperature: json['temperature'] as double?, + ); + } + + DeviceLocationInfo copyWith({ + double? airQuality, + double? humidity, + String? city, + String? country, + String? address, + double? temperature, + }) { + return DeviceLocationInfo( + airQuality: airQuality ?? this.airQuality, + humidity: humidity ?? this.humidity, + city: city ?? this.city, + country: country ?? this.country, + address: address ?? this.address, + temperature: temperature ?? this.temperature, + ); + } + + @override + List get props => [ + airQuality, + humidity, + city, + country, + address, + temperature, + ]; +} From 6ffb677c33edf1897395577d4073f16732e92843 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 29 May 2025 15:40:15 +0300 Subject: [PATCH 25/82] Created an interface and its fake implementation for loading device location data. --- .../device_location_service.dart | 6 +++++ .../fake_device_location_service.dart | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 lib/pages/analytics/services/device_location/device_location_service.dart create mode 100644 lib/pages/analytics/services/device_location/fake_device_location_service.dart diff --git a/lib/pages/analytics/services/device_location/device_location_service.dart b/lib/pages/analytics/services/device_location/device_location_service.dart new file mode 100644 index 00000000..d28b4a7b --- /dev/null +++ b/lib/pages/analytics/services/device_location/device_location_service.dart @@ -0,0 +1,6 @@ +import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; +import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; + +abstract interface class DeviceLocationService { + Future get(GetDeviceLocationDataParam param); +} diff --git a/lib/pages/analytics/services/device_location/fake_device_location_service.dart b/lib/pages/analytics/services/device_location/fake_device_location_service.dart new file mode 100644 index 00000000..c1a4e82f --- /dev/null +++ b/lib/pages/analytics/services/device_location/fake_device_location_service.dart @@ -0,0 +1,22 @@ +import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; +import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; + +class FakeDeviceLocationService implements DeviceLocationService { + const FakeDeviceLocationService(); + + @override + Future get(GetDeviceLocationDataParam param) async { + return await Future.delayed( + const Duration(milliseconds: 500), + () => const DeviceLocationInfo( + airQuality: 45.0, + humidity: 65.0, + city: 'Dubai', + country: 'UAE', + address: 'Business Bay', + temperature: 22.5, + ), + ); + } +} From d92b699a2b01d2a7e305e7e04352ad7ea4a9ce94 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 29 May 2025 15:40:44 +0300 Subject: [PATCH 26/82] Created a bloc for loading and managing the state of device location data. --- .../device_location/device_location_bloc.dart | 50 +++++++++++++++++++ .../device_location_event.dart | 21 ++++++++ .../device_location_state.dart | 18 +++++++ 3 files changed, 89 insertions(+) create mode 100644 lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart create mode 100644 lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart create mode 100644 lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart diff --git a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart new file mode 100644 index 00000000..4f41eb0c --- /dev/null +++ b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart @@ -0,0 +1,50 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; +import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; + +part 'device_location_event.dart'; +part 'device_location_state.dart'; + +class DeviceLocationBloc extends Bloc { + DeviceLocationBloc( + this._deviceLocationService, + ) : super(const DeviceLocationState()) { + on(_onLoadDeviceLocation); + on(_onClearDeviceLocation); + } + + final DeviceLocationService _deviceLocationService; + + Future _onLoadDeviceLocation( + LoadDeviceLocationEvent event, + Emitter emit, + ) async { + emit(const DeviceLocationState(status: DeviceLocationStatus.loading)); + + try { + final locationInfo = await _deviceLocationService.get(event.param); + emit( + DeviceLocationState( + status: DeviceLocationStatus.success, + locationInfo: locationInfo, + ), + ); + } catch (e) { + emit( + DeviceLocationState( + status: DeviceLocationStatus.failure, + errorMessage: e.toString(), + ), + ); + } + } + + void _onClearDeviceLocation( + ClearDeviceLocationEvent event, + Emitter emit, + ) { + emit(const DeviceLocationState()); + } +} diff --git a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart new file mode 100644 index 00000000..376d055b --- /dev/null +++ b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart @@ -0,0 +1,21 @@ +part of 'device_location_bloc.dart'; + +sealed class DeviceLocationEvent extends Equatable { + const DeviceLocationEvent(); + + @override + List get props => []; +} + +class LoadDeviceLocationEvent extends DeviceLocationEvent { + const LoadDeviceLocationEvent(this.param); + + final GetDeviceLocationDataParam param; + + @override + List get props => [param]; +} + +class ClearDeviceLocationEvent extends DeviceLocationEvent { + const ClearDeviceLocationEvent(); +} diff --git a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart new file mode 100644 index 00000000..15c681b6 --- /dev/null +++ b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart @@ -0,0 +1,18 @@ +part of 'device_location_bloc.dart'; + +enum DeviceLocationStatus { initial, loading, success, failure } + +class DeviceLocationState extends Equatable { + const DeviceLocationState({ + this.status = DeviceLocationStatus.initial, + this.locationInfo, + this.errorMessage, + }); + + final DeviceLocationStatus status; + final DeviceLocationInfo? locationInfo; + final String? errorMessage; + + @override + List get props => [status, locationInfo, errorMessage]; +} From 8ad048e18d95330165b06dfaf136096c82e00817 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 29 May 2025 15:47:24 +0300 Subject: [PATCH 27/82] Added `geocoding: ^4.0.0` package. --- pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pubspec.yaml b/pubspec.yaml index 7decc506..612477fc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,6 +61,7 @@ dependencies: firebase_crashlytics: ^4.3.2 firebase_database: ^11.3.2 bloc: ^9.0.0 + geocoding: ^4.0.0 dev_dependencies: From b6879035f069467efd24b7ab7069e9e12c9abdc9 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 29 May 2025 15:47:34 +0300 Subject: [PATCH 28/82] Implemented geocoding functionality to retrieve and manage device location data using the newly added `geocoding` package. --- ...ode_device_location_service_decorator.dart | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart diff --git a/lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart b/lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart new file mode 100644 index 00000000..a3ac1e55 --- /dev/null +++ b/lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart @@ -0,0 +1,40 @@ +import 'package:geocoding/geocoding.dart'; +import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; +import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; + +class ReverseGeocodeDeviceLocationServiceDecorator implements DeviceLocationService { + const ReverseGeocodeDeviceLocationServiceDecorator(this._decoratee); + + final DeviceLocationService _decoratee; + + @override + Future get(GetDeviceLocationDataParam param) async { + try { + final deviceLocationInfo = await _decoratee.get(param); + + final placemarks = await placemarkFromCoordinates( + param.latitude, + param.longitude, + ); + + if (placemarks.isNotEmpty) { + final place = placemarks.first; + + final city = place.locality; + final country = place.country; + final address = place.street; + + return deviceLocationInfo.copyWith( + city: city, + country: country, + address: address, + ); + } + + return deviceLocationInfo; + } catch (e) { + throw Exception('Failed to reverse load device location info'); + } + } +} From 5654d66b600555798dc6d7986a80bee4b6096b1d Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sun, 1 Jun 2025 09:51:01 +0300 Subject: [PATCH 29/82] Created a remote implementation for `DeviceLocationService`. --- .env.development | 3 +- .env.production | 3 +- .env.staging | 3 +- .../remote_device_location_service.dart | 88 +++++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 lib/pages/analytics/services/device_location/remote_device_location_service.dart diff --git a/.env.development b/.env.development index e77609dc..8b8c7587 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,3 @@ ENV_NAME=development -BASE_URL=https://syncrow-dev.azurewebsites.net \ No newline at end of file +BASE_URL=https://syncrow-dev.azurewebsites.net +OPEN_WEATHER_API_KEY=5253339f3f994603cd406b0817823d02 diff --git a/.env.production b/.env.production index 4e9dcb81..73a13524 100644 --- a/.env.production +++ b/.env.production @@ -1,2 +1,3 @@ ENV_NAME=production -BASE_URL=https://syncrow-staging.azurewebsites.net \ No newline at end of file +BASE_URL=https://syncrow-staging.azurewebsites.net +OPEN_WEATHER_API_KEY=5253339f3f994603cd406b0817823d02 \ No newline at end of file diff --git a/.env.staging b/.env.staging index 9565b426..8ab31d93 100644 --- a/.env.staging +++ b/.env.staging @@ -1,2 +1,3 @@ ENV_NAME=staging -BASE_URL=https://syncrow-staging.azurewebsites.net \ No newline at end of file +BASE_URL=https://syncrow-staging.azurewebsites.net +OPEN_WEATHER_API_KEY=5253339f3f994603cd406b0817823d02 \ No newline at end of file diff --git a/lib/pages/analytics/services/device_location/remote_device_location_service.dart b/lib/pages/analytics/services/device_location/remote_device_location_service.dart new file mode 100644 index 00000000..b78be6cc --- /dev/null +++ b/lib/pages/analytics/services/device_location/remote_device_location_service.dart @@ -0,0 +1,88 @@ +import 'package:dio/dio.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; +import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; + +class RemoteDeviceLocationService implements DeviceLocationService { + const RemoteDeviceLocationService(this._dio); + + final Dio _dio; + static final _openWeatherApiKey = dotenv.env['OPEN_WEATHER_API_KEY']!; + @override + Future get(GetDeviceLocationDataParam param) async { + try { + final results = await Future.wait([ + _getAirQualityData(param), + _getWeatherData(param), + ]); + + final airQuality = results[0] as double?; + final weatherData = results[1] as _WeatherData?; + + return DeviceLocationInfo( + airQuality: airQuality, + temperature: weatherData?.temperature, + humidity: weatherData?.humidity, + ); + } catch (e) { + throw Exception('Failed to fetch location data: $e'); + } + } + + Future _getAirQualityData(GetDeviceLocationDataParam param) async { + final response = await _dio.get( + 'https://api.openweathermap.org/data/2.5/air_pollution', + queryParameters: { + 'lat': param.latitude, + 'lon': param.longitude, + 'appid': _openWeatherApiKey, + }, + ); + + final data = response.data as Map; + final list = data['list'] as List; + if (list.isEmpty) return null; + + final main = list[0]['main'] as Map; + return (main['aqi'] as num).toDouble(); + } + + Future<_WeatherData?> _getWeatherData(GetDeviceLocationDataParam param) async { + final now = DateTime.now(); + final start = DateTime(now.year, now.month, now.day); + final end = DateTime(now.year, now.month, now.day, 23, 59, 59); + try { + final response = await _dio.get( + 'https://api.openweathermap.org/data/2.5/weather', + queryParameters: { + 'lat': param.latitude, + 'lon': param.longitude, + 'start': start.millisecondsSinceEpoch, + 'end': end.millisecondsSinceEpoch, + 'appid': _openWeatherApiKey, + }, + ); + + final data = response.data as Map; + final main = data['main'] as Map; + + return _WeatherData( + temperature: (main['temp'] as num).toDouble(), + humidity: (main['humidity'] as num).toDouble(), + ); + } catch (e) { + return null; + } + } +} + +class _WeatherData { + const _WeatherData({ + required this.temperature, + required this.humidity, + }); + + final double temperature; + final double humidity; +} From 2c4da63266ff35855c490e5a0850c584ca6aa1d5 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sun, 1 Jun 2025 10:50:51 +0300 Subject: [PATCH 30/82] Injected `DeviceLocationBloc` into `AnalyticsPage`. --- .../analytics/views/analytics_page.dart | 10 ++++++++++ .../remote_device_location_service.dart | 19 ++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/pages/analytics/modules/analytics/views/analytics_page.dart b/lib/pages/analytics/modules/analytics/views/analytics_page.dart index 68a531c8..ca07c389 100644 --- a/lib/pages/analytics/modules/analytics/views/analytics_page.dart +++ b/lib/pages/analytics/modules/analytics/views/analytics_page.dart @@ -1,5 +1,7 @@ +import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart'; @@ -16,6 +18,7 @@ import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy_he import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/remote_device_location_service.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart'; import 'package:syncrow_web/pages/analytics/services/occupacy/remote_occupancy_service.dart'; @@ -101,6 +104,13 @@ class _AnalyticsPageState extends State { FakeRangeOfAqiService(), ), ), + BlocProvider( + create: (context) => DeviceLocationBloc( + RemoteDeviceLocationService( + Dio(BaseOptions(baseUrl: 'https://api.openweathermap.org/data/2.5')), + ), + ), + ), ], child: const AnalyticsPageForm(), ); diff --git a/lib/pages/analytics/services/device_location/remote_device_location_service.dart b/lib/pages/analytics/services/device_location/remote_device_location_service.dart index b78be6cc..707d6c61 100644 --- a/lib/pages/analytics/services/device_location/remote_device_location_service.dart +++ b/lib/pages/analytics/services/device_location/remote_device_location_service.dart @@ -9,6 +9,7 @@ class RemoteDeviceLocationService implements DeviceLocationService { final Dio _dio; static final _openWeatherApiKey = dotenv.env['OPEN_WEATHER_API_KEY']!; + @override Future get(GetDeviceLocationDataParam param) async { try { @@ -31,8 +32,12 @@ class RemoteDeviceLocationService implements DeviceLocationService { } Future _getAirQualityData(GetDeviceLocationDataParam param) async { - final response = await _dio.get( - 'https://api.openweathermap.org/data/2.5/air_pollution', + final response = await _dio.get>( + '/air_pollution/history', + options: Options( + method: 'GET', + responseType: ResponseType.json, + ), queryParameters: { 'lat': param.latitude, 'lon': param.longitude, @@ -40,7 +45,7 @@ class RemoteDeviceLocationService implements DeviceLocationService { }, ); - final data = response.data as Map; + final data = response.data ?? {}; final list = data['list'] as List; if (list.isEmpty) return null; @@ -53,8 +58,12 @@ class RemoteDeviceLocationService implements DeviceLocationService { final start = DateTime(now.year, now.month, now.day); final end = DateTime(now.year, now.month, now.day, 23, 59, 59); try { - final response = await _dio.get( - 'https://api.openweathermap.org/data/2.5/weather', + final response = await _dio.get>( + '/weather', + options: Options( + method: 'GET', + responseType: ResponseType.json, + ), queryParameters: { 'lat': param.latitude, 'lon': param.longitude, From 3d183528c56c55daa12bf506caea1fd4ffa5e00b Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sun, 1 Jun 2025 10:57:49 +0300 Subject: [PATCH 31/82] Fixed thrown exceptions because of `Expanded` widgets. --- .../air_quality/widgets/aqi_device_info.dart | 97 +++++++++---------- .../widgets/aqi_location_info.dart | 36 +++---- 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart index f3773c29..ebe88614 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart @@ -72,55 +72,54 @@ class AqiDeviceInfo extends StatelessWidget { return Container( decoration: secondarySection.copyWith(boxShadow: const []), padding: const EdgeInsetsDirectional.all(20), - child: Expanded( - child: Column( - spacing: 6, - children: [ - const AirQualityEndSideLiveIndicator(), - AirQualityEndSideGaugeAndInfo( - aqiLevel: status - .firstWhere( - (e) => e.code == 'air_quality_index', - orElse: () => Status(code: 'air_quality_index', value: ''), - ) - .value - .toString(), - temperature: int.parse(tempValue), - humidity: int.parse(humidityValue), - ), - const SizedBox(height: 20), - AqiSubValueWidget( - range: (0, 999), - label: AqiType.pm25.value, - value: pm25Value, - unit: AqiType.pm25.unit, - ), - AqiSubValueWidget( - range: (0, 999), - label: AqiType.pm10.value, - value: pm10Value, - unit: AqiType.pm10.unit, - ), - AqiSubValueWidget( - range: (0, 5), - label: AqiType.hcho.value, - value: ch2oValue, - unit: AqiType.hcho.unit, - ), - AqiSubValueWidget( - range: (0, 999), - label: AqiType.tvoc.value, - value: tvocValue, - unit: AqiType.tvoc.unit, - ), - AqiSubValueWidget( - range: (0, 5000), - label: AqiType.co2.value, - value: co2Value, - unit: AqiType.co2.unit, - ), - ], - ), + child: Column( + spacing: 6, + mainAxisSize: MainAxisSize.max, + children: [ + const AirQualityEndSideLiveIndicator(), + AirQualityEndSideGaugeAndInfo( + aqiLevel: status + .firstWhere( + (e) => e.code == 'air_quality_index', + orElse: () => Status(code: 'air_quality_index', value: ''), + ) + .value + .toString(), + temperature: int.parse(tempValue), + humidity: int.parse(humidityValue), + ), + const SizedBox(height: 20), + AqiSubValueWidget( + range: (0, 999), + label: AqiType.pm25.value, + value: pm25Value, + unit: AqiType.pm25.unit, + ), + AqiSubValueWidget( + range: (0, 999), + label: AqiType.pm10.value, + value: pm10Value, + unit: AqiType.pm10.unit, + ), + AqiSubValueWidget( + range: (0, 5), + label: AqiType.hcho.value, + value: ch2oValue, + unit: AqiType.hcho.unit, + ), + AqiSubValueWidget( + range: (0, 999), + label: AqiType.tvoc.value, + value: tvocValue, + unit: AqiType.tvoc.unit, + ), + AqiSubValueWidget( + range: (0, 5000), + label: AqiType.co2.value, + value: co2Value, + unit: AqiType.co2.unit, + ), + ], ), ); }, diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart index f8e087b8..8426328e 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart @@ -18,24 +18,24 @@ class AqiLocationInfo extends StatelessWidget { AqiLocation(), Expanded( child: Row( - spacing: 8, - children: [ - AqiLocationInfoCell( - label: 'Temperature', - value: ' 25°', - svgPath: Assets.aqiTemperature, - ), - AqiLocationInfoCell( - label: 'Humidity', - value: '25%', - svgPath: Assets.aqiHumidity, - ), - AqiLocationInfoCell( - label: 'Air Quality', - value: ' 120', - svgPath: Assets.aqiAirQuality, - ), - ], + spacing: 8, + children: [ + AqiLocationInfoCell( + label: 'Temperature', + value: ' 25°', + svgPath: Assets.aqiTemperature, + ), + AqiLocationInfoCell( + label: 'Humidity', + value: '25%', + svgPath: Assets.aqiHumidity, + ), + AqiLocationInfoCell( + label: 'Air Quality', + value: ' 120', + svgPath: Assets.aqiAirQuality, + ), + ], ), ), ], From b0ed84489370ecaaaf7000d8c4e5fb0641e4e2e2 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sun, 1 Jun 2025 14:37:22 +0300 Subject: [PATCH 32/82] made events and state class `final`s, to better document that they shouldn't be extended. --- .../blocs/device_location/device_location_event.dart | 4 ++-- .../blocs/device_location/device_location_state.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart index 376d055b..37137e4a 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_event.dart @@ -7,7 +7,7 @@ sealed class DeviceLocationEvent extends Equatable { List get props => []; } -class LoadDeviceLocationEvent extends DeviceLocationEvent { +final class LoadDeviceLocationEvent extends DeviceLocationEvent { const LoadDeviceLocationEvent(this.param); final GetDeviceLocationDataParam param; @@ -16,6 +16,6 @@ class LoadDeviceLocationEvent extends DeviceLocationEvent { List get props => [param]; } -class ClearDeviceLocationEvent extends DeviceLocationEvent { +final class ClearDeviceLocationEvent extends DeviceLocationEvent { const ClearDeviceLocationEvent(); } diff --git a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart index 15c681b6..8f66ad28 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_state.dart @@ -2,7 +2,7 @@ part of 'device_location_bloc.dart'; enum DeviceLocationStatus { initial, loading, success, failure } -class DeviceLocationState extends Equatable { +final class DeviceLocationState extends Equatable { const DeviceLocationState({ this.status = DeviceLocationStatus.initial, this.locationInfo, From bcb6e49a015a695db5411b4593286aca68e3e461 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:17:38 +0300 Subject: [PATCH 33/82] Deleted `FakeDeviceLocationService` class, since it is no longer needed. --- .../fake_device_location_service.dart | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 lib/pages/analytics/services/device_location/fake_device_location_service.dart diff --git a/lib/pages/analytics/services/device_location/fake_device_location_service.dart b/lib/pages/analytics/services/device_location/fake_device_location_service.dart deleted file mode 100644 index c1a4e82f..00000000 --- a/lib/pages/analytics/services/device_location/fake_device_location_service.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; -import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; -import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; - -class FakeDeviceLocationService implements DeviceLocationService { - const FakeDeviceLocationService(); - - @override - Future get(GetDeviceLocationDataParam param) async { - return await Future.delayed( - const Duration(milliseconds: 500), - () => const DeviceLocationInfo( - airQuality: 45.0, - humidity: 65.0, - city: 'Dubai', - country: 'UAE', - address: 'Business Bay', - temperature: 22.5, - ), - ); - } -} From 8d999f118c458878ae37d398c414106b289a94e0 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:18:28 +0300 Subject: [PATCH 34/82] Connected `RemoteDeviceLocationService` to the new BE API, instead of directly fetching the data from OpenWeather Api's. --- .../remote_device_location_service.dart | 97 +++---------------- 1 file changed, 16 insertions(+), 81 deletions(-) diff --git a/lib/pages/analytics/services/device_location/remote_device_location_service.dart b/lib/pages/analytics/services/device_location/remote_device_location_service.dart index 707d6c61..dce547a2 100644 --- a/lib/pages/analytics/services/device_location/remote_device_location_service.dart +++ b/lib/pages/analytics/services/device_location/remote_device_location_service.dart @@ -1,97 +1,32 @@ import 'package:dio/dio.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; +import 'package:syncrow_web/services/api/http_service.dart'; class RemoteDeviceLocationService implements DeviceLocationService { - const RemoteDeviceLocationService(this._dio); + const RemoteDeviceLocationService(this._httpService); - final Dio _dio; - static final _openWeatherApiKey = dotenv.env['OPEN_WEATHER_API_KEY']!; + final HTTPService _httpService; + + static const _defaultErrorMessage = 'Failed to load device location'; @override Future get(GetDeviceLocationDataParam param) async { try { - final results = await Future.wait([ - _getAirQualityData(param), - _getWeatherData(param), - ]); - - final airQuality = results[0] as double?; - final weatherData = results[1] as _WeatherData?; - - return DeviceLocationInfo( - airQuality: airQuality, - temperature: weatherData?.temperature, - humidity: weatherData?.humidity, + final response = await _httpService.get( + path: '/weather', + queryParameters: param.toJson(), + expectedResponseModel: (data) => DeviceLocationInfo.fromJson(data), ); + return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + throw Exception(errorMessage); } catch (e) { - throw Exception('Failed to fetch location data: $e'); - } - } - - Future _getAirQualityData(GetDeviceLocationDataParam param) async { - final response = await _dio.get>( - '/air_pollution/history', - options: Options( - method: 'GET', - responseType: ResponseType.json, - ), - queryParameters: { - 'lat': param.latitude, - 'lon': param.longitude, - 'appid': _openWeatherApiKey, - }, - ); - - final data = response.data ?? {}; - final list = data['list'] as List; - if (list.isEmpty) return null; - - final main = list[0]['main'] as Map; - return (main['aqi'] as num).toDouble(); - } - - Future<_WeatherData?> _getWeatherData(GetDeviceLocationDataParam param) async { - final now = DateTime.now(); - final start = DateTime(now.year, now.month, now.day); - final end = DateTime(now.year, now.month, now.day, 23, 59, 59); - try { - final response = await _dio.get>( - '/weather', - options: Options( - method: 'GET', - responseType: ResponseType.json, - ), - queryParameters: { - 'lat': param.latitude, - 'lon': param.longitude, - 'start': start.millisecondsSinceEpoch, - 'end': end.millisecondsSinceEpoch, - 'appid': _openWeatherApiKey, - }, - ); - - final data = response.data as Map; - final main = data['main'] as Map; - - return _WeatherData( - temperature: (main['temp'] as num).toDouble(), - humidity: (main['humidity'] as num).toDouble(), - ); - } catch (e) { - return null; + throw Exception('$_defaultErrorMessage: $e'); } } } - -class _WeatherData { - const _WeatherData({ - required this.temperature, - required this.humidity, - }); - - final double temperature; - final double humidity; -} From e48fc8b82c7bf130f49899e54d23506b7056bf37 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:27:21 +0300 Subject: [PATCH 35/82] loads and clears `DeviceLocationBloc`. --- .../helpers/fetch_air_quality_data_helper.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart b/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart index 65e62365..aaffc3fd 100644 --- a/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart +++ b/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart @@ -1,11 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart'; import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart'; import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart'; +import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; import 'package:syncrow_web/pages/analytics/params/get_range_of_aqi_param.dart'; abstract final class FetchAirQualityDataHelper { @@ -39,6 +41,8 @@ abstract final class FetchAirQualityDataHelper { ); context.read().add(const ClearRangeOfAqiEvent()); + + context.read().add(const ClearDeviceLocationEvent()); } static void loadAnalyticsDevices( @@ -58,6 +62,15 @@ abstract final class FetchAirQualityDataHelper { context.read() ..add(const RealtimeDeviceChangesClosed()) ..add(RealtimeDeviceChangesStarted(device.uuid)); + + context.read().add( + const LoadDeviceLocationEvent( + GetDeviceLocationDataParam( + latitude: 35.6895, + longitude: 139.6917, + ), + ), + ); }, ), ); From 25a55ad82033ff6c1787bfe4c83c88478a1213b4 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:27:46 +0300 Subject: [PATCH 36/82] made `GetDeviceLocationDataParam.toJson` method have the correct keys for the API. --- .../analytics/params/get_device_location_data_param.dart | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/pages/analytics/params/get_device_location_data_param.dart b/lib/pages/analytics/params/get_device_location_data_param.dart index c66af4d8..29427d10 100644 --- a/lib/pages/analytics/params/get_device_location_data_param.dart +++ b/lib/pages/analytics/params/get_device_location_data_param.dart @@ -7,10 +7,5 @@ class GetDeviceLocationDataParam { final double latitude; final double longitude; - Map toJson() { - return { - 'latitude': latitude, - 'longitude': longitude, - }; - } + Map toJson() => {'lat': latitude, 'lon': longitude}; } From 1edeb664aa95249021a61f8a13c7725db904467a Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:28:16 +0300 Subject: [PATCH 37/82] Connected data coming from `DeviceLocationBloc` into the respective widgets. --- .../air_quality/widgets/aqi_location.dart | 31 +++++++++- .../widgets/aqi_location_info.dart | 61 +++++++++++-------- 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_location.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_location.dart index 3f1d1f09..2503874f 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_location.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_location.dart @@ -6,7 +6,34 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/style.dart'; class AqiLocation extends StatelessWidget { - const AqiLocation({super.key}); + const AqiLocation({ + required this.city, + required this.country, + required this.address, + super.key, + }); + + final String? city; + final String? country; + final String? address; + + String _getFormattedLocation() { + if (city == null && country == null && address == null) { + return 'N/A'; + } + + final parts = []; + + if (city != null) parts.add(city!); + if (address != null) parts.add(address!); + final locationPart = parts.join(', '); + + if (country != null) { + return locationPart.isEmpty ? country! : '$locationPart - $country'; + } + + return locationPart; + } @override Widget build(BuildContext context) { @@ -24,7 +51,7 @@ class AqiLocation extends StatelessWidget { _buildLocationPin(), Expanded( child: Text( - 'Business Bay, Dubai - UAE', + _getFormattedLocation(), style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart index 8426328e..983f76b2 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_location_info.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_location.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_location_info_cell.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -9,37 +11,46 @@ class AqiLocationInfo extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - decoration: secondarySection.copyWith(boxShadow: const []), - padding: const EdgeInsetsDirectional.all(20), - child: const Column( - spacing: 8, - children: [ - AqiLocation(), - Expanded( - child: Row( + return BlocBuilder( + builder: (context, state) { + final info = state.locationInfo; + return Container( + decoration: secondarySection.copyWith(boxShadow: const []), + padding: const EdgeInsetsDirectional.all(20), + child: Column( spacing: 8, children: [ - AqiLocationInfoCell( - label: 'Temperature', - value: ' 25°', - svgPath: Assets.aqiTemperature, + AqiLocation( + city: info?.city, + country: info?.country, + address: info?.address, ), - AqiLocationInfoCell( - label: 'Humidity', - value: '25%', - svgPath: Assets.aqiHumidity, - ), - AqiLocationInfoCell( - label: 'Air Quality', - value: ' 120', - svgPath: Assets.aqiAirQuality, + Expanded( + child: Row( + spacing: 8, + children: [ + AqiLocationInfoCell( + label: 'Temperature', + value: ' ${info?.temperature?.roundToDouble() ?? '--'}°', + svgPath: Assets.aqiTemperature, + ), + AqiLocationInfoCell( + label: 'Humidity', + value: '${info?.humidity?.roundToDouble() ?? '--'}%', + svgPath: Assets.aqiHumidity, + ), + AqiLocationInfoCell( + label: 'Air Quality', + value: ' ${info?.airQuality?.roundToDouble() ?? '--'}', + svgPath: Assets.aqiAirQuality, + ), + ], + ), ), ], - ), ), - ], - ), + ); + }, ); } } From e2c44ba85fdeabbd62018ca716937d43bcf6a1dc Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:28:50 +0300 Subject: [PATCH 38/82] injected the remote and reverse geocoder dependenies into `DeviceLocationBloc`. --- .../analytics/modules/analytics/views/analytics_page.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages/analytics/modules/analytics/views/analytics_page.dart b/lib/pages/analytics/modules/analytics/views/analytics_page.dart index ca07c389..0a45ba8d 100644 --- a/lib/pages/analytics/modules/analytics/views/analytics_page.dart +++ b/lib/pages/analytics/modules/analytics/views/analytics_page.dart @@ -1,4 +1,3 @@ -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart'; @@ -19,6 +18,7 @@ import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart'; import 'package:syncrow_web/pages/analytics/services/device_location/remote_device_location_service.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart'; import 'package:syncrow_web/pages/analytics/services/occupacy/remote_occupancy_service.dart'; @@ -106,8 +106,8 @@ class _AnalyticsPageState extends State { ), BlocProvider( create: (context) => DeviceLocationBloc( - RemoteDeviceLocationService( - Dio(BaseOptions(baseUrl: 'https://api.openweathermap.org/data/2.5')), + ReverseGeocodeDeviceLocationServiceDecorator( + RemoteDeviceLocationService(_httpService), ), ), ), From 651ac6785eb0afdf3f054c1bf0943a1d819bc971 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:32:56 +0300 Subject: [PATCH 39/82] removed open weather api keys from `.env` files. --- .env.development | 3 +-- .env.production | 3 +-- .env.staging | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.env.development b/.env.development index 8b8c7587..e77609dc 100644 --- a/.env.development +++ b/.env.development @@ -1,3 +1,2 @@ ENV_NAME=development -BASE_URL=https://syncrow-dev.azurewebsites.net -OPEN_WEATHER_API_KEY=5253339f3f994603cd406b0817823d02 +BASE_URL=https://syncrow-dev.azurewebsites.net \ No newline at end of file diff --git a/.env.production b/.env.production index 73a13524..4e9dcb81 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,2 @@ ENV_NAME=production -BASE_URL=https://syncrow-staging.azurewebsites.net -OPEN_WEATHER_API_KEY=5253339f3f994603cd406b0817823d02 \ No newline at end of file +BASE_URL=https://syncrow-staging.azurewebsites.net \ No newline at end of file diff --git a/.env.staging b/.env.staging index 8ab31d93..9565b426 100644 --- a/.env.staging +++ b/.env.staging @@ -1,3 +1,2 @@ ENV_NAME=staging -BASE_URL=https://syncrow-staging.azurewebsites.net -OPEN_WEATHER_API_KEY=5253339f3f994603cd406b0817823d02 \ No newline at end of file +BASE_URL=https://syncrow-staging.azurewebsites.net \ No newline at end of file From 79b974ee6cbe953096d11852d775a8f2f9696fb9 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 09:36:41 +0300 Subject: [PATCH 40/82] re-injected `AirQualityDistributionBloc` into `AnalyticsPage`. --- .../analytics/modules/analytics/views/analytics_page.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/pages/analytics/modules/analytics/views/analytics_page.dart b/lib/pages/analytics/modules/analytics/views/analytics_page.dart index 0a45ba8d..01dc8ef5 100644 --- a/lib/pages/analytics/modules/analytics/views/analytics_page.dart +++ b/lib/pages/analytics/modules/analytics/views/analytics_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart'; @@ -14,6 +15,7 @@ import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/real import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart'; +import 'package:syncrow_web/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart'; @@ -104,6 +106,11 @@ class _AnalyticsPageState extends State { FakeRangeOfAqiService(), ), ), + BlocProvider( + create: (context) => AirQualityDistributionBloc( + FakeAirQualityDistributionService(), + ), + ), BlocProvider( create: (context) => DeviceLocationBloc( ReverseGeocodeDeviceLocationServiceDecorator( From 24a7f3ac2a2f214eefaf32c1800591d7e8bfd557 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 13:06:27 +0300 Subject: [PATCH 41/82] SP-1594-device-location-api-integration. --- .../analytics/models/analytics_device.dart | 6 +++ .../models/device_location_info.dart | 5 +-- .../fetch_air_quality_data_helper.dart | 8 ++-- .../analytics/views/analytics_page.dart | 10 ++++- ...ce_location_details_service_decorator.dart | 40 +++++++++++++++++++ .../remote_device_location_service.dart | 7 +++- ...ode_device_location_service_decorator.dart | 40 ------------------- 7 files changed, 65 insertions(+), 51 deletions(-) create mode 100644 lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart delete mode 100644 lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart diff --git a/lib/pages/analytics/models/analytics_device.dart b/lib/pages/analytics/models/analytics_device.dart index eaac8b2b..3340a41d 100644 --- a/lib/pages/analytics/models/analytics_device.dart +++ b/lib/pages/analytics/models/analytics_device.dart @@ -8,6 +8,8 @@ class AnalyticsDevice { this.isActive, this.productDevice, this.spaceUuid, + this.latitude, + this.longitude, }); final String uuid; @@ -18,6 +20,8 @@ class AnalyticsDevice { final bool? isActive; final ProductDevice? productDevice; final String? spaceUuid; + final double? latitude; + final double? longitude; factory AnalyticsDevice.fromJson(Map json) { return AnalyticsDevice( @@ -35,6 +39,8 @@ class AnalyticsDevice { ? ProductDevice.fromJson(json['productDevice'] as Map) : null, spaceUuid: json['spaceUuid'] as String?, + latitude: json['lat'] != null ? double.parse(json['lat'] as String) : null, + longitude: json['lon'] != null ? double.parse(json['lon'] as String) : null, ); } } diff --git a/lib/pages/analytics/models/device_location_info.dart b/lib/pages/analytics/models/device_location_info.dart index 9b0095f7..aef7eebb 100644 --- a/lib/pages/analytics/models/device_location_info.dart +++ b/lib/pages/analytics/models/device_location_info.dart @@ -19,11 +19,8 @@ class DeviceLocationInfo extends Equatable { factory DeviceLocationInfo.fromJson(Map json) { return DeviceLocationInfo( - airQuality: json['airQuality'] as double?, + airQuality: json['aqi'] as double?, humidity: json['humidity'] as double?, - city: json['city'] as String?, - country: json['country'] as String?, - address: json['address'] as String?, temperature: json['temperature'] as double?, ); } diff --git a/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart b/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart index 7f26bb5a..cb37484c 100644 --- a/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart +++ b/lib/pages/analytics/modules/air_quality/helpers/fetch_air_quality_data_helper.dart @@ -65,7 +65,7 @@ abstract final class FetchAirQualityDataHelper { communityUuid: communityUuid, spaceUuid: spaceUuid, deviceTypes: ['AQI'], - requestType: AnalyticsDeviceRequestType.energyManagement, + requestType: AnalyticsDeviceRequestType.occupancy, ), onSuccess: (device) { context.read() @@ -73,10 +73,10 @@ abstract final class FetchAirQualityDataHelper { ..add(RealtimeDeviceChangesStarted(device.uuid)); context.read().add( - const LoadDeviceLocationEvent( + LoadDeviceLocationEvent( GetDeviceLocationDataParam( - latitude: 35.6895, - longitude: 139.6917, + latitude: device.latitude ?? 0, + longitude: device.longitude ?? 0, ), ), ); diff --git a/lib/pages/analytics/modules/analytics/views/analytics_page.dart b/lib/pages/analytics/modules/analytics/views/analytics_page.dart index 01dc8ef5..1ecd9aa3 100644 --- a/lib/pages/analytics/modules/analytics/views/analytics_page.dart +++ b/lib/pages/analytics/modules/analytics/views/analytics_page.dart @@ -1,3 +1,4 @@ +import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart'; @@ -19,8 +20,8 @@ import 'package:syncrow_web/pages/analytics/services/air_quality_distribution/fa import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/device_location_details_service_decorator.dart'; import 'package:syncrow_web/pages/analytics/services/device_location/remote_device_location_service.dart'; -import 'package:syncrow_web/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart'; import 'package:syncrow_web/pages/analytics/services/occupacy/remote_occupancy_service.dart'; @@ -113,8 +114,13 @@ class _AnalyticsPageState extends State { ), BlocProvider( create: (context) => DeviceLocationBloc( - ReverseGeocodeDeviceLocationServiceDecorator( + DeviceLocationDetailsServiceDecorator( RemoteDeviceLocationService(_httpService), + Dio( + BaseOptions( + baseUrl: 'https://nominatim.openstreetmap.org/', + ), + ), ), ), ), diff --git a/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart new file mode 100644 index 00000000..0239bcb7 --- /dev/null +++ b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart @@ -0,0 +1,40 @@ +import 'package:dio/dio.dart'; +import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; +import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; +import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; + +class DeviceLocationDetailsServiceDecorator implements DeviceLocationService { + const DeviceLocationDetailsServiceDecorator(this._decoratee, this._dio); + + final DeviceLocationService _decoratee; + final Dio _dio; + + @override + Future get(GetDeviceLocationDataParam param) async { + try { + final deviceLocationInfo = await _decoratee.get(param); + final response = await _dio.get>( + 'reverse', + queryParameters: { + 'format': 'json', + 'lat': param.latitude, + 'lon': param.longitude, + }, + ); + + final data = response.data; + if (data != null) { + final addressData = data['address'] as Map; + return deviceLocationInfo.copyWith( + city: addressData['city'], + country: addressData['country_code'].toString().toUpperCase(), + address: addressData['state'], + ); + } + + return deviceLocationInfo; + } catch (e) { + throw Exception('Failed to load device location info: ${e.toString()}'); + } + } +} diff --git a/lib/pages/analytics/services/device_location/remote_device_location_service.dart b/lib/pages/analytics/services/device_location/remote_device_location_service.dart index dce547a2..b8820180 100644 --- a/lib/pages/analytics/services/device_location/remote_device_location_service.dart +++ b/lib/pages/analytics/services/device_location/remote_device_location_service.dart @@ -17,7 +17,12 @@ class RemoteDeviceLocationService implements DeviceLocationService { final response = await _httpService.get( path: '/weather', queryParameters: param.toJson(), - expectedResponseModel: (data) => DeviceLocationInfo.fromJson(data), + expectedResponseModel: (data) { + final response = data as Map; + final location = response['data'] as Map; + + return DeviceLocationInfo.fromJson(location); + }, ); return response; } on DioException catch (e) { diff --git a/lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart b/lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart deleted file mode 100644 index a3ac1e55..00000000 --- a/lib/pages/analytics/services/device_location/reverse_geocode_device_location_service_decorator.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:geocoding/geocoding.dart'; -import 'package:syncrow_web/pages/analytics/models/device_location_info.dart'; -import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart'; -import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart'; - -class ReverseGeocodeDeviceLocationServiceDecorator implements DeviceLocationService { - const ReverseGeocodeDeviceLocationServiceDecorator(this._decoratee); - - final DeviceLocationService _decoratee; - - @override - Future get(GetDeviceLocationDataParam param) async { - try { - final deviceLocationInfo = await _decoratee.get(param); - - final placemarks = await placemarkFromCoordinates( - param.latitude, - param.longitude, - ); - - if (placemarks.isNotEmpty) { - final place = placemarks.first; - - final city = place.locality; - final country = place.country; - final address = place.street; - - return deviceLocationInfo.copyWith( - city: city, - country: country, - address: address, - ); - } - - return deviceLocationInfo; - } catch (e) { - throw Exception('Failed to reverse load device location info'); - } - } -} From 3a98f71ff3eed552403bfb925b94d82af705f347 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 14:42:41 +0300 Subject: [PATCH 42/82] SP-1665-FE-Return-a-readable-error-when-a-connection-error-Exception-occurs-on-the-charts. --- .../analytics_devices_bloc.dart | 8 +++++++ .../energy_consumption_by_phases_bloc.dart | 8 +++++++ .../energy_consumption_per_device_bloc.dart | 11 +++++++++- .../power_clamp_info_bloc.dart | 8 +++++++ .../total_energy_consumption_bloc.dart | 8 +++++++ .../blocs/occupancy/occupancy_bloc.dart | 3 +++ .../occupancy_heat_map_bloc.dart | 8 +++++++ ..._management_analytics_devices_service.dart | 12 ++++++++++- ...e_occupancy_analytics_devices_service.dart | 21 +++++++++++++++++-- ..._energy_consumption_by_phases_service.dart | 13 +++++++++++- ...energy_consumption_per_device_service.dart | 13 +++++++++++- .../occupacy/remote_occupancy_service.dart | 15 +++++++++++-- .../remote_occupancy_heat_map_service.dart | 13 +++++++++++- .../remote_power_clamp_info_service.dart | 13 +++++++++++- ...mote_total_energy_consumption_service.dart | 13 +++++++++++- 15 files changed, 156 insertions(+), 11 deletions(-) diff --git a/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart b/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart index 244b2fa0..fbd28dee 100644 --- a/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart +++ b/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/analytics/models/analytics_device.dart'; import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; part 'analytics_devices_event.dart'; part 'analytics_devices_state.dart'; @@ -36,6 +37,13 @@ class AnalyticsDevicesBloc if (devices.isNotEmpty) { event.onSuccess(devices.first); } + } on APIException catch (e) { + emit( + AnalyticsDevicesState( + status: AnalyticsDevicesStatus.failure, + errorMessage: e.message, + ), + ); } catch (e) { emit( AnalyticsDevicesState( diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart index 012f435a..1acf7df5 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart'; import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; part 'energy_consumption_by_phases_event.dart'; part 'energy_consumption_by_phases_state.dart'; @@ -31,6 +32,13 @@ class EnergyConsumptionByPhasesBloc chartData: chartData, ), ); + } on APIException catch (e) { + emit( + state.copyWith( + status: EnergyConsumptionByPhasesStatus.failure, + errorMessage: e.message, + ), + ); } catch (e) { emit( state.copyWith( diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart index c1c51a16..97d182c5 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart'; import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; part 'energy_consumption_per_device_event.dart'; part 'energy_consumption_per_device_state.dart'; @@ -13,7 +14,8 @@ class EnergyConsumptionPerDeviceBloc this._energyConsumptionPerDeviceService, ) : super(const EnergyConsumptionPerDeviceState()) { on(_onLoadEnergyConsumptionPerDeviceEvent); - on(_onClearEnergyConsumptionPerDeviceEvent); + on( + _onClearEnergyConsumptionPerDeviceEvent); } final EnergyConsumptionPerDeviceService _energyConsumptionPerDeviceService; @@ -31,6 +33,13 @@ class EnergyConsumptionPerDeviceBloc chartData: chartData, ), ); + } on APIException catch (e) { + emit( + state.copyWith( + status: EnergyConsumptionPerDeviceStatus.failure, + errorMessage: e.message, + ), + ); } catch (e) { emit( state.copyWith( diff --git a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart index d0e7aab6..2aefd798 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/analytics/services/power_clamp_info/power_clamp_info_service.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; part 'power_clamp_info_event.dart'; part 'power_clamp_info_state.dart'; @@ -31,6 +32,13 @@ class PowerClampInfoBloc extends Bloc powerClampModel: powerClampModel, ), ); + } on APIException catch (e) { + emit( + state.copyWith( + status: PowerClampInfoStatus.error, + errorMessage: e.message, + ), + ); } catch (e) { emit( state.copyWith( diff --git a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart index 42ad57e8..f51d20cf 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart'; import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart'; import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/total_energy_consumption_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; part 'total_energy_consumption_event.dart'; part 'total_energy_consumption_state.dart'; @@ -31,6 +32,13 @@ class TotalEnergyConsumptionBloc status: TotalEnergyConsumptionStatus.loaded, ), ); + } on APIException catch (e) { + emit( + state.copyWith( + errorMessage: e.message, + status: TotalEnergyConsumptionStatus.failure, + ), + ); } catch (e) { emit( state.copyWith( diff --git a/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart b/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart index 6eeda29b..110f3c60 100644 --- a/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart +++ b/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/analytics/models/occupacy.dart'; import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart'; import 'package:syncrow_web/pages/analytics/services/occupacy/occupacy_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; part 'occupancy_event.dart'; part 'occupancy_state.dart'; @@ -23,6 +24,8 @@ class OccupancyBloc extends Bloc { try { final chartData = await _occupacyService.load(event.param); emit(state.copyWith(chartData: chartData, status: OccupancyStatus.loaded)); + } on APIException catch (e) { + emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: e.message)); } catch (e) { emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: '$e')); } diff --git a/lib/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart b/lib/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart index 5d5cb914..453b68ce 100644 --- a/lib/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart +++ b/lib/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/analytics/models/occupancy_heat_map_model.dart'; import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart'; import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/occupancy_heat_map_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; part 'occupancy_heat_map_event.dart'; part 'occupancy_heat_map_state.dart'; @@ -30,6 +31,13 @@ class OccupancyHeatMapBloc heatMapData: occupancyHeatMap, ), ); + } on APIException catch (e) { + emit( + state.copyWith( + status: OccupancyHeatMapStatus.failure, + errorMessage: e.message, + ), + ); } catch (e) { emit( state.copyWith( diff --git a/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart b/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart index adf8a6fa..9ef711e9 100644 --- a/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart +++ b/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart @@ -1,6 +1,8 @@ +import 'package:dio/dio.dart'; import 'package:syncrow_web/pages/analytics/models/analytics_device.dart'; import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; final class RemoteEnergyManagementAnalyticsDevicesService @@ -9,6 +11,8 @@ final class RemoteEnergyManagementAnalyticsDevicesService final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to load analytics devices'; + @override Future> getDevices(GetAnalyticsDevicesParam param) async { try { @@ -29,8 +33,14 @@ final class RemoteEnergyManagementAnalyticsDevicesService ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to load total energy consumption: $e'); + throw APIException('$_defaultErrorMessage: $e'); } } } diff --git a/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart b/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart index 91bbe1f4..736b0804 100644 --- a/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart +++ b/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart @@ -1,7 +1,9 @@ +import 'package:dio/dio.dart'; import 'package:syncrow_web/pages/analytics/models/analytics_device.dart'; import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService { @@ -9,6 +11,8 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to load analytics devices'; + @override Future> getDevices(GetAnalyticsDevicesParam param) async { try { @@ -26,8 +30,15 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService final result = requests.map((e) => e.first).toList(); return result; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to load total energy consumption: $e'); + final formattedErrorMessage = [_defaultErrorMessage, e.toString()].join(': '); + throw APIException(formattedErrorMessage); } } @@ -54,8 +65,14 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService }, ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - rethrow; + throw APIException('$_defaultErrorMessage: $e'); } } } diff --git a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart index 28df5eed..17f9baff 100644 --- a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart +++ b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart @@ -1,6 +1,8 @@ +import 'package:dio/dio.dart'; import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart'; import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; final class RemoteEnergyConsumptionByPhasesService @@ -9,6 +11,8 @@ final class RemoteEnergyConsumptionByPhasesService final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to load energy consumption per phase'; + @override Future> load( GetEnergyConsumptionByPhasesParam param, @@ -28,8 +32,15 @@ final class RemoteEnergyConsumptionByPhasesService }, ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to load energy consumption per phase: $e'); + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); } } } diff --git a/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart b/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart index 165ab5ab..82b21b1c 100644 --- a/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart +++ b/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart @@ -1,8 +1,10 @@ +import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart'; import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart'; import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; class RemoteEnergyConsumptionPerDeviceService @@ -11,6 +13,8 @@ class RemoteEnergyConsumptionPerDeviceService final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to load energy consumption per device'; + @override Future> load( GetEnergyConsumptionPerDeviceParam param, @@ -23,8 +27,15 @@ class RemoteEnergyConsumptionPerDeviceService expectedResponseModel: _EnergyConsumptionPerDeviceMapper.map, ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to load energy consumption per device: $e'); + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); } } } diff --git a/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart b/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart index b8cce70a..afd3f79e 100644 --- a/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart +++ b/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart @@ -1,6 +1,8 @@ +import 'package:dio/dio.dart'; import 'package:syncrow_web/pages/analytics/models/occupacy.dart'; import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart'; import 'package:syncrow_web/pages/analytics/services/occupacy/occupacy_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; final class RemoteOccupancyService implements OccupacyService { @@ -8,6 +10,8 @@ final class RemoteOccupancyService implements OccupacyService { final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to load occupancy'; + @override Future> load(GetOccupancyParam param) async { try { @@ -25,8 +29,15 @@ final class RemoteOccupancyService implements OccupacyService { }, ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to load energy consumption per phase: $e'); + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); } } -} \ No newline at end of file +} diff --git a/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart b/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart index ac06ccf7..0d7f6500 100644 --- a/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart +++ b/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart @@ -1,6 +1,8 @@ +import 'package:dio/dio.dart'; import 'package:syncrow_web/pages/analytics/models/occupancy_heat_map_model.dart'; import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart'; import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/occupancy_heat_map_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { @@ -8,6 +10,8 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to load occupancy heat map'; + @override Future> load(GetOccupancyHeatMapParam param) async { try { @@ -28,8 +32,15 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to load total energy consumption:'); + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); } } } diff --git a/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart b/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart index 17d5a7fc..b4bc82c6 100644 --- a/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart +++ b/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart @@ -1,5 +1,7 @@ +import 'package:dio/dio.dart'; import 'package:syncrow_web/pages/analytics/services/power_clamp_info/power_clamp_info_service.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; final class RemotePowerClampInfoService implements PowerClampInfoService { @@ -7,6 +9,8 @@ final class RemotePowerClampInfoService implements PowerClampInfoService { final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to fetch power clamp info'; + @override Future getInfo(String deviceId) async { try { @@ -20,8 +24,15 @@ final class RemotePowerClampInfoService implements PowerClampInfoService { }, ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to fetch power clamp info: $e'); + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); } } } diff --git a/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart b/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart index 8c3041eb..838cc5e7 100644 --- a/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart +++ b/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart @@ -1,6 +1,8 @@ +import 'package:dio/dio.dart'; import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart'; import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart'; import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/total_energy_consumption_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionService { @@ -8,6 +10,8 @@ class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionServi final HTTPService _httpService; + static const _defaultErrorMessage = 'Failed to load total energy consumption'; + @override Future> load( GetTotalEnergyConsumptionParam param, @@ -21,8 +25,15 @@ class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionServi ); return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + throw APIException(formattedErrorMessage); } catch (e) { - throw Exception('Failed to load total energy consumption: $e'); + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); } } } From beb5239c4ff8d062a790b1deea27934182d3c244 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 10:12:19 +0300 Subject: [PATCH 43/82] enhanced ci/cd by not running the deply jobs on the PR itself, and now we only deploy when we merged a PR to `dev` or `main`, and created a separate GitHub action that only builds and install dependencies, which only runs on the PR itself. --- ...e-static-web-apps-mango-bush-01e607f10.yml | 4 --- ...static-web-apps-polite-smoke-017c65c10.yml | 6 ---- .github/workflows/pr-check.yml | 29 +++++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/pr-check.yml diff --git a/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml b/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml index db94e74f..892381f3 100644 --- a/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml +++ b/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml @@ -4,10 +4,6 @@ on: push: branches: - main - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - main jobs: build_and_deploy_job: diff --git a/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml b/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml index 738bd279..6a91fe27 100644 --- a/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml +++ b/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml @@ -4,18 +4,12 @@ on: push: branches: - dev - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - dev jobs: build_and_deploy_job: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') runs-on: ubuntu-latest name: Build and Deploy Job steps: - - name: Checkout Code uses: actions/checkout@v3 with: diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml new file mode 100644 index 00000000..621a54d3 --- /dev/null +++ b/.github/workflows/pr-check.yml @@ -0,0 +1,29 @@ +name: Pull Request Check + +on: + pull_request: + branches: + - dev + - main + +jobs: + setup_flutter: + runs-on: ubuntu-latest + name: Setup Flutter and Dependencies + steps: + - name: Checkout Code + uses: actions/checkout@v3 + with: + submodules: true + lfs: false + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: '3.27.3' + + - name: Install dependencies + run: flutter pub get + + - name: Run Flutter Build + run: flutter build web --web-renderer canvaskit -t lib/main_dev.dart From 3e329682097e24c0d529e80397499f49f48fb846 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 28 May 2025 16:46:24 +0300 Subject: [PATCH 44/82] Update pull_request_template.md --- .github/pull_request_template.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d18a89f3..70d6e519 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -7,11 +7,7 @@ --> ## Jira Ticket - - -## Status - -**READY/IN DEVELOPMENT/HOLD** +[SP-0000](https://syncrow.atlassian.net/browse/SP-0000) ## Description @@ -27,4 +23,4 @@ - [ ] 🧹 Code refactor - [ ] ✅ Build configuration change - [ ] 📝 Documentation -- [ ] 🗑️ Chore \ No newline at end of file +- [ ] 🗑️ Chore From 0c6e4fed80cec7f070a442133bed3e8dc45f98ee Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 4 Jun 2025 15:09:40 +0300 Subject: [PATCH 45/82] correctly fetch energy management data using `spaceUuid`. --- .../analytics_energy_management_view.dart | 25 +------------------ ...t_energy_consumption_per_device_param.dart | 2 +- .../get_total_energy_consumption_param.dart | 2 +- 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart b/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart index ffb09113..f88febcc 100644 --- a/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart +++ b/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart @@ -1,34 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart'; -import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; -class AnalyticsEnergyManagementView extends StatefulWidget { +class AnalyticsEnergyManagementView extends StatelessWidget { const AnalyticsEnergyManagementView({super.key}); - @override - State createState() => - _AnalyticsEnergyManagementViewState(); -} - -class _AnalyticsEnergyManagementViewState - extends State { - @override - void initState() { - final spaceTreeBloc = context.read(); - final communityId = spaceTreeBloc.state.selectedCommunities.firstOrNull; - final spaceId = spaceTreeBloc.state.selectedSpaces.firstOrNull; - FetchEnergyManagementDataHelper.loadEnergyManagementData( - context, - communityId: communityId ?? '', - spaceId: spaceId ?? '', - ); - super.initState(); - } - static const _padding = EdgeInsetsDirectional.all(32); @override Widget build(BuildContext context) { diff --git a/lib/pages/analytics/params/get_energy_consumption_per_device_param.dart b/lib/pages/analytics/params/get_energy_consumption_per_device_param.dart index 79d0f2f4..c219893e 100644 --- a/lib/pages/analytics/params/get_energy_consumption_per_device_param.dart +++ b/lib/pages/analytics/params/get_energy_consumption_per_device_param.dart @@ -10,7 +10,7 @@ class GetEnergyConsumptionPerDeviceParam { Map toJson() => { 'monthDate': '${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}', - if (spaceId == null || spaceId == null) 'spaceUuid': spaceId, + if (spaceId != null) 'spaceUuid': spaceId, 'groupByDevice': true, }; } diff --git a/lib/pages/analytics/params/get_total_energy_consumption_param.dart b/lib/pages/analytics/params/get_total_energy_consumption_param.dart index 6428fd30..f5615cca 100644 --- a/lib/pages/analytics/params/get_total_energy_consumption_param.dart +++ b/lib/pages/analytics/params/get_total_energy_consumption_param.dart @@ -11,7 +11,7 @@ class GetTotalEnergyConsumptionParam { return { 'monthDate': '${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}', - if (spaceId == null || spaceId == null) 'spaceUuid': spaceId, + if (spaceId != null) 'spaceUuid': spaceId, 'groupByDevice': false, }; } From 662fe211ebe0767cf9ada366b88727d9468631b4 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 9 Jun 2025 22:55:00 +0300 Subject: [PATCH 46/82] Refactor HomeBloc and GarageDoorBloc event handling; update CreateNewRoutinesDialog to use SpaceTreeDropdown; add settings button SVG. --- ...ettings_button.svg => sittings_button.svg} | 0 .../garage_door/bloc/garage_door_bloc.dart | 4 +- lib/pages/home/bloc/home_bloc.dart | 1 - lib/pages/home/view/home_page_web.dart | 18 +- .../create_new_routines/commu_dropdown.dart | 277 +++++++++--------- .../create_new_routines.dart | 36 +-- .../dropdown_menu_content.dart | 148 ++++++++++ 7 files changed, 313 insertions(+), 171 deletions(-) rename assets/icons/{settings_button.svg => sittings_button.svg} (100%) create mode 100644 lib/pages/routines/create_new_routines/dropdown_menu_content.dart diff --git a/assets/icons/settings_button.svg b/assets/icons/sittings_button.svg similarity index 100% rename from assets/icons/settings_button.svg rename to assets/icons/sittings_button.svg diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart index 593fdeab..28a7e33b 100644 --- a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart +++ b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart @@ -379,7 +379,7 @@ class GarageDoorBloc extends Bloc { } emit(GarageDoorLoadedState(status: deviceStatus)); add(GarageDoorControlEvent( - deviceId: event.deviceId, + deviceId: deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1')); } catch (e) { @@ -396,7 +396,7 @@ class GarageDoorBloc extends Bloc { _updateLocalValue(event.code, event.value); emit(GarageDoorLoadedState(status: deviceStatus)); final success = await _runDeBouncer( - deviceId: event.deviceId, + deviceId: deviceId, code: event.code, value: event.value, oldValue: oldValue, diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index f6aab9eb..dc6a1280 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -35,7 +35,6 @@ class HomeBloc extends Bloc { if (user != null && user!.project != null) { await ProjectManager.setProjectUUID(user!.project!.uuid); - NavigationService.navigatorKey.currentContext!.read().add(InitialEvent()); } add(FetchTermEvent()); add(FetchPolicyEvent()); diff --git a/lib/pages/home/view/home_page_web.dart b/lib/pages/home/view/home_page_web.dart index fb35fa04..e6251c86 100644 --- a/lib/pages/home/view/home_page_web.dart +++ b/lib/pages/home/view/home_page_web.dart @@ -20,12 +20,6 @@ class _HomeWebPageState extends State { // Flag to track whether the dialog is already shown. bool _dialogShown = false; - @override - void initState() { - super.initState(); - final homeBloc = BlocProvider.of(context); - homeBloc.add(const FetchUserInfo()); - } @override Widget build(BuildContext context) { @@ -38,8 +32,10 @@ class _HomeWebPageState extends State { child: BlocConsumer( listener: (BuildContext context, state) { if (state is HomeInitial) { - if (homeBloc.user!.hasAcceptedWebAgreement == false && !_dialogShown) { - _dialogShown = true; // Set the flag to true to indicate the dialog is showing. + if (homeBloc.user!.hasAcceptedWebAgreement == false && + !_dialogShown) { + _dialogShown = + true; // Set the flag to true to indicate the dialog is showing. Future.delayed(const Duration(seconds: 1), () { showDialog( context: context, @@ -98,7 +94,8 @@ class _HomeWebPageState extends State { width: size.width * 0.68, child: GridView.builder( itemCount: homeBloc.homeItems.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, // Adjust as needed. crossAxisSpacing: 20.0, mainAxisSpacing: 20.0, @@ -111,7 +108,8 @@ class _HomeWebPageState extends State { active: homeBloc.homeItems[index].active!, name: homeBloc.homeItems[index].title!, img: homeBloc.homeItems[index].icon!, - onTap: () => homeBloc.homeItems[index].onPress(context), + onTap: () => + homeBloc.homeItems[index].onPress(context), ); }, ), diff --git a/lib/pages/routines/create_new_routines/commu_dropdown.dart b/lib/pages/routines/create_new_routines/commu_dropdown.dart index 5b96e977..b6cece30 100644 --- a/lib/pages/routines/create_new_routines/commu_dropdown.dart +++ b/lib/pages/routines/create_new_routines/commu_dropdown.dart @@ -1,156 +1,157 @@ -import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/routines/create_new_routines/dropdown_menu_content.dart'; +import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.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/utils/color_manager.dart'; -class CommunityDropdown extends StatelessWidget { - final String? selectedValue; - final List communities; - final Function(String?) onChanged; - final TextEditingController _searchController = TextEditingController(); +class SpaceTreeDropdown extends StatefulWidget { + final String? selectedSpaceId; + final Function(String?)? onChanged; - CommunityDropdown({ - Key? key, - required this.selectedValue, - required this.onChanged, - required this.communities, - }) : super(key: key); + const SpaceTreeDropdown({ + super.key, + this.selectedSpaceId, + this.onChanged, + }); + + @override + State createState() => _SpaceTreeDropdownState(); +} + +class _SpaceTreeDropdownState extends State { + late String? _selectedSpaceId; + final LayerLink _layerLink = LayerLink(); + OverlayEntry? _overlayEntry; + + @override + void initState() { + super.initState(); + _selectedSpaceId = widget.selectedSpaceId; + } + + @override + void dispose() { + _removeOverlay(); + super.dispose(); + } + + void _removeOverlay() { + _overlayEntry?.remove(); + _overlayEntry = null; + } @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Community", - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w400, - fontSize: 13, - color: ColorsManager.blackColor, - ), - ), - const SizedBox(height: 8), - SizedBox( - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - ), - child: DropdownButton2( - underline: const SizedBox(), - value: selectedValue, - items: communities.map((community) { - return DropdownMenuItem( - value: community.uuid, - child: Text( - ' ${community.name}', - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ); - }).toList(), - onChanged: onChanged, - style: const TextStyle(color: Colors.black), - hint: Padding( - padding: const EdgeInsets.only(left: 10), - child: Text( - " Please Select", - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.textGray, - ), - ), + return BlocBuilder( + builder: (context, state) { + final communities = state.searchQuery.isNotEmpty + ? state.filteredCommunity + : state.communityList; + final selectedCommunity = _findCommunity(communities, _selectedSpaceId); + + return CompositedTransformTarget( + link: _layerLink, + child: GestureDetector( + onTap: _toggleDropdown, + child: Container( + height: 46, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(12), ), - customButton: Container( - height: 45, - decoration: BoxDecoration( - border: Border.all(color: ColorsManager.textGray, width: 1.0), - borderRadius: BorderRadius.circular(10), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 5, - child: Text( - selectedValue != null - ? " ${communities.firstWhere((element) => element.uuid == selectedValue).name}" - : ' Please Select', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: selectedValue != null - ? Colors.black - : ColorsManager.textGray, - ), + margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Text( + selectedCommunity?.name ?? 'Select a space', + style: TextStyle( + color: selectedCommunity != null + ? Colors.black + : Colors.grey, overflow: TextOverflow.ellipsis, - ), - ), - Expanded( - child: Container( - decoration: BoxDecoration( - color: Colors.grey[100], - borderRadius: const BorderRadius.only( - topRight: Radius.circular(10), - bottomRight: Radius.circular(10), - ), - ), - height: 45, - child: const Icon( - Icons.keyboard_arrow_down, - color: ColorsManager.textGray, - ), - ), - ), - ], - ), - ), - dropdownStyleData: DropdownStyleData( - maxHeight: MediaQuery.of(context).size.height * 0.4, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - ), - ), - dropdownSearchData: DropdownSearchData( - searchController: _searchController, - searchInnerWidgetHeight: 50, - searchInnerWidget: Container( - height: 50, - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - child: TextFormField( - style: const TextStyle(color: Colors.black), - controller: _searchController, - decoration: InputDecoration( - isDense: true, - contentPadding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 12, - ), - hintText: 'Search for community...', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), + fontWeight: FontWeight.w400, + fontSize: 15, ), ), ), - ), - searchMatchFn: (item, searchValue) { - final communityName = - (item.child as Text).data?.toLowerCase() ?? ''; - return communityName - .contains(searchValue.toLowerCase().trim()); - }, - ), - onMenuStateChange: (isOpen) { - if (!isOpen) { - _searchController.clear(); - } - }, - menuItemStyleData: const MenuItemStyleData( - height: 40, + Container( + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: const BorderRadius.only( + topRight: Radius.circular(10), + bottomRight: Radius.circular(10), + ), + ), + height: 45, + width: 35, + child: const Icon( + Icons.keyboard_arrow_down, + color: ColorsManager.textGray, + ), + ), + ], ), ), - )) - ], - ), + ), + ); + }, ); } + + void _toggleDropdown() { + if (_overlayEntry != null) { + _removeOverlay(); + return; + } + + _overlayEntry = OverlayEntry( + builder: (context) => Positioned( + width: 300, + child: CompositedTransformFollower( + link: _layerLink, + showWhenUnlinked: false, + offset: const Offset(0, 48), + child: Material( + elevation: 8, + borderRadius: BorderRadius.circular(12), + child: DropdownMenuContent( + selectedSpaceId: _selectedSpaceId, + onChanged: (id) { + if (id != null && mounted) { + setState(() => _selectedSpaceId = id); + widget.onChanged?.call(id); + _removeOverlay(); + } + }, + onClose: _removeOverlay, + ), + ), + ), + ), + ); + + Overlay.of(context).insert(_overlayEntry!); + } + + CommunityModel? _findCommunity( + List communities, String? communityId) { + if (communityId == null) return null; + + try { + return communities.firstWhere((c) => c.uuid == communityId); + } catch (e) { + return CommunityModel( + uuid: '', + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + name: '', + description: '', + spaces: []); + } + } } diff --git a/lib/pages/routines/create_new_routines/create_new_routines.dart b/lib/pages/routines/create_new_routines/create_new_routines.dart index 8f28208f..a763683d 100644 --- a/lib/pages/routines/create_new_routines/create_new_routines.dart +++ b/lib/pages/routines/create_new_routines/create_new_routines.dart @@ -18,6 +18,7 @@ class CreateNewRoutinesDialog extends StatefulWidget { class _CreateNewRoutinesDialogState extends State { String? _selectedCommunity; String? _selectedSpace; + String? _selectedId; @override Widget build(BuildContext context) { @@ -40,7 +41,10 @@ class _CreateNewRoutinesDialogState extends State { spaceHint = 'Select Space'; } } - + if (_selectedId != null && _selectedCommunity != _selectedId) { + _selectedSpace = null; + _selectedCommunity = _selectedId; + } return AlertDialog( backgroundColor: Colors.white, insetPadding: EdgeInsets.zero, @@ -61,25 +65,17 @@ class _CreateNewRoutinesDialogState extends State { children: [ const Divider(), Padding( - padding: const EdgeInsets.only(left: 15, right: 15), - child: CommunityDropdown( - communities: _bloc.communities..sort( - (a, b) => a.name.toLowerCase().compareTo( - b.name.toLowerCase(), - ), - ), - selectedValue: _selectedCommunity, - onChanged: (String? newValue) { - setState(() { - _selectedCommunity = newValue; - _selectedSpace = null; - }); - if (newValue != null) { - _bloc.add(SpaceOnlyWithDevicesEvent(newValue)); - } - }, - ), - ), + padding: const EdgeInsets.only(left: 15, right: 15), + child: SpaceTreeDropdown( + selectedSpaceId: _selectedId, + onChanged: (String? newValue) { + setState(() => _selectedId = newValue!); + if (_selectedId != null) { + _bloc.add( + SpaceOnlyWithDevicesEvent(_selectedId!)); + } + }, + )), const SizedBox(height: 5), Padding( padding: const EdgeInsets.only(left: 15, right: 15), diff --git a/lib/pages/routines/create_new_routines/dropdown_menu_content.dart b/lib/pages/routines/create_new_routines/dropdown_menu_content.dart new file mode 100644 index 00000000..70c88087 --- /dev/null +++ b/lib/pages/routines/create_new_routines/dropdown_menu_content.dart @@ -0,0 +1,148 @@ + + + + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_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/space_tree/bloc/space_tree_state.dart'; + +class DropdownMenuContent extends StatefulWidget { + final String? selectedSpaceId; + final ValueChanged onChanged; + final VoidCallback onClose; + + const DropdownMenuContent({ + required this.selectedSpaceId, + required this.onChanged, + required this.onClose, + }); + + @override + State createState() => _DropdownMenuContentState(); +} + +class _DropdownMenuContentState extends State { + final ScrollController _scrollController = ScrollController(); + final TextEditingController _searchController = TextEditingController(); + + @override + void initState() { + super.initState(); + _scrollController.addListener(_onScroll); + } + + @override + void dispose() { + _scrollController.dispose(); + _searchController.dispose(); + super.dispose(); + } + + void _onScroll() { + final bloc = context.read(); + final state = bloc.state; + if (_scrollController.position.pixels >= + _scrollController.position.maxScrollExtent - 30) { + if (state is SpaceTreeState && !state.paginationIsLoading) { + bloc.add(PaginationEvent(state.paginationModel, state.communityList)); + } + } + } + + @override + Widget build(BuildContext context) { + return ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 300), + child: BlocBuilder( + builder: (context, state) { + final communities = state.searchQuery.isNotEmpty + ? state.filteredCommunity + : state.communityList; + + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Search bar + Padding( + padding: const EdgeInsets.all(8.0), + child: TextFormField( + controller: _searchController, + onChanged: (query) { + context.read().add(SearchQueryEvent(query)); + }, + style: const TextStyle(fontSize: 14, color: Colors.black), + decoration: InputDecoration( + hintText: 'Search for space...', + prefixIcon: const Icon(Icons.search, size: 20), + contentPadding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + ), + isDense: true, + ), + ), + ), + // Community list + Expanded( + child: ListView.builder( + controller: _scrollController, + itemCount: + communities.length + (state.paginationIsLoading ? 1 : 0), + itemBuilder: (context, index) { + if (index >= communities.length) { + return state.paginationIsLoading + ? const Padding( + padding: EdgeInsets.all(8.0), + child: Center( + child: SizedBox( + width: 20, + height: 20, + child: + CircularProgressIndicator(strokeWidth: 2), + ), + ), + ) + : const SizedBox.shrink(); + } + + final community = communities[index]; + final isSelected = community.uuid == widget.selectedSpaceId; + + return ListTile( + title: Text( + community.name, + style: TextStyle( + color: isSelected ? Colors.blue : Colors.black, + fontWeight: + isSelected ? FontWeight.bold : FontWeight.normal, + ), + ), + onTap: () { + setState(() { + _searchController.clear(); + _searchController.text.isEmpty + ? context + .read() + .add(SearchQueryEvent('')) + : context.read().add( + SearchQueryEvent(_searchController.text)); + }); + // Future.delayed(const Duration(seconds: 1), () { + widget.onChanged(community.uuid); + widget.onClose(); + // }); + }, + ); + }, + ), + ), + ], + ); + }, + ), + ); + } +} From 15d3a05553344a0c70e1407cc7ad797a79ad7663 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 10:03:32 +0300 Subject: [PATCH 47/82] assign tag dropDown now show all Tags without condition --- lib/common/tag_dialog_textfield_dropdown.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/common/tag_dialog_textfield_dropdown.dart b/lib/common/tag_dialog_textfield_dropdown.dart index 6bc22fc0..9fa85284 100644 --- a/lib/common/tag_dialog_textfield_dropdown.dart +++ b/lib/common/tag_dialog_textfield_dropdown.dart @@ -50,9 +50,9 @@ class _DialogTextfieldDropdownState extends State { void _filterItems() { setState(() { - _filteredItems = widget.items - .where((tag) => tag.product?.uuid == widget.product) - .toList(); + _filteredItems = widget.items; + // .where((tag) => tag.product?.uuid == widget.product) + // .toList(); }); } From 8e9278c93c32b5fc64e6b9578cc0a8d6ade8ba10 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 10:05:50 +0300 Subject: [PATCH 48/82] edits with faris and main task to fix loading state forever and prevent rethrow exceptions without catching them --- .../bloc/space_management_bloc.dart | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 04087257..e5c9432f 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -478,8 +478,11 @@ class SpaceManagementBloc event.context, event.spaces, event.communityUuid); final allSpaces = await _fetchSpacesForCommunity(event.communityUuid); - emit(SpaceCreationSuccess(spaces: updatedSpaces)); - + // emit(SpaceCreationSuccess(spaces: updatedSpaces)); + // updatedSpaces.forEach( + // (element) => element.uuid, + // ); + // final lastUpdatedSpaced = updatedSpaces..addAll(allSpaces); if (previousState is SpaceManagementLoaded) { await _updateLoadedState( spaceTreeState, @@ -490,7 +493,7 @@ class SpaceManagementBloc ); } } catch (e) { - emit(SpaceManagementError('Error saving spaces: $e')); + // emit(SpaceManagementError('Error saving spaces: $e')); if (previousState is SpaceManagementLoaded) { emit(previousState); @@ -530,8 +533,10 @@ class SpaceManagementBloc return; } } + emit(previousState); } catch (e, stackTrace) { - rethrow; + emit(previousState); + // rethrow; } } @@ -549,6 +554,14 @@ class SpaceManagementBloc selectedCommunity = filteredCommunities.firstWhere( (community) => community.uuid == communityUuid, + orElse: () => CommunityModel( + uuid: '', + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + name: '', + description: '', + spaces: spaces, + ), ); } catch (e) { return []; @@ -563,9 +576,7 @@ class SpaceManagementBloc if (parent.uuid != null) { await _api.deleteSpace(communityUuid, parent.uuid!, projectUuid); } - } catch (e) { - rethrow; - } + } catch (e) {} } orderedSpaces.removeWhere((space) => parentsToDelete.contains(space)); @@ -579,7 +590,7 @@ class SpaceManagementBloc if (matchedSpaces.isEmpty) continue; - final prevSpace = matchedSpaces[0]; + final prevSpace = matchedSpaces.elementAtOrNull(0); final List subspaceUpdates = []; final List? prevSubspaces = prevSpace?.subspaces; @@ -658,8 +669,10 @@ class SpaceManagementBloc isPrivate: space.isPrivate, position: space.position, icon: space.icon, - subspaces: subspaceUpdates, - tags: tagUpdates, + subspaces: space.subspaces, + // subspaceUpdates, + tags: space.tags, + // tagUpdates, spaceModelUuid: space.spaceModel?.uuid, projectId: projectUuid); } else { @@ -698,7 +711,8 @@ class SpaceManagementBloc space.uuid = response?.uuid; } } catch (e) { - rethrow; // Stop further execution on failure + return []; + // Stop further execution on failure } } return spaces; From 8f7bfa984b1ee87f6053a97ab6ccb1efbc2468a3 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 10:06:36 +0300 Subject: [PATCH 49/82] edit spacemodel to use the right keys to integrate with backend --- lib/pages/spaces_management/all_spaces/model/space_model.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/model/space_model.dart b/lib/pages/spaces_management/all_spaces/model/space_model.dart index 6b570004..4956d472 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_model.dart @@ -101,7 +101,7 @@ class SpaceModel { spaceModel: json['spaceModel'] != null ? SpaceTemplateModel.fromJson(json['spaceModel']) : null, - tags: (json['tags'] as List?) + tags: (json['productAllocations'] as List?) ?.where((item) => item is Map) // Validate type .map((item) => Tag.fromJson(item as Map)) .toList() ?? @@ -116,7 +116,6 @@ class SpaceModel { instance.incomingConnection = Connection( startSpace: instance.parent ?? instance, // Parent space endSpace: instance, // This space instance - ); } From ca02de20934d6071a4c8d446b91d5994ab017b52 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 10:07:26 +0300 Subject: [PATCH 50/82] edit subspace model to fix keys and integrate with backend --- .../spaces_management/all_spaces/model/subspace_model.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart index a89ec409..fd3e780e 100644 --- a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart @@ -27,7 +27,7 @@ class SubspaceModel { subspaceName: json['subspaceName'] ?? '', disabled: json['disabled'] ?? false, internalId: internalId, - tags: (json['tags'] as List?) + tags: (json['productAllocations'] as List?) ?.map((item) => Tag.fromJson(item)) .toList() ?? [], @@ -36,7 +36,7 @@ class SubspaceModel { Map toJson() { return { - 'uuid': uuid, + if (uuid != null) 'uuid': uuid, 'subspaceName': subspaceName, 'disabled': disabled, 'tags': tags?.map((e) => e.toJson()).toList() ?? [], From 1d30c753f54bdd580cc24215001b73948c643ef1 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 10:08:49 +0300 Subject: [PATCH 51/82] edit tag model keys to integrate with backend --- .../spaces_management/all_spaces/model/tag.dart | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/model/tag.dart b/lib/pages/spaces_management/all_spaces/model/tag.dart index 8959986c..a7ec1e15 100644 --- a/lib/pages/spaces_management/all_spaces/model/tag.dart +++ b/lib/pages/spaces_management/all_spaces/model/tag.dart @@ -23,10 +23,13 @@ class Tag extends BaseTag { final String internalId = json['internalId'] ?? const Uuid().v4(); return Tag( - uuid: json['uuid'] ?? '', + //TODO:insure UUId for tag or prodAlloc + uuid: json['name'] != null ? json['uuid'] : json['tag']?['uuid'] ?? '', internalId: internalId, - tag: json['name'] ?? '', - product: json['product'] != null ? ProductModel.fromMap(json['product']) : null, + tag: json['name'] ?? json['tag']?['name'] ?? '', + product: json['product'] != null + ? ProductModel.fromMap(json['product']) + : null, ); } @@ -49,9 +52,10 @@ class Tag extends BaseTag { Map toJson() { return { - 'uuid': uuid, - 'tag': tag, - 'product': product?.toMap(), + if (uuid != null) 'uuid': uuid, + 'name': tag, + 'productUuid': product?.uuid, + // .toMap(), }; } } From d2a2d391e0af1e6edc24e7b8ea357130962611cb Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 10:19:48 +0300 Subject: [PATCH 52/82] send subspaces with onSave in okCancel inside subspace dialog as parameters --- .../views/create_subspace_model_dialog.dart | 7 ++----- .../views/widgets/ok_cancel_sub_space_widget.dart | 7 +++++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart index 501ad5a1..82df866a 100644 --- a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart +++ b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart @@ -1,14 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_state.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -20,7 +16,8 @@ class CreateSubSpaceDialog extends StatefulWidget { final List? existingSubSpaces; final String? spaceName; final List? products; - final void Function(List?)? onSave; + final void Function( + List?, List updatedSubSpaces)? onSave; const CreateSubSpaceDialog({ required this.dialogTitle, diff --git a/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart index 3c3db8f0..3952e105 100644 --- a/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart +++ b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart @@ -17,7 +17,8 @@ class OkCancelSubSpaceWidget extends StatelessWidget { }); final TextEditingController subspaceNameController; - final void Function(List?)? onSave; + final void Function( + List?, List updatedSubSpaces)? onSave; final String errorMessage; @override Widget build(BuildContext context) { @@ -53,7 +54,9 @@ class OkCancelSubSpaceWidget extends StatelessWidget { await Future.delayed(const Duration(milliseconds: 10)); final subSpaces = subSpacesBloc.state.subSpaces; - onSave?.call(subSpaces); + + onSave?.call( + subSpaces, subSpacesBloc.state.updatedSubSpaceModels); Navigator.of(context).pop(); } From e22bab00d9bc7b790c50a7bbeffbdf1231ce38f9 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 10:27:08 +0300 Subject: [PATCH 53/82] just format code in assign tag bloc --- .../assign_tag/bloc/assign_tag_bloc.dart | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart index 74161b6f..afc0c852 100644 --- a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart +++ b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart @@ -13,7 +13,8 @@ class AssignTagBloc extends Bloc { final existingTagCounts = {}; for (var tag in initialTags) { if (tag.product != null) { - existingTagCounts[tag.product!.uuid] = (existingTagCounts[tag.product!.uuid] ?? 0) + 1; + existingTagCounts[tag.product!.uuid] = + (existingTagCounts[tag.product!.uuid] ?? 0) + 1; } } @@ -22,14 +23,17 @@ class AssignTagBloc extends Bloc { for (var selectedProduct in event.addedProducts) { final existingCount = existingTagCounts[selectedProduct.productId] ?? 0; - if (selectedProduct.count == 0 || selectedProduct.count <= existingCount) { - tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId)); + if (selectedProduct.count == 0 || + selectedProduct.count <= existingCount) { + tags.addAll(initialTags + .where((tag) => tag.product?.uuid == selectedProduct.productId)); continue; } final missingCount = selectedProduct.count - existingCount; - tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId)); + tags.addAll(initialTags + .where((tag) => tag.product?.uuid == selectedProduct.productId)); if (missingCount > 0) { tags.addAll(List.generate( @@ -85,7 +89,8 @@ class AssignTagBloc extends Bloc { final tags = List.from(currentState.tags); // Update the location - tags[event.index] = tags[event.index].copyWith(location: event.location); + tags[event.index] = + tags[event.index].copyWith(location: event.location); final updatedTags = _calculateAvailableTags(projectTags, tags); @@ -117,7 +122,8 @@ class AssignTagBloc extends Bloc { final currentState = state; if (currentState is AssignTagLoaded && currentState.tags.isNotEmpty) { - final tags = List.from(currentState.tags)..remove(event.tagToDelete); + final tags = List.from(currentState.tags) + ..remove(event.tagToDelete); // Recalculate available tags final updatedTags = _calculateAvailableTags(projectTags, tags); @@ -141,8 +147,10 @@ class AssignTagBloc extends Bloc { // Get validation error for duplicate tags String? _getValidationError(List tags) { - final nonEmptyTags = - tags.map((tag) => tag.tag?.trim() ?? '').where((tag) => tag.isNotEmpty).toList(); + final nonEmptyTags = tags + .map((tag) => tag.tag?.trim() ?? '') + .where((tag) => tag.isNotEmpty) + .toList(); final duplicateTags = nonEmptyTags .fold>({}, (map, tag) { @@ -168,9 +176,11 @@ class AssignTagBloc extends Bloc { .toSet(); final availableTags = allTags - .where((tag) => tag.tag != null && !selectedTagSet.contains(tag.tag!.trim())) + .where((tag) => + tag.tag != null && !selectedTagSet.contains(tag.tag!.trim())) .toList(); - return availableTags; + return projectTags; + // availableTags; } } From ed06a760d2b018b86d74bbc47770dc2177e314b7 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 10 Jun 2025 11:41:42 +0300 Subject: [PATCH 54/82] change spaceHint and size --- .../create_new_routines/commu_dropdown.dart | 107 +++++++++++------- .../create_new_routines.dart | 68 ++++++----- .../create_new_routines/space_dropdown.dart | 6 +- 3 files changed, 107 insertions(+), 74 deletions(-) diff --git a/lib/pages/routines/create_new_routines/commu_dropdown.dart b/lib/pages/routines/create_new_routines/commu_dropdown.dart index b6cece30..431e633a 100644 --- a/lib/pages/routines/create_new_routines/commu_dropdown.dart +++ b/lib/pages/routines/create_new_routines/commu_dropdown.dart @@ -51,53 +51,74 @@ class _SpaceTreeDropdownState extends State { : state.communityList; final selectedCommunity = _findCommunity(communities, _selectedSpaceId); - return CompositedTransformTarget( - link: _layerLink, - child: GestureDetector( - onTap: _toggleDropdown, - child: Container( - height: 46, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(12), + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10, ), - margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Text( - selectedCommunity?.name ?? 'Select a space', - style: TextStyle( - color: selectedCommunity != null - ? Colors.black - : Colors.grey, - overflow: TextOverflow.ellipsis, - fontWeight: FontWeight.w400, - fontSize: 15, - ), + child: Text( + "Community", + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.w400, + fontSize: 13, + color: ColorsManager.blackColor, ), - ), - Container( - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: const BorderRadius.only( - topRight: Radius.circular(10), - bottomRight: Radius.circular(10), - ), - ), - height: 45, - width: 35, - child: const Icon( - Icons.keyboard_arrow_down, - color: ColorsManager.textGray, - ), - ), - ], ), ), - ), + CompositedTransformTarget( + link: _layerLink, + child: GestureDetector( + onTap: _toggleDropdown, + child: Container( + height: 46, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(12), + ), + margin: const EdgeInsets.symmetric( + horizontal: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Text( + selectedCommunity?.name ?? 'Please Select', + style: TextStyle( + color: selectedCommunity != null + ? ColorsManager.blackColor + : ColorsManager.textGray, + overflow: TextOverflow.ellipsis, + fontWeight: FontWeight.w400, + fontSize: 13, + ), + ), + ), + Container( + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: const BorderRadius.only( + topRight: Radius.circular(10), + bottomRight: Radius.circular(10), + ), + ), + height: 45, + width: 33, + child: const Icon( + Icons.keyboard_arrow_down, + color: ColorsManager.textGray, + ), + ), + ], + ), + ), + ), + ), + ], ); }, ); diff --git a/lib/pages/routines/create_new_routines/create_new_routines.dart b/lib/pages/routines/create_new_routines/create_new_routines.dart index a763683d..fe207910 100644 --- a/lib/pages/routines/create_new_routines/create_new_routines.dart +++ b/lib/pages/routines/create_new_routines/create_new_routines.dart @@ -31,7 +31,7 @@ class _CreateNewRoutinesDialogState extends State { final spaces = _bloc.spacesOnlyWithDevices; final isLoadingCommunities = state is CommunitiesLoadingState; final isLoadingSpaces = state is SpaceWithDeviceLoadingState; - String spaceHint = 'Select a community first'; + String spaceHint = 'Please Select'; if (_selectedCommunity != null) { if (isLoadingSpaces) { spaceHint = 'Loading spaces...'; @@ -55,7 +55,9 @@ class _CreateNewRoutinesDialogState extends State { 'Create New Routines', textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.primaryColor, + color: ColorsManager.spaceColor, + fontSize: 20, + fontWeight: FontWeight.w700, ), ), content: Stack( @@ -64,32 +66,44 @@ class _CreateNewRoutinesDialogState extends State { mainAxisSize: MainAxisSize.min, children: [ const Divider(), - Padding( - padding: const EdgeInsets.only(left: 15, right: 15), - child: SpaceTreeDropdown( - selectedSpaceId: _selectedId, - onChanged: (String? newValue) { - setState(() => _selectedId = newValue!); - if (_selectedId != null) { - _bloc.add( - SpaceOnlyWithDevicesEvent(_selectedId!)); - } - }, - )), - const SizedBox(height: 5), - Padding( - padding: const EdgeInsets.only(left: 15, right: 15), - child: SpaceDropdown( - hintMessage: spaceHint, - spaces: spaces, - selectedValue: _selectedSpace, - onChanged: (String? newValue) { - setState(() { - _selectedSpace = newValue; - }); - }, - ), + const SizedBox(height: 20), + Column( + children: [ + Padding( + padding: + const EdgeInsets.only(left: 13, right: 8), + child: Column( + children: [ + SpaceTreeDropdown( + selectedSpaceId: _selectedId, + onChanged: (String? newValue) { + setState(() => _selectedId = newValue!); + if (_selectedId != null) { + _bloc.add(SpaceOnlyWithDevicesEvent( + _selectedId!)); + } + }, + ), + ], + )), + const SizedBox(height: 5), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 15, right: 15), + child: SpaceDropdown( + hintMessage: spaceHint, + spaces: spaces, + selectedValue: _selectedSpace, + onChanged: (String? newValue) { + setState(() { + _selectedSpace = newValue; + }); + }, + ), + ), + ], ), + const SizedBox(height: 20), const Divider(), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, diff --git a/lib/pages/routines/create_new_routines/space_dropdown.dart b/lib/pages/routines/create_new_routines/space_dropdown.dart index a26ff9f4..1d11b02d 100644 --- a/lib/pages/routines/create_new_routines/space_dropdown.dart +++ b/lib/pages/routines/create_new_routines/space_dropdown.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; - class SpaceDropdown extends StatelessWidget { final List spaces; final String? selectedValue; @@ -21,7 +20,7 @@ class SpaceDropdown extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.all(10.0), + padding: const EdgeInsets.only(left: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -33,7 +32,6 @@ class SpaceDropdown extends StatelessWidget { color: ColorsManager.blackColor, ), ), - const SizedBox(height: 8), SizedBox( child: Container( decoration: BoxDecoration( @@ -90,7 +88,7 @@ class SpaceDropdown extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( - flex: 5, + flex: 6, child: Padding( padding: const EdgeInsets.only(left: 10), child: Text( From a1b20078a3f97f8ac060f37e5c162f6fd7eedc94 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 10 Jun 2025 12:10:47 +0300 Subject: [PATCH 55/82] Refactor AccessBloc to emit filtered data instead of fetching; clean up device search filters for improved readability. --- lib/pages/access_management/bloc/access_bloc.dart | 3 ++- .../all_devices/widgets/device_search_filters.dart | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pages/access_management/bloc/access_bloc.dart b/lib/pages/access_management/bloc/access_bloc.dart index 562bd5b5..dd82d739 100644 --- a/lib/pages/access_management/bloc/access_bloc.dart +++ b/lib/pages/access_management/bloc/access_bloc.dart @@ -267,7 +267,8 @@ class AccessBloc extends Bloc { selectedIndex = 0; effectiveTimeTimeStamp = null; expirationTimeTimeStamp = null; - add(FetchTableData()); + filteredData = List.from(data); + emit(TableLoaded(filteredData)); } String timestampToDate(dynamic timestamp) { diff --git a/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart b/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart index 18d72fc9..6440d18f 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart @@ -34,7 +34,8 @@ class _DeviceSearchFiltersState extends State runSpacing: 10, children: [ _buildSearchField("Space Name", _unitNameController, 200), - _buildSearchField("Device Name / Product Name", _productNameController, 300), + _buildSearchField( + "Device Name / Product Name", _productNameController, 300), _buildSearchResetButtons(), ], ); @@ -74,9 +75,7 @@ class _DeviceSearchFiltersState extends State onReset: () { _unitNameController.clear(); _productNameController.clear(); - context.read() - ..add(ResetFilters()) - ..add(FetchDevices(context)); + context.read().add(ResetFilters()); }, ); } From 0d5734a2365f67a358fa65ea78e2f5099c3117cc Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 15:06:31 +0300 Subject: [PATCH 56/82] use tag instead of UpdatedTagModel cuz no need for updatedmodel anymore&&key should be spaces with S --- lib/services/space_mana_api.dart | 68 +++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/lib/services/space_mana_api.dart b/lib/services/space_mana_api.dart index a1372618..a20163da 100644 --- a/lib/services/space_mana_api.dart +++ b/lib/services/space_mana_api.dart @@ -4,22 +4,27 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_m import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_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_response_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/tag_body_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/utils/constants/api_const.dart'; +import '../pages/spaces_management/all_spaces/model/subspace_model.dart'; + class CommunitySpaceManagementApi { // Community Management APIs - Future> fetchCommunities(String projectId, {int page = 1}) async { + Future> fetchCommunities(String projectId, + {int page = 1}) async { try { List allCommunities = []; bool hasNext = true; while (hasNext) { await HTTPService().get( - path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId), + path: ApiEndpoints.getCommunityList + .replaceAll('{projectId}', projectId), queryParameters: { 'page': page, }, @@ -55,8 +60,14 @@ class CommunitySpaceManagementApi { try { bool hasNext = false; await HTTPService().get( - path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId), - queryParameters: {'page': page, 'includeSpaces': true, 'size': 25, 'search': search}, + path: + ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId), + queryParameters: { + 'page': page, + 'includeSpaces': true, + 'size': 25, + 'search': search + }, expectedResponseModel: (json) { try { List jsonData = json['data'] ?? []; @@ -68,7 +79,10 @@ class CommunitySpaceManagementApi { page = currentPage + 1; paginationModel = PaginationModel( - pageNum: page, hasNext: hasNext, size: 25, communities: communityList); + pageNum: page, + hasNext: hasNext, + size: 25, + communities: communityList); return paginationModel; } catch (_) { hasNext = false; @@ -83,7 +97,8 @@ class CommunitySpaceManagementApi { Future getCommunityById(String communityId) async { try { final response = await HTTPService().get( - path: ApiEndpoints.getCommunityById.replaceAll('{communityId}', communityId), + path: ApiEndpoints.getCommunityById + .replaceAll('{communityId}', communityId), expectedResponseModel: (json) { return CommunityModel.fromJson(json['data']); }, @@ -95,7 +110,8 @@ class CommunitySpaceManagementApi { } } - Future createCommunity(String name, String description, String projectId) async { + Future createCommunity( + String name, String description, String projectId) async { try { final response = await HTTPService().post( path: ApiEndpoints.createCommunity.replaceAll('{projectId}', projectId), @@ -114,7 +130,8 @@ class CommunitySpaceManagementApi { } } - Future updateCommunity(String communityId, String name, String projectId) async { + Future updateCommunity( + String communityId, String name, String projectId) async { try { final response = await HTTPService().put( path: ApiEndpoints.updateCommunity @@ -151,7 +168,8 @@ class CommunitySpaceManagementApi { } } - Future fetchSpaces(String communityId, String projectId) async { + Future fetchSpaces( + String communityId, String projectId) async { try { final response = await HTTPService().get( path: ApiEndpoints.listSpaces @@ -177,7 +195,8 @@ class CommunitySpaceManagementApi { } } - Future getSpace(String communityId, String spaceId, String projectId) async { + Future getSpace( + String communityId, String spaceId, String projectId) async { try { final response = await HTTPService().get( path: ApiEndpoints.getSpace @@ -199,7 +218,6 @@ class CommunitySpaceManagementApi { {required String communityId, required String name, String? parentId, - bool isPrivate = false, required Offset position, String? spaceModelUuid, @@ -213,7 +231,6 @@ class CommunitySpaceManagementApi { 'isPrivate': isPrivate, 'x': position.dx, 'y': position.dy, - 'icon': icon, }; if (parentId != null) { @@ -248,11 +265,10 @@ class CommunitySpaceManagementApi { required String name, String? parentId, String? icon, - bool isPrivate = false, required Offset position, - List? tags, - List? subspaces, + List? tags, + List? subspaces, String? spaceModelUuid, required String projectId}) async { try { @@ -261,9 +277,8 @@ class CommunitySpaceManagementApi { 'isPrivate': isPrivate, 'x': position.dx, 'y': position.dy, - 'icon': icon, - 'subspace': subspaces, + 'subspaces': subspaces, 'tags': tags, 'spaceModelUuid': spaceModelUuid, }; @@ -289,7 +304,8 @@ class CommunitySpaceManagementApi { } } - Future deleteSpace(String communityId, String spaceId, String projectId) async { + Future deleteSpace( + String communityId, String spaceId, String projectId) async { try { final response = await HTTPService().delete( path: ApiEndpoints.deleteSpace @@ -307,15 +323,17 @@ class CommunitySpaceManagementApi { } } - Future> getSpaceHierarchy(String communityId, String projectId) async { + Future> getSpaceHierarchy( + String communityId, String projectId) async { try { final response = await HTTPService().get( path: ApiEndpoints.getSpaceHierarchy .replaceAll('{communityId}', communityId) .replaceAll('{projectId}', projectId), expectedResponseModel: (json) { - final spaceModels = - (json['data'] as List).map((spaceJson) => SpaceModel.fromJson(spaceJson)).toList(); + final spaceModels = (json['data'] as List) + .map((spaceJson) => SpaceModel.fromJson(spaceJson)) + .toList(); return spaceModels; }, @@ -327,15 +345,17 @@ class CommunitySpaceManagementApi { } } - Future> getSpaceOnlyWithDevices({String? communityId, String? projectId}) async { + Future> getSpaceOnlyWithDevices( + {String? communityId, String? projectId}) async { try { final response = await HTTPService().get( path: ApiEndpoints.spaceOnlyWithDevices .replaceAll('{communityId}', communityId!) .replaceAll('{projectId}', projectId!), expectedResponseModel: (json) { - final spaceModels = - (json['data'] as List).map((spaceJson) => SpaceModel.fromJson(spaceJson)).toList(); + final spaceModels = (json['data'] as List) + .map((spaceJson) => SpaceModel.fromJson(spaceJson)) + .toList(); return spaceModels; }, ); From 7eb1d5b0b095a01ff7486ca0f490f7647904bb20 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 15:07:32 +0300 Subject: [PATCH 57/82] comment listSpace func which calls SpaceModels that suspended for now --- lib/services/space_model_mang_api.dart | 37 ++++++++++++++++---------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/services/space_model_mang_api.dart b/lib/services/space_model_mang_api.dart index 5ae3e4d9..cbb9cfeb 100644 --- a/lib/services/space_model_mang_api.dart +++ b/lib/services/space_model_mang_api.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/space_template_model.dart'; @@ -7,17 +9,23 @@ import 'package:syncrow_web/utils/constants/api_const.dart'; class SpaceModelManagementApi { Future> listSpaceModels( {required String projectId, int page = 1}) async { - final response = await HTTPService().get( - path: ApiEndpoints.listSpaceModels.replaceAll('{projectId}', projectId), - queryParameters: {'page': page}, - expectedResponseModel: (json) { - List jsonData = json['data']; - return jsonData.map((jsonItem) { - return SpaceTemplateModel.fromJson(jsonItem); - }).toList(); - }, - ); - return response; + try { + // final response = await HTTPService().get( + // path: ApiEndpoints.listSpaceModels.replaceAll('{projectId}', projectId), + // queryParameters: {'page': page}, + // expectedResponseModel: (json) { + // List jsonData = json['data']; + // return jsonData.map((jsonItem) { + // return SpaceTemplateModel.fromJson(jsonItem); + // }).toList(); + // }, + // ); + return []; + // response; + } catch (e) { + log(e.toString()); + return []; + } } Future createSpaceModel( @@ -33,8 +41,8 @@ class SpaceModelManagementApi { return response; } - Future updateSpaceModel( - CreateSpaceTemplateBodyModel spaceModel, String spaceModelUuid, String projectId) async { + Future updateSpaceModel(CreateSpaceTemplateBodyModel spaceModel, + String spaceModelUuid, String projectId) async { final response = await HTTPService().put( path: ApiEndpoints.updateSpaceModel .replaceAll('{projectId}', projectId) @@ -47,7 +55,8 @@ class SpaceModelManagementApi { return response; } - Future getSpaceModel(String spaceModelUuid, String projectId) async { + Future getSpaceModel( + String spaceModelUuid, String projectId) async { final response = await HTTPService().get( path: ApiEndpoints.getSpaceModel .replaceAll('{projectId}', projectId) From 08a9a5c71f6ca1529870cc7d8eadef69735dbb16 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 15:08:50 +0300 Subject: [PATCH 58/82] comment the tab of spaceModel to prevent routing there --- .../view/center_body_widget.dart | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart index 0f40ddbb..0f63ebb1 100644 --- a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart +++ b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart @@ -14,11 +14,11 @@ class CenterBodyWidget extends StatelessWidget { if (state is InitialState) { context.read().add(CommunityStructureSelectedEvent()); } - if (state is CommunityStructureState) { + if (state is CommunityStructureState) { context.read().add(BlankStateEvent(context)); } - if (state is SpaceModelState) { + if (state is SpaceModelState) { context.read().add(SpaceModelLoadEvent(context)); } @@ -31,15 +31,19 @@ class CenterBodyWidget extends StatelessWidget { children: [ GestureDetector( onTap: () { - context.read().add(CommunityStructureSelectedEvent()); + context + .read() + .add(CommunityStructureSelectedEvent()); }, child: Text( 'Community Structure', style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontWeight: state is CommunityStructureState || state is CommunitySelectedState + fontWeight: state is CommunityStructureState || + state is CommunitySelectedState ? FontWeight.bold : FontWeight.normal, - color: state is CommunityStructureState || state is CommunitySelectedState + color: state is CommunityStructureState || + state is CommunitySelectedState ? Theme.of(context).textTheme.bodyLarge!.color : Theme.of(context) .textTheme @@ -50,26 +54,26 @@ class CenterBodyWidget extends StatelessWidget { ), ), const SizedBox(width: 20), - GestureDetector( - onTap: () { - context.read().add(SpaceModelSelectedEvent()); - }, - child: Text( - 'Space Model', - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontWeight: state is SpaceModelState - ? FontWeight.bold - : FontWeight.normal, - color: state is SpaceModelState - ? Theme.of(context).textTheme.bodyLarge!.color - : Theme.of(context) - .textTheme - .bodyLarge! - .color! - .withOpacity(0.5), - ), - ), - ), + // GestureDetector( + // onTap: () { + // context.read().add(SpaceModelSelectedEvent()); + // }, + // child: Text( + // 'Space Model', + // style: Theme.of(context).textTheme.bodyLarge!.copyWith( + // fontWeight: state is SpaceModelState + // ? FontWeight.bold + // : FontWeight.normal, + // color: state is SpaceModelState + // ? Theme.of(context).textTheme.bodyLarge!.color + // : Theme.of(context) + // .textTheme + // .bodyLarge! + // .color! + // .withOpacity(0.5), + // ), + // ), + // ), ], ), ], From 692c9e7792904ce4b121607cceae566f60f47973 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 15:11:33 +0300 Subject: [PATCH 59/82] comment (SpaceModelLinking && Or)Widgets cuz no need for spaceModel for now&& fix the delete devices from subSpaces to keep in main space not to get deleted --- .../widgets/dialogs/create_space_dialog.dart | 141 +++++++++++------- 1 file changed, 89 insertions(+), 52 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index eaadf671..9e2f6dbb 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -155,63 +155,76 @@ class CreateSpaceDialogState extends State { }, ), const SizedBox(height: 10), - SpaceModelLinkingWidget( - isSpaceModelDisabled: isSpaceModelDisabled, - onPressed: () { - isSpaceModelDisabled - ? null - : _showLinkSpaceModelDialog(context); - }, - onDeleted: () => setState(() { - selectedSpaceModel = null; - subspaces = widget.subspaces ?? []; - tags = widget.tags ?? []; - }), - screenWidth: screenWidth, - selectedSpaceModel: selectedSpaceModel, - ), + // SpaceModelLinkingWidget( + // isSpaceModelDisabled: true, + // // isSpaceModelDisabled, + // onPressed: () { + // isSpaceModelDisabled + // ? null + // : _showLinkSpaceModelDialog(context); + // }, + // onDeleted: () => setState(() { + // selectedSpaceModel = null; + // subspaces = widget.subspaces ?? []; + // tags = widget.tags ?? []; + // }), + // screenWidth: screenWidth, + // selectedSpaceModel: selectedSpaceModel, + // ), const SizedBox(height: 25), - Row( - children: [ - const Expanded( - child: Divider( - color: ColorsManager.neutralGray, - thickness: 1.0, - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 6.0), - child: Text( - 'OR', - style: Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith(fontWeight: FontWeight.bold), - ), - ), - const Expanded( - child: Divider( - color: ColorsManager.neutralGray, - thickness: 1.0, - ), - ), - ], - ), + // Row( + // children: [ + // const Expanded( + // child: Divider( + // color: ColorsManager.neutralGray, + // thickness: 1.0, + // ), + // ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 6.0), + // child: Text( + // 'OR', + // style: Theme.of(context) + // .textTheme + // .bodyMedium + // ?.copyWith(fontWeight: FontWeight.bold), + // ), + // ), + // const Expanded( + // child: Divider( + // color: ColorsManager.neutralGray, + // thickness: 1.0, + // ), + // ), + // ], + // ), const SizedBox(height: 25), SubSpacePartWidget( subspaces: subspaces, onPressed: () { isTagsAndSubspaceModelDisabled ? null - : _showSubSpaceDialog(context, enteredName, [], - false, widget.products, subspaces); + : _showSubSpaceDialog( + context, + enteredName, + [], + false, + widget.products, + subspaces, + ); }, isTagsAndSubspaceModelDisabled: isTagsAndSubspaceModelDisabled, screenWidth: screenWidth, editChipOnTap: () async { - _showSubSpaceDialog(context, enteredName, [], true, - widget.products, subspaces); + _showSubSpaceDialog( + context, + enteredName, + [], + true, + widget.products, + subspaces, + ); }, ), const SizedBox(height: 10), @@ -289,6 +302,13 @@ class CreateSpaceDialogState extends State { ? enteredName : (widget.name ?? ''); if (newName.isNotEmpty) { + if (tags != null && tags!.isNotEmpty) { + if (tags!.any( + (tag) => tag.uuid == null || tag.uuid!.isEmpty, + )) { + return; + } + } widget.onCreateSpace( newName, selectedIcon, @@ -352,12 +372,13 @@ class CreateSpaceDialogState extends State { } void _showSubSpaceDialog( - BuildContext context, - String name, - final List? spaceTags, - bool isEdit, - List? products, - final List? existingSubSpaces) { + BuildContext context, + String name, + final List? spaceTags, + bool isEdit, + List? products, + final List? existingSubSpaces, + ) { showDialog( context: context, builder: (BuildContext context) { @@ -366,7 +387,7 @@ class CreateSpaceDialogState extends State { dialogTitle: isEdit ? 'Edit Sub-spaces' : 'Create Sub-spaces', products: products, existingSubSpaces: existingSubSpaces, - onSave: (slectedSubspaces) { + onSave: (slectedSubspaces, updatedSubSpaces) { final List tagsToAppendToSpace = []; if (slectedSubspaces != null && slectedSubspaces.isNotEmpty) { @@ -378,6 +399,22 @@ class CreateSpaceDialogState extends State { .toList(); for (var s in deletedSubspaces) { if (s.tags != null) { + s.tags!.forEach( + (tag) => tag.location = null, + ); + tagsToAppendToSpace.addAll(s.tags!); + } + } + } + } else { + if (existingSubSpaces != null) { + final deletedSubspaces = existingSubSpaces; + + for (var s in deletedSubspaces) { + if (s.tags != null) { + s.tags!.forEach( + (tag) => tag.location = null, + ); tagsToAppendToSpace.addAll(s.tags!); } } From f7f3843fa7788c4df8cd958949a50a0f5aadece0 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 10 Jun 2025 16:29:14 +0300 Subject: [PATCH 60/82] Enhance device management UI with improved padding and SVG icon integration --- .../device_management_content.dart | 27 ++-- .../device_setting/device_settings_panel.dart | 138 +++++++++++------- 2 files changed, 101 insertions(+), 64 deletions(-) diff --git a/lib/pages/device_managment/device_setting/device_management_content.dart b/lib/pages/device_managment/device_setting/device_management_content.dart index 9c758341..e7cd514b 100644 --- a/lib/pages/device_managment/device_setting/device_management_content.dart +++ b/lib/pages/device_managment/device_setting/device_management_content.dart @@ -1,10 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/sub_space_dialog.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/web_layout/default_container.dart'; @@ -28,7 +30,7 @@ class DeviceManagementContent extends StatelessWidget { Widget? trailing, required Color? valueColor}) { return Padding( - padding: const EdgeInsets.symmetric(vertical: 6.0), + padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -39,6 +41,7 @@ class DeviceManagementContent extends StatelessWidget { color: ColorsManager.grayColor, ), ), + const SizedBox(width: 15), Expanded( child: Text( value, @@ -48,7 +51,7 @@ class DeviceManagementContent extends StatelessWidget { overflow: TextOverflow.ellipsis, ), ), - const SizedBox(width: 8), + const SizedBox(width: 12), trailing ?? const SizedBox.shrink(), ], ), @@ -73,15 +76,15 @@ class DeviceManagementContent extends StatelessWidget { ); }, child: infoRow( - label: 'Sub-Space:', - value: deviceInfo.subspace.subspaceName, - valueColor: ColorsManager.textGray, - trailing: const Icon( - Icons.arrow_forward_ios, - size: 16, - color: ColorsManager.greyColor, - ), - ), + label: 'Sub-Space:', + value: deviceInfo.subspace.subspaceName, + valueColor: ColorsManager.blackColor, + trailing: SvgPicture.asset( + Assets.arrowDown, + width: 10, + height: 10, + color: ColorsManager.greyColor, + )), ), ), const Divider(color: ColorsManager.dividerColor), @@ -104,7 +107,7 @@ class DeviceManagementContent extends StatelessWidget { }, child: const Icon( Icons.copy, - size: 16, + size: 15, color: ColorsManager.greyColor, ), ), diff --git a/lib/pages/device_managment/device_setting/device_settings_panel.dart b/lib/pages/device_managment/device_setting/device_settings_panel.dart index cebd80b3..48458b3b 100644 --- a/lib/pages/device_managment/device_setting/device_settings_panel.dart +++ b/lib/pages/device_managment/device_setting/device_settings_panel.dart @@ -51,8 +51,7 @@ class DeviceSettingsPanel extends StatelessWidget { Container( width: MediaQuery.of(context).size.width * 0.3, color: ColorsManager.grey25, - padding: const EdgeInsets.symmetric( - horizontal: 20, vertical: 24), + padding: const EdgeInsets.all(10), child: ListView( children: [ Row( @@ -70,37 +69,43 @@ class DeviceSettingsPanel extends StatelessWidget { children: [ Text( 'Device Settings', - style: - context.theme.textTheme.titleLarge!.copyWith( - fontWeight: FontWeight.bold, - color: ColorsManager.primaryColor, - ), + style: context.theme.textTheme.titleLarge! + .copyWith( + fontWeight: FontWeight.w700, + color: ColorsManager.vividBlue + .withOpacity(0.7), + fontSize: 24), ), ], ), const SizedBox(height: 24), DefaultContainer( + borderRadius: BorderRadius.circular(15), child: Row( children: [ - CircleAvatar( - radius: 40, - backgroundColor: - const Color.fromARGB(177, 213, 213, 213), + Padding( + padding: const EdgeInsets.only(left: 15), child: CircleAvatar( - backgroundColor: ColorsManager.whiteColors, - radius: 36, - child: SvgPicture.asset( - iconPath, - fit: BoxFit.cover, + radius: 38, + backgroundColor: + ColorsManager.grayBorder.withOpacity(0.5), + child: CircleAvatar( + backgroundColor: ColorsManager.whiteColors, + radius: 36, + child: SvgPicture.asset( + iconPath, + fit: BoxFit.cover, + ), ), ), ), - const SizedBox(width: 12), + const SizedBox(width: 25), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + const SizedBox(height: 15), Text( 'Device Name:', style: context.textTheme.bodyMedium! @@ -108,50 +113,79 @@ class DeviceSettingsPanel extends StatelessWidget { color: ColorsManager.grayColor, ), ), - TextFormField( - maxLength: 30, - style: const TextStyle( - color: ColorsManager.blackColor, - ), - textAlign: TextAlign.start, - focusNode: _bloc.focusNode, - controller: _bloc.nameController, - enabled: _bloc.editName, - onFieldSubmitted: (value) { - _bloc.add(const ChangeNameEvent( - value: false)); - }, - decoration: const InputDecoration( - border: InputBorder.none, - fillColor: Colors.white10, - counterText: '', + SizedBox( + height: 35, + child: Row( + children: [ + SizedBox( + height: 50, + width: 190, + child: TextFormField( + scrollPadding: EdgeInsets.zero, + maxLength: 30, + style: const TextStyle( + color: ColorsManager.blackColor, + fontSize: 16, + ), + textAlign: TextAlign.start, + focusNode: _bloc.focusNode, + controller: _bloc.nameController, + enabled: _bloc.editName, + onFieldSubmitted: (value) { + _bloc.add(const ChangeNameEvent( + value: false)); + }, + decoration: InputDecoration( + isDense: true, + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + fillColor: Colors.white10, + counterText: '', + ), + ), + ), + Column( + children: [ + SizedBox( + width: 15, + height: 25, + child: Visibility( + visible: + _bloc.editName != true, + replacement: const SizedBox(), + child: InkWell( + onTap: () { + _bloc.add( + const ChangeNameEvent( + value: true)); + }, + child: SvgPicture.asset( + Assets + .editNameIconSettings, + color: ColorsManager + .lightGrayBorderColor, + height: 15, + width: 15, + ), + ), + ), + ), + ], + ), + ], ), ), ], ), ), - const SizedBox(width: 8), - Visibility( - visible: _bloc.editName != true, - replacement: const SizedBox(), - child: GestureDetector( - onTap: () { - _bloc.add( - const ChangeNameEvent(value: true)); - }, - child: SvgPicture.asset( - Assets.editNameIconSettings, - color: ColorsManager.grayColor, - height: 20, - width: 20, - ), - ), - ) ], ), ), const SizedBox(height: 32), - Text('Device Management', style: sectionTitle), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Text('Device Management', style: sectionTitle), + ), DeviceManagementContent( device: device, subSpaces: subSpaces.cast(), From fd192894cdb36fae7d5629c4ff59e7fb43e03932 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 16:32:33 +0300 Subject: [PATCH 61/82] stop calling initEvent for spactree bloc inside homeBloc --- lib/pages/home/bloc/home_bloc.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index 33d55628..bc6a3165 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -51,12 +51,13 @@ class HomeBloc extends Bloc { Future _fetchUserInfo(FetchUserInfo event, Emitter emit) async { try { - var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); + var uuid = + await const FlutterSecureStorage().read(key: UserModel.userUuidKey); user = await HomeApi().fetchUserInfo(uuid); if (user != null && user!.project != null) { await ProjectManager.setProjectUUID(user!.project!.uuid); - NavigationService.navigatorKey.currentContext!.read().add(InitialEvent()); + // NavigationService.navigatorKey.currentContext!.read().add(InitialEvent()); } add(FetchTermEvent()); add(FetchPolicyEvent()); @@ -88,10 +89,12 @@ class HomeBloc extends Bloc { } } - Future _confirmUserAgreement(ConfirmUserAgreementEvent event, Emitter emit) async { + Future _confirmUserAgreement( + ConfirmUserAgreementEvent event, Emitter emit) async { try { emit(LoadingHome()); - var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); + var uuid = + await const FlutterSecureStorage().read(key: UserModel.userUuidKey); policy = await HomeApi().confirmUserAgreements(uuid); emit(PolicyAgreement()); } catch (e) { @@ -155,7 +158,7 @@ class HomeBloc extends Bloc { }, color: ColorsManager.primaryColor, ), - + // HomeItemModel( // title: 'Move in', // icon: Assets.moveinIcon, From 0e31a3ea96bd78e2f295083d638cdf5937f5ed94 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 16:33:33 +0300 Subject: [PATCH 62/82] no need to fetch use info in init state of homepage and agreement dialog --- lib/pages/home/view/home_page_web.dart | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/pages/home/view/home_page_web.dart b/lib/pages/home/view/home_page_web.dart index 9a59f51c..a7a0eee4 100644 --- a/lib/pages/home/view/home_page_web.dart +++ b/lib/pages/home/view/home_page_web.dart @@ -24,7 +24,7 @@ class _HomeWebPageState extends State { void initState() { super.initState(); final homeBloc = BlocProvider.of(context); - homeBloc.add(const FetchUserInfo()); + // homeBloc.add(const FetchUserInfo()); } @override @@ -38,8 +38,10 @@ class _HomeWebPageState extends State { child: BlocConsumer( listener: (BuildContext context, state) { if (state is HomeInitial) { - if (homeBloc.user!.hasAcceptedWebAgreement == false && !_dialogShown) { - _dialogShown = true; // Set the flag to true to indicate the dialog is showing. + if (homeBloc.user!.hasAcceptedWebAgreement == false && + !_dialogShown) { + _dialogShown = + true; // Set the flag to true to indicate the dialog is showing. Future.delayed(const Duration(seconds: 1), () { showDialog( context: context, @@ -54,7 +56,7 @@ class _HomeWebPageState extends State { _dialogShown = false; if (v != null) { homeBloc.add(ConfirmUserAgreementEvent()); - homeBloc.add(const FetchUserInfo()); + // homeBloc.add(const FetchUserInfo()); } }); }); @@ -98,7 +100,8 @@ class _HomeWebPageState extends State { width: size.width * 0.68, child: GridView.builder( itemCount: homeBloc.homeItems.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, // Adjust as needed. crossAxisSpacing: 20.0, mainAxisSpacing: 20.0, @@ -110,7 +113,8 @@ class _HomeWebPageState extends State { active: homeBloc.homeItems[index].active!, name: homeBloc.homeItems[index].title!, img: homeBloc.homeItems[index].icon!, - onTap: () => homeBloc.homeItems[index].onPress(context), + onTap: () => + homeBloc.homeItems[index].onPress(context), ); }, ), From aa3b79bdafbe5df540922397986a700dc7362a63 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Tue, 10 Jun 2025 16:34:49 +0300 Subject: [PATCH 63/82] stop fetching tags onBlank Event --- .../all_spaces/bloc/space_management_bloc.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index e5c9432f..f666c078 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -261,7 +261,7 @@ class SpaceManagementBloc List communities = await _waitForCommunityList(spaceBloc, spaceTreeState); await fetchSpaceModels(); - await fetchTags(); + // await fetchTags(); var prevSpaceModels = await fetchSpaceModels(); From 8a274af7be25936751709fe321bd360bf750161c Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 11 Jun 2025 10:47:59 +0300 Subject: [PATCH 64/82] Update button behavior in DeviceManagementPage based on routineTab state --- .../view/device_managment_page.dart | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/pages/device_managment/all_devices/view/device_managment_page.dart b/lib/pages/device_managment/all_devices/view/device_managment_page.dart index 755bc8b7..2379c22d 100644 --- a/lib/pages/device_managment/all_devices/view/device_managment_page.dart +++ b/lib/pages/device_managment/all_devices/view/device_managment_page.dart @@ -40,17 +40,18 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { style: TextButton.styleFrom( backgroundColor: null, ), - onPressed: () { - BlocProvider.of(context) - .add(const ResetSelectedEvent()); + onPressed: !state.routineTab + ? null + : () { + BlocProvider.of(context) + .add(const ResetSelectedEvent()); - context - .read() - .add(const TriggerSwitchTabsEvent(isRoutineTab: false)); - context - .read() - .add(FetchDevices(context)); - }, + context.read().add( + const TriggerSwitchTabsEvent(isRoutineTab: false)); + context + .read() + .add(FetchDevices(context)); + }, child: Text( 'Devices', style: context.textTheme.titleMedium?.copyWith( @@ -66,14 +67,15 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { style: TextButton.styleFrom( backgroundColor: null, ), - onPressed: () { - BlocProvider.of(context) - .add(const ResetSelectedEvent()); + onPressed: state.routineTab + ? null + : () { + BlocProvider.of(context) + .add(const ResetSelectedEvent()); - context - .read() - .add(const TriggerSwitchTabsEvent(isRoutineTab: true)); - }, + context.read().add( + const TriggerSwitchTabsEvent(isRoutineTab: true)); + }, child: Text( 'Routines', style: context.textTheme.titleMedium?.copyWith( From 5ddfb4797763febc026b50856dd225301f846f7d Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 12:54:38 +0300 Subject: [PATCH 65/82] Delete unused File --- lib/core/network/custom_exceptions.dart | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 lib/core/network/custom_exceptions.dart diff --git a/lib/core/network/custom_exceptions.dart b/lib/core/network/custom_exceptions.dart deleted file mode 100644 index 23b81a8d..00000000 --- a/lib/core/network/custom_exceptions.dart +++ /dev/null @@ -1,16 +0,0 @@ - -import 'enums.dart'; - -class GenericException implements Exception { - final ExceptionType type; - final String errorMessage; - const GenericException( - {required this.type, this.errorMessage = "Unknown Error"}); - - @override - String toString() { - return errorMessage; - } - - List get props => [type, errorMessage]; -} From 940b17968652ffc78ceb3f5578fa0b5f2410bfd8 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 12:55:14 +0300 Subject: [PATCH 66/82] Delete unused file --- lib/core/network/dio.dart | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 lib/core/network/dio.dart diff --git a/lib/core/network/dio.dart b/lib/core/network/dio.dart deleted file mode 100644 index e01fef90..00000000 --- a/lib/core/network/dio.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:dio/dio.dart'; - -import '../../utils/constants/api_const.dart'; - -class DioInstance { - Dio? _dio; - - Dio get dio => _dio ?? _instantiate(); - - String? baseUrl; - - DioInstance({this.baseUrl}); - - Dio _instantiate() { - Dio dio = Dio( - BaseOptions( - baseUrl: baseUrl ?? '${ApiEndpoints.baseUrl}/', - receiveDataWhenStatusError: true, - headers: { - 'content_Type': 'application/json', - }, - ), - ); - - dio.interceptors.add( - LogInterceptor( - responseHeader: false, - requestHeader: false, - requestBody: true, - responseBody: true, - ), - ); - - return dio; - } -} From 329a4ef0276c17a31a5b1d84645a9d396e1fedfc Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 12:55:54 +0300 Subject: [PATCH 67/82] Delete --- lib/core/network/end_points.dart | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 lib/core/network/end_points.dart diff --git a/lib/core/network/end_points.dart b/lib/core/network/end_points.dart deleted file mode 100644 index 3e2afd84..00000000 --- a/lib/core/network/end_points.dart +++ /dev/null @@ -1,3 +0,0 @@ -class EndPoints { - static const String fetchCommunities = 'projects/{projectUuid}/communities'; -} From 08f8c3c79a97e6a93458c86c7b614c1d5a355398 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 12:56:28 +0300 Subject: [PATCH 68/82] Delete unused File --- lib/core/network/enums.dart | 50 ------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 lib/core/network/enums.dart diff --git a/lib/core/network/enums.dart b/lib/core/network/enums.dart deleted file mode 100644 index 488d7cb9..00000000 --- a/lib/core/network/enums.dart +++ /dev/null @@ -1,50 +0,0 @@ -enum RequestType { - get, - post, - delete, - put, -} - -enum ExceptionType { - notAuthenticated, - connectionError, - // related to http status code exceptions - notAuthorized, - notFound, - internalServerException, - serviceUnavailableException, - pageGone, - - // related to bad request status code - // related to auth requests - invalidCredentials, - solutionAlreadySunmitted, - invalidValidation, - // other - other, -} - -enum ExceptionMessage { - NOT_AUTHENTICATED, - INVALID_CREDENTIALS, - The_password_field_must_be_at_least_8_characters, - SOLUTION_ALREADY_SUBMITTED, - you_are_not_authorized, - page_not_found, - page_gone, - INTERNAL_SERVER_ERROR, - service_unavailable, -} - -enum NotificationsType { - payment, - transporation, - product, - zero, -} - -enum ImagesType { - assets, - svg, - network, -} From f415aa16762d9ebc7eaa0118ed5caab162e5c4e8 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 12:57:00 +0300 Subject: [PATCH 69/82] Delete unused File --- lib/core/network/request.dart | 121 ---------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 lib/core/network/request.dart diff --git a/lib/core/network/request.dart b/lib/core/network/request.dart deleted file mode 100644 index c242b8a6..00000000 --- a/lib/core/network/request.dart +++ /dev/null @@ -1,121 +0,0 @@ -import 'dart:convert'; - -import 'package:dio/dio.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; - -import '../../pages/auth/model/token.dart'; -import 'custom_exceptions.dart'; -import 'dio.dart'; -import 'enums.dart'; - -class Request { - String endPoint; - bool? autherized; - bool? isFormData; - RequestType? method; - Map? headers; - final Map? queryParams; - Map? body; - Duration? receiveTimeout; - Request( - this.endPoint, { - this.autherized, - this.isFormData, - this.method, - this.headers, - this.queryParams, - this.body, - this.receiveTimeout, - }) { - headers = { - 'content_Type': 'application/json', - 'Accept': 'application/json', - }; - } - Future> sendRequest() async { - Response? response; - if (autherized != null && autherized!) { - final storage = const FlutterSecureStorage(); - final token = await storage.read(key: Token.loginAccessTokenKey); - if (token != null) { - headers!["authorization"] = "Bearer $token"; - } - } - try { - response = await DioInstance().dio.request( - endPoint, - queryParameters: queryParams, - data: isFormData != null && isFormData == true - ? FormData.fromMap(body!) - : body, - options: Options( - method: method!.name.toUpperCase(), - headers: headers, - contentType: 'application/json', - receiveTimeout: receiveTimeout, - ), - ); - if (response.statusCode! >= 200 && response.statusCode! < 300) { - return response.data; - } - } on DioException catch (error) { - if (error.type == DioExceptionType.badResponse) { - throw badRequestException[error.response!.data["error"]] ?? - const GenericException( - type: ExceptionType.other, - ); - } - if (error.type == DioExceptionType.connectionError || - error.type == DioExceptionType.connectionTimeout || - error.type == DioExceptionType.receiveTimeout || - error.type == DioExceptionType.sendTimeout || - error.type == DioExceptionType.unknown) { - throw const GenericException( - type: ExceptionType.connectionError, - errorMessage: 'no_internet_connection', - ); - } - } - return {}; - } - - Map toJson() => { - 'endPoint': endPoint, - 'method': method!.name.toUpperCase(), - 'body': json.encode(body), - 'headers': headers, - 'queryParams': queryParams, - 'autherized': autherized, - 'isFormData': isFormData, - }; - @override - String toString() { - return jsonEncode(toJson()); - } - - List get props => [ - endPoint, - autherized, - isFormData, - method, - headers, - queryParams, - body, - receiveTimeout, - ]; -} - -Map badRequestException = { - ExceptionMessage.INVALID_CREDENTIALS.name: const GenericException( - type: ExceptionType.invalidCredentials, - errorMessage: "Invalid credentials ...", - ), - "The password field must be at least 8 characters.": const GenericException( - type: ExceptionType.invalidValidation, - errorMessage: 'password must be 8 or more characters', - ), - ExceptionMessage.NOT_AUTHENTICATED.name: const GenericException( - type: ExceptionType.notAuthenticated, - errorMessage: "not authenticated", - ), -}; From cd6bf32aedc9c3ee8aeafa7ce16dbca3ffc4f8e1 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 14:00:15 +0300 Subject: [PATCH 70/82] fix bug /non uuid assign tag to be accepted --- .../all_spaces/widgets/dialogs/create_space_dialog.dart | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index 9e2f6dbb..8cf30f7c 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -302,13 +302,6 @@ class CreateSpaceDialogState extends State { ? enteredName : (widget.name ?? ''); if (newName.isNotEmpty) { - if (tags != null && tags!.isNotEmpty) { - if (tags!.any( - (tag) => tag.uuid == null || tag.uuid!.isEmpty, - )) { - return; - } - } widget.onCreateSpace( newName, selectedIcon, From fc86042af7dd399d7ce1b17c9e6590ef1c293eea Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 11 Jun 2025 14:14:21 +0300 Subject: [PATCH 71/82] Implement SpaceTreeDropdownBloc for improved state management in SpaceTreeDropdown; refactor dropdown logic and event handling. --- .../create_new_routines/commu_dropdown.dart | 173 +++++++++--------- .../space_tree_dropdown_bloc.dart | 27 +++ .../space_tree_dropdown_event.dart | 15 ++ .../space_tree_dropdown_state.dart | 7 + 4 files changed, 137 insertions(+), 85 deletions(-) create mode 100644 lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart create mode 100644 lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart create mode 100644 lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart diff --git a/lib/pages/routines/create_new_routines/commu_dropdown.dart b/lib/pages/routines/create_new_routines/commu_dropdown.dart index 431e633a..6fd562b0 100644 --- a/lib/pages/routines/create_new_routines/commu_dropdown.dart +++ b/lib/pages/routines/create_new_routines/commu_dropdown.dart @@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.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/utils/color_manager.dart'; +import 'space_tree_dropdown_bloc.dart'; class SpaceTreeDropdown extends StatefulWidget { final String? selectedSpaceId; @@ -21,18 +22,19 @@ class SpaceTreeDropdown extends StatefulWidget { } class _SpaceTreeDropdownState extends State { - late String? _selectedSpaceId; + late SpaceTreeDropdownBloc _dropdownBloc; final LayerLink _layerLink = LayerLink(); OverlayEntry? _overlayEntry; @override void initState() { super.initState(); - _selectedSpaceId = widget.selectedSpaceId; + _dropdownBloc = SpaceTreeDropdownBloc(widget.selectedSpaceId); } @override void dispose() { + _dropdownBloc.close(); _removeOverlay(); super.dispose(); } @@ -44,87 +46,95 @@ class _SpaceTreeDropdownState extends State { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - final communities = state.searchQuery.isNotEmpty - ? state.filteredCommunity - : state.communityList; - final selectedCommunity = _findCommunity(communities, _selectedSpaceId); + return BlocProvider.value( + value: _dropdownBloc, + child: BlocBuilder( + builder: (context, spaceTreeState) { + final communities = spaceTreeState.searchQuery.isNotEmpty + ? spaceTreeState.filteredCommunity + : spaceTreeState.communityList; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 10, - ), - child: Text( - "Community", - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w400, - fontSize: 13, - color: ColorsManager.blackColor, - ), - ), - ), - CompositedTransformTarget( - link: _layerLink, - child: GestureDetector( - onTap: _toggleDropdown, - child: Container( - height: 46, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(12), - ), - margin: const EdgeInsets.symmetric( - horizontal: 10, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Text( - selectedCommunity?.name ?? 'Please Select', - style: TextStyle( - color: selectedCommunity != null - ? ColorsManager.blackColor - : ColorsManager.textGray, - overflow: TextOverflow.ellipsis, + return BlocBuilder( + builder: (context, dropdownState) { + final selectedCommunity = _findCommunity( + communities, + dropdownState.selectedSpaceId, + ); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Text( + "Community", + style: Theme.of(context).textTheme.bodyMedium!.copyWith( fontWeight: FontWeight.w400, fontSize: 13, + color: ColorsManager.blackColor, ), - ), - ), - Container( - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: const BorderRadius.only( - topRight: Radius.circular(10), - bottomRight: Radius.circular(10), - ), - ), - height: 45, - width: 33, - child: const Icon( - Icons.keyboard_arrow_down, - color: ColorsManager.textGray, - ), - ), - ], + ), ), - ), - ), - ), - ], - ); - }, + CompositedTransformTarget( + link: _layerLink, + child: GestureDetector( + onTap: () => _toggleDropdown(context, communities), + child: Container( + height: 46, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(12), + ), + margin: const EdgeInsets.symmetric(horizontal: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 10), + child: Text( + selectedCommunity?.name ?? 'Please Select', + style: TextStyle( + color: selectedCommunity != null + ? ColorsManager.blackColor + : ColorsManager.textGray, + overflow: TextOverflow.ellipsis, + fontWeight: FontWeight.w400, + fontSize: 13, + ), + ), + ), + Container( + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: const BorderRadius.only( + topRight: Radius.circular(10), + bottomRight: Radius.circular(10), + ), + ), + height: 45, + width: 33, + child: const Icon( + Icons.keyboard_arrow_down, + color: ColorsManager.textGray, + ), + ), + ], + ), + ), + ), + ), + ], + ); + }, + ); + }, + ), ); } - void _toggleDropdown() { + void _toggleDropdown(BuildContext context, List communities) { if (_overlayEntry != null) { _removeOverlay(); return; @@ -141,10 +151,10 @@ class _SpaceTreeDropdownState extends State { elevation: 8, borderRadius: BorderRadius.circular(12), child: DropdownMenuContent( - selectedSpaceId: _selectedSpaceId, + selectedSpaceId: _dropdownBloc.state.selectedSpaceId, onChanged: (id) { if (id != null && mounted) { - setState(() => _selectedSpaceId = id); + _dropdownBloc.add(SpaceTreeDropdownSelectEvent(id)); widget.onChanged?.call(id); _removeOverlay(); } @@ -162,17 +172,10 @@ class _SpaceTreeDropdownState extends State { CommunityModel? _findCommunity( List communities, String? communityId) { if (communityId == null) return null; - try { return communities.firstWhere((c) => c.uuid == communityId); } catch (e) { - return CommunityModel( - uuid: '', - createdAt: DateTime.now(), - updatedAt: DateTime.now(), - name: '', - description: '', - spaces: []); + return null; } } } diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart new file mode 100644 index 00000000..be2a7e9b --- /dev/null +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart @@ -0,0 +1,27 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; + +part 'space_tree_dropdown_event.dart'; +part 'space_tree_dropdown_state.dart'; + +class SpaceTreeDropdownBloc + extends Bloc { + SpaceTreeDropdownBloc(String? initialId) + : super(SpaceTreeDropdownState(selectedSpaceId: initialId)) { + on(_onSelect); + on(_onReset); + } + + void _onSelect( + SpaceTreeDropdownSelectEvent event, + Emitter emit, + ) { + emit(SpaceTreeDropdownState(selectedSpaceId: event.spaceId)); + } + + void _onReset( + SpaceTreeDropdownResetEvent event, + Emitter emit, + ) { + emit(SpaceTreeDropdownState(selectedSpaceId: event.initialId)); + } +} \ No newline at end of file diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart new file mode 100644 index 00000000..dec701dc --- /dev/null +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart @@ -0,0 +1,15 @@ +part of 'space_tree_dropdown_bloc.dart'; + +abstract class SpaceTreeDropdownEvent {} + +class SpaceTreeDropdownSelectEvent extends SpaceTreeDropdownEvent { + final String? spaceId; + + SpaceTreeDropdownSelectEvent(this.spaceId); +} + +class SpaceTreeDropdownResetEvent extends SpaceTreeDropdownEvent { + final String? initialId; + + SpaceTreeDropdownResetEvent(this.initialId); +} \ No newline at end of file diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart new file mode 100644 index 00000000..dd22d095 --- /dev/null +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart @@ -0,0 +1,7 @@ +part of 'space_tree_dropdown_bloc.dart'; + +class SpaceTreeDropdownState { + final String? selectedSpaceId; + + SpaceTreeDropdownState({this.selectedSpaceId}); +} \ No newline at end of file From 1393a15ecac92606cf0f94882b2e4736d1d468e2 Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 11 Jun 2025 16:02:40 +0300 Subject: [PATCH 72/82] Disable tap action on Community Structure when in specific states --- .../structure_selector/view/center_body_widget.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart index 0f63ebb1..dbc6c7ef 100644 --- a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart +++ b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart @@ -30,11 +30,14 @@ class CenterBodyWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( - onTap: () { - context - .read() - .add(CommunityStructureSelectedEvent()); - }, + onTap: state is CommunityStructureState || + state is CommunitySelectedState + ? null + : () { + context + .read() + .add(CommunityStructureSelectedEvent()); + }, child: Text( 'Community Structure', style: Theme.of(context).textTheme.bodyLarge!.copyWith( From 0c5db9dfeb1f63889b3968db1a7445a979e5a948 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 16:35:19 +0300 Subject: [PATCH 73/82] add bool function to space model if no changes made on object --- .../spaces_management/all_spaces/model/space_model.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/pages/spaces_management/all_spaces/model/space_model.dart b/lib/pages/spaces_management/all_spaces/model/space_model.dart index 4956d472..f9c59d24 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_model.dart @@ -171,4 +171,13 @@ extension SpaceExtensions on SpaceModel { return tagValues; } + + bool isNoChangesSubmited(String name, icon, SpaceTemplateModel? spaceModel, + List? subspaces, List? tags) { + return (name == this.name && + icon == this.icon && + spaceModel == this.spaceModel && + subspaces == this.subspaces && + tags == this.tags); + } } From 27dbcb26f1c2070bb45cc2931c26502fe6006db0 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Wed, 11 Jun 2025 16:35:34 +0300 Subject: [PATCH 74/82] use function to fix bug --- .../all_spaces/widgets/community_structure_widget.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index 178f7659..4f68fb7e 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -384,6 +384,15 @@ class _CommunityStructureAreaState extends State { SpaceTemplateModel? spaceModel, List? subspaces, List? tags) { + if (widget.selectedSpace!.isNoChangesSubmited( + name, + icon, + spaceModel, + subspaces, + tags, + )) { + return; + } setState(() { // Update the space's properties widget.selectedSpace!.name = name; From 0b0e235f266941cf3dad7f359701f5328259f725 Mon Sep 17 00:00:00 2001 From: raf-dev1 Date: Thu, 12 Jun 2025 14:13:25 +0300 Subject: [PATCH 75/82] fix the save button by removing deleted items from spaces then return all other elements status to unchanged --- .../all_spaces/bloc/space_management_bloc.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index f666c078..a4d6628e 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -491,6 +491,12 @@ class SpaceManagementBloc event.communityUuid, emit, ); + event.spaces.removeWhere( + (space) => space.status == SpaceStatus.deleted, + ); + event.spaces.forEach( + (space) => space.status = SpaceStatus.unchanged, + ); } } catch (e) { // emit(SpaceManagementError('Error saving spaces: $e')); From e867c290865a12c5d6966625cf2380e72146df06 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 12 Jun 2025 14:30:39 +0300 Subject: [PATCH 76/82] use `very_good_analysis` lints. --- analysis_options.yaml | 48 ++++++++----------- macos/Flutter/GeneratedPluginRegistrant.swift | 2 +- pubspec.yaml | 7 +-- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 80a63bcb..611cf313 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,33 +1,27 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. +include: package:very_good_analysis/analysis_options.yaml -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. analyzer: errors: - constant_identifier_names: ignore - overridden_fields: ignore -include: package:flutter_lints/flutter.yaml + strict_raw_type: warning + argument_type_not_assignable: warning + invalid_assignment: warning + return_of_invalid_type: warning + return_of_invalid_type_from_closure: warning + list_element_type_not_assignable: warning + for_in_of_invalid_type: warning + cast_nullable_to_non_nullable: warning + non_bool_condition: warning + field_initializer_not_assignable: warning + non_bool_negation_expression: warning + non_bool_operand: warning linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at https://dart.dev/lints. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - prefer_const_constructors: true - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options + prefer_single_quotes: true + avoid_print: false + public_member_api_docs: false + sort_pub_dependencies: false + one_member_abstracts: false + prefer_int_literals: false + sort_constructors_first: false + avoid_redundant_argument_values: false diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index e6f3527d..585688ef 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -15,7 +15,7 @@ import shared_preferences_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) + FirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FirebaseAnalyticsPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin")) FLTFirebaseDatabasePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseDatabasePlugin")) diff --git a/pubspec.yaml b/pubspec.yaml index edd003cf..c4692ac4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -69,12 +69,7 @@ dev_dependencies: flutter_test: sdk: flutter - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. - flutter_lints: ^5.0.0 + very_good_analysis: ^9.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec From 1a2378df6e5515798038555a682d4fd689f6d8f2 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 12 Jun 2025 14:35:54 +0300 Subject: [PATCH 77/82] Deleted all unnecessary build targets --- android/.gitignore | 13 - android/app/build.gradle | 71 -- android/app/google-services.json | 68 -- android/app/src/debug/AndroidManifest.xml | 7 - android/app/src/main/AndroidManifest.xml | 44 - .../com/example/syncrow_web/MainActivity.kt | 5 - .../res/drawable-v21/launch_background.xml | 12 - .../main/res/drawable/launch_background.xml | 12 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 0 bytes .../app/src/main/res/values-night/styles.xml | 18 - android/app/src/main/res/values/styles.xml | 18 - android/app/src/profile/AndroidManifest.xml | 7 - android/build.gradle | 18 - android/gradle.properties | 3 - .../gradle/wrapper/gradle-wrapper.properties | 5 - android/settings.gradle | 30 - ios/.gitignore | 34 - ios/Flutter/AppFrameworkInfo.plist | 26 - ios/Flutter/Debug.xcconfig | 2 - ios/Flutter/Release.xcconfig | 2 - ios/Podfile | 44 - ios/Podfile.lock | 36 - ios/Runner.xcodeproj/project.pbxproj | 751 ---------------- .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 8 - .../xcshareddata/xcschemes/Runner.xcscheme | 98 --- .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 8 - ios/Runner/AppDelegate.swift | 13 - .../AppIcon.appiconset/Contents.json | 122 --- .../Icon-App-1024x1024@1x.png | Bin 10932 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 295 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 406 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 450 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 282 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 462 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 704 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 406 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 586 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 862 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 862 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 1674 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 762 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 1226 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 1418 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - ios/Runner/Base.lproj/LaunchScreen.storyboard | 37 - ios/Runner/Base.lproj/Main.storyboard | 26 - ios/Runner/GoogleService-Info.plist | 32 - ios/Runner/Info.plist | 49 -- ios/Runner/Runner-Bridging-Header.h | 1 - ios/RunnerTests/RunnerTests.swift | 12 - linux/.gitignore | 1 - linux/CMakeLists.txt | 145 --- linux/flutter/CMakeLists.txt | 88 -- linux/flutter/generated_plugin_registrant.cc | 19 - linux/flutter/generated_plugin_registrant.h | 15 - linux/flutter/generated_plugins.cmake | 25 - linux/main.cc | 6 - linux/my_application.cc | 124 --- linux/my_application.h | 18 - macos/.gitignore | 7 - .../Runner/Logs/Build/.dat.nosync1585.W9c579 | 95 -- ...-9521-4D0C-959C-43A07F62CC12.xcactivitylog | Bin 217 -> 0 bytes ...-C79D-4D4B-891A-12C476DFCB10.xcactivitylog | Bin 209 -> 0 bytes .../Runner/Logs/Build/LogStoreManifest.plist | 53 -- .../Runner/Logs/Launch/LogStoreManifest.plist | 10 - .../Logs/Localization/LogStoreManifest.plist | 10 - .../Logs/Package/LogStoreManifest.plist | 10 - .../Runner/Logs/Test/LogStoreManifest.plist | 10 - macos/DerivedData/Runner/info.plist | 10 - macos/Flutter/Flutter-Debug.xcconfig | 2 - macos/Flutter/Flutter-Release.xcconfig | 2 - macos/Flutter/GeneratedPluginRegistrant.swift | 26 - macos/Podfile | 43 - macos/Podfile.lock | 36 - macos/Runner.xcodeproj/project.pbxproj | 824 ------------------ .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/xcschemes/Runner.xcscheme | 98 --- .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - macos/Runner/AppDelegate.swift | 9 - .../AppIcon.appiconset/Contents.json | 68 -- .../AppIcon.appiconset/app_icon_1024.png | Bin 102994 -> 0 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 5680 -> 0 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 520 -> 0 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 14142 -> 0 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 1066 -> 0 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 36406 -> 0 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 2218 -> 0 bytes macos/Runner/Base.lproj/MainMenu.xib | 343 -------- macos/Runner/Configs/AppInfo.xcconfig | 14 - macos/Runner/Configs/Debug.xcconfig | 2 - macos/Runner/Configs/Release.xcconfig | 2 - macos/Runner/Configs/Warnings.xcconfig | 13 - macos/Runner/DebugProfile.entitlements | 12 - macos/Runner/GoogleService-Info.plist | 32 - macos/Runner/Info.plist | 32 - macos/Runner/MainFlutterWindow.swift | 15 - macos/Runner/Release.entitlements | 8 - macos/RunnerTests/RunnerTests.swift | 12 - windows/.gitignore | 17 - windows/CMakeLists.txt | 108 --- windows/flutter/CMakeLists.txt | 109 --- .../flutter/generated_plugin_registrant.cc | 20 - windows/flutter/generated_plugin_registrant.h | 15 - windows/flutter/generated_plugins.cmake | 26 - windows/runner/CMakeLists.txt | 40 - windows/runner/Runner.rc | 121 --- windows/runner/flutter_window.cpp | 71 -- windows/runner/flutter_window.h | 33 - windows/runner/main.cpp | 43 - windows/runner/resource.h | 16 - windows/runner/resources/app_icon.ico | Bin 33772 -> 0 bytes windows/runner/runner.exe.manifest | 20 - windows/runner/utils.cpp | 65 -- windows/runner/utils.h | 19 - windows/runner/win32_window.cpp | 288 ------ windows/runner/win32_window.h | 102 --- 129 files changed, 5071 deletions(-) delete mode 100644 android/.gitignore delete mode 100644 android/app/build.gradle delete mode 100644 android/app/google-services.json delete mode 100644 android/app/src/debug/AndroidManifest.xml delete mode 100644 android/app/src/main/AndroidManifest.xml delete mode 100644 android/app/src/main/kotlin/com/example/syncrow_web/MainActivity.kt delete mode 100644 android/app/src/main/res/drawable-v21/launch_background.xml delete mode 100644 android/app/src/main/res/drawable/launch_background.xml delete mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 android/app/src/main/res/values-night/styles.xml delete mode 100644 android/app/src/main/res/values/styles.xml delete mode 100644 android/app/src/profile/AndroidManifest.xml delete mode 100644 android/build.gradle delete mode 100644 android/gradle.properties delete mode 100644 android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 android/settings.gradle delete mode 100644 ios/.gitignore delete mode 100644 ios/Flutter/AppFrameworkInfo.plist delete mode 100644 ios/Flutter/Debug.xcconfig delete mode 100644 ios/Flutter/Release.xcconfig delete mode 100644 ios/Podfile delete mode 100644 ios/Podfile.lock delete mode 100644 ios/Runner.xcodeproj/project.pbxproj delete mode 100644 ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 ios/Runner/AppDelegate.swift delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 ios/Runner/Base.lproj/Main.storyboard delete mode 100644 ios/Runner/GoogleService-Info.plist delete mode 100644 ios/Runner/Info.plist delete mode 100644 ios/Runner/Runner-Bridging-Header.h delete mode 100644 ios/RunnerTests/RunnerTests.swift delete mode 100644 linux/.gitignore delete mode 100644 linux/CMakeLists.txt delete mode 100644 linux/flutter/CMakeLists.txt delete mode 100644 linux/flutter/generated_plugin_registrant.cc delete mode 100644 linux/flutter/generated_plugin_registrant.h delete mode 100644 linux/flutter/generated_plugins.cmake delete mode 100644 linux/main.cc delete mode 100644 linux/my_application.cc delete mode 100644 linux/my_application.h delete mode 100644 macos/.gitignore delete mode 100644 macos/DerivedData/Runner/Logs/Build/.dat.nosync1585.W9c579 delete mode 100644 macos/DerivedData/Runner/Logs/Build/DEC061F9-9521-4D0C-959C-43A07F62CC12.xcactivitylog delete mode 100644 macos/DerivedData/Runner/Logs/Build/FB42CDDD-C79D-4D4B-891A-12C476DFCB10.xcactivitylog delete mode 100644 macos/DerivedData/Runner/Logs/Build/LogStoreManifest.plist delete mode 100644 macos/DerivedData/Runner/Logs/Launch/LogStoreManifest.plist delete mode 100644 macos/DerivedData/Runner/Logs/Localization/LogStoreManifest.plist delete mode 100644 macos/DerivedData/Runner/Logs/Package/LogStoreManifest.plist delete mode 100644 macos/DerivedData/Runner/Logs/Test/LogStoreManifest.plist delete mode 100644 macos/DerivedData/Runner/info.plist delete mode 100644 macos/Flutter/Flutter-Debug.xcconfig delete mode 100644 macos/Flutter/Flutter-Release.xcconfig delete mode 100644 macos/Flutter/GeneratedPluginRegistrant.swift delete mode 100644 macos/Podfile delete mode 100644 macos/Podfile.lock delete mode 100644 macos/Runner.xcodeproj/project.pbxproj delete mode 100644 macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 macos/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 macos/Runner/AppDelegate.swift delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png delete mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png delete mode 100644 macos/Runner/Base.lproj/MainMenu.xib delete mode 100644 macos/Runner/Configs/AppInfo.xcconfig delete mode 100644 macos/Runner/Configs/Debug.xcconfig delete mode 100644 macos/Runner/Configs/Release.xcconfig delete mode 100644 macos/Runner/Configs/Warnings.xcconfig delete mode 100644 macos/Runner/DebugProfile.entitlements delete mode 100644 macos/Runner/GoogleService-Info.plist delete mode 100644 macos/Runner/Info.plist delete mode 100644 macos/Runner/MainFlutterWindow.swift delete mode 100644 macos/Runner/Release.entitlements delete mode 100644 macos/RunnerTests/RunnerTests.swift delete mode 100644 windows/.gitignore delete mode 100644 windows/CMakeLists.txt delete mode 100644 windows/flutter/CMakeLists.txt delete mode 100644 windows/flutter/generated_plugin_registrant.cc delete mode 100644 windows/flutter/generated_plugin_registrant.h delete mode 100644 windows/flutter/generated_plugins.cmake delete mode 100644 windows/runner/CMakeLists.txt delete mode 100644 windows/runner/Runner.rc delete mode 100644 windows/runner/flutter_window.cpp delete mode 100644 windows/runner/flutter_window.h delete mode 100644 windows/runner/main.cpp delete mode 100644 windows/runner/resource.h delete mode 100644 windows/runner/resources/app_icon.ico delete mode 100644 windows/runner/runner.exe.manifest delete mode 100644 windows/runner/utils.cpp delete mode 100644 windows/runner/utils.h delete mode 100644 windows/runner/win32_window.cpp delete mode 100644 windows/runner/win32_window.h diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index 6f568019..00000000 --- a/android/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties -**/*.keystore -**/*.jks diff --git a/android/app/build.gradle b/android/app/build.gradle deleted file mode 100644 index 8981dae5..00000000 --- a/android/app/build.gradle +++ /dev/null @@ -1,71 +0,0 @@ -plugins { - 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 "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -android { - namespace "com.example.syncrow_web" - compileSdk flutter.compileSdkVersion - ndkVersion flutter.ndkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.syncrow_web" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies {} diff --git a/android/app/google-services.json b/android/app/google-services.json deleted file mode 100644 index 3cc77ccd..00000000 --- a/android/app/google-services.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 399f6981..00000000 --- a/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index efddc5a1..00000000 --- a/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/kotlin/com/example/syncrow_web/MainActivity.kt b/android/app/src/main/kotlin/com/example/syncrow_web/MainActivity.kt deleted file mode 100644 index 85468d7a..00000000 --- a/android/app/src/main/kotlin/com/example/syncrow_web/MainActivity.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.syncrow_web - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index f74085f3..00000000 --- a/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f8..00000000 --- a/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372eebdb28e45604e46eeda8dd24651419bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 06952be7..00000000 --- a/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml deleted file mode 100644 index cb1ef880..00000000 --- a/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index 399f6981..00000000 --- a/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index bc157bd1..00000000 --- a/android/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index 598d13fe..00000000 --- a/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx4G -android.useAndroidX=true -android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e1ca574e..00000000 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index 85edcfc9..00000000 --- a/android/settings.gradle +++ /dev/null @@ -1,30 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - } - settings.ext.flutterSdkPath = flutterSdkPath() - - includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - 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 -} - -include ":app" diff --git a/ios/.gitignore b/ios/.gitignore deleted file mode 100644 index 7a7f9873..00000000 --- a/ios/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -**/dgph -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/ephemeral/ -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 7c569640..00000000 --- a/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 12.0 - - diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6f..00000000 --- a/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bfe..00000000 --- a/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile deleted file mode 100644 index d97f17e2..00000000 --- a/ios/Podfile +++ /dev/null @@ -1,44 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '12.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/ios/Podfile.lock b/ios/Podfile.lock deleted file mode 100644 index 85fd7a99..00000000 --- a/ios/Podfile.lock +++ /dev/null @@ -1,36 +0,0 @@ -PODS: - - Flutter (1.0.0) - - flutter_secure_storage (6.0.0): - - Flutter - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - - shared_preferences_foundation (0.0.1): - - Flutter - - FlutterMacOS - -DEPENDENCIES: - - Flutter (from `Flutter`) - - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - -EXTERNAL SOURCES: - Flutter: - :path: Flutter - flutter_secure_storage: - :path: ".symlinks/plugins/flutter_secure_storage/ios" - path_provider_foundation: - :path: ".symlinks/plugins/path_provider_foundation/darwin" - shared_preferences_foundation: - :path: ".symlinks/plugins/shared_preferences_foundation/darwin" - -SPEC CHECKSUMS: - Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - -PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 - -COCOAPODS: 1.15.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 4f245401..00000000 --- a/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,751 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - 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 */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 22428D486F110EE0B969469D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 253C5EA6840355311DB030EA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 2C0D722D2ED971BF672D18D5 /* 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 = ""; }; - 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 544621C7727C798253BAB2C8 /* 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 = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 877FDC97D8B87080E35B3EB7 /* 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 = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - B14AB50E8716720E10D074BD /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; - 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 = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 759A57780A409ED209817654 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - E44A9405B1EB1B638DD05A58 /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - FF49F60EC38658783D8D66DA /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1454C118FFCECEEDF59152D2 /* Pods */ = { - isa = PBXGroup; - children = ( - 253C5EA6840355311DB030EA /* Pods-Runner.debug.xcconfig */, - 22428D486F110EE0B969469D /* Pods-Runner.release.xcconfig */, - D3AD250AADBF93406007C9EB /* Pods-Runner.profile.xcconfig */, - 2C0D722D2ED971BF672D18D5 /* Pods-RunnerTests.debug.xcconfig */, - 877FDC97D8B87080E35B3EB7 /* Pods-RunnerTests.release.xcconfig */, - 544621C7727C798253BAB2C8 /* Pods-RunnerTests.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - 20A3C64D2B1CFED5A81C3251 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 2AFAE479A87ECDEBD5D6EB30 /* Pods_Runner.framework */, - 7ABF0EC746A2D686A0ED574F /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 331C8082294A63A400263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 331C8082294A63A400263BE5 /* RunnerTests */, - 1454C118FFCECEEDF59152D2 /* Pods */, - 20A3C64D2B1CFED5A81C3251 /* Frameworks */, - B14AB50E8716720E10D074BD /* GoogleService-Info.plist */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - 331C8081294A63A400263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C8080294A63A400263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - B9A66CAAF434B6A1BD8C4E09 /* [CP] Check Pods Manifest.lock */, - 331C807D294A63A400263BE5 /* Sources */, - 331C807F294A63A400263BE5 /* Resources */, - 759A57780A409ED209817654 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 331C8086294A63A400263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - C1C48B0232C0B26BFF405512 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */, - 7A77858F6F15CB76D2D3A872 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1510; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C8080294A63A400263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 97C146ED1CF9000F007C117D; - }; - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - 331C8080294A63A400263BE5 /* RunnerTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C807F294A63A400263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - F2A3345EC3021060731668D3 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 33590C9CD073D3D5EBA02CDE /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - 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 */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - B9A66CAAF434B6A1BD8C4E09 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C1C48B0232C0B26BFF405512 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C807D294A63A400263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 331C8088294A63A400263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2C0D722D2ED971BF672D18D5 /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Debug; - }; - 331C8089294A63A400263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 877FDC97D8B87080E35B3EB7 /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Release; - }; - 331C808A294A63A400263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 544621C7727C798253BAB2C8 /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C8088294A63A400263BE5 /* Debug */, - 331C8089294A63A400263BE5 /* Release */, - 331C808A294A63A400263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a6..00000000 --- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 8e3ca5df..00000000 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14..00000000 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift deleted file mode 100644 index b6363034..00000000 --- a/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@main -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab..00000000 --- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4725e9b0ddb1deab583e5b5102493aa332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10932 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 797d452e458972bab9d994556c8305db4c827017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 406 zcmV;H0crk;P))>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index 6ed2d933e1120817fe9182483a228007b18ab6ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 450 zcmV;z0X_bSP)iGWQ_5NJQ_~rNh*z)}eT%KUb z`7gNk0#AwF^#0T0?hIa^`~Ck;!}#m+_uT050aTR(J!bU#|IzRL%^UsMS#KsYnTF*!YeDOytlP4VhV?b} z%rz_<=#CPc)tU1MZTq~*2=8~iZ!lSa<{9b@2Jl;?IEV8)=fG217*|@)CCYgFze-x? zIFODUIA>nWKpE+bn~n7;-89sa>#DR>TSlqWk*!2hSN6D~Qb#VqbP~4Fk&m`@1$JGr zXPIdeRE&b2Thd#{MtDK$px*d3-Wx``>!oimf%|A-&-q*6KAH)e$3|6JV%HX{Hig)k suLT-RhftRq8b9;(V=235Wa|I=027H2wCDra;{X5v07*qoM6N<$f;9x^2LJ#7 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cd7b0099ca80c806f8fe495613e8d6c69460d76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282 zcmV+#0p(^bcu7P-R4C8Q z&e;xxFbF_Vrezo%_kH*OKhshZ6BFpG-Y1e10`QXJKbND7AMQ&cMj60B5TNObaZxYybcN07*qoM6N<$g3m;S%K!iX diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index fe730945a01f64a61e2235dbe3f45b08f7729182..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)-}iV`2<;=$?g5M=KQbZ{F&YRNy7Nn@%_*5{gvDM0aKI4?ESmw z{NnZg)A0R`+4?NF_RZexyVB&^^ZvN!{I28tr{Vje;QNTz`dG&Jz0~Ek&f2;*Z7>B|cg}xYpxEFY+0YrKLF;^Q+-HreN0P{&i zK~zY`?b7ECf-n?@;d<&orQ*Q7KoR%4|C>{W^h6@&01>0SKS`dn{Q}GT%Qj_{PLZ_& zs`MFI#j-(>?bvdZ!8^xTwlY{qA)T4QLbY@j(!YJ7aXJervHy6HaG_2SB`6CC{He}f zHVw(fJWApwPq!6VY7r1w-Fs)@ox~N+q|w~e;JI~C4Vf^@d>Wvj=fl`^u9x9wd9 zR%3*Q+)t%S!MU_`id^@&Y{y7-r98lZX0?YrHlfmwb?#}^1b{8g&KzmkE(L>Z&)179 zp<)v6Y}pRl100G2FL_t(o!|l{-Q-VMg#&MKg7c{O0 z2wJImOS3Gy*Z2Qifdv~JYOp;v+U)a|nLoc7hNH;I$;lzDt$}rkaFw1mYK5_0Q(Sut zvbEloxON7$+HSOgC9Z8ltuC&0OSF!-mXv5caV>#bc3@hBPX@I$58-z}(ZZE!t-aOG zpjNkbau@>yEzH(5Yj4kZiMH32XI!4~gVXNnjAvRx;Sdg^`>2DpUEwoMhTs_st8pKG z(%SHyHdU&v%f36~uERh!bd`!T2dw;z6PrOTQ7Vt*#9F2uHlUVnb#ev_o^fh}Dzmq} zWtlk35}k=?xj28uO|5>>$yXadTUE@@IPpgH`gJ~Ro4>jd1IF|(+IX>8M4Ps{PNvmI zNj4D+XgN83gPt_Gm}`Ybv{;+&yu-C(Grdiahmo~BjG-l&mWM+{e5M1sm&=xduwgM9 z`8OEh`=F3r`^E{n_;%9weN{cf2%7=VzC@cYj+lg>+3|D|_1C@{hcU(DyQG_BvBWe? zvTv``=%b1zrol#=R`JB)>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index 502f463a9bc882b461c96aadf492d1729e49e725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 586 zcmV-Q0=4~#P)+}#`wDE{8-2Mebf5<{{PqV{TgVcv*r8?UZ3{-|G?_}T*&y;@cqf{ z{Q*~+qr%%p!1pS*_Uicl#q9lc(D`!D`LN62sNwq{oYw(Wmhk)k<@f$!$@ng~_5)Ru z0Z)trIA5^j{DIW^c+vT2%lW+2<(RtE2wR;4O@)Tm`Xr*?A(qYoM}7i5Yxw>D(&6ou zxz!_Xr~yNF+waPe00049Nkl*;a!v6h%{rlvIH#gW3s8p;bFr=l}mRqpW2h zw=OA%hdyL~z+UHOzl0eKhEr$YYOL-c-%Y<)=j?(bzDweB7{b+%_ypvm_cG{SvM=DK zhv{K@m>#Bw>2W$eUI#iU)Wdgs8Y3U+A$Gd&{+j)d)BmGKx+43U_!tik_YlN)>$7G! zhkE!s;%oku3;IwG3U^2kw?z+HM)jB{@zFhK8P#KMSytSthr+4!c(5c%+^UBn`0X*2 zy3(k600_CSZj?O$Qu%&$;|TGUJrptR(HzyIx>5E(2r{eA(<6t3e3I0B)7d6s7?Z5J zZ!rtKvA{MiEBm&KFtoifx>5P^Z=vl)95XJn()aS5%ad(s?4-=Tkis9IGu{`Fy8r+H07*qoM6N<$f20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index 0ec303439225b78712f49115768196d8d76f6790..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 862 zcmV-k1EKthP)20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index e9f5fea27c705180eb716271f41b582e76dcbd90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1674 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index 0467bf12aa4d28f374bb26596605a46dcbb3e7c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1418 zcmV;51$Fv~P)q zKfU)WzW*n(@|xWGCA9ScMt*e9`2kdxPQ&&>|-UCa7_51w+ zLUsW@ZzZSW0y$)Hp~e9%PvP|a03ks1`~K?q{u;6NC8*{AOqIUq{CL&;p56Lf$oQGq z^={4hPQv)y=I|4n+?>7Fim=dxt1 z2H+Dm+1+fh+IF>G0SjJMkQQre1x4|G*Z==(Ot&kCnUrL4I(rf(ucITwmuHf^hXiJT zkdTm&kdTm&kdTm&kdP`esgWG0BcWCVkVZ&2dUwN`cgM8QJb`Z7Z~e<&Yj2(}>Tmf` zm1{eLgw!b{bXkjWbF%dTkTZEJWyWOb##Lfw4EK2}<0d6%>AGS{po>WCOy&f$Tay_> z?NBlkpo@s-O;0V%Y_Xa-G#_O08q5LR*~F%&)}{}r&L%Sbs8AS4t7Y0NEx*{soY=0MZExqA5XHQkqi#4gW3 zqODM^iyZl;dvf)-bOXtOru(s)Uc7~BFx{w-FK;2{`VA?(g&@3z&bfLFyctOH!cVsF z7IL=fo-qBndRUm;kAdXR4e6>k-z|21AaN%ubeVrHl*<|s&Ax@W-t?LR(P-24A5=>a z*R9#QvjzF8n%@1Nw@?CG@6(%>+-0ASK~jEmCV|&a*7-GKT72W<(TbSjf)&Eme6nGE z>Gkj4Sq&2e+-G%|+NM8OOm5zVl9{Z8Dd8A5z3y8mZ=4Bv4%>as_{9cN#bm~;h>62( zdqY93Zy}v&c4n($Vv!UybR8ocs7#zbfX1IY-*w~)p}XyZ-SFC~4w>BvMVr`dFbelV{lLL0bx7@*ZZdebr3`sP;? zVImji)kG)(6Juv0lz@q`F!k1FE;CQ(D0iG$wchPbKZQELlsZ#~rt8#90Y_Xh&3U-< z{s<&cCV_1`^TD^ia9!*mQDq& zn2{r`j};V|uV%_wsP!zB?m%;FeaRe+X47K0e+KE!8C{gAWF8)lCd1u1%~|M!XNRvw zvtqy3iz0WSpWdhn6$hP8PaRBmp)q`#PCA`Vd#Tc$@f1tAcM>f_I@bC)hkI9|o(Iqv zo}Piadq!j76}004RBio<`)70k^`K1NK)q>w?p^C6J2ZC!+UppiK6&y3Kmbv&O!oYF z34$0Z;QO!JOY#!`qyGH<3Pd}Pt@q*A0V=3SVtWKRR8d8Z&@)3qLPA19LPA19LPEUC YUoZo%k(ykuW&i*H07*qoM6N<$f+CH{y8r+H diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2f..00000000 --- a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b..00000000 --- a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7..00000000 --- a/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516..00000000 --- a/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist deleted file mode 100644 index 9cdebed0..00000000 --- a/ios/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - API_KEY - AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw - GCM_SENDER_ID - 427332280600 - PLIST_VERSION - 1 - BUNDLE_ID - com.example.syncrowWeb - PROJECT_ID - test2-8a3d2 - STORAGE_BUCKET - test2-8a3d2.firebasestorage.app - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:427332280600:ios:14346b200780dc760c7e6d - DATABASE_URL - https://test2-8a3d2-default-rtdb.firebaseio.com - - \ No newline at end of file diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist deleted file mode 100644 index ba673060..00000000 --- a/ios/Runner/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Syncrow Web - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - syncrow_web - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - - diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a56..00000000 --- a/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 86a7c3b1..00000000 --- a/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Flutter -import UIKit -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/linux/.gitignore b/linux/.gitignore deleted file mode 100644 index d3896c98..00000000 --- a/linux/.gitignore +++ /dev/null @@ -1 +0,0 @@ -flutter/ephemeral diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt deleted file mode 100644 index 3f1132f0..00000000 --- a/linux/CMakeLists.txt +++ /dev/null @@ -1,145 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "syncrow_web") -# The unique GTK application identifier for this application. See: -# https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "com.example.syncrow_web") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(SET CMP0063 NEW) - -# Load bundled libraries from the lib/ directory relative to the binary. -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Root filesystem for cross-building. -if(FLUTTER_TARGET_PLATFORM_SYSROOT) - set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endif() - -# Define build configuration options. -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") -endif() - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_14) - target_compile_options(${TARGET} PRIVATE -Wall -Werror) - target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") - target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) - -add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") - -# Define the application target. To change its name, change BINARY_NAME above, -# not the value here, or `flutter run` will no longer work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} - "main.cc" - "my_application.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add dependency libraries. Add any application-specific dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) - -# Only the install-generated bundle's copy of the executable will launch -# correctly, since the resources must in the right relative locations. To avoid -# people trying to run the unbundled copy, put it in a subdirectory instead of -# the default top-level location. -set_target_properties(${BINARY_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" -) - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# By default, "installing" just makes a relocatable bundle in the build -# directory. -set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -# Start with a clean build bundle directory every time. -install(CODE " - file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") - " COMPONENT Runtime) - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) - install(FILES "${bundled_library}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endforeach(bundled_library) - -# Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() diff --git a/linux/flutter/CMakeLists.txt b/linux/flutter/CMakeLists.txt deleted file mode 100644 index d5bd0164..00000000 --- a/linux/flutter/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.10) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. - -# Serves the same purpose as list(TRANSFORM ... PREPEND ...), -# which isn't available in 3.10. -function(list_prepend LIST_NAME PREFIX) - set(NEW_LIST "") - foreach(element ${${LIST_NAME}}) - list(APPEND NEW_LIST "${PREFIX}${element}") - endforeach(element) - set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) -endfunction() - -# === Flutter Library === -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) -pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) - -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "fl_basic_message_channel.h" - "fl_binary_codec.h" - "fl_binary_messenger.h" - "fl_dart_project.h" - "fl_engine.h" - "fl_json_message_codec.h" - "fl_json_method_codec.h" - "fl_message_codec.h" - "fl_method_call.h" - "fl_method_channel.h" - "fl_method_codec.h" - "fl_method_response.h" - "fl_plugin_registrar.h" - "fl_plugin_registry.h" - "fl_standard_message_codec.h" - "fl_standard_method_codec.h" - "fl_string_codec.h" - "fl_value.h" - "fl_view.h" - "flutter_linux.h" -) -list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") -target_link_libraries(flutter INTERFACE - PkgConfig::GTK - PkgConfig::GLIB - PkgConfig::GIO -) -add_dependencies(flutter flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CMAKE_CURRENT_BINARY_DIR}/_phony_ - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" - ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} -) diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 38dd0bc6..00000000 --- a/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,19 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include - -void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); - flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); - g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); - url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); -} diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47b..00000000 --- a/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake deleted file mode 100644 index 65240e99..00000000 --- a/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - flutter_secure_storage_linux - url_launcher_linux -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/linux/main.cc b/linux/main.cc deleted file mode 100644 index e7c5c543..00000000 --- a/linux/main.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "my_application.h" - -int main(int argc, char** argv) { - g_autoptr(MyApplication) app = my_application_new(); - return g_application_run(G_APPLICATION(app), argc, argv); -} diff --git a/linux/my_application.cc b/linux/my_application.cc deleted file mode 100644 index 82e018ea..00000000 --- a/linux/my_application.cc +++ /dev/null @@ -1,124 +0,0 @@ -#include "my_application.h" - -#include -#ifdef GDK_WINDOWING_X11 -#include -#endif - -#include "flutter/generated_plugin_registrant.h" - -struct _MyApplication { - GtkApplication parent_instance; - char** dart_entrypoint_arguments; -}; - -G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) - -// Implements GApplication::activate. -static void my_application_activate(GApplication* application) { - MyApplication* self = MY_APPLICATION(application); - GtkWindow* window = - GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); - - // Use a header bar when running in GNOME as this is the common style used - // by applications and is the setup most users will be using (e.g. Ubuntu - // desktop). - // If running on X and not using GNOME then just use a traditional title bar - // in case the window manager does more exotic layout, e.g. tiling. - // If running on Wayland assume the header bar will work (may need changing - // if future cases occur). - gboolean use_header_bar = TRUE; -#ifdef GDK_WINDOWING_X11 - GdkScreen* screen = gtk_window_get_screen(window); - if (GDK_IS_X11_SCREEN(screen)) { - const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); - if (g_strcmp0(wm_name, "GNOME Shell") != 0) { - use_header_bar = FALSE; - } - } -#endif - if (use_header_bar) { - GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); - gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "syncrow_web"); - gtk_header_bar_set_show_close_button(header_bar, TRUE); - gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); - } else { - gtk_window_set_title(window, "syncrow_web"); - } - - gtk_window_set_default_size(window, 1280, 720); - gtk_widget_show(GTK_WIDGET(window)); - - g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); - - FlView* view = fl_view_new(project); - gtk_widget_show(GTK_WIDGET(view)); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); - - gtk_widget_grab_focus(GTK_WIDGET(view)); -} - -// Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { - MyApplication* self = MY_APPLICATION(application); - // Strip out the first argument as it is the binary name. - self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); - - g_autoptr(GError) error = nullptr; - if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; - } - - g_application_activate(application); - *exit_status = 0; - - return TRUE; -} - -// Implements GApplication::startup. -static void my_application_startup(GApplication* application) { - //MyApplication* self = MY_APPLICATION(object); - - // Perform any actions required at application startup. - - G_APPLICATION_CLASS(my_application_parent_class)->startup(application); -} - -// Implements GApplication::shutdown. -static void my_application_shutdown(GApplication* application) { - //MyApplication* self = MY_APPLICATION(object); - - // Perform any actions required at application shutdown. - - G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); -} - -// Implements GObject::dispose. -static void my_application_dispose(GObject* object) { - MyApplication* self = MY_APPLICATION(object); - g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); - G_OBJECT_CLASS(my_application_parent_class)->dispose(object); -} - -static void my_application_class_init(MyApplicationClass* klass) { - G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; - G_APPLICATION_CLASS(klass)->startup = my_application_startup; - G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; - G_OBJECT_CLASS(klass)->dispose = my_application_dispose; -} - -static void my_application_init(MyApplication* self) {} - -MyApplication* my_application_new() { - return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, - "flags", G_APPLICATION_NON_UNIQUE, - nullptr)); -} diff --git a/linux/my_application.h b/linux/my_application.h deleted file mode 100644 index 72271d5e..00000000 --- a/linux/my_application.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FLUTTER_MY_APPLICATION_H_ -#define FLUTTER_MY_APPLICATION_H_ - -#include - -G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, - GtkApplication) - -/** - * my_application_new: - * - * Creates a new Flutter-based application. - * - * Returns: a new #MyApplication. - */ -MyApplication* my_application_new(); - -#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/macos/.gitignore b/macos/.gitignore deleted file mode 100644 index 746adbb6..00000000 --- a/macos/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Flutter-related -**/Flutter/ephemeral/ -**/Pods/ - -# Xcode-related -**/dgph -**/xcuserdata/ diff --git a/macos/DerivedData/Runner/Logs/Build/.dat.nosync1585.W9c579 b/macos/DerivedData/Runner/Logs/Build/.dat.nosync1585.W9c579 deleted file mode 100644 index 309af193..00000000 --- a/macos/DerivedData/Runner/Logs/Build/.dat.nosync1585.W9c579 +++ /dev/null @@ -1,95 +0,0 @@ - - - - - logFormatVersion - 11 - logs - - DEC061F9-9521-4D0C-959C-43A07F62CC12 - - className - IDECommandLineBuildLog - documentTypeString - <nil> - domainType - Xcode.IDEActivityLogDomainType.BuildLog - fileName - DEC061F9-9521-4D0C-959C-43A07F62CC12.xcactivitylog - hasPrimaryLog - - primaryObservable - - highLevelStatus - S - totalNumberOfAnalyzerIssues - 0 - totalNumberOfErrors - 0 - totalNumberOfTestFailures - 0 - totalNumberOfWarnings - 0 - - schemeIdentifier-containerName - Runner project - schemeIdentifier-schemeName - Flutter Assemble - schemeIdentifier-sharedScheme - 1 - signature - Cleaning workspace Runner with scheme Flutter Assemble - timeStartedRecording - 752000674.27645695 - timeStoppedRecording - 752000674.42918503 - title - Cleaning workspace Runner with scheme Flutter Assemble - uniqueIdentifier - DEC061F9-9521-4D0C-959C-43A07F62CC12 - - FB42CDDD-C79D-4D4B-891A-12C476DFCB10 - - className - IDECommandLineBuildLog - documentTypeString - <nil> - domainType - Xcode.IDEActivityLogDomainType.BuildLog - fileName - FB42CDDD-C79D-4D4B-891A-12C476DFCB10.xcactivitylog - hasPrimaryLog - - primaryObservable - - highLevelStatus - S - totalNumberOfAnalyzerIssues - 0 - totalNumberOfErrors - 0 - totalNumberOfTestFailures - 0 - totalNumberOfWarnings - 0 - - schemeIdentifier-containerName - Runner project - schemeIdentifier-schemeName - Runner - schemeIdentifier-sharedScheme - 1 - signature - Cleaning workspace Runner with scheme Runner - timeStartedRecording - 752000674.90370798 - timeStoppedRecording - 752000675.05962098 - title - Cleaning workspace Runner with scheme Runner - uniqueIdentifier - FB42CDDD-C79D-4D4B-891A-12C476DFCB10 - - - - diff --git a/macos/DerivedData/Runner/Logs/Build/DEC061F9-9521-4D0C-959C-43A07F62CC12.xcactivitylog b/macos/DerivedData/Runner/Logs/Build/DEC061F9-9521-4D0C-959C-43A07F62CC12.xcactivitylog deleted file mode 100644 index c811e6cbcebca9a7a43e017168389b0481562c19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217 zcmV;~04Dz*iwFP!000006P-`ZO2jZ2e3j55c*&A4Nu#-0Qwu^*>cNvxldrqMCRsMA z%f7u45j@LWhWUY+=V@dBE$3H{!-Gj7%+XCg;{E1VH>Ew?u~z8j)h36#8tHBEpT1nG zHKZ{6_;NYo?l;}Z#;iC;ANS;(P9OO=TO?0gjCdkvUk)VO0|q4Hx|LG3K4%Q?EB?E< zfZ|+qAQz>rlJIt`aS`f|Kq+PIH!2aTsV|v=QB&P - - - - logFormatVersion - 11 - logs - - DEC061F9-9521-4D0C-959C-43A07F62CC12 - - className - IDECommandLineBuildLog - documentTypeString - <nil> - domainType - Xcode.IDEActivityLogDomainType.BuildLog - fileName - DEC061F9-9521-4D0C-959C-43A07F62CC12.xcactivitylog - hasPrimaryLog - - primaryObservable - - highLevelStatus - S - totalNumberOfAnalyzerIssues - 0 - totalNumberOfErrors - 0 - totalNumberOfTestFailures - 0 - totalNumberOfWarnings - 0 - - schemeIdentifier-containerName - Runner project - schemeIdentifier-schemeName - Flutter Assemble - schemeIdentifier-sharedScheme - 1 - signature - Cleaning workspace Runner with scheme Flutter Assemble - timeStartedRecording - 752000674.27645695 - timeStoppedRecording - 752000674.42918503 - title - Cleaning workspace Runner with scheme Flutter Assemble - uniqueIdentifier - DEC061F9-9521-4D0C-959C-43A07F62CC12 - - - - diff --git a/macos/DerivedData/Runner/Logs/Launch/LogStoreManifest.plist b/macos/DerivedData/Runner/Logs/Launch/LogStoreManifest.plist deleted file mode 100644 index f38de442..00000000 --- a/macos/DerivedData/Runner/Logs/Launch/LogStoreManifest.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - logFormatVersion - 11 - logs - - - diff --git a/macos/DerivedData/Runner/Logs/Localization/LogStoreManifest.plist b/macos/DerivedData/Runner/Logs/Localization/LogStoreManifest.plist deleted file mode 100644 index f38de442..00000000 --- a/macos/DerivedData/Runner/Logs/Localization/LogStoreManifest.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - logFormatVersion - 11 - logs - - - diff --git a/macos/DerivedData/Runner/Logs/Package/LogStoreManifest.plist b/macos/DerivedData/Runner/Logs/Package/LogStoreManifest.plist deleted file mode 100644 index f38de442..00000000 --- a/macos/DerivedData/Runner/Logs/Package/LogStoreManifest.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - logFormatVersion - 11 - logs - - - diff --git a/macos/DerivedData/Runner/Logs/Test/LogStoreManifest.plist b/macos/DerivedData/Runner/Logs/Test/LogStoreManifest.plist deleted file mode 100644 index f38de442..00000000 --- a/macos/DerivedData/Runner/Logs/Test/LogStoreManifest.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - logFormatVersion - 11 - logs - - - diff --git a/macos/DerivedData/Runner/info.plist b/macos/DerivedData/Runner/info.plist deleted file mode 100644 index 3594c152..00000000 --- a/macos/DerivedData/Runner/info.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - LastAccessedDate - 2024-10-30T17:04:35Z - WorkspacePath - /Users/akmz/Developer/web/syncrow-web/web/macos/Runner.xcworkspace - - diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig deleted file mode 100644 index 4b81f9b2..00000000 --- a/macos/Flutter/Flutter-Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig deleted file mode 100644 index 5caa9d15..00000000 --- a/macos/Flutter/Flutter-Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index e6f3527d..00000000 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - -import firebase_analytics -import firebase_core -import firebase_crashlytics -import firebase_database -import flutter_secure_storage_macos -import path_provider_foundation -import shared_preferences_foundation -import url_launcher_macos - -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")) - PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) - SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) - UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) -} diff --git a/macos/Podfile b/macos/Podfile deleted file mode 100644 index c795730d..00000000 --- a/macos/Podfile +++ /dev/null @@ -1,43 +0,0 @@ -platform :osx, '10.14' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_macos_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_macos_build_settings(target) - end -end diff --git a/macos/Podfile.lock b/macos/Podfile.lock deleted file mode 100644 index 0639648b..00000000 --- a/macos/Podfile.lock +++ /dev/null @@ -1,36 +0,0 @@ -PODS: - - flutter_secure_storage_macos (6.1.1): - - FlutterMacOS - - FlutterMacOS (1.0.0) - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - - shared_preferences_foundation (0.0.1): - - Flutter - - FlutterMacOS - -DEPENDENCIES: - - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - - FlutterMacOS (from `Flutter/ephemeral`) - - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - -EXTERNAL SOURCES: - flutter_secure_storage_macos: - :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos - FlutterMacOS: - :path: Flutter/ephemeral - path_provider_foundation: - :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin - shared_preferences_foundation: - :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin - -SPEC CHECKSUMS: - flutter_secure_storage_macos: 59459653abe1adb92abbc8ea747d79f8d19866c9 - FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - -PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 - -COCOAPODS: 1.16.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 7bfb45ff..00000000 --- a/macos/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,824 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXAggregateTarget section */ - 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; - buildPhases = ( - 33CC111E2044C6BF0003C045 /* ShellScript */, - ); - dependencies = ( - ); - name = "Flutter Assemble"; - productName = FLX; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 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 */; }; - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC10EC2044A3C60003C045; - remoteInfo = Runner; - }; - 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC111A2044C6BA0003C045; - remoteInfo = FLX; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 33CC110E2044A8840003C045 /* Bundle Framework */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Bundle Framework"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 24D7BEF98D33245EFB9F6A1B /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* syncrow_web.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = syncrow_web.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; - 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; - 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; - 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 5DAF1C60594A51D692304366 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 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 = ""; }; - 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 = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - 996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; - 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 = ""; }; - 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 = ""; }; - E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F244F079A053D959E1C5C362 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 331C80D2294CF70F00263BE5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D0F1F294F673EF0DB5E4CA1 /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EA2044A3C60003C045 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 108157F896CD9F637B06D7C0 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 331C80D6294CF71000263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C80D7294CF71000263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 33BA886A226E78AF003329D5 /* Configs */ = { - isa = PBXGroup; - children = ( - 33E5194F232828860026EE4D /* AppInfo.xcconfig */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, - ); - path = Configs; - sourceTree = ""; - }; - 33CC10E42044A3C60003C045 = { - isa = PBXGroup; - children = ( - 33FAB671232836740065AC1E /* Runner */, - 33CEB47122A05771004F2AC0 /* Flutter */, - 331C80D6294CF71000263BE5 /* RunnerTests */, - 33CC10EE2044A3C60003C045 /* Products */, - D73912EC22F37F3D000D13A0 /* Frameworks */, - 75DCDFECC7757C5159E8F0C5 /* Pods */, - 996A2A515D007C9FED5396A5 /* GoogleService-Info.plist */, - ); - sourceTree = ""; - }; - 33CC10EE2044A3C60003C045 /* Products */ = { - isa = PBXGroup; - children = ( - 33CC10ED2044A3C60003C045 /* syncrow_web.app */, - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 33CC11242044D66E0003C045 /* Resources */ = { - isa = PBXGroup; - children = ( - 33CC10F22044A3C60003C045 /* Assets.xcassets */, - 33CC10F42044A3C60003C045 /* MainMenu.xib */, - 33CC10F72044A3C60003C045 /* Info.plist */, - ); - name = Resources; - path = ..; - sourceTree = ""; - }; - 33CEB47122A05771004F2AC0 /* Flutter */ = { - isa = PBXGroup; - children = ( - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - ); - path = Flutter; - sourceTree = ""; - }; - 33FAB671232836740065AC1E /* Runner */ = { - isa = PBXGroup; - children = ( - 33CC10F02044A3C60003C045 /* AppDelegate.swift */, - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, - 33E51913231747F40026EE4D /* DebugProfile.entitlements */, - 33E51914231749380026EE4D /* Release.entitlements */, - 33CC11242044D66E0003C045 /* Resources */, - 33BA886A226E78AF003329D5 /* Configs */, - ); - path = Runner; - sourceTree = ""; - }; - 75DCDFECC7757C5159E8F0C5 /* Pods */ = { - isa = PBXGroup; - children = ( - 24D7BEF98D33245EFB9F6A1B /* Pods-Runner.debug.xcconfig */, - F244F079A053D959E1C5C362 /* Pods-Runner.release.xcconfig */, - AB949539E0D0A8E2BDAB9ADF /* Pods-Runner.profile.xcconfig */, - 96C46007EE0A4E9E1D6D74CE /* Pods-RunnerTests.debug.xcconfig */, - A604E311B663FBF4B7C54DC5 /* Pods-RunnerTests.release.xcconfig */, - 81F2F315AC5109F6F5D27BE6 /* Pods-RunnerTests.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - D73912EC22F37F3D000D13A0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 5DAF1C60594A51D692304366 /* Pods_Runner.framework */, - E148CBDFFE42BF88E8C34DE0 /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C80D4294CF70F00263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - A1935203066F42991FF0ED43 /* [CP] Check Pods Manifest.lock */, - 331C80D1294CF70F00263BE5 /* Sources */, - 331C80D2294CF70F00263BE5 /* Frameworks */, - 331C80D3294CF70F00263BE5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 331C80DA294CF71000263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 33CC10EC2044A3C60003C045 /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 8ECFD939A4D371A145DBA191 /* [CP] Check Pods Manifest.lock */, - 33CC10E92044A3C60003C045 /* Sources */, - 33CC10EA2044A3C60003C045 /* Frameworks */, - 33CC10EB2044A3C60003C045 /* Resources */, - 33CC110E2044A8840003C045 /* Bundle Framework */, - 3399D490228B24CF009A79C7 /* ShellScript */, - 92D754792F50A5D35F6D5AEE /* [CP] Embed Pods Frameworks */, - 7E188D2155D07A3E9E027C0F /* FlutterFire: "flutterfire upload-crashlytics-symbols" */, - ); - buildRules = ( - ); - dependencies = ( - 33CC11202044C79F0003C045 /* PBXTargetDependency */, - ); - name = Runner; - productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* syncrow_web.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 33CC10E52044A3C60003C045 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1510; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C80D4294CF70F00263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 33CC10EC2044A3C60003C045; - }; - 33CC10EC2044A3C60003C045 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Sandbox = { - enabled = 1; - }; - }; - }; - 33CC111A2044C6BA0003C045 = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 33CC10E42044A3C60003C045; - productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 33CC10EC2044A3C60003C045 /* Runner */, - 331C80D4294CF70F00263BE5 /* RunnerTests */, - 33CC111A2044C6BA0003C045 /* Flutter Assemble */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C80D3294CF70F00263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EB2044A3C60003C045 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, - 2901225E5FAB0C696EE79F77 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3399D490228B24CF009A79C7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; - }; - 33CC111E2044C6BF0003C045 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - Flutter/ephemeral/FlutterInputs.xcfilelist, - ); - inputPaths = ( - Flutter/ephemeral/tripwire, - ); - outputFileListPaths = ( - Flutter/ephemeral/FlutterOutputs.xcfilelist, - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - 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 */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 92D754792F50A5D35F6D5AEE /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - A1935203066F42991FF0ED43 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C80D1294CF70F00263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10E92044A3C60003C045 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC10EC2044A3C60003C045 /* Runner */; - targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; - }; - 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; - targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 33CC10F52044A3C60003C045 /* Base */, - ); - name = MainMenu.xib; - path = Runner; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 331C80DB294CF71000263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 96C46007EE0A4E9E1D6D74CE /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/syncrow_web.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/syncrow_web"; - }; - name = Debug; - }; - 331C80DC294CF71000263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A604E311B663FBF4B7C54DC5 /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/syncrow_web.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/syncrow_web"; - }; - name = Release; - }; - 331C80DD294CF71000263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 81F2F315AC5109F6F5D27BE6 /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/syncrow_web.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/syncrow_web"; - }; - name = Profile; - }; - 338D0CE9231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Profile; - }; - 338D0CEA231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Profile; - }; - 338D0CEB231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Profile; - }; - 33CC10F92044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 33CC10FA2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 33CC10FC2044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 33CC10FD2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 33CC111C2044C6BA0003C045 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 33CC111D2044C6BA0003C045 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C80DB294CF71000263BE5 /* Debug */, - 331C80DC294CF71000263BE5 /* Release */, - 331C80DD294CF71000263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10F92044A3C60003C045 /* Debug */, - 33CC10FA2044A3C60003C045 /* Release */, - 338D0CE9231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10FC2044A3C60003C045 /* Debug */, - 33CC10FD2044A3C60003C045 /* Release */, - 338D0CEA231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC111C2044C6BA0003C045 /* Debug */, - 33CC111D2044C6BA0003C045 /* Release */, - 338D0CEB231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 33CC10E52044A3C60003C045 /* Project object */; -} diff --git a/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index f16dfbdc..00000000 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/macos/Runner.xcworkspace/contents.xcworkspacedata b/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14..00000000 --- a/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift deleted file mode 100644 index d53ef643..00000000 --- a/macos/Runner/AppDelegate.swift +++ /dev/null @@ -1,9 +0,0 @@ -import Cocoa -import FlutterMacOS - -@NSApplicationMain -class AppDelegate: FlutterAppDelegate { - override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true - } -} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a2ec33f1..00000000 --- a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png deleted file mode 100644 index 82b6f9d9a33e198f5747104729e1fcef999772a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102994 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ⅅ8MglG&ER{i5lN315cO?EdHNLrg? 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 z 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 Pe7HEdAEg|=c=LY&YVNkY diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png deleted file mode 100644 index 13b35eba55c6dabc3aac36f33d859266c18fa0d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5680 zcmaiYXH?Tqu=Xz`p-L#B_gI#0we$cm_HcmYFP$?wjD#BaCN4mzC5#`>w9y6=ThxrYZc0WPXprg zYjB`UsV}0=eUtY$(P6YW}npdd;%9pi?zS3k-nqCob zSX_AQEf|=wYT3r?f!*Yt)ar^;l3Sro{z(7deUBPd2~(SzZ-s@0r&~Km2S?8r##9-< z)2UOSVaHqq6}%sA9Ww;V2LG=PnNAh6mA2iWOuV7T_lRDR z&N8-eN=U)-T|;wo^Wv=34wtV0g}sAAe}`Ph@~!|<;z7*K8(qkX0}o=!(+N*UWrkEja*$_H6mhK1u{P!AC39} z|3+Z(mAOq#XRYS)TLoHv<)d%$$I@+x+2)V{@o~~J-!YUI-Q9%!Ldi4Op&Lw&B>jj* zwAgC#Y>gbIqv!d|J5f!$dbCXoq(l3GR(S>(rtZ~Z*agXMMKN!@mWT_vmCbSd3dUUm z4M&+gz?@^#RRGal%G3dDvj7C5QTb@9+!MG+>0dcjtZEB45c+qx*c?)d<%htn1o!#1 zpIGonh>P1LHu3s)fGFF-qS}AXjW|M*2Xjkh7(~r(lN=o#mBD9?jt74=Rz85I4Nfx_ z7Z)q?!};>IUjMNM6ee2Thq7))a>My?iWFxQ&}WvsFP5LP+iGz+QiYek+K1`bZiTV- zHHYng?ct@Uw5!gquJ(tEv1wTrRR7cemI>aSzLI^$PxW`wL_zt@RSfZ1M3c2sbebM* ze0=;sy^!90gL~YKISz*x;*^~hcCoO&CRD)zjT(A2b_uRue=QXFe5|!cf0z1m!iwv5GUnLw9Dr*Ux z)3Lc!J@Ei;&&yxGpf2kn@2wJ2?t6~obUg;?tBiD#uo$SkFIasu+^~h33W~`r82rSa ztyE;ehFjC2hjpJ-e__EH&z?!~>UBb=&%DS>NT)1O3Isn-!SElBV2!~m6v0$vx^a<@ISutdTk1@?;i z<8w#b-%|a#?e5(n@7>M|v<<0Kpg?BiHYMRe!3Z{wYc2hN{2`6(;q`9BtXIhVq6t~KMH~J0~XtUuT06hL8c1BYZWhN zk4F2I;|za*R{ToHH2L?MfRAm5(i1Ijw;f+0&J}pZ=A0;A4M`|10ZskA!a4VibFKn^ zdVH4OlsFV{R}vFlD~aA4xxSCTTMW@Gws4bFWI@xume%smAnuJ0b91QIF?ZV!%VSRJ zO7FmG!swKO{xuH{DYZ^##gGrXsUwYfD0dxXX3>QmD&`mSi;k)YvEQX?UyfIjQeIm! z0ME3gmQ`qRZ;{qYOWt}$-mW*>D~SPZKOgP)T-Sg%d;cw^#$>3A9I(%#vsTRQe%moT zU`geRJ16l>FV^HKX1GG7fR9AT((jaVb~E|0(c-WYQscVl(z?W!rJp`etF$dBXP|EG z=WXbcZ8mI)WBN>3<@%4eD597FD5nlZajwh8(c$lum>yP)F}=(D5g1-WVZRc)(!E3} z-6jy(x$OZOwE=~{EQS(Tp`yV2&t;KBpG*XWX!yG+>tc4aoxbXi7u@O*8WWFOxUjcq z^uV_|*818$+@_{|d~VOP{NcNi+FpJ9)aA2So<7sB%j`$Prje&auIiTBb{oD7q~3g0 z>QNIwcz(V-y{Ona?L&=JaV5`o71nIsWUMA~HOdCs10H+Irew#Kr(2cn>orG2J!jvP zqcVX0OiF}c<)+5&p}a>_Uuv)L_j}nqnJ5a?RPBNi8k$R~zpZ33AA4=xJ@Z($s3pG9 zkURJY5ZI=cZGRt_;`hs$kE@B0FrRx(6K{`i1^*TY;Vn?|IAv9|NrN*KnJqO|8$e1& zb?OgMV&q5|w7PNlHLHF) zB+AK#?EtCgCvwvZ6*u|TDhJcCO+%I^@Td8CR}+nz;OZ*4Dn?mSi97m*CXXc=};!P`B?}X`F-B5v-%ACa8fo0W++j&ztmqK z;&A)cT4ob9&MxpQU41agyMU8jFq~RzXOAsy>}hBQdFVL%aTn~M>5t9go2j$i9=(rZ zADmVj;Qntcr3NIPPTggpUxL_z#5~C!Gk2Rk^3jSiDqsbpOXf^f&|h^jT4|l2ehPat zb$<*B+x^qO8Po2+DAmrQ$Zqc`1%?gp*mDk>ERf6I|42^tjR6>}4`F_Mo^N(~Spjcg z_uY$}zui*PuDJjrpP0Pd+x^5ds3TG#f?57dFL{auS_W8|G*o}gcnsKYjS6*t8VI<) zcjqTzW(Hk*t-Qhq`Xe+x%}sxXRerScbPGv8hlJ;CnU-!Nl=# zR=iTFf9`EItr9iAlAGi}i&~nJ-&+)Y| zMZigh{LXe)uR+4D_Yb+1?I93mHQ5{pId2Fq%DBr7`?ipi;CT!Q&|EO3gH~7g?8>~l zT@%*5BbetH)~%TrAF1!-!=)`FIS{^EVA4WlXYtEy^|@y@yr!C~gX+cp2;|O4x1_Ol z4fPOE^nj(}KPQasY#U{m)}TZt1C5O}vz`A|1J!-D)bR%^+=J-yJsQXDzFiqb+PT0! zIaDWWU(AfOKlSBMS};3xBN*1F2j1-_=%o($ETm8@oR_NvtMDVIv_k zlnNBiHU&h8425{MCa=`vb2YP5KM7**!{1O>5Khzu+5OVGY;V=Vl+24fOE;tMfujoF z0M``}MNnTg3f%Uy6hZi$#g%PUA_-W>uVCYpE*1j>U8cYP6m(>KAVCmbsDf39Lqv0^ zt}V6FWjOU@AbruB7MH2XqtnwiXS2scgjVMH&aF~AIduh#^aT1>*V>-st8%=Kk*{bL zzbQcK(l2~)*A8gvfX=RPsNnjfkRZ@3DZ*ff5rmx{@iYJV+a@&++}ZW+za2fU>&(4y`6wgMpQGG5Ah(9oGcJ^P(H< zvYn5JE$2B`Z7F6ihy>_49!6}(-)oZ(zryIXt=*a$bpIw^k?>RJ2 zQYr>-D#T`2ZWDU$pM89Cl+C<;J!EzHwn(NNnWpYFqDDZ_*FZ{9KQRcSrl5T>dj+eA zi|okW;6)6LR5zebZJtZ%6Gx8^=2d9>_670!8Qm$wd+?zc4RAfV!ZZ$jV0qrv(D`db zm_T*KGCh3CJGb(*X6nXzh!h9@BZ-NO8py|wG8Qv^N*g?kouH4%QkPU~Vizh-D3<@% zGomx%q42B7B}?MVdv1DFb!axQ73AUxqr!yTyFlp%Z1IAgG49usqaEbI_RnbweR;Xs zpJq7GKL_iqi8Md?f>cR?^0CA+Uk(#mTlGdZbuC*$PrdB$+EGiW**=$A3X&^lM^K2s zzwc3LtEs5|ho z2>U(-GL`}eNgL-nv3h7E<*<>C%O^=mmmX0`jQb6$mP7jUKaY4je&dCG{x$`0=_s$+ zSpgn!8f~ya&U@c%{HyrmiW2&Wzc#Sw@+14sCpTWReYpF9EQ|7vF*g|sqG3hx67g}9 zwUj5QP2Q-(KxovRtL|-62_QsHLD4Mu&qS|iDp%!rs(~ah8FcrGb?Uv^Qub5ZT_kn%I^U2rxo1DDpmN@8uejxik`DK2~IDi1d?%~pR7i#KTS zA78XRx<(RYO0_uKnw~vBKi9zX8VnjZEi?vD?YAw}y+)wIjIVg&5(=%rjx3xQ_vGCy z*&$A+bT#9%ZjI;0w(k$|*x{I1c!ECMus|TEA#QE%#&LxfGvijl7Ih!B2 z6((F_gwkV;+oSKrtr&pX&fKo3s3`TG@ye+k3Ov)<#J|p8?vKh@<$YE@YIU1~@7{f+ zydTna#zv?)6&s=1gqH<-piG>E6XW8ZI7&b@-+Yk0Oan_CW!~Q2R{QvMm8_W1IV8<+ zQTyy=(Wf*qcQubRK)$B;QF}Y>V6d_NM#=-ydM?%EPo$Q+jkf}*UrzR?Nsf?~pzIj$ z<$wN;7c!WDZ(G_7N@YgZ``l;_eAd3+;omNjlpfn;0(B7L)^;;1SsI6Le+c^ULe;O@ zl+Z@OOAr4$a;=I~R0w4jO`*PKBp?3K+uJ+Tu8^%i<_~bU!p%so z^sjol^slR`W@jiqn!M~eClIIl+`A5%lGT{z^mRbpv}~AyO%R*jmG_Wrng{B9TwIuS z0!@fsM~!57K1l0%{yy(#no}roy#r!?0wm~HT!vLDfEBs9x#`9yCKgufm0MjVRfZ=f z4*ZRc2Lgr(P+j2zQE_JzYmP0*;trl7{*N341Cq}%^M^VC3gKG-hY zmPT>ECyrhIoFhnMB^qpdbiuI}pk{qPbK^}0?Rf7^{98+95zNq6!RuV_zAe&nDk0;f zez~oXlE5%ve^TmBEt*x_X#fs(-En$jXr-R4sb$b~`nS=iOy|OVrph(U&cVS!IhmZ~ zKIRA9X%Wp1J=vTvHZ~SDe_JXOe9*fa zgEPf;gD^|qE=dl>Qkx3(80#SE7oxXQ(n4qQ#by{uppSKoDbaq`U+fRqk0BwI>IXV3 zD#K%ASkzd7u>@|pA=)Z>rQr@dLH}*r7r0ng zxa^eME+l*s7{5TNu!+bD{Pp@2)v%g6^>yj{XP&mShhg9GszNu4ITW=XCIUp2Xro&1 zg_D=J3r)6hp$8+94?D$Yn2@Kp-3LDsci)<-H!wCeQt$e9Jk)K86hvV^*Nj-Ea*o;G zsuhRw$H{$o>8qByz1V!(yV{p_0X?Kmy%g#1oSmlHsw;FQ%j9S#}ha zm0Nx09@jmOtP8Q+onN^BAgd8QI^(y!n;-APUpo5WVdmp8!`yKTlF>cqn>ag`4;o>i zl!M0G-(S*fm6VjYy}J}0nX7nJ$h`|b&KuW4d&W5IhbR;-)*9Y0(Jj|@j`$xoPQ=Cl diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png deleted file mode 100644 index 0a3f5fa40fb3d1e0710331a48de5d256da3f275d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 520 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 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png deleted file mode 100644 index 2f1632cfddf3d9dade342351e627a0a75609fb46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2218 zcmV;b2vzrqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuE6iGxuRCodHTWf3-RTMruyW6Fu zQYeUM04eX6D5c0FCjKKPrco1(K`<0SL=crI{PC3-^hZU0kQie$gh-5!7z6SH6Q0J% zqot*`H1q{R5fHFYS}dje@;kG=v$L0(yY0?wY2%*c?A&{2?!D*x?m71{of2gv!$5|C z3>qG_BW}7K_yUcT3A5C6QD<+{aq?x;MAUyAiJn#Jv8_zZtQ{P zTRzbL3U9!qVuZzS$xKU10KiW~Bgdcv1-!uAhQxf3a7q+dU6lj?yoO4Lq4TUN4}h{N z*fIM=SS8|C2$(T>w$`t@3Tka!(r!7W`x z-isCVgQD^mG-MJ;XtJuK3V{Vy72GQ83KRWsHU?e*wrhKk=ApIYeDqLi;JI1e zuvv}5^Dc=k7F7?nm3nIw$NVmU-+R>> zyqOR$-2SDpJ}Pt;^RkJytDVXNTsu|mI1`~G7yw`EJR?VkGfNdqK9^^8P`JdtTV&tX4CNcV4 z&N06nZa??Fw1AgQOUSE2AmPE@WO(Fvo`%m`cDgiv(fAeRA%3AGXUbsGw{7Q`cY;1BI#ac3iN$$Hw z0LT0;xc%=q)me?Y*$xI@GRAw?+}>=9D+KTk??-HJ4=A>`V&vKFS75@MKdSF1JTq{S zc1!^8?YA|t+uKigaq!sT;Z!&0F2=k7F0PIU;F$leJLaw2UI6FL^w}OG&!;+b%ya1c z1n+6-inU<0VM-Y_s5iTElq)ThyF?StVcebpGI znw#+zLx2@ah{$_2jn+@}(zJZ{+}_N9BM;z)0yr|gF-4=Iyu@hI*Lk=-A8f#bAzc9f z`Kd6K--x@t04swJVC3JK1cHY-Hq+=|PN-VO;?^_C#;coU6TDP7Bt`;{JTG;!+jj(` zw5cLQ-(Cz-Tlb`A^w7|R56Ce;Wmr0)$KWOUZ6ai0PhzPeHwdl0H(etP zUV`va_i0s-4#DkNM8lUlqI7>YQLf)(lz9Q3Uw`)nc(z3{m5ZE77Ul$V%m)E}3&8L0 z-XaU|eB~Is08eORPk;=<>!1w)Kf}FOVS2l&9~A+@R#koFJ$Czd%Y(ENTV&A~U(IPI z;UY+gf+&6ioZ=roly<0Yst8ck>(M=S?B-ys3mLdM&)ex!hbt+ol|T6CTS+Sc0jv(& z7ijdvFwBq;0a{%3GGwkDKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U z@~$z0V`OVtIbEx5pa|Tct|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-M2 z@O~lQ0OiKQp}o9I;?uxCgYVV?FH|?Riri*U$Zi_`V2eiA>l zdSm6;SEm6#T+SpcE8Ro_f2AwxzI z44hfe^WE3!h@W3RDyA_H440cpmYkv*)6m1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYr - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig deleted file mode 100644 index ec06430f..00000000 --- a/macos/Runner/Configs/AppInfo.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -// Application-level settings for the Runner target. -// -// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the -// future. If not, the values below would default to using the project name when this becomes a -// 'flutter create' template. - -// The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = syncrow_web - -// The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrowWeb - -// The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. diff --git a/macos/Runner/Configs/Debug.xcconfig b/macos/Runner/Configs/Debug.xcconfig deleted file mode 100644 index 36b0fd94..00000000 --- a/macos/Runner/Configs/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Debug.xcconfig" -#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Release.xcconfig b/macos/Runner/Configs/Release.xcconfig deleted file mode 100644 index dff4f495..00000000 --- a/macos/Runner/Configs/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Release.xcconfig" -#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Warnings.xcconfig b/macos/Runner/Configs/Warnings.xcconfig deleted file mode 100644 index 42bcbf47..00000000 --- a/macos/Runner/Configs/Warnings.xcconfig +++ /dev/null @@ -1,13 +0,0 @@ -WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings -GCC_WARN_UNDECLARED_SELECTOR = YES -CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES -CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE -CLANG_WARN__DUPLICATE_METHOD_MATCH = YES -CLANG_WARN_PRAGMA_PACK = YES -CLANG_WARN_STRICT_PROTOTYPES = YES -CLANG_WARN_COMMA = YES -GCC_WARN_STRICT_SELECTOR_MATCH = YES -CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES -CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES -GCC_WARN_SHADOW = YES -CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements deleted file mode 100644 index dddb8a30..00000000 --- a/macos/Runner/DebugProfile.entitlements +++ /dev/null @@ -1,12 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.cs.allow-jit - - com.apple.security.network.server - - - diff --git a/macos/Runner/GoogleService-Info.plist b/macos/Runner/GoogleService-Info.plist deleted file mode 100644 index 9cdebed0..00000000 --- a/macos/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - API_KEY - AIzaSyABnpH6yo2RRjtkp4PlvtK84hKwRm2DhBw - GCM_SENDER_ID - 427332280600 - PLIST_VERSION - 1 - BUNDLE_ID - com.example.syncrowWeb - PROJECT_ID - test2-8a3d2 - STORAGE_BUCKET - test2-8a3d2.firebasestorage.app - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:427332280600:ios:14346b200780dc760c7e6d - DATABASE_URL - https://test2-8a3d2-default-rtdb.firebaseio.com - - \ No newline at end of file diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist deleted file mode 100644 index 4789daa6..00000000 --- a/macos/Runner/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - $(PRODUCT_COPYRIGHT) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift deleted file mode 100644 index 3cc05eb2..00000000 --- a/macos/Runner/MainFlutterWindow.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Cocoa -import FlutterMacOS - -class MainFlutterWindow: NSWindow { - override func awakeFromNib() { - let flutterViewController = FlutterViewController() - let windowFrame = self.frame - self.contentViewController = flutterViewController - self.setFrame(windowFrame, display: true) - - RegisterGeneratedPlugins(registry: flutterViewController) - - super.awakeFromNib() - } -} diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements deleted file mode 100644 index 852fa1a4..00000000 --- a/macos/Runner/Release.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.app-sandbox - - - diff --git a/macos/RunnerTests/RunnerTests.swift b/macos/RunnerTests/RunnerTests.swift deleted file mode 100644 index 5418c9f5..00000000 --- a/macos/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import FlutterMacOS -import Cocoa -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/windows/.gitignore b/windows/.gitignore deleted file mode 100644 index d492d0d9..00000000 --- a/windows/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -flutter/ephemeral/ - -# Visual Studio user-specific files. -*.suo -*.user -*.userosscache -*.sln.docstates - -# Visual Studio build-related files. -x64/ -x86/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt deleted file mode 100644 index 05470a06..00000000 --- a/windows/CMakeLists.txt +++ /dev/null @@ -1,108 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.14) -project(syncrow_web LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "syncrow_web") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(VERSION 3.14...3.25) - -# Define build configuration option. -get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(IS_MULTICONFIG) - set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" - CACHE STRING "" FORCE) -else() - if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") - endif() -endif() -# Define settings for the Profile build mode. -set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") -set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") -set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") - -# Use Unicode for all projects. -add_definitions(-DUNICODE -D_UNICODE) - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") - target_compile_options(${TARGET} PRIVATE /EHsc) - target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") - target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build; see runner/CMakeLists.txt. -add_subdirectory("runner") - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# Support files are copied into place next to the executable, so that it can -# run in place. This is done instead of making a separate bundle (as on Linux) -# so that building and running from within Visual Studio will work. -set(BUILD_BUNDLE_DIR "$") -# Make the "install" step default, as it's required to run. -set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - CONFIGURATIONS Profile;Release - COMPONENT Runtime) diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt deleted file mode 100644 index 903f4899..00000000 --- a/windows/flutter/CMakeLists.txt +++ /dev/null @@ -1,109 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.14) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. -set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") - -# Set fallback configurations for older versions of the flutter tool. -if (NOT DEFINED FLUTTER_TARGET_PLATFORM) - set(FLUTTER_TARGET_PLATFORM "windows-x64") -endif() - -# === Flutter Library === -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "flutter_export.h" - "flutter_windows.h" - "flutter_messenger.h" - "flutter_plugin_registrar.h" - "flutter_texture_registrar.h" -) -list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") -add_dependencies(flutter flutter_assemble) - -# === Wrapper === -list(APPEND CPP_WRAPPER_SOURCES_CORE - "core_implementations.cc" - "standard_codec.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_PLUGIN - "plugin_registrar.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_APP - "flutter_engine.cc" - "flutter_view_controller.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") - -# Wrapper sources needed for a plugin. -add_library(flutter_wrapper_plugin STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} -) -apply_standard_settings(flutter_wrapper_plugin) -set_target_properties(flutter_wrapper_plugin PROPERTIES - POSITION_INDEPENDENT_CODE ON) -set_target_properties(flutter_wrapper_plugin PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) -target_include_directories(flutter_wrapper_plugin PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_plugin flutter_assemble) - -# Wrapper sources needed for the runner. -add_library(flutter_wrapper_app STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_APP} -) -apply_standard_settings(flutter_wrapper_app) -target_link_libraries(flutter_wrapper_app PUBLIC flutter) -target_include_directories(flutter_wrapper_app PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_app flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") -set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} - ${PHONY_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - ${FLUTTER_TARGET_PLATFORM} $ - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 0e0afee0..00000000 --- a/windows/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,20 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include -#include - -void RegisterPlugins(flutter::PluginRegistry* registry) { - FirebaseCorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); - FlutterSecureStorageWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); - UrlLauncherWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("UrlLauncherWindows")); -} diff --git a/windows/flutter/generated_plugin_registrant.h b/windows/flutter/generated_plugin_registrant.h deleted file mode 100644 index dc139d85..00000000 --- a/windows/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake deleted file mode 100644 index 9efea82a..00000000 --- a/windows/flutter/generated_plugins.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - firebase_core - flutter_secure_storage_windows - url_launcher_windows -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt deleted file mode 100644 index 394917c0..00000000 --- a/windows/runner/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(runner LANGUAGES CXX) - -# Define the application target. To change its name, change BINARY_NAME in the -# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer -# work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} WIN32 - "flutter_window.cpp" - "main.cpp" - "utils.cpp" - "win32_window.cpp" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" - "Runner.rc" - "runner.exe.manifest" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add preprocessor definitions for the build version. -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") - -# Disable Windows macros that collide with C++ standard library functions. -target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") - -# Add dependency libraries and include directories. Add any application-specific -# dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc deleted file mode 100644 index fd19641d..00000000 --- a/windows/runner/Runner.rc +++ /dev/null @@ -1,121 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APP_ICON ICON "resources\\app_icon.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) -#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD -#else -#define VERSION_AS_NUMBER 1,0,0,0 -#endif - -#if defined(FLUTTER_VERSION) -#define VERSION_AS_STRING FLUTTER_VERSION -#else -#define VERSION_AS_STRING "1.0.0" -#endif - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_AS_NUMBER - PRODUCTVERSION VERSION_AS_NUMBER - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "com.example" "\0" - VALUE "FileDescription", "syncrow_web" "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "syncrow_web" "\0" - VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "syncrow_web.exe" "\0" - VALUE "ProductName", "syncrow_web" "\0" - VALUE "ProductVersion", VERSION_AS_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp deleted file mode 100644 index 955ee303..00000000 --- a/windows/runner/flutter_window.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "flutter_window.h" - -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow(const flutter::DartProject& project) - : project_(project) {} - -FlutterWindow::~FlutterWindow() {} - -bool FlutterWindow::OnCreate() { - if (!Win32Window::OnCreate()) { - return false; - } - - RECT frame = GetClientArea(); - - // The size here must match the window dimensions to avoid unnecessary surface - // creation / destruction in the startup path. - flutter_controller_ = std::make_unique( - frame.right - frame.left, frame.bottom - frame.top, project_); - // Ensure that basic setup of the controller was successful. - if (!flutter_controller_->engine() || !flutter_controller_->view()) { - return false; - } - RegisterPlugins(flutter_controller_->engine()); - SetChildContent(flutter_controller_->view()->GetNativeWindow()); - - flutter_controller_->engine()->SetNextFrameCallback([&]() { - this->Show(); - }); - - // Flutter can complete the first frame before the "show window" callback is - // registered. The following call ensures a frame is pending to ensure the - // window is shown. It is a no-op if the first frame hasn't completed yet. - flutter_controller_->ForceRedraw(); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_controller_) { - flutter_controller_ = nullptr; - } - - Win32Window::OnDestroy(); -} - -LRESULT -FlutterWindow::MessageHandler(HWND hwnd, UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - // Give Flutter, including plugins, an opportunity to handle window messages. - if (flutter_controller_) { - std::optional result = - flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, - lparam); - if (result) { - return *result; - } - } - - switch (message) { - case WM_FONTCHANGE: - flutter_controller_->engine()->ReloadSystemFonts(); - break; - } - - return Win32Window::MessageHandler(hwnd, message, wparam, lparam); -} diff --git a/windows/runner/flutter_window.h b/windows/runner/flutter_window.h deleted file mode 100644 index 6da0652f..00000000 --- a/windows/runner/flutter_window.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RUNNER_FLUTTER_WINDOW_H_ -#define RUNNER_FLUTTER_WINDOW_H_ - -#include -#include - -#include - -#include "win32_window.h" - -// A window that does nothing but host a Flutter view. -class FlutterWindow : public Win32Window { - public: - // Creates a new FlutterWindow hosting a Flutter view running |project|. - explicit FlutterWindow(const flutter::DartProject& project); - virtual ~FlutterWindow(); - - protected: - // Win32Window: - bool OnCreate() override; - void OnDestroy() override; - LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, - LPARAM const lparam) noexcept override; - - private: - // The project to run. - flutter::DartProject project_; - - // The Flutter instance hosted by this window. - std::unique_ptr flutter_controller_; -}; - -#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp deleted file mode 100644 index 4cb652fd..00000000 --- a/windows/runner/main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "flutter_window.h" -#include "utils.h" - -int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, - _In_ wchar_t *command_line, _In_ int show_command) { - // Attach to console when present (e.g., 'flutter run') or create a - // new console when running with a debugger. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { - CreateAndAttachConsole(); - } - - // Initialize COM, so that it is available for use in the library and/or - // plugins. - ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - - flutter::DartProject project(L"data"); - - std::vector command_line_arguments = - GetCommandLineArguments(); - - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - FlutterWindow window(project); - Win32Window::Point origin(10, 10); - Win32Window::Size size(1280, 720); - if (!window.Create(L"syncrow_web", origin, size)) { - return EXIT_FAILURE; - } - window.SetQuitOnClose(true); - - ::MSG msg; - while (::GetMessage(&msg, nullptr, 0, 0)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - ::CoUninitialize(); - return EXIT_SUCCESS; -} diff --git a/windows/runner/resource.h b/windows/runner/resource.h deleted file mode 100644 index 66a65d1e..00000000 --- a/windows/runner/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Runner.rc -// -#define IDI_APP_ICON 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico deleted file mode 100644 index c04e20caf6370ebb9253ad831cc31de4a9c965f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33772 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 diff --git a/windows/runner/runner.exe.manifest b/windows/runner/runner.exe.manifest deleted file mode 100644 index a42ea768..00000000 --- a/windows/runner/runner.exe.manifest +++ /dev/null @@ -1,20 +0,0 @@ - - - - - PerMonitorV2 - - - - - - - - - - - - - - - diff --git a/windows/runner/utils.cpp b/windows/runner/utils.cpp deleted file mode 100644 index b2b08734..00000000 --- a/windows/runner/utils.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "utils.h" - -#include -#include -#include -#include - -#include - -void CreateAndAttachConsole() { - if (::AllocConsole()) { - FILE *unused; - if (freopen_s(&unused, "CONOUT$", "w", stdout)) { - _dup2(_fileno(stdout), 1); - } - if (freopen_s(&unused, "CONOUT$", "w", stderr)) { - _dup2(_fileno(stdout), 2); - } - std::ios::sync_with_stdio(); - FlutterDesktopResyncOutputStreams(); - } -} - -std::vector GetCommandLineArguments() { - // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. - int argc; - wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - if (argv == nullptr) { - return std::vector(); - } - - std::vector command_line_arguments; - - // Skip the first argument as it's the binary name. - for (int i = 1; i < argc; i++) { - command_line_arguments.push_back(Utf8FromUtf16(argv[i])); - } - - ::LocalFree(argv); - - return command_line_arguments; -} - -std::string Utf8FromUtf16(const wchar_t* utf16_string) { - if (utf16_string == nullptr) { - return std::string(); - } - int target_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr) - -1; // remove the trailing null character - int input_length = (int)wcslen(utf16_string); - std::string utf8_string; - if (target_length <= 0 || target_length > utf8_string.max_size()) { - return utf8_string; - } - utf8_string.resize(target_length); - int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - input_length, utf8_string.data(), target_length, nullptr, nullptr); - if (converted_length == 0) { - return std::string(); - } - return utf8_string; -} diff --git a/windows/runner/utils.h b/windows/runner/utils.h deleted file mode 100644 index 3879d547..00000000 --- a/windows/runner/utils.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RUNNER_UTILS_H_ -#define RUNNER_UTILS_H_ - -#include -#include - -// Creates a console for the process, and redirects stdout and stderr to -// it for both the runner and the Flutter library. -void CreateAndAttachConsole(); - -// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string -// encoded in UTF-8. Returns an empty std::string on failure. -std::string Utf8FromUtf16(const wchar_t* utf16_string); - -// Gets the command line arguments passed in as a std::vector, -// encoded in UTF-8. Returns an empty std::vector on failure. -std::vector GetCommandLineArguments(); - -#endif // RUNNER_UTILS_H_ diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp deleted file mode 100644 index 60608d0f..00000000 --- a/windows/runner/win32_window.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include "win32_window.h" - -#include -#include - -#include "resource.h" - -namespace { - -/// Window attribute that enables dark mode window decorations. -/// -/// Redefined in case the developer's machine has a Windows SDK older than -/// version 10.0.22000.0. -/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute -#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 -#endif - -constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; - -/// Registry key for app theme preference. -/// -/// A value of 0 indicates apps should use dark mode. A non-zero or missing -/// value indicates apps should use light mode. -constexpr const wchar_t kGetPreferredBrightnessRegKey[] = - L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; -constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; - -// The number of Win32Window objects that currently exist. -static int g_active_window_count = 0; - -using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); - -// Scale helper to convert logical scaler values to physical using passed in -// scale factor -int Scale(int source, double scale_factor) { - return static_cast(source * scale_factor); -} - -// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. -// This API is only needed for PerMonitor V1 awareness mode. -void EnableFullDpiSupportIfAvailable(HWND hwnd) { - HMODULE user32_module = LoadLibraryA("User32.dll"); - if (!user32_module) { - return; - } - auto enable_non_client_dpi_scaling = - reinterpret_cast( - GetProcAddress(user32_module, "EnableNonClientDpiScaling")); - if (enable_non_client_dpi_scaling != nullptr) { - enable_non_client_dpi_scaling(hwnd); - } - FreeLibrary(user32_module); -} - -} // namespace - -// Manages the Win32Window's window class registration. -class WindowClassRegistrar { - public: - ~WindowClassRegistrar() = default; - - // Returns the singleton registrar instance. - static WindowClassRegistrar* GetInstance() { - if (!instance_) { - instance_ = new WindowClassRegistrar(); - } - return instance_; - } - - // Returns the name of the window class, registering the class if it hasn't - // previously been registered. - const wchar_t* GetWindowClass(); - - // Unregisters the window class. Should only be called if there are no - // instances of the window. - void UnregisterWindowClass(); - - private: - WindowClassRegistrar() = default; - - static WindowClassRegistrar* instance_; - - bool class_registered_ = false; -}; - -WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; - -const wchar_t* WindowClassRegistrar::GetWindowClass() { - if (!class_registered_) { - WNDCLASS window_class{}; - window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); - window_class.lpszClassName = kWindowClassName; - window_class.style = CS_HREDRAW | CS_VREDRAW; - window_class.cbClsExtra = 0; - window_class.cbWndExtra = 0; - window_class.hInstance = GetModuleHandle(nullptr); - window_class.hIcon = - LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); - window_class.hbrBackground = 0; - window_class.lpszMenuName = nullptr; - window_class.lpfnWndProc = Win32Window::WndProc; - RegisterClass(&window_class); - class_registered_ = true; - } - return kWindowClassName; -} - -void WindowClassRegistrar::UnregisterWindowClass() { - UnregisterClass(kWindowClassName, nullptr); - class_registered_ = false; -} - -Win32Window::Win32Window() { - ++g_active_window_count; -} - -Win32Window::~Win32Window() { - --g_active_window_count; - Destroy(); -} - -bool Win32Window::Create(const std::wstring& title, - const Point& origin, - const Size& size) { - Destroy(); - - const wchar_t* window_class = - WindowClassRegistrar::GetInstance()->GetWindowClass(); - - const POINT target_point = {static_cast(origin.x), - static_cast(origin.y)}; - HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); - UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); - double scale_factor = dpi / 96.0; - - HWND window = CreateWindow( - window_class, title.c_str(), WS_OVERLAPPEDWINDOW, - Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), - Scale(size.width, scale_factor), Scale(size.height, scale_factor), - nullptr, nullptr, GetModuleHandle(nullptr), this); - - if (!window) { - return false; - } - - UpdateTheme(window); - - return OnCreate(); -} - -bool Win32Window::Show() { - return ShowWindow(window_handle_, SW_SHOWNORMAL); -} - -// static -LRESULT CALLBACK Win32Window::WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - if (message == WM_NCCREATE) { - auto window_struct = reinterpret_cast(lparam); - SetWindowLongPtr(window, GWLP_USERDATA, - reinterpret_cast(window_struct->lpCreateParams)); - - auto that = static_cast(window_struct->lpCreateParams); - EnableFullDpiSupportIfAvailable(window); - that->window_handle_ = window; - } else if (Win32Window* that = GetThisFromHandle(window)) { - return that->MessageHandler(window, message, wparam, lparam); - } - - return DefWindowProc(window, message, wparam, lparam); -} - -LRESULT -Win32Window::MessageHandler(HWND hwnd, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - switch (message) { - case WM_DESTROY: - window_handle_ = nullptr; - Destroy(); - if (quit_on_close_) { - PostQuitMessage(0); - } - return 0; - - case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); - LONG newWidth = newRectSize->right - newRectSize->left; - LONG newHeight = newRectSize->bottom - newRectSize->top; - - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - - return 0; - } - case WM_SIZE: { - RECT rect = GetClientArea(); - if (child_content_ != nullptr) { - // Size and position the child window. - MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE); - } - return 0; - } - - case WM_ACTIVATE: - if (child_content_ != nullptr) { - SetFocus(child_content_); - } - return 0; - - case WM_DWMCOLORIZATIONCOLORCHANGED: - UpdateTheme(hwnd); - return 0; - } - - return DefWindowProc(window_handle_, message, wparam, lparam); -} - -void Win32Window::Destroy() { - OnDestroy(); - - if (window_handle_) { - DestroyWindow(window_handle_); - window_handle_ = nullptr; - } - if (g_active_window_count == 0) { - WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); - } -} - -Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( - GetWindowLongPtr(window, GWLP_USERDATA)); -} - -void Win32Window::SetChildContent(HWND content) { - child_content_ = content; - SetParent(content, window_handle_); - RECT frame = GetClientArea(); - - MoveWindow(content, frame.left, frame.top, frame.right - frame.left, - frame.bottom - frame.top, true); - - SetFocus(child_content_); -} - -RECT Win32Window::GetClientArea() { - RECT frame; - GetClientRect(window_handle_, &frame); - return frame; -} - -HWND Win32Window::GetHandle() { - return window_handle_; -} - -void Win32Window::SetQuitOnClose(bool quit_on_close) { - quit_on_close_ = quit_on_close; -} - -bool Win32Window::OnCreate() { - // No-op; provided for subclasses. - return true; -} - -void Win32Window::OnDestroy() { - // No-op; provided for subclasses. -} - -void Win32Window::UpdateTheme(HWND const window) { - DWORD light_mode; - DWORD light_mode_size = sizeof(light_mode); - LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, - kGetPreferredBrightnessRegValue, - RRF_RT_REG_DWORD, nullptr, &light_mode, - &light_mode_size); - - if (result == ERROR_SUCCESS) { - BOOL enable_dark_mode = light_mode == 0; - DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, - &enable_dark_mode, sizeof(enable_dark_mode)); - } -} diff --git a/windows/runner/win32_window.h b/windows/runner/win32_window.h deleted file mode 100644 index e901dde6..00000000 --- a/windows/runner/win32_window.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef RUNNER_WIN32_WINDOW_H_ -#define RUNNER_WIN32_WINDOW_H_ - -#include - -#include -#include -#include - -// A class abstraction for a high DPI-aware Win32 Window. Intended to be -// inherited from by classes that wish to specialize with custom -// rendering and input handling -class Win32Window { - public: - struct Point { - unsigned int x; - unsigned int y; - Point(unsigned int x, unsigned int y) : x(x), y(y) {} - }; - - struct Size { - unsigned int width; - unsigned int height; - Size(unsigned int width, unsigned int height) - : width(width), height(height) {} - }; - - Win32Window(); - virtual ~Win32Window(); - - // Creates a win32 window with |title| that is positioned and sized using - // |origin| and |size|. New windows are created on the default monitor. Window - // sizes are specified to the OS in physical pixels, hence to ensure a - // consistent size this function will scale the inputted width and height as - // as appropriate for the default monitor. The window is invisible until - // |Show| is called. Returns true if the window was created successfully. - bool Create(const std::wstring& title, const Point& origin, const Size& size); - - // Show the current window. Returns true if the window was successfully shown. - bool Show(); - - // Release OS resources associated with window. - void Destroy(); - - // Inserts |content| into the window tree. - void SetChildContent(HWND content); - - // Returns the backing Window handle to enable clients to set icon and other - // window properties. Returns nullptr if the window has been destroyed. - HWND GetHandle(); - - // If true, closing this window will quit the application. - void SetQuitOnClose(bool quit_on_close); - - // Return a RECT representing the bounds of the current client area. - RECT GetClientArea(); - - protected: - // Processes and route salient window messages for mouse handling, - // size change and DPI. Delegates handling of these to member overloads that - // inheriting classes can handle. - virtual LRESULT MessageHandler(HWND window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Called when CreateAndShow is called, allowing subclass window-related - // setup. Subclasses should return false if setup fails. - virtual bool OnCreate(); - - // Called when Destroy is called. - virtual void OnDestroy(); - - private: - friend class WindowClassRegistrar; - - // OS callback called by message pump. Handles the WM_NCCREATE message which - // is passed when the non-client area is being created and enables automatic - // non-client DPI scaling so that the non-client area automatically - // responds to changes in DPI. All other messages are handled by - // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(HWND const window) noexcept; - - // Update the window frame's theme to match the system theme. - static void UpdateTheme(HWND const window); - - bool quit_on_close_ = false; - - // window handle for top level window. - HWND window_handle_ = nullptr; - - // window handle for hosted content. - HWND child_content_ = nullptr; -}; - -#endif // RUNNER_WIN32_WINDOW_H_ From 7109f3712abfd76958671ee088c889f3bb56f2da Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 12 Jun 2025 14:50:50 +0300 Subject: [PATCH 78/82] Update pr-check.yml --- .github/workflows/pr-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 621a54d3..20a629a4 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Flutter uses: subosito/flutter-action@v2 with: - flutter-version: '3.27.3' + flutter-version: '3.32.1' - name: Install dependencies run: flutter pub get From 5203491d15ca2ef67c7a0337277e44da3681fc69 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 12 Jun 2025 14:57:55 +0300 Subject: [PATCH 79/82] upgrade-flutter-version-in-deployment-actions. --- .../workflows/azure-static-web-apps-mango-bush-01e607f10.yml | 2 +- .../workflows/azure-static-web-apps-polite-smoke-017c65c10.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml b/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml index 892381f3..64a77fe1 100644 --- a/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml +++ b/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Flutter uses: subosito/flutter-action@v2 with: - flutter-version: '3.27.3' # Specify the Flutter version you want to use + flutter-version: '3.32.1' # Specify the Flutter version you want to use - name: Install dependencies run: flutter pub get diff --git a/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml b/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml index 6a91fe27..c3a36a5c 100644 --- a/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml +++ b/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Flutter uses: subosito/flutter-action@v2 with: - flutter-version: '3.27.3' # Specify the Flutter version you want to use + flutter-version: '3.32.1' # Specify the Flutter version you want to use - name: Install dependencies run: flutter pub get From fe3b5263a35333ce00eeed1737b75397f013e6b8 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 12 Jun 2025 15:04:21 +0300 Subject: [PATCH 80/82] upgrade to not using webkit renderer command in ci/cd actions because it is deprecated. --- .../workflows/azure-static-web-apps-mango-bush-01e607f10.yml | 2 +- .../workflows/azure-static-web-apps-polite-smoke-017c65c10.yml | 2 +- .github/workflows/pr-check.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml b/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml index 64a77fe1..5f872338 100644 --- a/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml +++ b/.github/workflows/azure-static-web-apps-mango-bush-01e607f10.yml @@ -27,7 +27,7 @@ jobs: run: flutter pub get - name: Build Flutter Web App - run: flutter build web --web-renderer canvaskit -t lib/main.dart + run: flutter build web --release -t lib/main.dart - name: Build And Deploy id: builddeploy diff --git a/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml b/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml index c3a36a5c..0721eeec 100644 --- a/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml +++ b/.github/workflows/azure-static-web-apps-polite-smoke-017c65c10.yml @@ -25,7 +25,7 @@ jobs: run: flutter pub get - name: Build Flutter Web App - run: flutter build web --web-renderer canvaskit -t lib/main_dev.dart + run: flutter build web --release -t lib/main_dev.dart - name: Build And Deploy id: builddeploy diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 20a629a4..f6ef8c91 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -26,4 +26,4 @@ jobs: run: flutter pub get - name: Run Flutter Build - run: flutter build web --web-renderer canvaskit -t lib/main_dev.dart + run: flutter build web --release -t lib/main_dev.dart From 04250ebc98fc0b59b40711d75d0861a6552eed53 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 12 Jun 2025 15:33:32 +0300 Subject: [PATCH 81/82] formatted all files. --- analysis_options.yaml | 5 + lib/common/dialog_dropdown.dart | 22 +- lib/common/edit_chip.dart | 13 +- lib/common/tag_dialog_textfield_dropdown.dart | 6 +- lib/common/widgets/custom_expansion_tile.dart | 3 +- lib/common/widgets/search_bar.dart | 6 +- lib/firebase_options_prod.dart | 3 +- lib/main.dart | 2 +- lib/main_dev.dart | 8 +- lib/main_staging.dart | 8 +- .../access_management/bloc/access_bloc.dart | 56 +- .../access_management/bloc/access_state.dart | 2 +- .../model/password_model.dart | 2 +- .../helpers/dashed_border_painter.dart | 17 +- .../helpers/get_month_name_from_int.dart | 2 +- .../models/air_quality_data_model.dart | 5 +- .../analytics/models/analytics_device.dart | 9 +- lib/pages/analytics/models/occupacy.dart | 3 +- .../models/occupancy_heat_map_model.dart | 3 +- .../air_quality_distribution_bloc.dart | 6 +- .../device_location/device_location_bloc.dart | 3 +- .../blocs/range_of_aqi/range_of_aqi_bloc.dart | 3 +- .../helpers/range_of_aqi_charts_helper.dart | 3 +- .../air_quality/widgets/aqi_device_info.dart | 3 +- .../widgets/aqi_distribution_chart.dart | 23 +- .../widgets/aqi_sub_value_widget.dart | 2 +- .../widgets/aqi_type_dropdown.dart | 3 +- .../widgets/range_of_aqi_chart.dart | 5 +- .../widgets/range_of_aqi_chart_box.dart | 3 +- .../analytics_devices_event.dart | 3 +- .../analytics_tab/analytics_tab_event.dart | 2 +- .../air_quality_data_loading_strategy.dart | 8 +- ...alytics_data_loading_strategy_factory.dart | 3 +- ...ergy_management_data_loading_strategy.dart | 6 +- .../occupancy_data_loading_strategy.dart | 5 +- .../analytics_communities_sidebar.dart | 3 +- .../widgets/analytics_date_filter_button.dart | 2 +- .../widgets/analytics_page_tab_button.dart | 9 +- .../widgets/month_picker_widget.dart | 37 +- .../sidebar/analytics_space_tree_view.dart | 20 +- .../analytics/widgets/year_picker_widget.dart | 13 +- .../energy_consumption_by_phases_bloc.dart | 15 +- .../energy_consumption_by_phases_event.dart | 6 +- .../energy_consumption_per_device_bloc.dart | 12 +- .../power_clamp_info_bloc.dart | 8 +- .../power_clamp_info_event.dart | 3 +- .../realtime_device_changes_event.dart | 2 +- .../total_energy_consumption_bloc.dart | 2 +- .../total_energy_consumption_event.dart | 6 +- .../energy_management_charts_helper.dart | 6 +- .../fetch_energy_management_data_helper.dart | 3 +- .../analytics_energy_management_view.dart | 3 +- .../widgets/analytics_device_dropdown.dart | 3 +- .../energy_consumption_by_phases_chart.dart | 11 +- ...nergy_consumption_by_phases_chart_box.dart | 3 +- .../energy_consumption_per_device_chart.dart | 1 - ...ergy_consumption_per_device_chart_box.dart | 6 +- .../power_clamp_energy_data_widget.dart | 12 +- .../power_clamp_phases_data_widget.dart | 12 +- .../total_energy_consumption_chart.dart | 1 - .../total_energy_consumption_chart_box.dart | 3 +- .../blocs/occupancy/occupancy_bloc.dart | 6 +- .../helpers/fetch_occupancy_data_helper.dart | 12 +- .../views/analytics_occupancy_view.dart | 9 +- .../occupancy/widgets/occupancy_chart.dart | 9 +- .../widgets/occupancy_chart_box.dart | 6 +- .../widgets/occupancy_heat_map_box.dart | 6 +- .../occupancy/widgets/occupancy_painter.dart | 28 +- ...fake_air_quality_distribution_service.dart | 6 +- ...mote_air_quality_distribution_service.dart | 3 +- .../analytics_devices_service_delagate.dart | 3 +- ..._management_analytics_devices_service.dart | 6 +- ...e_occupancy_analytics_devices_service.dart | 18 +- ...ce_location_details_service_decorator.dart | 2 +- ..._energy_consumption_by_phases_service.dart | 6 +- ...energy_consumption_per_device_service.dart | 9 +- .../occupacy/remote_occupancy_service.dart | 3 +- .../remote_occupancy_heat_map_service.dart | 9 +- .../remote_power_clamp_info_service.dart | 3 +- .../fake_range_of_aqi_service.dart | 22 +- .../range_of_aqi/range_of_aqi_service.dart | 2 +- .../realtime_device_service.dart | 2 +- ...mote_total_energy_consumption_service.dart | 6 +- .../widgets/analytics_sidebar_header.dart | 3 +- lib/pages/auth/bloc/auth_bloc.dart | 65 ++- lib/pages/auth/bloc/auth_event.dart | 3 +- lib/pages/auth/bloc/auth_state.dart | 5 +- .../auth/model/login_with_email_model.dart | 4 +- lib/pages/auth/model/token.dart | 18 +- lib/pages/auth/model/user_model.dart | 27 +- .../auth/view/forget_password_web_page.dart | 236 +++++--- lib/pages/auth/view/login_mobile_page.dart | 82 ++- lib/pages/auth/view/login_web_page.dart | 88 +-- lib/pages/common/access_device_table.dart | 96 ++-- lib/pages/common/buttons/cancel_button.dart | 14 +- lib/pages/common/buttons/default_button.dart | 2 +- lib/pages/common/curtain_toggle.dart | 4 +- lib/pages/common/custom_dialog.dart | 12 +- lib/pages/common/custom_table.dart | 23 +- lib/pages/common/filter/filter_widget.dart | 4 +- lib/pages/common/hour_picker_dialog.dart | 12 +- lib/pages/common/info_dialog.dart | 3 +- .../device_managment/ac/bloc/ac_bloc.dart | 38 +- .../device_managment/ac/bloc/ac_event.dart | 7 +- .../device_managment/ac/bloc/ac_state.dart | 3 +- .../device_managment/ac/model/ac_model.dart | 8 +- .../ac/view/ac_device_batch_control.dart | 10 +- .../ac/view/ac_device_control.dart | 2 +- .../batch_current_temp.dart | 63 +- .../ac/view/control_list/ac_toggle.dart | 2 +- .../ac/view/control_list/current_temp.dart | 19 +- .../device_managment_bloc.dart | 35 +- .../helper/route_controls_based_code.dart | 100 +++- .../all_devices/models/device_sub_space.dart | 7 +- .../all_devices/models/devices_model.dart | 48 +- .../models/factory_reset_model.dart | 5 +- .../widgets/device_managment_body.dart | 37 +- .../widgets/device_search_filters.dart | 4 +- .../ceiling_sensor/bloc/ceiling_bloc.dart | 11 +- .../ceiling_sensor/bloc/ceiling_event.dart | 2 - .../model/ceiling_sensor_model.dart | 67 ++- .../view/ceiling_sensor_batch_control.dart | 17 +- .../curtain/bloc/curtain_bloc.dart | 8 +- .../curtain/bloc/curtain_event.dart | 3 +- .../curtain/bloc/curtain_state.dart | 3 +- .../curtain/model/curtain_model.dart | 4 +- .../view/curtain_batch_status_view.dart | 7 +- .../bloc/setting_bloc_bloc.dart | 19 +- .../device_setting/device_settings_panel.dart | 32 +- .../settings_model/sub_space_model.dart | 4 +- .../device_setting/sub_space_dialog.dart | 8 +- .../door_lock/bloc/door_lock_bloc.dart | 12 +- .../door_lock/bloc/door_lock_state.dart | 1 - .../models/door_lock_status_model.dart | 2 +- .../view/door_lock_batch_control_view.dart | 3 +- .../door_lock/widget/door_button.dart | 2 +- .../flush_mounted_presence_sensor_bloc.dart | 18 +- .../flush_mounted_presence_sensor_event.dart | 3 +- .../flush_mounted_presence_sensor_state.dart | 12 +- ..._mounted_presence_sensor_bloc_factory.dart | 6 +- .../flush_mounted_presence_sensor_model.dart | 26 +- ...ed_presence_sensor_batch_control_view.dart | 49 +- ..._mounted_presence_sensor_control_view.dart | 53 +- .../garage_door/bloc/garage_door_bloc.dart | 48 +- .../helper/garage_door_helper.dart | 78 ++- .../garage_door/models/garage_door_model.dart | 4 +- .../view/garage_door_batch_control_view.dart | 8 +- .../opening_clsoing_time_dialog_body.dart | 4 +- .../widgets/schedule__garage_table.dart | 52 +- .../widgets/schedule_garage_managment_ui.dart | 2 +- .../schedule_garage_mode_selector.dart | 3 +- .../garage_door/widgets/seconds_picker.dart | 3 +- .../widgets/time_out_alarm_dialog_body.dart | 2 +- .../gateway/bloc/gate_way_bloc.dart | 9 +- .../gateway/view/gateway_batch_control.dart | 6 +- .../gateway/view/gateway_view.dart | 6 +- .../bloc/main_door_sensor_bloc.dart | 12 +- .../bloc/main_door_sensor_event.dart | 5 +- .../models/main_door_status_model.dart | 6 +- .../view/main_door_control_view.dart | 27 +- .../view/main_door_sensor_batch_view.dart | 3 +- .../widgets/notification_dialog.dart | 2 +- .../bloc/one_gang_glass_switch_bloc.dart | 18 +- .../models/once_gang_glass_status_model.dart | 5 +- .../one_gang_glass_batch_control_view.dart | 14 +- .../one_gang_glass_switch_control_view.dart | 11 +- .../bloc/wall_light_switch_bloc.dart | 14 +- .../models/wall_light_status_model.dart | 2 +- .../view/wall_light_batch_control.dart | 17 +- .../power_clamp/bloc/smart_power_bloc.dart | 86 +-- .../power_clamp/bloc/smart_power_event.dart | 10 +- .../power_clamp/models/device_event.dart | 3 +- .../models/power_clamp_batch_model.dart | 6 +- .../power_clamp/models/power_clamp_model.dart | 3 +- .../power_clamp/view/phase_widget.dart | 48 +- .../power_clamp/view/power_chart.dart | 22 +- .../view/power_clamp_batch_control_view.dart | 12 +- .../power_clamp/view/power_info_card.dart | 4 +- .../view/smart_power_device_control.dart | 9 +- .../shared/device_batch_control_dialog.dart | 39 +- .../shared/device_control_dialog.dart | 8 +- .../shared/device_controls_container.dart | 5 +- .../presence_display_data.dart | 13 +- .../sensors_widgets/presence_space_type.dart | 8 +- .../presence_static_widget.dart | 7 +- .../sensors_widgets/presence_status.dart | 8 +- .../sensors_widgets/presense_nobody_time.dart | 10 +- .../shared/table/report_table.dart | 36 +- .../shared/toggle_widget.dart | 39 +- .../sos/bloc/sos_device_bloc.dart | 35 +- .../sos/models/sos_status_model.dart | 2 +- .../sos/view/sos_device_control_view.dart | 7 +- .../sos/widgets/sos_notification_dialog.dart | 2 +- .../bloc/three_gang_glass_switch_bloc.dart | 15 +- .../models/three_gang_glass_switch.dart | 2 +- ..._gang_glass_switch_batch_control_view.dart | 20 +- .../three_gang_glass_switch_control_view.dart | 18 +- .../bloc/living_room_bloc.dart | 13 +- .../models/living_room_model.dart | 2 +- .../view/living_room_batch_controls.dart | 14 +- .../view/living_room_device_control.dart | 2 +- .../widgets/cieling_light.dart | 11 +- .../three_gang_switch/widgets/spot_light.dart | 11 +- .../three_gang_switch/widgets/wall_light.dart | 11 +- .../bloc/two_gang_glass_switch_bloc.dart | 16 +- .../models/two_gang_glass_status_model.dart | 2 +- ..._gang_glass_switch_batch_control_view.dart | 14 +- .../two_gang_glass_switch_control_view.dart | 5 +- .../bloc/two_gang_switch_bloc.dart | 10 +- .../bloc/two_gang_switch_state.dart | 2 +- .../models/two_gang_status_model.dart | 2 +- .../view/wall_light_batch_control.dart | 11 +- .../wall_sensor/bloc/wall_bloc.dart | 7 +- .../wall_sensor/model/wall_sensor_model.dart | 56 +- .../view/wall_sensor_batch_control.dart | 32 +- .../view/wall_sensor_conrtols.dart | 53 +- .../water_heater/bloc/water_heater_bloc.dart | 58 +- .../water_heater/bloc/water_heater_event.dart | 2 - .../helper/add_schedule_dialog_helper.dart | 43 +- .../water_heater/models/schedule_entry.dart | 8 +- .../water_heater/models/schedule_model.dart | 7 +- .../models/water_heater_status_model.dart | 14 +- .../view/water_heater_batch_control.dart | 3 +- .../view/water_heater_device_control.dart | 3 +- .../widgets/count_down_button.dart | 2 +- .../widgets/inching_mode_buttons.dart | 6 +- .../widgets/schedule_managment_ui.dart | 2 +- .../widgets/schedule_mode_selector.dart | 2 +- .../water_heater/widgets/schedule_table.dart | 7 +- .../water_leak/bloc/water_leak_bloc.dart | 23 +- .../view/water_leak_batch_control_view.dart | 12 +- .../view/water_leak_control_view.dart | 29 +- .../widgets/water_leak_notifi_dialog.dart | 5 +- lib/pages/home/bloc/home_bloc.dart | 16 +- .../view/agreement_and_privacy_dialog.dart | 12 +- lib/pages/home/view/home_page.dart | 2 +- lib/pages/home/view/home_page_mobile.dart | 12 +- lib/pages/home/view/home_page_web.dart | 4 +- lib/pages/home/view/tree_page.dart | 2 +- .../bloc/roles_permission_bloc.dart | 2 +- .../model/role_type_model.dart | 2 +- .../model/roles_user_model.dart | 8 +- .../add_user_dialog/bloc/users_bloc.dart | 107 ++-- .../add_user_dialog/bloc/users_event.dart | 2 +- .../model/permission_option_model.dart | 2 +- .../model/tree_node_model.dart | 2 +- .../add_user_dialog/view/add_user_dialog.dart | 62 +- .../add_user_dialog/view/basics_view.dart | 61 +- .../add_user_dialog/view/build_tree_view.dart | 7 +- .../view/delete_user_dialog.dart | 7 +- .../view/edit_user_dialog.dart | 68 ++- .../view/permission_management.dart | 77 ++- .../view/popup_menu_filter.dart | 17 +- .../add_user_dialog/view/role_dropdown.dart | 6 +- .../view/roles_and_permission.dart | 19 +- .../view/spaces_access_view.dart | 12 +- .../users_table/bloc/user_table_bloc.dart | 92 ++- .../users_table/bloc/user_table_event.dart | 12 +- .../users_table/bloc/user_table_state.dart | 2 + .../view/creation_date_filter.dart | 13 +- .../users_table/view/de_activate_filter.dart | 13 +- .../users_table/view/name_filter.dart | 13 +- .../users_table/view/user_table.dart | 18 +- .../users_table/view/users_page.dart | 223 ++++---- .../view/create_role_card.dart | 1 + .../roles_and_permission/view/role_card.dart | 5 +- .../view/roles_and_permission_page.dart | 9 +- .../roles_and_permission/view/roles_page.dart | 9 +- .../automation_status_update.dart | 17 +- .../create_routine_bloc.dart | 5 +- .../create_routine_event.dart | 3 +- .../create_routine_state.dart | 4 +- .../effective_period/effect_period_bloc.dart | 24 +- .../effective_period/effect_period_state.dart | 9 +- .../bloc/routine_bloc/routine_bloc.dart | 116 ++-- .../bloc/routine_bloc/routine_event.dart | 13 +- .../bloc/setting_bloc/setting_bloc.dart | 19 +- .../create_new_routines/commu_dropdown.dart | 4 +- .../create_new_routines.dart | 12 +- .../dropdown_menu_content.dart | 9 +- .../create_new_routines/space_dropdown.dart | 8 +- .../space_tree_dropdown_bloc.dart | 2 +- .../space_tree_dropdown_event.dart | 2 +- .../space_tree_dropdown_state.dart | 2 +- .../routines/helper/save_routine_helper.dart | 54 +- lib/pages/routines/models/ac/ac_function.dart | 43 +- .../ceiling_presence_sensor_functions.dart | 78 ++- .../create_scene_model.dart | 4 +- .../models/delay/delay_fucntions.dart | 2 +- .../models/flush/flush_functions.dart | 60 +- .../one_gang_switch/one_gang_switch.dart | 6 +- .../three_gang_switch/three_gang_switch.dart | 60 +- .../two_gang_switch/two_gang_switch.dart | 18 +- lib/pages/routines/models/gateway.dart | 15 +- .../models/pc/energy_clamp_functions.dart | 38 +- .../models/routine_details_model.dart | 17 +- lib/pages/routines/models/routine_model.dart | 34 +- .../water_heater/water_heater_functions.dart | 8 +- .../routines/models/wps/wps_functions.dart | 45 +- .../routines/view/effective_period_view.dart | 2 +- lib/pages/routines/view/routines_view.dart | 4 +- .../routines/widgets/condition_toggle.dart | 8 +- .../widgets/custom_routines_textbox.dart | 36 +- lib/pages/routines/widgets/delete_scene.dart | 13 +- lib/pages/routines/widgets/dragable_card.dart | 39 +- .../routines/widgets/function_slider.dart | 7 +- lib/pages/routines/widgets/if_container.dart | 2 +- .../fetch_routine_scenes_automation.dart | 11 +- .../main_routine_view/routine_view_card.dart | 90 +-- lib/pages/routines/widgets/period_option.dart | 20 +- lib/pages/routines/widgets/repeat_days.dart | 15 +- .../routines/widgets/routine_devices.dart | 8 +- .../widgets/routine_dialogs/ac_dialog.dart | 5 +- .../routine_dialogs/automation_dialog.dart | 13 +- .../cps_dialog_value_selector.dart | 3 +- .../ceiling_sensor/cps_functions_list.dart | 2 +- .../ceiling_sensor/cps_slider_helpers.dart | 8 +- .../widgets/routine_dialogs/delay_dialog.dart | 11 +- .../routine_dialogs/discard_dialog.dart | 6 +- .../effictive_period_dialog.dart | 29 +- .../flush_value_selector_widget.dart | 5 +- .../flush_presence_sensor/time_wheel.dart | 4 +- .../gateway_dialog_value_selector.dart | 3 +- .../one_gang_switch_dialog.dart | 7 +- .../enargy_operational_values_list.dart | 2 - .../energy_value_selector_widget.dart | 12 +- .../routine_dialogs/setting_dialog.dart | 236 +++++--- .../three_gang_switch_dialog.dart | 3 +- .../two_gang_switch_dialog.dart | 11 +- .../wall_sensor/time_wheel.dart | 4 +- .../wall_sensor/wall_presence_sensor.dart | 3 +- .../wps_operational_values_list.dart | 6 +- .../water_heater_operational_values_list.dart | 1 - .../water_heater_value_selector_widget.dart | 17 +- .../widgets/routine_search_and_buttons.dart | 140 +++-- .../widgets/scenes_and_automations.dart | 6 +- .../widgets/search_bar_condition_title.dart | 3 +- .../routines/widgets/then_container.dart | 231 ++++---- lib/pages/routines/widgets/value_display.dart | 2 +- .../space_tree/bloc/space_tree_bloc.dart | 141 ++--- .../space_tree/bloc/space_tree_state.dart | 7 +- .../bloc/add_device_model_bloc.dart | 2 +- .../bloc/add_device_type_model_event.dart | 3 +- .../views/add_device_type_widget.dart | 7 +- .../bloc/space_management_bloc.dart | 146 +++-- .../bloc/space_management_event.dart | 4 +- .../bloc/space_management_state.dart | 5 +- .../all_spaces/model/base_tag.dart | 2 +- .../all_spaces/model/community_model.dart | 11 +- .../all_spaces/model/product_model.dart | 3 +- .../model/selected_product_model.dart | 8 +- .../all_spaces/model/space_model.dart | 16 +- .../model/space_response_model.dart | 3 +- .../all_spaces/model/subspace_model.dart | 3 +- .../all_spaces/model/tag.dart | 19 +- .../view/spaces_management_page.dart | 4 +- .../widgets/add_device_type_widget.dart | 30 +- .../widgets/blank_community_widget.dart | 4 +- ...munity_structure_header_action_button.dart | 8 +- .../community_structure_header_widget.dart | 2 +- .../widgets/community_structure_widget.dart | 112 ++-- .../all_spaces/widgets/counter_widget.dart | 17 +- .../devices_part_widget.dart | 141 +++-- .../icon_choose_part_widget.dart | 4 +- .../space_model_linking_widget.dart | 128 ++--- .../space_name_textfield_widget.dart | 2 +- .../sub_space_part_widget.dart | 136 ++--- .../widgets/curved_line_painter.dart | 10 +- .../widgets/dialogs/create_space_dialog.dart | 27 +- .../widgets/dialogs/delete_dialogue.dart | 34 +- .../dialogs/duplicate_process_dialog.dart | 9 +- .../dialogs/icon_selection_dialog.dart | 12 +- .../gradient_canvas_border_widget.dart | 2 +- .../all_spaces/widgets/hoverable_button.dart | 13 +- .../widgets/loaded_space_widget.dart | 78 +-- .../selected_products_button_widget.dart | 8 +- .../all_spaces/widgets/sidebar_widget.dart | 33 +- .../all_spaces/widgets/space_card_widget.dart | 2 +- .../widgets/space_container_widget.dart | 2 +- .../all_spaces/widgets/space_widget.dart | 2 +- .../assign_tag/bloc/assign_tag_bloc.dart | 6 +- .../assign_tag/bloc/assign_tag_event.dart | 2 +- .../assign_tag/bloc/assign_tag_state.dart | 3 +- .../assign_tag/views/assign_tag_dialog.dart | 5 +- .../widgets/save_add_device_row_widget.dart | 9 +- .../bloc/assign_tag_model_bloc.dart | 48 +- .../bloc/assign_tag_model_event.dart | 2 +- .../views/assign_tag_models_dialog.dart | 12 +- .../views/widgets/RowOfCancelSaveWidget.dart | 25 +- .../widgets/assign_tags_tables_widget.dart | 7 +- .../bloc/community_dialog_bloc.dart | 7 +- .../view/create_community_dialog.dart | 12 +- .../create_subspace/bloc/subspace_bloc.dart | 7 +- .../views/create_subspace_model_dialog.dart | 5 +- .../widgets/ok_cancel_sub_space_widget.dart | 9 +- .../textfield_sub_space_dialog_widget.dart | 13 +- .../bloc/subspace_model_bloc.dart | 4 +- .../widgets/subspace_chip.dart | 3 +- .../helper/space_helper.dart | 44 +- .../spaces_management/helper/tag_helper.dart | 58 +- .../bloc/link_space_to_model_bloc.dart | 20 +- .../bloc/link_space_to_model_state.dart | 2 +- .../view/link_space_model_dialog.dart | 13 +- .../bloc/create_space_model_bloc.dart | 78 ++- .../bloc/create_space_model_event.dart | 12 +- .../bloc/create_space_model_state.dart | 4 +- .../space_model/bloc/space_model_bloc.dart | 23 +- .../models/space_template_model.dart | 13 +- .../space_model/view/space_model_page.dart | 21 +- .../widgets/add_space_model_widget.dart | 2 +- .../widgets/button_content_widget.dart | 4 +- .../widgets/dialog/confirm_merge_dialog.dart | 4 +- .../dialog/confirm_overwrite_dialog.dart | 4 +- .../dialog/create_space_model_dialog.dart | 124 ++-- .../widgets/dialog/custom_loading_dialog.dart | 25 +- .../dialog/delete_space_model_dialog.dart | 11 +- .../link_space_model_spaces_dialog.dart | 29 +- .../dialog/linking_attention_dialog.dart | 4 +- .../widgets/dialog/overwrite_dialog.dart | 10 +- .../widgets/dynamic_product_widget.dart | 26 +- .../widgets/dynamic_room_widget.dart | 29 +- .../widgets/ellipsis_item_widget.dart | 4 +- .../widgets/flexible_item_widget.dart | 4 +- .../space_model/widgets/room_name_widget.dart | 2 +- .../widgets/space_model_card_widget.dart | 92 +-- .../widgets/subspace_chip_widget.dart | 4 +- .../widgets/subspace_model_create_widget.dart | 10 +- .../widgets/subspace_name_label_widget.dart | 4 +- .../widgets/tag_chips_display_widget.dart | 3 +- .../bloc/center_body_bloc.dart | 2 +- .../bloc/center_body_event.dart | 2 +- .../view/center_body_widget.dart | 8 +- .../bloc/add_device_type_model_event.dart | 3 +- .../views/add_device_type_model_widget.dart | 22 +- .../widgets/scrollable_grid_view_widget.dart | 13 +- .../bloc/visitor_password_bloc.dart | 79 ++- .../bloc/visitor_password_event.dart | 2 +- .../visitor_password/model/device_model.dart | 4 +- .../model/failed_operation.dart | 5 - .../view/add_device_dialog.dart | 28 +- .../visitor_password/view/repeat_widget.dart | 4 +- .../view/visitor_password_dialog.dart | 537 +++++++++++------- lib/services/access_mang_api.dart | 64 ++- lib/services/api/http_interceptor.dart | 28 +- lib/services/api/http_service.dart | 4 +- lib/services/api/network_exception.dart | 28 +- lib/services/auth_api.dart | 6 +- .../batch_control_devices_service.dart | 3 +- lib/services/devices_mang_api.dart | 18 +- lib/services/locator.dart | 2 +- lib/services/product_api.dart | 4 +- lib/services/routines_api.dart | 31 +- lib/services/space_mana_api.dart | 33 +- lib/services/space_model_mang_api.dart | 6 +- lib/services/user_permission.dart | 69 +-- lib/utils/color_manager.dart | 12 +- lib/utils/constants/api_const.dart | 2 +- lib/utils/constants/app_enum.dart | 38 +- lib/utils/constants/assets.dart | 290 +++++----- lib/utils/constants/strings_manager.dart | 18 +- lib/utils/enum/device_types.dart | 26 +- lib/utils/extension/build_context_x.dart | 103 ++-- lib/utils/format_date_time.dart | 4 +- lib/utils/helpers/decodeBase64.dart | 2 +- .../helpers/shared_preferences_helper.dart | 18 +- lib/utils/navigation_service.dart | 3 - lib/utils/snack_bar.dart | 22 +- lib/utils/style.dart | 14 +- lib/utils/theme/theme.dart | 2 +- lib/utils/user_drop_down_menu.dart | 12 +- lib/web_layout/default_container.dart | 2 +- lib/web_layout/web_app_bar.dart | 13 +- lib/web_layout/web_scaffold.dart | 3 +- test/widget_test.dart | 1 + 474 files changed, 5425 insertions(+), 4338 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 611cf313..cfae8a7e 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -25,3 +25,8 @@ linter: prefer_int_literals: false sort_constructors_first: false avoid_redundant_argument_values: false + always_put_required_named_parameters_first: false + unnecessary_breaks: false + avoid_catches_without_on_clauses: false + cascade_invocations: false + overridden_fields: false diff --git a/lib/common/dialog_dropdown.dart b/lib/common/dialog_dropdown.dart index 7274b3c0..2d1c3f43 100644 --- a/lib/common/dialog_dropdown.dart +++ b/lib/common/dialog_dropdown.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; class DialogDropdown extends StatefulWidget { final List items; @@ -7,14 +8,14 @@ class DialogDropdown extends StatefulWidget { final String? selectedValue; const DialogDropdown({ - Key? key, + super.key, required this.items, required this.onSelected, this.selectedValue, - }) : super(key: key); + }); @override - _DialogDropdownState createState() => _DialogDropdownState(); + State createState() => _DialogDropdownState(); } class _DialogDropdownState extends State { @@ -46,16 +47,14 @@ class _DialogDropdownState extends State { } OverlayEntry _createOverlayEntry() { - final renderBox = context.findRenderObject() as RenderBox; + final renderBox = context.findRenderObject()! as RenderBox; final size = renderBox.size; final offset = renderBox.localToGlobal(Offset.zero); return OverlayEntry( builder: (context) { return GestureDetector( - onTap: () { - _closeDropdown(); - }, + onTap: _closeDropdown, behavior: HitTestBehavior.translucent, child: Stack( children: [ @@ -87,12 +86,9 @@ class _DialogDropdownState extends State { child: ListTile( title: Text( item, - style: Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith( - color: ColorsManager.textPrimaryColor, - ), + style: context.textTheme.bodyMedium?.copyWith( + color: ColorsManager.textPrimaryColor, + ), ), onTap: () { widget.onSelected(item); diff --git a/lib/common/edit_chip.dart b/lib/common/edit_chip.dart index 1643b414..ecda643e 100644 --- a/lib/common/edit_chip.dart +++ b/lib/common/edit_chip.dart @@ -10,24 +10,25 @@ class EditChip extends StatelessWidget { final double borderRadius; const EditChip({ - Key? key, + super.key, this.label = 'Edit', required this.onTap, this.labelColor = ColorsManager.spaceColor, this.backgroundColor = ColorsManager.whiteColors, this.borderColor = ColorsManager.spaceColor, this.borderRadius = 16.0, - }) : super(key: key); + }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Chip( - label: Text( - label, - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: labelColor) - ), + label: Text(label, + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: labelColor)), backgroundColor: backgroundColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(borderRadius), diff --git a/lib/common/tag_dialog_textfield_dropdown.dart b/lib/common/tag_dialog_textfield_dropdown.dart index 9fa85284..45d05614 100644 --- a/lib/common/tag_dialog_textfield_dropdown.dart +++ b/lib/common/tag_dialog_textfield_dropdown.dart @@ -9,12 +9,12 @@ class TagDialogTextfieldDropdown extends StatefulWidget { final String product; const TagDialogTextfieldDropdown({ - Key? key, + super.key, required this.items, required this.onSelected, this.initialValue, required this.product, - }) : super(key: key); + }); @override _DialogTextfieldDropdownState createState() => @@ -79,7 +79,7 @@ class _DialogTextfieldDropdownState extends State { } OverlayEntry _createOverlayEntry() { - final renderBox = context.findRenderObject() as RenderBox; + final renderBox = context.findRenderObject()! as RenderBox; final size = renderBox.size; final offset = renderBox.localToGlobal(Offset.zero); diff --git a/lib/common/widgets/custom_expansion_tile.dart b/lib/common/widgets/custom_expansion_tile.dart index 74151ca2..bbe6a074 100644 --- a/lib/common/widgets/custom_expansion_tile.dart +++ b/lib/common/widgets/custom_expansion_tile.dart @@ -10,7 +10,8 @@ class CustomExpansionTile extends StatefulWidget { final ValueChanged? onExpansionChanged; // Notify when expansion changes final VoidCallback? onItemSelected; // Callback for selecting the item - CustomExpansionTile({ + const CustomExpansionTile({ + super.key, required this.title, this.children, this.initiallyExpanded = false, diff --git a/lib/common/widgets/search_bar.dart b/lib/common/widgets/search_bar.dart index a99ac510..a706f155 100644 --- a/lib/common/widgets/search_bar.dart +++ b/lib/common/widgets/search_bar.dart @@ -7,7 +7,7 @@ class CustomSearchBar extends StatefulWidget { final TextEditingController? controller; final String hintText; final String? searchQuery; - final Function(String)? onSearchChanged; // Callback for search input changes + final void Function(String)? onSearchChanged; const CustomSearchBar({ super.key, @@ -37,7 +37,7 @@ class _CustomSearchBarState extends State { color: ColorsManager.whiteColors, boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.2), + color: Colors.black.withValues(alpha: 0.2), spreadRadius: 0, blurRadius: 8, offset: const Offset(0, 4), @@ -57,7 +57,7 @@ class _CustomSearchBarState extends State { style: const TextStyle( color: Colors.black, ), - onChanged: widget.onSearchChanged, // Call the callback on text change + onChanged: widget.onSearchChanged, decoration: InputDecoration( filled: true, fillColor: ColorsManager.textFieldGreyColor, diff --git a/lib/firebase_options_prod.dart b/lib/firebase_options_prod.dart index 485696b8..0d9ac673 100644 --- a/lib/firebase_options_prod.dart +++ b/lib/firebase_options_prod.dart @@ -1,7 +1,8 @@ // 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; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; /// Default [FirebaseOptions] for use with your Firebase apps. /// diff --git a/lib/main.dart b/lib/main.dart index 8eb6ce38..f875cc04 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -40,7 +40,7 @@ class MyApp extends StatelessWidget { initialLocation: RoutesConst.auth, routes: AppRoutes.getRoutes(), redirect: (context, state) async { - String checkToken = await AuthBloc.getTokenAndValidate(); + final checkToken = await AuthBloc.getTokenAndValidate(); final loggedIn = checkToken == 'Success'; final goingToLogin = state.uri.toString() == RoutesConst.auth; diff --git a/lib/main_dev.dart b/lib/main_dev.dart index 578b2c30..81c71a5f 100644 --- a/lib/main_dev.dart +++ b/lib/main_dev.dart @@ -21,7 +21,8 @@ import 'package:syncrow_web/utils/theme/theme.dart'; Future main() async { try { - const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development'); + const environment = + String.fromEnvironment('FLAVOR', defaultValue: 'development'); await dotenv.load(fileName: '.env.$environment'); WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( @@ -39,7 +40,7 @@ class MyApp extends StatelessWidget { initialLocation: RoutesConst.auth, routes: AppRoutes.getRoutes(), redirect: (context, state) async { - String checkToken = await AuthBloc.getTokenAndValidate(); + final checkToken = await AuthBloc.getTokenAndValidate(); final loggedIn = checkToken == 'Success'; final goingToLogin = state.uri.toString() == RoutesConst.auth; @@ -57,7 +58,8 @@ class MyApp extends StatelessWidget { BlocProvider( create: (context) => CreateRoutineBloc(), ), - BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())), + BlocProvider( + create: (context) => HomeBloc()..add(const FetchUserInfo())), BlocProvider( create: (context) => VisitorPasswordBloc(), ), diff --git a/lib/main_staging.dart b/lib/main_staging.dart index e7f95c57..afccae74 100644 --- a/lib/main_staging.dart +++ b/lib/main_staging.dart @@ -21,7 +21,8 @@ import 'package:syncrow_web/utils/theme/theme.dart'; Future main() async { try { - const environment = String.fromEnvironment('FLAVOR', defaultValue: 'staging'); + const environment = + String.fromEnvironment('FLAVOR', defaultValue: 'staging'); await dotenv.load(fileName: '.env.$environment'); WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( @@ -39,7 +40,7 @@ class MyApp extends StatelessWidget { initialLocation: RoutesConst.auth, routes: AppRoutes.getRoutes(), redirect: (context, state) async { - String checkToken = await AuthBloc.getTokenAndValidate(); + final checkToken = await AuthBloc.getTokenAndValidate(); final loggedIn = checkToken == 'Success'; final goingToLogin = state.uri.toString() == RoutesConst.auth; @@ -57,7 +58,8 @@ class MyApp extends StatelessWidget { BlocProvider( create: (context) => CreateRoutineBloc(), ), - BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())), + BlocProvider( + create: (context) => HomeBloc()..add(const FetchUserInfo())), BlocProvider( create: (context) => VisitorPasswordBloc(), ), diff --git a/lib/pages/access_management/bloc/access_bloc.dart b/lib/pages/access_management/bloc/access_bloc.dart index dd82d739..8b216f04 100644 --- a/lib/pages/access_management/bloc/access_bloc.dart +++ b/lib/pages/access_management/bloc/access_bloc.dart @@ -11,7 +11,7 @@ import 'package:syncrow_web/utils/constants/app_enum.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; class AccessBloc extends Bloc { - AccessBloc() : super((AccessInitial())) { + AccessBloc() : super(AccessInitial()) { on(_onFetchTableData); on(selectTime); on(_filterData); @@ -43,12 +43,12 @@ class AccessBloc extends Bloc { } void updateTabsCount() { - int toBeEffectiveCount = data + final toBeEffectiveCount = data .where((item) => item.passwordStatus.value == 'To be effective') .length; - int effectiveCount = + final effectiveCount = data.where((item) => item.passwordStatus.value == 'Effective').length; - int expiredCount = + final expiredCount = data.where((item) => item.passwordStatus.value == 'Expired').length; tabs[1] = 'To Be Effective ($toBeEffectiveCount)'; tabs[2] = 'Effective ($effectiveCount)'; @@ -81,7 +81,7 @@ class AccessBloc extends Bloc { Emitter emit, ) async { emit(AccessLoaded()); - final DateTime? picked = await showDatePicker( + final picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), firstDate: DateTime.now().add(const Duration(days: -5095)), @@ -89,7 +89,7 @@ class AccessBloc extends Bloc { builder: (BuildContext context, Widget? child) { return Theme( data: ThemeData.light().copyWith( - colorScheme: ColorScheme.light( + colorScheme: const ColorScheme.light( primary: ColorsManager.blackColor, onPrimary: Colors.white, onSurface: ColorsManager.grayColor, @@ -105,20 +105,20 @@ class AccessBloc extends Bloc { }, ); if (picked != null) { - final TimeOfDay? timePicked = await showHourPicker( + final timePicked = await showHourPicker( context: event.context, initialTime: TimeOfDay.now(), ); if (timePicked != null) { - final DateTime selectedDateTime = DateTime( + final selectedDateTime = DateTime( picked.year, picked.month, picked.day, timePicked.hour, timePicked.minute, ); - final int selectedTimestamp = + final selectedTimestamp = selectedDateTime.millisecondsSinceEpoch ~/ 1000; if (event.isStart) { if (expirationTimeTimeStamp != null && @@ -152,39 +152,35 @@ class AccessBloc extends Bloc { final searchText = event.passwordName?.toLowerCase() ?? ''; final searchEmailText = event.emailAuthorizer?.toLowerCase() ?? ''; filteredData = data.where((item) { - bool matchesCriteria = true; + var matchesCriteria = true; // Convert timestamp to DateTime and extract date component - DateTime effectiveDate = DateTime.fromMillisecondsSinceEpoch( + final effectiveDate = DateTime.fromMillisecondsSinceEpoch( int.parse(item.effectiveTime.toString()) * 1000) .toUtc() .toLocal(); - DateTime invalidDate = DateTime.fromMillisecondsSinceEpoch( + final invalidDate = DateTime.fromMillisecondsSinceEpoch( int.parse(item.invalidTime.toString()) * 1000) .toUtc() .toLocal(); - DateTime effectiveDateAndTime = DateTime( + final effectiveDateAndTime = DateTime( effectiveDate.year, effectiveDate.month, effectiveDate.day, effectiveDate.hour, effectiveDate.minute); - DateTime invalidDateAndTime = DateTime( - invalidDate.year, - invalidDate.month, - invalidDate.day, - invalidDate.hour, - invalidDate.minute); + final invalidDateAndTime = DateTime(invalidDate.year, invalidDate.month, + invalidDate.day, invalidDate.hour, invalidDate.minute); // Filter by password name, making the search case-insensitive if (searchText.isNotEmpty) { - final bool matchesName = + final matchesName = item.passwordName.toString().toLowerCase().contains(searchText); if (!matchesName) { matchesCriteria = false; } } if (searchEmailText.isNotEmpty) { - final bool matchesName = item.authorizerEmail + final matchesName = item.authorizerEmail .toString() .toLowerCase() .contains(searchEmailText); @@ -194,7 +190,7 @@ class AccessBloc extends Bloc { } // Filter by start date only if (event.startTime != null && event.endTime == null) { - DateTime startDateTime = + var startDateTime = DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000) .toUtc() .toLocal(); @@ -206,7 +202,7 @@ class AccessBloc extends Bloc { } // Filter by end date only if (event.endTime != null && event.startTime == null) { - DateTime startDateTime = + var startDateTime = DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000) .toUtc() .toLocal(); @@ -219,11 +215,11 @@ class AccessBloc extends Bloc { // Filter by both start date and end date if (event.startTime != null && event.endTime != null) { - DateTime startDateTime = + var startDateTime = DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000) .toUtc() .toLocal(); - DateTime endDateTime = + var endDateTime = DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000) .toUtc() .toLocal(); @@ -258,7 +254,7 @@ class AccessBloc extends Bloc { } } - resetSearch(ResetSearch event, Emitter emit) async { + Future resetSearch(ResetSearch event, Emitter emit) async { emit(AccessLoaded()); startTime = 'Start Time'; endTime = 'End Time'; @@ -272,7 +268,7 @@ class AccessBloc extends Bloc { } String timestampToDate(dynamic timestamp) { - DateTime dateTime = + final dateTime = DateTime.fromMillisecondsSinceEpoch(int.parse(timestamp) * 1000); return "${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')} " " ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}"; @@ -289,17 +285,17 @@ class AccessBloc extends Bloc { break; case 1: // To Be Effective filteredData = data - .where((item) => item.passwordStatus.value == "To Be Effective") + .where((item) => item.passwordStatus.value == 'To Be Effective') .toList(); break; case 2: // Effective filteredData = data - .where((item) => item.passwordStatus.value == "Effective") + .where((item) => item.passwordStatus.value == 'Effective') .toList(); break; case 3: // Expired filteredData = data - .where((item) => item.passwordStatus.value == "Expired") + .where((item) => item.passwordStatus.value == 'Expired') .toList(); break; default: diff --git a/lib/pages/access_management/bloc/access_state.dart b/lib/pages/access_management/bloc/access_state.dart index 0790a735..122e16ad 100644 --- a/lib/pages/access_management/bloc/access_state.dart +++ b/lib/pages/access_management/bloc/access_state.dart @@ -15,7 +15,7 @@ class AccessLoaded extends AccessState {} class FailedState extends AccessState { final String message; - FailedState(this.message); + const FailedState(this.message); @override List get props => [message]; diff --git a/lib/pages/access_management/model/password_model.dart b/lib/pages/access_management/model/password_model.dart index 0ce4426a..ccff1cb8 100644 --- a/lib/pages/access_management/model/password_model.dart +++ b/lib/pages/access_management/model/password_model.dart @@ -36,7 +36,7 @@ class PasswordModel { effectiveTime: json['effectiveTime'], passwordCreated: json['passwordCreated'], createdTime: json['createdTime'], - passwordName: json['passwordName']??'No Name', + passwordName: json['passwordName'] ?? 'No Name', passwordStatus: AccessStatusExtension.fromString(json['passwordStatus']), passwordType: AccessTypeExtension.fromString(json['passwordType']), deviceUuid: json['deviceUuid'], diff --git a/lib/pages/analytics/helpers/dashed_border_painter.dart b/lib/pages/analytics/helpers/dashed_border_painter.dart index 410cadfd..f32741fc 100644 --- a/lib/pages/analytics/helpers/dashed_border_painter.dart +++ b/lib/pages/analytics/helpers/dashed_border_painter.dart @@ -1,5 +1,3 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; class DashedBorderPainter extends CustomPainter { @@ -20,27 +18,28 @@ class DashedBorderPainter extends CustomPainter { ..strokeWidth = 0.5 ..style = PaintingStyle.stroke; - final Path topPath = Path() + final topPath = Path() ..moveTo(0, 0) ..lineTo(size.width, 0); - final Path bottomPath = Path() + final bottomPath = Path() ..moveTo(0, size.height) ..lineTo(size.width, size.height); final dashedTopPath = _createDashedPath(topPath, dashWidth, dashSpace); - final dashedBottomPath = _createDashedPath(bottomPath, dashWidth, dashSpace); + final dashedBottomPath = + _createDashedPath(bottomPath, dashWidth, dashSpace); canvas.drawPath(dashedTopPath, paint); canvas.drawPath(dashedBottomPath, paint); } Path _createDashedPath(Path source, double dashWidth, double dashSpace) { - final Path dashedPath = Path(); - for (PathMetric pathMetric in source.computeMetrics()) { - double distance = 0.0; + final dashedPath = Path(); + for (final pathMetric in source.computeMetrics()) { + var distance = 0.0; while (distance < pathMetric.length) { - final double nextDistance = distance + dashWidth; + final nextDistance = distance + dashWidth; dashedPath.addPath( pathMetric.extractPath(distance, nextDistance), Offset.zero, diff --git a/lib/pages/analytics/helpers/get_month_name_from_int.dart b/lib/pages/analytics/helpers/get_month_name_from_int.dart index 54b0fa87..0ee35a38 100644 --- a/lib/pages/analytics/helpers/get_month_name_from_int.dart +++ b/lib/pages/analytics/helpers/get_month_name_from_int.dart @@ -16,4 +16,4 @@ extension GetMonthNameFromNumber on num { _ => 'N/A' }; } -} \ No newline at end of file +} diff --git a/lib/pages/analytics/models/air_quality_data_model.dart b/lib/pages/analytics/models/air_quality_data_model.dart index 2eab2ddb..95de21c2 100644 --- a/lib/pages/analytics/models/air_quality_data_model.dart +++ b/lib/pages/analytics/models/air_quality_data_model.dart @@ -15,7 +15,8 @@ class AirQualityDataModel extends Equatable { return AirQualityDataModel( date: DateTime.parse(json['date'] as String), data: (json['data'] as List) - .map((e) => AirQualityPercentageData.fromJson(e as Map)) + .map((e) => + AirQualityPercentageData.fromJson(e as Map)) .toList(), ); } @@ -46,7 +47,7 @@ class AirQualityPercentageData extends Equatable { factory AirQualityPercentageData.fromJson(Map json) { return AirQualityPercentageData( - type: json['type'] as String? ?? '', + type: json['type'] as String? ?? '', name: json['name'] as String? ?? '', percentage: (json['percentage'] as num?)?.toDouble() ?? 0, ); diff --git a/lib/pages/analytics/models/analytics_device.dart b/lib/pages/analytics/models/analytics_device.dart index 3340a41d..0a36362a 100644 --- a/lib/pages/analytics/models/analytics_device.dart +++ b/lib/pages/analytics/models/analytics_device.dart @@ -36,11 +36,14 @@ class AnalyticsDevice { deviceTuyaUuid: json['deviceTuyaUuid'] as String?, isActive: json['isActive'] as bool?, productDevice: json['productDevice'] != null - ? ProductDevice.fromJson(json['productDevice'] as Map) + ? ProductDevice.fromJson( + json['productDevice'] as Map) : null, spaceUuid: json['spaceUuid'] as String?, - latitude: json['lat'] != null ? double.parse(json['lat'] as String) : null, - longitude: json['lon'] != null ? double.parse(json['lon'] as String) : null, + latitude: + json['lat'] != null ? double.parse(json['lat'] as String) : null, + longitude: + json['lon'] != null ? double.parse(json['lon'] as String) : null, ); } } diff --git a/lib/pages/analytics/models/occupacy.dart b/lib/pages/analytics/models/occupacy.dart index b4b8dac9..1d158869 100644 --- a/lib/pages/analytics/models/occupacy.dart +++ b/lib/pages/analytics/models/occupacy.dart @@ -15,7 +15,8 @@ class Occupacy extends Equatable { factory Occupacy.fromJson(Map json) { return Occupacy( - date: DateTime.parse(json['event_date'] as String? ?? '${DateTime.now()}'), + date: + DateTime.parse(json['event_date'] as String? ?? '${DateTime.now()}'), occupancy: (json['occupancy_percentage'] ?? 0).toString(), spaceUuid: json['space_uuid'] as String? ?? '', occupiedSeconds: json['occupied_seconds'] as int? ?? 0, diff --git a/lib/pages/analytics/models/occupancy_heat_map_model.dart b/lib/pages/analytics/models/occupancy_heat_map_model.dart index 73e7d5d7..a5fa3ba7 100644 --- a/lib/pages/analytics/models/occupancy_heat_map_model.dart +++ b/lib/pages/analytics/models/occupancy_heat_map_model.dart @@ -19,7 +19,8 @@ class OccupancyHeatMapModel extends Equatable { eventDate: DateTime.parse( json['event_date'] as String? ?? '${DateTime.now()}', ), - countTotalPresenceDetected: json['count_total_presence_detected'] as int? ?? 0, + countTotalPresenceDetected: + json['count_total_presence_detected'] as int? ?? 0, ); } diff --git a/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart index fb7e2352..6d9f1c52 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart @@ -33,7 +33,8 @@ class AirQualityDistributionBloc state.copyWith( status: AirQualityDistributionStatus.success, chartData: result, - filteredChartData: _arrangeChartDataByType(result, state.selectedAqiType), + filteredChartData: + _arrangeChartDataByType(result, state.selectedAqiType), ), ); } catch (e) { @@ -61,7 +62,8 @@ class AirQualityDistributionBloc emit( state.copyWith( selectedAqiType: event.aqiType, - filteredChartData: _arrangeChartDataByType(state.chartData, event.aqiType), + filteredChartData: + _arrangeChartDataByType(state.chartData, event.aqiType), ), ); } diff --git a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart index 4f41eb0c..9bac8120 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart @@ -7,7 +7,8 @@ import 'package:syncrow_web/pages/analytics/services/device_location/device_loca part 'device_location_event.dart'; part 'device_location_state.dart'; -class DeviceLocationBloc extends Bloc { +class DeviceLocationBloc + extends Bloc { DeviceLocationBloc( this._deviceLocationService, ) : super(const DeviceLocationState()) { diff --git a/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart index 88c3715e..cb959051 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart @@ -53,7 +53,8 @@ class RangeOfAqiBloc extends Bloc { emit( state.copyWith( selectedAqiType: event.aqiType, - filteredRangeOfAqi: _arrangeChartDataByType(state.rangeOfAqi, event.aqiType), + filteredRangeOfAqi: + _arrangeChartDataByType(state.rangeOfAqi, event.aqiType), ), ); } diff --git a/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart b/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart index 21cb2a9e..889936c4 100644 --- a/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart +++ b/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart @@ -105,7 +105,8 @@ abstract final class RangeOfAqiChartsHelper { tooltipRoundedRadius: 16, showOnTopOfTheChartBoxArea: false, tooltipPadding: const EdgeInsets.all(8), - getTooltipItems: (touchedSpots) => RangeOfAqiChartsHelper.getTooltipItems( + getTooltipItems: (touchedSpots) => + RangeOfAqiChartsHelper.getTooltipItems( touchedSpots, chartData, ), diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart index ebe88614..634c86ab 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart @@ -81,7 +81,8 @@ class AqiDeviceInfo extends StatelessWidget { aqiLevel: status .firstWhere( (e) => e.code == 'air_quality_index', - orElse: () => Status(code: 'air_quality_index', value: ''), + orElse: () => + Status(code: 'air_quality_index', value: ''), ) .value .toString(), diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart index 373e36ca..36346cb6 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart @@ -36,23 +36,25 @@ class AqiDistributionChart extends StatelessWidget { ); } - List _buildBarGroups(List sortedData) { + List _buildBarGroups( + List sortedData) { return List.generate(sortedData.length, (index) { final data = sortedData[index]; final stackItems = []; double currentY = 0; - bool isFirstElement = true; + var isFirstElement = true; // Sort data by type to ensure consistent order - final sortedPercentageData = List.from(data.data) - ..sort((a, b) => a.type.compareTo(b.type)); + final sortedPercentageData = + List.from(data.data) + ..sort((a, b) => a.type.compareTo(b.type)); for (final percentageData in sortedPercentageData) { stackItems.add( BarChartRodData( fromY: currentY, - toY: currentY + percentageData.percentage , - color: AirQualityDataModel.metricColors[percentageData.name]!, + toY: currentY + percentageData.percentage, + color: AirQualityDataModel.metricColors[percentageData.name], borderRadius: isFirstElement ? const BorderRadius.only( topLeft: Radius.circular(22), @@ -84,9 +86,9 @@ class AqiDistributionChart extends StatelessWidget { tooltipRoundedRadius: 16, tooltipPadding: const EdgeInsets.all(8), getTooltipItem: (group, groupIndex, rod, rodIndex) { - final data = chartData[group.x.toInt()]; + final data = chartData[group.x]; - final List children = []; + final children = []; final textStyle = context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, @@ -94,8 +96,9 @@ class AqiDistributionChart extends StatelessWidget { ); // Sort data by type to ensure consistent order - final sortedPercentageData = List.from(data.data) - ..sort((a, b) => a.type.compareTo(b.type)); + final sortedPercentageData = + List.from(data.data) + ..sort((a, b) => a.type.compareTo(b.type)); for (final percentageData in sortedPercentageData) { children.add(TextSpan( diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart index 5a8e6e6c..6f2eb198 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart @@ -49,7 +49,7 @@ class AqiSubValueWidget extends StatelessWidget { int _getActiveSegmentByRange(double value, (double min, double max) range) { final ranges = _getRangesForValue(range); - for (int i = 0; i < ranges.length; i++) { + for (var i = 0; i < ranges.length; i++) { if (value <= ranges[i].max) return i; } return ranges.length - 1; diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart index 60a686ff..242c5d4b 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart @@ -29,7 +29,8 @@ class AqiTypeDropdown extends StatefulWidget { class _AqiTypeDropdownState extends State { AqiType? _selectedItem = AqiType.aqi; - void _updateSelectedItem(AqiType? item) => setState(() => _selectedItem = item); + void _updateSelectedItem(AqiType? item) => + setState(() => _selectedItem = item); @override Widget build(BuildContext context) { diff --git a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart index fc63e413..a392dc2e 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart @@ -63,7 +63,7 @@ class RangeOfAqiChart extends StatelessWidget { gradient: LinearGradient( begin: Alignment.bottomCenter, end: Alignment.topCenter, - stops: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0], + stops: const [0.0, 0.2, 0.4, 0.6, 0.8, 1.0], colors: RangeOfAqiChartsHelper.gradientData.map((e) { final (color, _) = e; return color.withValues(alpha: 0.6); @@ -99,7 +99,8 @@ class RangeOfAqiChart extends StatelessWidget { }) { const invisibleDot = FlDotData(show: false); return LineChartBarData( - spots: List.generate(values.length, (i) => FlSpot(i.toDouble(), values[i])), + spots: + List.generate(values.length, (i) => FlSpot(i.toDouble(), values[i])), isCurved: true, color: color, barWidth: 4, diff --git a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart index 6548c696..3885ffc2 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart @@ -32,7 +32,8 @@ class RangeOfAqiChartBox extends StatelessWidget { const SizedBox(height: 10), const Divider(), const SizedBox(height: 20), - Expanded(child: RangeOfAqiChart(chartData: state.filteredRangeOfAqi)), + Expanded( + child: RangeOfAqiChart(chartData: state.filteredRangeOfAqi)), ], ), ); diff --git a/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart b/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart index fb61e73b..723df1c3 100644 --- a/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart +++ b/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart @@ -8,7 +8,8 @@ sealed class AnalyticsDevicesEvent extends Equatable { } final class LoadAnalyticsDevicesEvent extends AnalyticsDevicesEvent { - const LoadAnalyticsDevicesEvent({required this.param, required this.onSuccess}); + const LoadAnalyticsDevicesEvent( + {required this.param, required this.onSuccess}); final GetAnalyticsDevicesParam param; final void Function(AnalyticsDevice device) onSuccess; diff --git a/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart b/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart index 0ae7d8c5..20eddb43 100644 --- a/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart +++ b/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart @@ -7,7 +7,7 @@ sealed class AnalyticsTabEvent extends Equatable { List get props => []; } -class UpdateAnalyticsTabEvent extends AnalyticsTabEvent { +class UpdateAnalyticsTabEvent extends AnalyticsTabEvent { const UpdateAnalyticsTabEvent(this.analyticsTab); final AnalyticsPageTab analyticsTab; diff --git a/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart b/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart index 8b1802af..2614ea28 100644 --- a/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart +++ b/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart @@ -8,7 +8,8 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; -final class AirQualityDataLoadingStrategy implements AnalyticsDataLoadingStrategy { +final class AirQualityDataLoadingStrategy + implements AnalyticsDataLoadingStrategy { @override void onCommunitySelected( BuildContext context, @@ -25,7 +26,8 @@ final class AirQualityDataLoadingStrategy implements AnalyticsDataLoadingStrateg SpaceModel space, ) { final spaceTreeBloc = context.read(); - final isSpaceSelected = spaceTreeBloc.state.selectedSpaces.contains(space.uuid); + final isSpaceSelected = + spaceTreeBloc.state.selectedSpaces.contains(space.uuid); final hasSelectedSpaces = spaceTreeBloc.state.selectedSpaces.isNotEmpty; if (hasSelectedSpaces) clearData(context); @@ -34,7 +36,7 @@ final class AirQualityDataLoadingStrategy implements AnalyticsDataLoadingStrateg spaceTreeBloc ..add(const SpaceTreeClearSelectionEvent()) - ..add(OnSpaceSelected(community, space.uuid ?? '', [])); + ..add(OnSpaceSelected(community, space.uuid ?? '', const [])); FetchAirQualityDataHelper.loadAirQualityData( context, diff --git a/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart b/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart index 19b0aff2..f48fd7f2 100644 --- a/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart +++ b/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart @@ -8,7 +8,8 @@ abstract final class AnalyticsDataLoadingStrategyFactory { const AnalyticsDataLoadingStrategyFactory._(); static AnalyticsDataLoadingStrategy getStrategy(AnalyticsPageTab tab) { return switch (tab) { - AnalyticsPageTab.energyManagement => EnergyManagementDataLoadingStrategy(), + AnalyticsPageTab.energyManagement => + EnergyManagementDataLoadingStrategy(), AnalyticsPageTab.occupancy => OccupancyDataLoadingStrategy(), AnalyticsPageTab.airQuality => AirQualityDataLoadingStrategy(), }; diff --git a/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart b/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart index 757b2a9a..14e27515 100644 --- a/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart +++ b/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart @@ -7,7 +7,8 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; -class EnergyManagementDataLoadingStrategy implements AnalyticsDataLoadingStrategy { +class EnergyManagementDataLoadingStrategy + implements AnalyticsDataLoadingStrategy { @override void onCommunitySelected( BuildContext context, @@ -31,7 +32,8 @@ class EnergyManagementDataLoadingStrategy implements AnalyticsDataLoadingStrateg SpaceModel space, ) { final spaceTreeBloc = context.read(); - final isSpaceSelected = spaceTreeBloc.state.selectedSpaces.contains(space.uuid); + final isSpaceSelected = + spaceTreeBloc.state.selectedSpaces.contains(space.uuid); final hasSelectedSpaces = spaceTreeBloc.state.selectedSpaces.isNotEmpty; if (isSpaceSelected) { diff --git a/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart b/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart index 9bffe3b4..e7055b61 100644 --- a/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart +++ b/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart @@ -24,7 +24,8 @@ class OccupancyDataLoadingStrategy implements AnalyticsDataLoadingStrategy { SpaceModel space, ) { final spaceTreeBloc = context.read(); - final isSpaceSelected = spaceTreeBloc.state.selectedSpaces.contains(space.uuid); + final isSpaceSelected = + spaceTreeBloc.state.selectedSpaces.contains(space.uuid); final hasSelectedSpaces = spaceTreeBloc.state.selectedSpaces.isNotEmpty; if (hasSelectedSpaces) clearData(context); @@ -33,7 +34,7 @@ class OccupancyDataLoadingStrategy implements AnalyticsDataLoadingStrategy { spaceTreeBloc ..add(const SpaceTreeClearSelectionEvent()) - ..add(OnSpaceSelected(community, space.uuid ?? '', [])); + ..add(OnSpaceSelected(community, space.uuid ?? '', const [])); FetchOccupancyDataHelper.loadOccupancyData( context, diff --git a/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart b/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart index ab07737a..a8b43943 100644 --- a/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart +++ b/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart @@ -10,7 +10,8 @@ class AnalyticsCommunitiesSidebar extends StatelessWidget { @override Widget build(BuildContext context) { final selectedTab = context.watch().state; - final strategy = AnalyticsDataLoadingStrategyFactory.getStrategy(selectedTab); + final strategy = + AnalyticsDataLoadingStrategyFactory.getStrategy(selectedTab); return Expanded( child: AnalyticsSpaceTreeView( diff --git a/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart b/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart index af70cd86..ab41c7d7 100644 --- a/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart +++ b/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart @@ -20,7 +20,7 @@ class AnalyticsDateFilterButton extends StatefulWidget { final void Function(DateTime)? onDateSelected; final DatePickerType datePickerType; - static final _color = ColorsManager.blackColor.withValues(alpha: 0.8); + static final Color _color = ColorsManager.blackColor.withValues(alpha: 0.8); @override State createState() => diff --git a/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart b/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart index 9ff98ef2..abc688fc 100644 --- a/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart +++ b/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart @@ -21,8 +21,8 @@ class AnalyticsPageTabButton extends StatelessWidget { onPressed: () { AnalyticsDataLoadingStrategyFactory.getStrategy(tab).clearData(context); context.read().add( - UpdateAnalyticsTabEvent(tab), - ); + UpdateAnalyticsTabEvent(tab), + ); }, child: Text( tab.title, @@ -33,8 +33,9 @@ class AnalyticsPageTabButton extends StatelessWidget { style: TextStyle( fontWeight: isSelected ? FontWeight.w700 : FontWeight.w400, fontSize: 16, - color: - isSelected ? ColorsManager.slidingBlueColor : ColorsManager.textGray, + color: isSelected + ? ColorsManager.slidingBlueColor + : ColorsManager.textGray, ), ), ); diff --git a/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart b/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart index 57133b02..41dcd108 100644 --- a/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart +++ b/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart @@ -21,18 +21,18 @@ class _MonthPickerWidgetState extends State { int? _selectedMonth; static const _monthNames = [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', ]; @override @@ -189,14 +189,19 @@ class _MonthPickerWidgetState extends State { final isFutureMonth = isCurrentYear && index > currentDate.month - 1; return InkWell( - onTap: isFutureMonth ? null : () => setState(() => _selectedMonth = index), + onTap: isFutureMonth + ? null + : () => setState(() => _selectedMonth = index), child: DecoratedBox( decoration: BoxDecoration( color: const Color(0xFFEDF2F7), borderRadius: BorderRadius.only( - topLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - bottomLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - topRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, + topLeft: + index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + bottomLeft: + index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + topRight: + index % 3 == 2 ? const Radius.circular(16) : Radius.zero, bottomRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, ), diff --git a/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart b/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart index f900a040..9521ab24 100644 --- a/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart +++ b/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart @@ -53,7 +53,8 @@ class _AnalyticsSpaceTreeViewState extends State { @override Widget build(BuildContext context) { - return BlocBuilder(builder: (context, state) { + return BlocBuilder( + builder: (context, state) { final communities = state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList; @@ -76,9 +77,10 @@ class _AnalyticsSpaceTreeViewState extends State { ), ), CustomSearchBar( - onSearchChanged: (query) => context.read().add( - SearchQueryEvent(query), - ), + onSearchChanged: (query) => + context.read().add( + SearchQueryEvent(query), + ), ), const SizedBox(height: 16), Expanded( @@ -113,7 +115,8 @@ class _AnalyticsSpaceTreeViewState extends State { isExpanded: state.expandedCommunities.contains( communities[index].uuid, ), - onItemSelected: () => widget.onSelectCommunity?.call( + onItemSelected: () => + widget.onSelectCommunity?.call( communities[index], communities[index].spaces, ), @@ -121,8 +124,8 @@ class _AnalyticsSpaceTreeViewState extends State { (space) { return CustomExpansionTileSpaceTree( title: space.name, - isExpanded: - state.expandedSpaces.contains(space.uuid), + isExpanded: state.expandedSpaces + .contains(space.uuid), onItemSelected: () => widget.onSelectSpace?.call( communities[index], @@ -153,7 +156,8 @@ class _AnalyticsSpaceTreeViewState extends State { }, ), ), - if (state.paginationIsLoading) const CircularProgressIndicator(), + if (state.paginationIsLoading) + const CircularProgressIndicator(), ], ), ); diff --git a/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart b/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart index 22eb6646..711d1ccd 100644 --- a/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart +++ b/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart @@ -19,9 +19,9 @@ class YearPickerWidget extends StatefulWidget { class _YearPickerWidgetState extends State { late int _currentYear; - static final years = List.generate( + static final List years = List.generate( DateTime.now().year - (DateTime.now().year - 5) + 1, - (index) => (2020 + index), + (index) => 2020 + index, ).where((year) => year <= DateTime.now().year).toList(); @override @@ -123,9 +123,12 @@ class _YearPickerWidgetState extends State { decoration: BoxDecoration( color: const Color(0xFFEDF2F7), borderRadius: BorderRadius.only( - topLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - bottomLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - topRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, + topLeft: + index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + bottomLeft: + index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + topRight: + index % 3 == 2 ? const Radius.circular(16) : Radius.zero, bottomRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, ), diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart index 1acf7df5..a3f21f44 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart @@ -8,13 +8,15 @@ import 'package:syncrow_web/services/api/api_exception.dart'; part 'energy_consumption_by_phases_event.dart'; part 'energy_consumption_by_phases_state.dart'; -class EnergyConsumptionByPhasesBloc - extends Bloc { +class EnergyConsumptionByPhasesBloc extends Bloc { EnergyConsumptionByPhasesBloc( this._energyConsumptionByPhasesService, ) : super(const EnergyConsumptionByPhasesState()) { - on(_onLoadEnergyConsumptionByPhasesEvent); - on(_onClearEnergyConsumptionByPhasesEvent); + on( + _onLoadEnergyConsumptionByPhasesEvent); + on( + _onClearEnergyConsumptionByPhasesEvent); } final EnergyConsumptionByPhasesService _energyConsumptionByPhasesService; @@ -25,7 +27,8 @@ class EnergyConsumptionByPhasesBloc ) async { emit(state.copyWith(status: EnergyConsumptionByPhasesStatus.loading)); try { - final chartData = await _energyConsumptionByPhasesService.load(event.param); + final chartData = + await _energyConsumptionByPhasesService.load(event.param); emit( state.copyWith( status: EnergyConsumptionByPhasesStatus.loaded, @@ -49,7 +52,7 @@ class EnergyConsumptionByPhasesBloc } } - void _onClearEnergyConsumptionByPhasesEvent( + Future _onClearEnergyConsumptionByPhasesEvent( ClearEnergyConsumptionByPhasesEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart index 87bcf447..0c1248ae 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart @@ -7,7 +7,8 @@ sealed class EnergyConsumptionByPhasesEvent extends Equatable { List get props => []; } -class LoadEnergyConsumptionByPhasesEvent extends EnergyConsumptionByPhasesEvent { +class LoadEnergyConsumptionByPhasesEvent + extends EnergyConsumptionByPhasesEvent { const LoadEnergyConsumptionByPhasesEvent({ required this.param, }); @@ -18,6 +19,7 @@ class LoadEnergyConsumptionByPhasesEvent extends EnergyConsumptionByPhasesEvent List get props => [param]; } -final class ClearEnergyConsumptionByPhasesEvent extends EnergyConsumptionByPhasesEvent { +final class ClearEnergyConsumptionByPhasesEvent + extends EnergyConsumptionByPhasesEvent { const ClearEnergyConsumptionByPhasesEvent(); } diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart index 97d182c5..3f0806a1 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart @@ -8,12 +8,13 @@ import 'package:syncrow_web/services/api/api_exception.dart'; part 'energy_consumption_per_device_event.dart'; part 'energy_consumption_per_device_state.dart'; -class EnergyConsumptionPerDeviceBloc - extends Bloc { +class EnergyConsumptionPerDeviceBloc extends Bloc< + EnergyConsumptionPerDeviceEvent, EnergyConsumptionPerDeviceState> { EnergyConsumptionPerDeviceBloc( this._energyConsumptionPerDeviceService, ) : super(const EnergyConsumptionPerDeviceState()) { - on(_onLoadEnergyConsumptionPerDeviceEvent); + on( + _onLoadEnergyConsumptionPerDeviceEvent); on( _onClearEnergyConsumptionPerDeviceEvent); } @@ -26,7 +27,8 @@ class EnergyConsumptionPerDeviceBloc ) async { emit(state.copyWith(status: EnergyConsumptionPerDeviceStatus.loading)); try { - final chartData = await _energyConsumptionPerDeviceService.load(event.param); + final chartData = + await _energyConsumptionPerDeviceService.load(event.param); emit( state.copyWith( status: EnergyConsumptionPerDeviceStatus.loaded, @@ -50,7 +52,7 @@ class EnergyConsumptionPerDeviceBloc } } - void _onClearEnergyConsumptionPerDeviceEvent( + Future _onClearEnergyConsumptionPerDeviceEvent( ClearEnergyConsumptionPerDeviceEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart index 2aefd798..aa37078b 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart @@ -8,7 +8,8 @@ import 'package:syncrow_web/services/api/api_exception.dart'; part 'power_clamp_info_event.dart'; part 'power_clamp_info_state.dart'; -class PowerClampInfoBloc extends Bloc { +class PowerClampInfoBloc + extends Bloc { PowerClampInfoBloc( this._powerClampInfoService, ) : super(const PowerClampInfoState()) { @@ -25,7 +26,8 @@ class PowerClampInfoBloc extends Bloc ) async { emit(state.copyWith(status: PowerClampInfoStatus.loading)); try { - final powerClampModel = await _powerClampInfoService.getInfo(event.deviceId); + final powerClampModel = + await _powerClampInfoService.getInfo(event.deviceId); emit( state.copyWith( status: PowerClampInfoStatus.loaded, @@ -49,7 +51,7 @@ class PowerClampInfoBloc extends Bloc } } - void _onUpdatePowerClampStatusEvent( + Future _onUpdatePowerClampStatusEvent( UpdatePowerClampStatusEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart index b69a2556..dc20f6f7 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart @@ -16,7 +16,6 @@ final class LoadPowerClampInfoEvent extends PowerClampInfoEvent { List get props => [deviceId]; } - final class UpdatePowerClampStatusEvent extends PowerClampInfoEvent { const UpdatePowerClampStatusEvent(this.statusList); @@ -28,4 +27,4 @@ final class UpdatePowerClampStatusEvent extends PowerClampInfoEvent { final class ClearPowerClampInfoEvent extends PowerClampInfoEvent { const ClearPowerClampInfoEvent(); -} \ No newline at end of file +} diff --git a/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart b/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart index 1eba8f7e..c56588b8 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart @@ -24,4 +24,4 @@ class _RealtimeDeviceChangesUpdated extends RealtimeDeviceChangesEvent { final List deviceStatusList; const _RealtimeDeviceChangesUpdated(this.deviceStatusList); -} \ No newline at end of file +} diff --git a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart index f51d20cf..578899f9 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart @@ -49,7 +49,7 @@ class TotalEnergyConsumptionBloc } } - void _onClearTotalEnergyConsumptionEvent( + Future _onClearTotalEnergyConsumptionEvent( ClearTotalEnergyConsumptionEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart index f9510737..7240b669 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart @@ -7,7 +7,8 @@ sealed class TotalEnergyConsumptionEvent extends Equatable { List get props => []; } -final class TotalEnergyConsumptionLoadEvent extends TotalEnergyConsumptionEvent { +final class TotalEnergyConsumptionLoadEvent + extends TotalEnergyConsumptionEvent { const TotalEnergyConsumptionLoadEvent({required this.param}); final GetTotalEnergyConsumptionParam param; @@ -16,6 +17,7 @@ final class TotalEnergyConsumptionLoadEvent extends TotalEnergyConsumptionEvent List get props => [param]; } -final class ClearTotalEnergyConsumptionEvent extends TotalEnergyConsumptionEvent { +final class ClearTotalEnergyConsumptionEvent + extends TotalEnergyConsumptionEvent { const ClearTotalEnergyConsumptionEvent(); } diff --git a/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart b/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart index 2ed68e76..6de1e278 100644 --- a/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart +++ b/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart @@ -69,7 +69,8 @@ abstract final class EnergyManagementChartsHelper { return labels.where((element) => element.isNotEmpty).join(', '); } - static List getTooltipItems(List touchedSpots) { + static List getTooltipItems( + List touchedSpots) { return touchedSpots.map((spot) { return LineTooltipItem( getToolTipLabel(spot.x, spot.y), @@ -85,7 +86,8 @@ abstract final class EnergyManagementChartsHelper { static LineTouchTooltipData lineTouchTooltipData() { return LineTouchTooltipData( getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors, - tooltipBorder: const BorderSide(color: ColorsManager.semiTransparentBlack), + tooltipBorder: + const BorderSide(color: ColorsManager.semiTransparentBlack), tooltipRoundedRadius: 16, showOnTopOfTheChartBoxArea: false, tooltipPadding: const EdgeInsets.all(8), diff --git a/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart b/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart index 8de92098..f2796671 100644 --- a/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart +++ b/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart @@ -122,7 +122,8 @@ abstract final class FetchEnergyManagementDataHelper { final selectedDevice = getSelectedDevice(context); context.read().add( - RealtimeDeviceChangesStarted(deviceUuid ?? selectedDevice?.uuid ?? ''), + RealtimeDeviceChangesStarted( + deviceUuid ?? selectedDevice?.uuid ?? ''), ); } diff --git a/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart b/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart index f88febcc..797821a4 100644 --- a/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart +++ b/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart @@ -51,7 +51,8 @@ class AnalyticsEnergyManagementView extends StatelessWidget { spacing: 20, children: [ Expanded(child: TotalEnergyConsumptionChartBox()), - Expanded(child: EnergyConsumptionPerDeviceChartBox()), + Expanded( + child: EnergyConsumptionPerDeviceChartBox()), ], ), ), diff --git a/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart b/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart index f7b33309..5d7f37a9 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart @@ -52,7 +52,8 @@ class AnalyticsDeviceDropdown extends StatelessWidget { ); } - Widget _buildDevicesDropdown(BuildContext context, AnalyticsDevicesState state) { + Widget _buildDevicesDropdown( + BuildContext context, AnalyticsDevicesState state) { final spaceUuid = state.selectedDevice?.spaceUuid; return DropdownButton( value: state.selectedDevice, diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart index 52c6f591..e169d660 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart @@ -18,7 +18,6 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { Widget build(BuildContext context) { return BarChart( BarChartData( - gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, horizontalInterval: 250, @@ -100,11 +99,11 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { }) { final data = energyData; - final date = DateFormat('dd/MM/yyyy').format(data[group.x.toInt()].date); - final phaseA = data[group.x.toInt()].energyConsumedA; - final phaseB = data[group.x.toInt()].energyConsumedB; - final phaseC = data[group.x.toInt()].energyConsumedC; - final total = data[group.x.toInt()].energyConsumedKw; + final date = DateFormat('dd/MM/yyyy').format(data[group.x].date); + final phaseA = data[group.x].energyConsumedA; + final phaseB = data[group.x].energyConsumedB; + final phaseC = data[group.x].energyConsumedC; + final total = data[group.x].energyConsumedKw; return BarTooltipItem( '$date\n', diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart index 1bd1ed9e..0c4e972d 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart @@ -22,7 +22,8 @@ class EnergyConsumptionByPhasesChartBox extends StatelessWidget { children: [ AnalyticsErrorWidget(state.errorMessage), EnergyConsumptionByPhasesTitle( - isLoading: state.status == EnergyConsumptionByPhasesStatus.loading, + isLoading: + state.status == EnergyConsumptionByPhasesStatus.loading, ), const SizedBox(height: 20), Expanded( diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart index 1e74ad31..4bed5682 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart @@ -17,7 +17,6 @@ class EnergyConsumptionPerDeviceChart extends StatelessWidget { context, leftTitlesInterval: 250, ), - gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, horizontalInterval: 250, diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart index be5faf57..5fd6b8d6 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart @@ -46,7 +46,8 @@ class EnergyConsumptionPerDeviceChartBox extends StatelessWidget { flex: 2, child: EnergyConsumptionPerDeviceDevicesList( chartData: state.chartData, - devices: context.watch().state.devices, + devices: + context.watch().state.devices, ), ), ], @@ -55,7 +56,8 @@ class EnergyConsumptionPerDeviceChartBox extends StatelessWidget { const Divider(height: 0), const SizedBox(height: 20), Expanded( - child: EnergyConsumptionPerDeviceChart(chartData: state.chartData), + child: + EnergyConsumptionPerDeviceChart(chartData: state.chartData), ), ], ), diff --git a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart index f95ff7d1..3feda916 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart @@ -43,11 +43,14 @@ class PowerClampEnergyDataWidget extends StatelessWidget { title: 'Smart Power Clamp', showSpaceUuidInDevicesDropdown: true, onChanged: (device) { - FetchEnergyManagementDataHelper.loadEnergyConsumptionByPhases( + FetchEnergyManagementDataHelper + .loadEnergyConsumptionByPhases( context, powerClampUuid: device.uuid, - selectedDate: - context.read().state.monthlyDate, + selectedDate: context + .read() + .state + .monthlyDate, ); }, ), @@ -91,7 +94,8 @@ class PowerClampEnergyDataWidget extends StatelessWidget { ), ), const SizedBox(height: 14), - const Expanded(flex: 3, child: EnergyConsumptionByPhasesChartBox()), + const Expanded( + flex: 3, child: EnergyConsumptionByPhasesChartBox()), ], ), ); diff --git a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart index a96a7298..e1cc4238 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart @@ -140,9 +140,9 @@ class PowerClampPhasesDataWidget extends StatelessWidget { String _formatCurrentValue(String? value) { if (value == null) return '--'; - String str = value; + var str = value; if (str.isEmpty || str == '--') return '--'; - str = str.replaceAll(RegExp(r'[^0-9]'), ''); + str = str.replaceAll(RegExp('[^0-9]'), ''); if (str.isEmpty) return '--'; if (str.length == 1) return '${str[0]}.0'; return '${str[0]}.${str.substring(1)}'; @@ -150,9 +150,9 @@ class PowerClampPhasesDataWidget extends StatelessWidget { String _formatPowerFactor(String? value) { if (value == null) return '--'; - String str = value; + var str = value; if (str.isEmpty || str == '--') return '--'; - str = str.replaceAll(RegExp(r'[^0-9]'), ''); + str = str.replaceAll(RegExp('[^0-9]'), ''); if (str.isEmpty) return '--'; final intValue = int.tryParse(str); if (intValue == null) return '--'; @@ -162,9 +162,9 @@ class PowerClampPhasesDataWidget extends StatelessWidget { String _formatVoltage(String? value) { if (value == null) return '--'; - String str = value; + var str = value; if (str.isEmpty || str == '--') return '--'; - str = str.replaceAll(RegExp(r'[^0-9]'), ''); + str = str.replaceAll(RegExp('[^0-9]'), ''); if (str.isEmpty) return '--'; if (str.length == 1) return '0.${str[0]}'; return '${str.substring(0, str.length - 1)}.${str.substring(str.length - 1)}'; diff --git a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart index 85b95c29..9ce6295b 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart @@ -29,7 +29,6 @@ class TotalEnergyConsumptionChart extends StatelessWidget { ), duration: Duration.zero, curve: Curves.easeIn, - ), ); } diff --git a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart index e197c297..7596c7d0 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart @@ -25,7 +25,8 @@ class TotalEnergyConsumptionChartBox extends StatelessWidget { Row( children: [ ChartsLoadingWidget( - isLoading: state.status == TotalEnergyConsumptionStatus.loading, + isLoading: + state.status == TotalEnergyConsumptionStatus.loading, ), const Expanded( flex: 3, diff --git a/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart b/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart index 110f3c60..c6966c7e 100644 --- a/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart +++ b/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart @@ -23,9 +23,11 @@ class OccupancyBloc extends Bloc { emit(state.copyWith(status: OccupancyStatus.loading)); try { final chartData = await _occupacyService.load(event.param); - emit(state.copyWith(chartData: chartData, status: OccupancyStatus.loaded)); + emit( + state.copyWith(chartData: chartData, status: OccupancyStatus.loaded)); } on APIException catch (e) { - emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: e.message)); + emit(state.copyWith( + status: OccupancyStatus.failure, errorMessage: e.message)); } catch (e) { emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: '$e')); } diff --git a/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart b/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart index 0b01fda2..a56c0c9f 100644 --- a/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart +++ b/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart @@ -25,15 +25,18 @@ abstract final class FetchOccupancyDataHelper { final datePickerState = context.read().state; - loadAnalyticsDevices(context, communityUuid: communityId, spaceUuid: spaceId); - final selectedDevice = context.read().state.selectedDevice; + loadAnalyticsDevices(context, + communityUuid: communityId, spaceUuid: spaceId); + final selectedDevice = + context.read().state.selectedDevice; loadOccupancyChartData( context, spaceUuid: spaceId, date: datePickerState.monthlyDate, ); - loadHeatMapData(context, spaceUuid: spaceId, year: datePickerState.yearlyDate); + loadHeatMapData(context, + spaceUuid: spaceId, year: datePickerState.yearlyDate); if (selectedDevice case final AnalyticsDevice device) { context.read() @@ -64,7 +67,8 @@ abstract final class FetchOccupancyDataHelper { context.read().add( LoadOccupancyEvent( GetOccupancyParam( - monthDate: '${date.year}-${date.month.toString().padLeft(2, '0')}', + monthDate: + '${date.year}-${date.month.toString().padLeft(2, '0')}', spaceUuid: spaceUuid, ), ), diff --git a/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart b/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart index 679c9927..7db4f90c 100644 --- a/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart +++ b/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart @@ -20,9 +20,12 @@ class AnalyticsOccupancyView extends StatelessWidget { child: Column( spacing: 32, children: [ - SizedBox(height: height * 0.46, child: const OccupancyEndSideBar()), - SizedBox(height: height * 0.5, child: const OccupancyChartBox()), - SizedBox(height: height * 0.5, child: const OccupancyHeatMapBox()), + SizedBox( + height: height * 0.46, child: const OccupancyEndSideBar()), + SizedBox( + height: height * 0.5, child: const OccupancyChartBox()), + SizedBox( + height: height * 0.5, child: const OccupancyHeatMapBox()), ], ), ); diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart index 70087c46..d328b972 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart @@ -41,7 +41,8 @@ class OccupancyChart extends StatelessWidget { barRods: [ BarChartRodData( toY: 100.0, - fromY: occupancyValue == 0 ? occupancyValue : occupancyValue + 2.5, + fromY: + occupancyValue == 0 ? occupancyValue : occupancyValue + 2.5, color: ColorsManager.graysColor, width: _chartWidth, borderRadius: BorderRadius.circular(10), @@ -88,8 +89,8 @@ class OccupancyChart extends StatelessWidget { }) { final data = chartData; - final occupancyValue = double.parse(data[group.x.toInt()].occupancy); - final percentage = '${(occupancyValue).toStringAsFixed(0)}%'; + final occupancyValue = double.parse(data[group.x].occupancy); + final percentage = '${occupancyValue.toStringAsFixed(0)}%'; return BarTooltipItem( percentage, @@ -116,7 +117,7 @@ class OccupancyChart extends StatelessWidget { alignment: AlignmentDirectional.centerStart, fit: BoxFit.scaleDown, child: Text( - '${(value).toStringAsFixed(0)}%', + '${value.toStringAsFixed(0)}%', style: context.textTheme.bodySmall?.copyWith( fontSize: 12, color: ColorsManager.greyColor, diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart index 08f7223f..a950593d 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart @@ -44,13 +44,15 @@ class OccupancyChartBox extends StatelessWidget { child: AnalyticsDateFilterButton( onDateSelected: (DateTime value) { context.read().add( - UpdateAnalyticsDatePickerEvent(montlyDate: value), + UpdateAnalyticsDatePickerEvent( + montlyDate: value), ); if (spaceTreeState.selectedSpaces.isNotEmpty) { FetchOccupancyDataHelper.loadOccupancyChartData( context, spaceUuid: - spaceTreeState.selectedSpaces.firstOrNull ?? '', + spaceTreeState.selectedSpaces.firstOrNull ?? + '', date: value, ); } diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart index c3b537e0..846b9d30 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart @@ -44,13 +44,15 @@ class OccupancyHeatMapBox extends StatelessWidget { child: AnalyticsDateFilterButton( onDateSelected: (DateTime value) { context.read().add( - UpdateAnalyticsDatePickerEvent(yearlyDate: value), + UpdateAnalyticsDatePickerEvent( + yearlyDate: value), ); if (spaceTreeState.selectedSpaces.isNotEmpty) { FetchOccupancyDataHelper.loadHeatMapData( context, spaceUuid: - spaceTreeState.selectedSpaces.firstOrNull ?? '', + spaceTreeState.selectedSpaces.firstOrNull ?? + '', year: value, ); } diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart index 633b8c54..b57a73e1 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart @@ -28,11 +28,11 @@ class OccupancyPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final Paint fillPaint = Paint(); - final Paint borderPaint = Paint() + final fillPaint = Paint(); + final borderPaint = Paint() ..color = ColorsManager.grayBorder.withValues(alpha: 0.4) ..style = PaintingStyle.stroke; - final Paint hoveredBorderPaint = Paint() + final hoveredBorderPaint = Paint() ..color = Colors.black ..style = PaintingStyle.stroke ..strokeWidth = 1.5; @@ -66,24 +66,24 @@ class OccupancyPainter extends CustomPainter { ); canvas.drawLine(Offset(x, y), Offset(x, y + cellSize), borderPaint); - canvas.drawLine(Offset(x + cellSize, y), Offset(x + cellSize, y + cellSize), - borderPaint); + canvas.drawLine(Offset(x + cellSize, y), + Offset(x + cellSize, y + cellSize), borderPaint); } } } void _drawDashedLine(Canvas canvas, Offset start, Offset end, Paint paint) { - const double dashWidth = 2.0; - const double dashSpace = 4.0; - final double totalLength = (end - start).distance; - final Offset direction = (end - start) / (end - start).distance; + const dashWidth = 2.0; + const dashSpace = 4.0; + final totalLength = (end - start).distance; + final direction = (end - start) / (end - start).distance; - double currentLength = 0.0; + var currentLength = 0.0; while (currentLength < totalLength) { - final Offset dashStart = start + direction * currentLength; - final double nextLength = currentLength + dashWidth; - final Offset dashEnd = - start + direction * (nextLength < totalLength ? nextLength : totalLength); + final dashStart = start + direction * currentLength; + final nextLength = currentLength + dashWidth; + final dashEnd = start + + direction * (nextLength < totalLength ? nextLength : totalLength); canvas.drawLine(dashStart, dashEnd, paint); currentLength = nextLength + dashSpace; } diff --git a/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart b/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart index e0023f53..69189b60 100644 --- a/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart +++ b/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart @@ -5,7 +5,8 @@ import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_type import 'package:syncrow_web/pages/analytics/params/get_air_quality_distribution_param.dart'; import 'package:syncrow_web/pages/analytics/services/air_quality_distribution/air_quality_distribution_service.dart'; -class FakeAirQualityDistributionService implements AirQualityDistributionService { +class FakeAirQualityDistributionService + implements AirQualityDistributionService { final _random = Random(); @override @@ -43,7 +44,6 @@ class FakeAirQualityDistributionService implements AirQualityDistributionService name: 'poor', percentage: nonNullValues[2], type: AqiType.hcho.code, - ), AirQualityPercentageData( name: 'unhealthy', @@ -71,7 +71,7 @@ class FakeAirQualityDistributionService implements AirQualityDistributionService List nullMask, ) { double nonNullSum = 0; - for (int i = 0; i < originalValues.length; i++) { + for (var i = 0; i < originalValues.length; i++) { if (!nullMask[i]) { nonNullSum += originalValues[i]; } diff --git a/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart b/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart index dcf00600..7054c97b 100644 --- a/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart +++ b/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart @@ -3,7 +3,8 @@ import 'package:syncrow_web/pages/analytics/params/get_air_quality_distribution_ import 'package:syncrow_web/pages/analytics/services/air_quality_distribution/air_quality_distribution_service.dart'; import 'package:syncrow_web/services/api/http_service.dart'; -class RemoteAirQualityDistributionService implements AirQualityDistributionService { +class RemoteAirQualityDistributionService + implements AirQualityDistributionService { RemoteAirQualityDistributionService(this._httpService); final HTTPService _httpService; diff --git a/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart b/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart index 2d735df6..ee4fb431 100644 --- a/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart +++ b/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart @@ -16,7 +16,8 @@ class AnalyticsDevicesServiceDelegate implements AnalyticsDevicesService { GetAnalyticsDevicesParam param, ) { return switch (param.requestType) { - AnalyticsDeviceRequestType.occupancy => _occupancyService.getDevices(param), + AnalyticsDeviceRequestType.occupancy => + _occupancyService.getDevices(param), AnalyticsDeviceRequestType.energyManagement => _energyManagementService.getDevices(param), }; diff --git a/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart b/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart index 9ef711e9..62c0908b 100644 --- a/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart +++ b/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart @@ -14,7 +14,8 @@ final class RemoteEnergyManagementAnalyticsDevicesService static const _defaultErrorMessage = 'Failed to load analytics devices'; @override - Future> getDevices(GetAnalyticsDevicesParam param) async { + Future> getDevices( + GetAnalyticsDevicesParam param) async { try { final response = await _httpService.get( path: '/devices-space-community/recursive-child', @@ -37,7 +38,8 @@ final class RemoteEnergyManagementAnalyticsDevicesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { throw APIException('$_defaultErrorMessage: $e'); diff --git a/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart b/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart index 736b0804..37b9663c 100644 --- a/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart +++ b/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart @@ -6,7 +6,8 @@ import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; -class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService { +class RemoteOccupancyAnalyticsDevicesService + implements AnalyticsDevicesService { const RemoteOccupancyAnalyticsDevicesService(this._httpService); final HTTPService _httpService; @@ -14,7 +15,8 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService static const _defaultErrorMessage = 'Failed to load analytics devices'; @override - Future> getDevices(GetAnalyticsDevicesParam param) async { + Future> getDevices( + GetAnalyticsDevicesParam param) async { try { final requests = await Future.wait>( param.deviceTypes.map((e) { @@ -34,15 +36,18 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { - final formattedErrorMessage = [_defaultErrorMessage, e.toString()].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, e.toString()].join(': '); throw APIException(formattedErrorMessage); } } - Future> _makeRequest(GetAnalyticsDevicesParam param) async { + Future> _makeRequest( + GetAnalyticsDevicesParam param) async { try { final projectUuid = await ProjectManager.getProjectUUID(); @@ -69,7 +74,8 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { throw APIException('$_defaultErrorMessage: $e'); diff --git a/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart index 0239bcb7..eb77fa5a 100644 --- a/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart +++ b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart @@ -34,7 +34,7 @@ class DeviceLocationDetailsServiceDecorator implements DeviceLocationService { return deviceLocationInfo; } catch (e) { - throw Exception('Failed to load device location info: ${e.toString()}'); + throw Exception('Failed to load device location info: $e'); } } } diff --git a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart index 17f9baff..5546bf65 100644 --- a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart +++ b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart @@ -11,7 +11,8 @@ final class RemoteEnergyConsumptionByPhasesService final HTTPService _httpService; - static const _defaultErrorMessage = 'Failed to load energy consumption per phase'; + static const _defaultErrorMessage = + 'Failed to load energy consumption per phase'; @override Future> load( @@ -36,7 +37,8 @@ final class RemoteEnergyConsumptionByPhasesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart b/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart index 82b21b1c..1845ac6e 100644 --- a/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart +++ b/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart @@ -13,7 +13,8 @@ class RemoteEnergyConsumptionPerDeviceService final HTTPService _httpService; - static const _defaultErrorMessage = 'Failed to load energy consumption per device'; + static const _defaultErrorMessage = + 'Failed to load energy consumption per device'; @override Future> load( @@ -31,7 +32,8 @@ class RemoteEnergyConsumptionPerDeviceService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); @@ -59,7 +61,8 @@ abstract final class _EnergyConsumptionPerDeviceMapper { final energyJson = data as Map; return EnergyDataModel( date: DateTime.parse(energyJson['date'] as String), - value: double.parse(energyJson['total_energy_consumed_kw'] as String), + value: + double.parse(energyJson['total_energy_consumed_kw'] as String), ); }).toList(), ); diff --git a/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart b/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart index afd3f79e..149ae31c 100644 --- a/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart +++ b/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart @@ -33,7 +33,8 @@ final class RemoteOccupancyService implements OccupacyService { final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart b/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart index 0d7f6500..38865981 100644 --- a/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart +++ b/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart @@ -13,7 +13,8 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { static const _defaultErrorMessage = 'Failed to load occupancy heat map'; @override - Future> load(GetOccupancyHeatMapParam param) async { + Future> load( + GetOccupancyHeatMapParam param) async { try { final response = await _httpService.get( path: '/occupancy/heat-map/space/${param.spaceUuid}', @@ -24,7 +25,8 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { final dailyData = json['data'] as List? ?? []; final result = dailyData.map( - (json) => OccupancyHeatMapModel.fromJson(json as Map), + (json) => + OccupancyHeatMapModel.fromJson(json as Map), ); return result.toList(); @@ -36,7 +38,8 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart b/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart index b4bc82c6..3930c252 100644 --- a/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart +++ b/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart @@ -28,7 +28,8 @@ final class RemotePowerClampInfoService implements PowerClampInfoService { final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart b/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart index 01ad6fa1..3140cae3 100644 --- a/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart +++ b/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart @@ -6,7 +6,7 @@ import 'package:syncrow_web/pages/analytics/services/range_of_aqi/range_of_aqi_s class FakeRangeOfAqiService implements RangeOfAqiService { @override Future> load(GetRangeOfAqiParam param) async { - return await Future.delayed(const Duration(milliseconds: 800), () { + return Future.delayed(const Duration(milliseconds: 800), () { final random = DateTime.now().millisecondsSinceEpoch; return List.generate(30, (index) { @@ -19,14 +19,20 @@ class FakeRangeOfAqiService implements RangeOfAqiService { final avg = (min + avgDelta).clamp(0.0, 301.0); final max = (avg + maxDelta).clamp(0.0, 301.0); - return RangeOfAqi( + return RangeOfAqi( data: [ - RangeOfAqiValue(type: AqiType.aqi.code, min: min, average: avg, max: max), - RangeOfAqiValue(type: AqiType.pm25.code, min: min, average: avg, max: max), - RangeOfAqiValue(type: AqiType.pm10.code, min: min, average: avg, max: max), - RangeOfAqiValue(type: AqiType.hcho.code, min: min, average: avg, max: max), - RangeOfAqiValue(type: AqiType.tvoc.code, min: min, average: avg, max: max), - RangeOfAqiValue(type: AqiType.co2.code, min: min, average: avg, max: max), + RangeOfAqiValue( + type: AqiType.aqi.code, min: min, average: avg, max: max), + RangeOfAqiValue( + type: AqiType.pm25.code, min: min, average: avg, max: max), + RangeOfAqiValue( + type: AqiType.pm10.code, min: min, average: avg, max: max), + RangeOfAqiValue( + type: AqiType.hcho.code, min: min, average: avg, max: max), + RangeOfAqiValue( + type: AqiType.tvoc.code, min: min, average: avg, max: max), + RangeOfAqiValue( + type: AqiType.co2.code, min: min, average: avg, max: max), ], date: date, ); diff --git a/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart b/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart index 9e1657e3..6f5f00b1 100644 --- a/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart +++ b/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart @@ -3,4 +3,4 @@ import 'package:syncrow_web/pages/analytics/params/get_range_of_aqi_param.dart'; abstract interface class RangeOfAqiService { Future> load(GetRangeOfAqiParam param); -} \ No newline at end of file +} diff --git a/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart b/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart index 7afece6a..92c152ca 100644 --- a/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart +++ b/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart @@ -2,4 +2,4 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_sta abstract interface class RealtimeDeviceService { Stream> subscribe(String deviceId); -} \ No newline at end of file +} diff --git a/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart b/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart index 838cc5e7..42cdadbf 100644 --- a/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart +++ b/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart @@ -5,7 +5,8 @@ import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/to import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; -class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionService { +class RemoteTotalEnergyConsumptionService + implements TotalEnergyConsumptionService { const RemoteTotalEnergyConsumptionService(this._httpService); final HTTPService _httpService; @@ -29,7 +30,8 @@ class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionServi final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = + [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/widgets/analytics_sidebar_header.dart b/lib/pages/analytics/widgets/analytics_sidebar_header.dart index 5ff1d042..33f59032 100644 --- a/lib/pages/analytics/widgets/analytics_sidebar_header.dart +++ b/lib/pages/analytics/widgets/analytics_sidebar_header.dart @@ -75,7 +75,8 @@ class AnalyticsSidebarHeader extends StatelessWidget { ), const SizedBox(height: 6), SelectableText( - context.watch().state.selectedDevice?.uuid ?? 'N/A', + context.watch().state.selectedDevice?.uuid ?? + 'N/A', style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, fontWeight: FontWeight.w400, diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index 58950089..c2774263 100644 --- a/lib/pages/auth/bloc/auth_bloc.dart +++ b/lib/pages/auth/bloc/auth_bloc.dart @@ -36,7 +36,8 @@ class AuthBloc extends Bloc { ////////////////////////////// forget password ////////////////////////////////// final TextEditingController forgetEmailController = TextEditingController(); - final TextEditingController forgetPasswordController = TextEditingController(); + final TextEditingController forgetPasswordController = + TextEditingController(); final TextEditingController forgetOtp = TextEditingController(); final forgetFormKey = GlobalKey(); final forgetEmailKey = GlobalKey(); @@ -53,7 +54,8 @@ class AuthBloc extends Bloc { return; } _remainingTime = 1; - add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false)); + add(UpdateTimerEvent( + remainingTime: _remainingTime, isButtonEnabled: false)); try { forgetEmailValidate = ''; _remainingTime = (await AuthenticationAPI.sendOtp( @@ -62,7 +64,7 @@ class AuthBloc extends Bloc { } on DioException catch (e) { if (e.response!.statusCode == 400) { final errorData = e.response!.data; - String errorMessage = errorData['message']; + final String errorMessage = errorData['message']; if (errorMessage == 'User not found') { validate = 'Invalid Credential'; emit(AuthInitialState()); @@ -90,7 +92,8 @@ class AuthBloc extends Bloc { _timer?.cancel(); add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true)); } else { - add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false)); + add(UpdateTimerEvent( + remainingTime: _remainingTime, isButtonEnabled: false)); } }); } @@ -100,11 +103,11 @@ class AuthBloc extends Bloc { emit(const TimerState(isButtonEnabled: true, remainingTime: 0)); } -Future changePassword( + Future changePassword( ChangePasswordEvent event, Emitter emit) async { emit(LoadingForgetState()); try { - var response = await AuthenticationAPI.verifyOtp( + final response = await AuthenticationAPI.verifyOtp( email: forgetEmailController.text, otpCode: forgetOtp.text); if (response == true) { await AuthenticationAPI.forgetPassword( @@ -122,7 +125,6 @@ Future changePassword( } } - String? validateCode(String? value) { if (value == null || value.isEmpty) { return 'Code is required'; @@ -131,7 +133,9 @@ Future changePassword( } void _onUpdateTimer(UpdateTimerEvent event, Emitter emit) { - emit(TimerState(isButtonEnabled: event.isButtonEnabled, remainingTime: event.remainingTime)); + emit(TimerState( + isButtonEnabled: event.isButtonEnabled, + remainingTime: event.remainingTime)); } ///////////////////////////////////// login ///////////////////////////////////// @@ -151,8 +155,7 @@ Future changePassword( static UserModel? user; bool showValidationMessage = false; - - void _login(LoginButtonPressed event, Emitter emit) async { + Future _login(LoginButtonPressed event, Emitter emit) async { emit(AuthLoading()); if (isChecked) { try { @@ -179,7 +182,7 @@ Future changePassword( } if (token.accessTokenIsNotEmpty) { - FlutterSecureStorage storage = const FlutterSecureStorage(); + const storage = FlutterSecureStorage(); await storage.write( key: Token.loginAccessTokenKey, value: token.accessToken); const FlutterSecureStorage().write( @@ -197,8 +200,7 @@ Future changePassword( } } - - checkBoxToggle( + void checkBoxToggle( CheckBoxEvent event, Emitter emit, ) { @@ -277,12 +279,12 @@ Future changePassword( if (value == null || value.isEmpty) { return 'Please enter your password'; } - List validationErrors = []; + final validationErrors = []; - if (!RegExp(r'^(?=.*[a-z])').hasMatch(value)) { + if (!RegExp('^(?=.*[a-z])').hasMatch(value)) { validationErrors.add(' - one lowercase letter'); } - if (!RegExp(r'^(?=.*[A-Z])').hasMatch(value)) { + if (!RegExp('^(?=.*[A-Z])').hasMatch(value)) { validationErrors.add(' - one uppercase letter'); } if (!RegExp(r'^(?=.*\d)').hasMatch(value)) { @@ -304,7 +306,7 @@ Future changePassword( String? fullNameValidator(String? value) { if (value == null) return 'Full name is required'; - final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); + final withoutExtraSpaces = value.replaceAll(RegExp(r'\s+'), ' ').trim(); if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { return 'Full name must be between 2 and 30 characters long'; } @@ -339,12 +341,14 @@ Future changePassword( static Future getTokenAndValidate() async { try { const storage = FlutterSecureStorage(); - final firstLaunch = - await SharedPreferencesHelper.readBoolFromSP(StringsManager.firstLaunch) ?? true; + final firstLaunch = await SharedPreferencesHelper.readBoolFromSP( + StringsManager.firstLaunch) ?? + true; if (firstLaunch) { storage.deleteAll(); } - await SharedPreferencesHelper.saveBoolToSP(StringsManager.firstLaunch, false); + await SharedPreferencesHelper.saveBoolToSP( + StringsManager.firstLaunch, false); final value = await storage.read(key: Token.loginAccessTokenKey) ?? ''; if (value.isEmpty) { return 'Token not found'; @@ -366,7 +370,8 @@ Future changePassword( } } - void _fetchRegion(RegionInitialEvent event, Emitter emit) async { + Future _fetchRegion( + RegionInitialEvent event, Emitter emit) async { try { emit(AuthLoading()); regionList = await AuthenticationAPI.fetchRegion(); @@ -389,15 +394,17 @@ Future changePassword( } String formattedTime(int time) { - final int days = (time / 86400).floor(); // 86400 seconds in a day - final int hours = ((time % 86400) / 3600).floor(); - final int minutes = (((time % 86400) % 3600) / 60).floor(); - final int seconds = (((time % 86400) % 3600) % 60).floor(); + final days = (time / 86400).floor(); // 86400 seconds in a day + final hours = ((time % 86400) / 3600).floor(); + final minutes = (((time % 86400) % 3600) / 60).floor(); + final seconds = ((time % 86400) % 3600) % 60; - final String formattedTime = [ + final formattedTime = [ if (days > 0) '${days}d', // Append 'd' for days if (days > 0 || hours > 0) - hours.toString().padLeft(2, '0'), // Show hours if there are days or hours + hours + .toString() + .padLeft(2, '0'), // Show hours if there are days or hours minutes.toString().padLeft(2, '0'), seconds.toString().padLeft(2, '0'), ].join(':'); @@ -417,7 +424,7 @@ Future changePassword( return checkValidate; } - changeValidate( + void changeValidate( ChangeValidateEvent event, Emitter emit, ) { @@ -426,7 +433,7 @@ Future changePassword( emit(LoginInitial()); } - changeForgetValidate( + void changeForgetValidate( ChangeValidateEvent event, Emitter emit, ) { diff --git a/lib/pages/auth/bloc/auth_event.dart b/lib/pages/auth/bloc/auth_event.dart index 2b6a4eef..392270e3 100644 --- a/lib/pages/auth/bloc/auth_event.dart +++ b/lib/pages/auth/bloc/auth_event.dart @@ -46,7 +46,8 @@ class StopTimerEvent extends AuthEvent {} class UpdateTimerEvent extends AuthEvent { final int remainingTime; final bool isButtonEnabled; - const UpdateTimerEvent({required this.remainingTime, required this.isButtonEnabled}); + const UpdateTimerEvent( + {required this.remainingTime, required this.isButtonEnabled}); } class ChangePasswordEvent extends AuthEvent {} diff --git a/lib/pages/auth/bloc/auth_state.dart b/lib/pages/auth/bloc/auth_state.dart index f3a95157..05790a7b 100644 --- a/lib/pages/auth/bloc/auth_state.dart +++ b/lib/pages/auth/bloc/auth_state.dart @@ -56,7 +56,8 @@ class TimerState extends AuthState { final bool isButtonEnabled; final int remainingTime; - const TimerState({required this.isButtonEnabled, required this.remainingTime}); + const TimerState( + {required this.isButtonEnabled, required this.remainingTime}); @override List get props => [isButtonEnabled, remainingTime]; @@ -80,7 +81,7 @@ class TimerUpdated extends AuthState { final String formattedTime; final bool isButtonEnabled; - TimerUpdated({ + const TimerUpdated({ required this.formattedTime, required this.isButtonEnabled, }); diff --git a/lib/pages/auth/model/login_with_email_model.dart b/lib/pages/auth/model/login_with_email_model.dart index dca3f8f9..fcde9f17 100644 --- a/lib/pages/auth/model/login_with_email_model.dart +++ b/lib/pages/auth/model/login_with_email_model.dart @@ -21,9 +21,9 @@ class LoginWithEmailModel { return { 'email': email, 'password': password, - "platform": "web" + 'platform': 'web' // 'regionUuid': regionUuid, }; } } -//tst@tst.com \ No newline at end of file +//tst@tst.com diff --git a/lib/pages/auth/model/token.dart b/lib/pages/auth/model/token.dart index 53c6f401..24ee46f2 100644 --- a/lib/pages/auth/model/token.dart +++ b/lib/pages/auth/model/token.dart @@ -11,6 +11,14 @@ class Token { final int iat; final int exp; + Token( + this.accessToken, + this.refreshToken, + this.sessionId, + this.iat, + this.exp, + ); + Token.emptyConstructor() : accessToken = '', refreshToken = '', @@ -24,14 +32,6 @@ class Token { bool get isNotEmpty => accessToken.isNotEmpty && refreshToken.isNotEmpty; - Token( - this.accessToken, - this.refreshToken, - this.sessionId, - this.iat, - this.exp, - ); - Token.refreshToken(this.refreshToken) : accessToken = '', sessionId = '', @@ -40,7 +40,7 @@ class Token { factory Token.fromJson(Map json) { //save token to secure storage - var storage = const FlutterSecureStorage(); + const storage = FlutterSecureStorage(); storage.write( key: loginAccessTokenKey, value: json[loginAccessTokenKey] ?? ''); storage.write( diff --git a/lib/pages/auth/model/user_model.dart b/lib/pages/auth/model/user_model.dart index 267d0b3e..98da8bd3 100644 --- a/lib/pages/auth/model/user_model.dart +++ b/lib/pages/auth/model/user_model.dart @@ -55,22 +55,21 @@ class UserModel { //from token factory UserModel.fromToken(Token token) { - Map tempJson = Token.decodeToken(token.accessToken); + final tempJson = Token.decodeToken(token.accessToken); return UserModel( - hasAcceptedWebAgreement: null, - role: null, - webAgreementAcceptedAt: null, - uuid: tempJson['uuid'].toString(), - email: tempJson['email'], - firstName: null, - lastName: null, - photoUrl: null, - phoneNumber: null, - isEmailVerified: null, - isAgreementAccepted: null, - project: null - ); + hasAcceptedWebAgreement: null, + role: null, + webAgreementAcceptedAt: null, + uuid: tempJson['uuid'].toString(), + email: tempJson['email'], + firstName: null, + lastName: null, + photoUrl: null, + phoneNumber: null, + isEmailVerified: null, + isAgreementAccepted: null, + project: null); } Map toJson() { diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index 7686ea8f..b32644db 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -36,20 +36,18 @@ class ForgetPasswordWebPage extends StatelessWidget { ); } }, - builder: (context, state) { - return _buildForm(context, state); - }, + builder: _buildForm, ), ), ); } Widget _buildForm(BuildContext context, AuthState state) { - late ScrollController _scrollController; - _scrollController = ScrollController(); - void _scrollToCenter() { - final double middlePosition = _scrollController.position.maxScrollExtent / 2; - _scrollController.animateTo( + late ScrollController scrollController; + scrollController = ScrollController(); + void scrollToCenter() { + final middlePosition = scrollController.position.maxScrollExtent / 2; + scrollController.animateTo( middlePosition, duration: const Duration(seconds: 1), curve: Curves.easeInOut, @@ -57,24 +55,25 @@ class ForgetPasswordWebPage extends StatelessWidget { } WidgetsBinding.instance.addPostFrameCallback((_) { - _scrollToCenter(); + scrollToCenter(); }); final forgetBloc = BlocProvider.of(context); - Size size = MediaQuery.of(context).size; + final size = MediaQuery.of(context).size; return FirstLayer( second: Center( child: Stack( children: [ - if (state is AuthLoading) const Center(child: CircularProgressIndicator()), + if (state is AuthLoading) + const Center(child: CircularProgressIndicator()), ListView( shrinkWrap: true, - controller: _scrollController, + controller: scrollController, children: [ Container( padding: EdgeInsets.all(size.width * 0.02), margin: EdgeInsets.all(size.width * 0.09), decoration: BoxDecoration( - color: Colors.black.withOpacity(0.3), + color: Colors.black.withValues(alpha: 0.3), borderRadius: const BorderRadius.all(Radius.circular(20)), ), child: Center( @@ -94,17 +93,22 @@ class ForgetPasswordWebPage extends StatelessWidget { flex: 3, child: Container( decoration: BoxDecoration( - color: Colors.white.withOpacity(0.1), - borderRadius: const BorderRadius.all(Radius.circular(30)), - border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2)), + color: Colors.white.withValues(alpha: 0.1), + borderRadius: + const BorderRadius.all(Radius.circular(30)), + border: Border.all( + color: ColorsManager.graysColor + .withValues(alpha: 0.2)), ), child: Form( key: forgetBloc.forgetFormKey, child: Padding( padding: EdgeInsets.symmetric( - horizontal: size.width * 0.02, vertical: size.width * 0.003), + horizontal: size.width * 0.02, + vertical: size.width * 0.003), child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 10), @@ -121,7 +125,9 @@ class ForgetPasswordWebPage extends StatelessWidget { style: Theme.of(context) .textTheme .bodySmall! - .copyWith(fontSize: 14, fontWeight: FontWeight.w400), + .copyWith( + fontSize: 14, + fontWeight: FontWeight.w400), ), const SizedBox(height: 10), // Column( @@ -140,69 +146,90 @@ class ForgetPasswordWebPage extends StatelessWidget { Form( key: forgetBloc.forgetEmailKey, child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, children: [ Text( - "Account", - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontSize: 14, fontWeight: FontWeight.w400), + 'Account', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + fontSize: 14, + fontWeight: + FontWeight.w400), ), const SizedBox(height: 10), SizedBox( child: TextFormField( - controller: forgetBloc.forgetEmailController, - validator: forgetBloc.validateEmail, - decoration: textBoxDecoration()!.copyWith( + controller: forgetBloc + .forgetEmailController, + validator: + forgetBloc.validateEmail, + decoration: + textBoxDecoration()!.copyWith( hintText: 'Enter your email', hintStyle: Theme.of(context) .textTheme .bodySmall! .copyWith( - color: ColorsManager.grayColor, - fontWeight: FontWeight.w400), + color: ColorsManager + .grayColor, + fontWeight: + FontWeight.w400), ), - style: const TextStyle(color: Colors.black), + style: const TextStyle( + color: Colors.black), ), ), ], )), const SizedBox(height: 20.0), Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "One Time Password", + 'One Time Password', style: Theme.of(context) .textTheme .bodySmall! - .copyWith(fontSize: 14, fontWeight: FontWeight.w400), + .copyWith( + fontSize: 14, + fontWeight: FontWeight.w400), ), const SizedBox(height: 10), SizedBox( child: TextFormField( validator: forgetBloc.validateCode, - keyboardType: TextInputType.visiblePassword, + keyboardType: + TextInputType.visiblePassword, controller: forgetBloc.forgetOtp, - decoration: textBoxDecoration()!.copyWith( + decoration: + textBoxDecoration()!.copyWith( hintText: 'Enter Code', hintStyle: Theme.of(context) .textTheme .bodySmall! .copyWith( - color: ColorsManager.grayColor, - fontWeight: FontWeight.w400), + color: + ColorsManager.grayColor, + fontWeight: + FontWeight.w400), suffixIcon: SizedBox( width: 100, child: Center( child: InkWell( onTap: state is TimerState && - !state.isButtonEnabled && - state.remainingTime != 1 + !state + .isButtonEnabled && + state.remainingTime != + 1 ? null - : - () { + : () { if (forgetBloc .forgetEmailKey .currentState! @@ -211,27 +238,31 @@ class ForgetPasswordWebPage extends StatelessWidget { StartTimerEvent()); } }, - child: Text( 'Get Code ${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "(${forgetBloc.formattedTime(state.remainingTime)}) " : ""}', style: TextStyle( - color: state is TimerState && - !state.isButtonEnabled + color: state + is TimerState && + !state + .isButtonEnabled ? Colors.grey - : ColorsManager.btnColor, + : ColorsManager + .btnColor, ), ), ), ), ), ), - style: const TextStyle(color: Colors.black), + style: const TextStyle( + color: Colors.black), ), ), if (forgetBloc.forgetValidate != '') // Check if there is a validation message Padding( - padding: const EdgeInsets.only(top: 8.0), + padding: + const EdgeInsets.only(top: 8.0), child: Text( forgetBloc.forgetValidate, style: const TextStyle( @@ -244,34 +275,44 @@ class ForgetPasswordWebPage extends StatelessWidget { ), const SizedBox(height: 20.0), Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Password", + 'Password', style: Theme.of(context) .textTheme .bodySmall! - .copyWith(fontSize: 14, fontWeight: FontWeight.w400), + .copyWith( + fontSize: 14, + fontWeight: FontWeight.w400), ), const SizedBox(height: 10), SizedBox( child: TextFormField( obscureText: forgetBloc.obscureText, - keyboardType: TextInputType.visiblePassword, - validator: forgetBloc.passwordValidator, - controller: forgetBloc.forgetPasswordController, - decoration: textBoxDecoration()!.copyWith( + keyboardType: + TextInputType.visiblePassword, + validator: + forgetBloc.passwordValidator, + controller: forgetBloc + .forgetPasswordController, + decoration: + textBoxDecoration()!.copyWith( suffixIcon: IconButton( onPressed: () { - forgetBloc.add(PasswordVisibleEvent( - newValue: forgetBloc.obscureText)); + forgetBloc.add( + PasswordVisibleEvent( + newValue: forgetBloc + .obscureText)); }, icon: SizedBox( child: SvgPicture.asset( forgetBloc.obscureText ? Assets.visiblePassword - : Assets.invisiblePassword, + : Assets + .invisiblePassword, height: 15, width: 15, ), @@ -282,10 +323,13 @@ class ForgetPasswordWebPage extends StatelessWidget { .textTheme .bodySmall! .copyWith( - color: ColorsManager.grayColor, - fontWeight: FontWeight.w400), + color: + ColorsManager.grayColor, + fontWeight: + FontWeight.w400), ), - style: const TextStyle(color: Colors.black), + style: const TextStyle( + color: Colors.black), ), ), ], @@ -295,23 +339,31 @@ class ForgetPasswordWebPage extends StatelessWidget { ), const SizedBox(height: 20.0), Row( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: size.width * 0.2, child: DefaultButton( - backgroundColor: ColorsManager.btnColor, + backgroundColor: + ColorsManager.btnColor, child: const Text('Submit'), onPressed: () { - if (forgetBloc.forgetFormKey.currentState!.validate() || - forgetBloc.forgetEmailKey.currentState! + if (forgetBloc + .forgetFormKey.currentState! + .validate() || + forgetBloc.forgetEmailKey + .currentState! .validate()) { - if (forgetBloc.forgetEmailKey.currentState! + if (forgetBloc.forgetEmailKey + .currentState! .validate() && - forgetBloc.forgetFormKey.currentState! + forgetBloc.forgetFormKey + .currentState! .validate()) { - forgetBloc.add(ChangePasswordEvent()); + forgetBloc + .add(ChangePasswordEvent()); } } }, @@ -325,7 +377,8 @@ class ForgetPasswordWebPage extends StatelessWidget { child: Text( forgetBloc.validate, style: const TextStyle( - fontWeight: FontWeight.w700, color: ColorsManager.red), + fontWeight: FontWeight.w700, + color: ColorsManager.red), ), ), ), @@ -337,8 +390,9 @@ class ForgetPasswordWebPage extends StatelessWidget { child: Wrap( children: [ const Text( - "Do you have an account? ", - style: TextStyle(color: Colors.white), + 'Do you have an account? ', + style: + TextStyle(color: Colors.white), ), InkWell( onTap: () { @@ -346,7 +400,7 @@ class ForgetPasswordWebPage extends StatelessWidget { Navigator.pop(context); }, child: const Text( - "Sign in", + 'Sign in', ), ), ], @@ -372,14 +426,15 @@ class ForgetPasswordWebPage extends StatelessWidget { )); } - Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) { - final TextEditingController textEditingController = TextEditingController(); + Widget _buildDropdownField( + BuildContext context, AuthBloc loginBloc, Size size) { + final textEditingController = TextEditingController(); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Country/Region", + 'Country/Region', style: Theme.of(context).textTheme.bodySmall!.copyWith( fontSize: 14, fontWeight: FontWeight.w400, @@ -398,10 +453,13 @@ class ForgetPasswordWebPage extends StatelessWidget { builder: (FormFieldState field) { return InputDecorator( decoration: InputDecoration( - contentPadding: const EdgeInsets.symmetric(horizontal: 2, vertical: 10), + contentPadding: + const EdgeInsets.symmetric(horizontal: 2, vertical: 10), errorText: field.errorText, - filled: true, // Ensure the dropdown is filled with the background color - fillColor: ColorsManager.boxColor, // Match the dropdown container color + filled: + true, // Ensure the dropdown is filled with the background color + fillColor: ColorsManager + .boxColor, // Match the dropdown container color border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide( @@ -412,14 +470,16 @@ class ForgetPasswordWebPage extends StatelessWidget { enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide( - color: field.hasError ? Colors.red : ColorsManager.grayColor, + color: + field.hasError ? Colors.red : ColorsManager.grayColor, width: 1.5, ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide( - color: field.hasError ? Colors.red : ColorsManager.grayColor, + color: + field.hasError ? Colors.red : ColorsManager.grayColor, width: 1.5, ), ), @@ -446,10 +506,11 @@ class ForgetPasswordWebPage extends StatelessWidget { return DropdownMenuItem( value: region.id, child: Text( - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 14, - fontWeight: FontWeight.w400, - ), + style: + Theme.of(context).textTheme.bodyMedium!.copyWith( + fontSize: 14, + fontWeight: FontWeight.w400, + ), region.name, overflow: TextOverflow.ellipsis, maxLines: 1, @@ -462,7 +523,8 @@ class ForgetPasswordWebPage extends StatelessWidget { onChanged: (String? value) { if (value != null) { loginBloc.add(SelectRegionEvent(val: value)); - field.didChange(value); // Notify the form field of the change + field.didChange( + value); // Notify the form field of the change } }, buttonStyleData: const ButtonStyleData( @@ -486,7 +548,8 @@ class ForgetPasswordWebPage extends StatelessWidget { searchInnerWidgetHeight: 50, searchInnerWidget: Container( height: 50, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + padding: const EdgeInsets.symmetric( + horizontal: 8, vertical: 4), child: TextFormField( style: const TextStyle(color: Colors.black), controller: textEditingController, @@ -500,7 +563,8 @@ class ForgetPasswordWebPage extends StatelessWidget { ), ), searchMatchFn: (item, searchValue) { - final regionName = (item.child as Text).data?.toLowerCase() ?? ''; + final regionName = + (item.child as Text).data?.toLowerCase() ?? ''; final search = searchValue.toLowerCase().trim(); return regionName.contains(search); }, diff --git a/lib/pages/auth/view/login_mobile_page.dart b/lib/pages/auth/view/login_mobile_page.dart index 4f001bc6..a32944dc 100644 --- a/lib/pages/auth/view/login_mobile_page.dart +++ b/lib/pages/auth/view/login_mobile_page.dart @@ -79,7 +79,7 @@ class LoginMobilePage extends StatelessWidget { child: Container( margin: const EdgeInsets.all(50), decoration: BoxDecoration( - color: Colors.black.withOpacity(0.3), + color: Colors.black.withValues(alpha: 0.3), borderRadius: const BorderRadius.all(Radius.circular(20))), child: Column( mainAxisSize: MainAxisSize.min, @@ -93,12 +93,15 @@ class LoginMobilePage extends StatelessWidget { ), ), Container( - margin: EdgeInsets.all(30), - padding: EdgeInsets.all(20), + margin: const EdgeInsets.all(30), + padding: const EdgeInsets.all(20), decoration: BoxDecoration( - color: Colors.white.withOpacity(0.1), - borderRadius: const BorderRadius.all(Radius.circular(30)), - border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2))), + color: Colors.white.withValues(alpha: 0.1), + borderRadius: + const BorderRadius.all(Radius.circular(30)), + border: Border.all( + color: ColorsManager.graysColor + .withValues(alpha: 0.2))), child: Form( key: loginBloc.loginFormKey, child: Column( @@ -109,7 +112,9 @@ class LoginMobilePage extends StatelessWidget { const Text( 'Login', style: TextStyle( - color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold), + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold), ), const SizedBox(height: 30), // Column( @@ -155,15 +160,15 @@ class LoginMobilePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Email", + 'Email', style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: TextFormField( validator: loginBloc.validateEmail, controller: loginBloc.loginEmailController, - decoration: - textBoxDecoration()!.copyWith(hintText: 'Enter your email'), + decoration: textBoxDecoration()! + .copyWith(hintText: 'Enter your email'), style: const TextStyle(color: Colors.black), ), ), @@ -175,7 +180,7 @@ class LoginMobilePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Password", + 'Password', style: Theme.of(context).textTheme.bodySmall, ), SizedBox( @@ -183,7 +188,8 @@ class LoginMobilePage extends StatelessWidget { validator: loginBloc.validatePassword, obscureText: loginBloc.obscureText, keyboardType: TextInputType.visiblePassword, - controller: loginBloc.loginPasswordController, + controller: + loginBloc.loginPasswordController, decoration: textBoxDecoration()!.copyWith( hintText: 'At least 8 characters', ), @@ -201,16 +207,19 @@ class LoginMobilePage extends StatelessWidget { children: [ InkWell( onTap: () { - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => const ForgetPasswordPage(), + Navigator.of(context) + .push(MaterialPageRoute( + builder: (context) => + const ForgetPasswordPage(), )); }, child: Text( - "Forgot Password?", + 'Forgot Password?', style: Theme.of(context) .textTheme .bodySmall! - .copyWith(color: ColorsManager.blackColor), + .copyWith( + color: ColorsManager.blackColor), ), ), ], @@ -221,13 +230,15 @@ class LoginMobilePage extends StatelessWidget { Transform.scale( scale: 1.2, // Adjust the scale as needed child: Checkbox( - fillColor: MaterialStateProperty.all(Colors.white), + fillColor: WidgetStateProperty.all( + Colors.white), activeColor: Colors.white, value: loginBloc.isChecked, checkColor: Colors.black, shape: const CircleBorder(), onChanged: (bool? newValue) { - loginBloc.add(CheckBoxEvent(newValue: newValue)); + loginBloc.add( + CheckBoxEvent(newValue: newValue)); }, ), ), @@ -236,30 +247,37 @@ class LoginMobilePage extends StatelessWidget { child: RichText( text: TextSpan( text: 'Agree to ', - style: const TextStyle(color: Colors.white), + style: + const TextStyle(color: Colors.white), children: [ TextSpan( text: '(Terms of Service)', - style: const TextStyle(color: Colors.black), + style: const TextStyle( + color: Colors.black), recognizer: TapGestureRecognizer() ..onTap = () { - loginBloc.launchURL('https://example.com/terms'); + loginBloc.launchURL( + 'https://example.com/terms'); }, ), TextSpan( text: ' (Legal Statement)', - style: const TextStyle(color: Colors.black), + style: const TextStyle( + color: Colors.black), recognizer: TapGestureRecognizer() ..onTap = () { - loginBloc.launchURL('https://example.com/legal'); + loginBloc.launchURL( + 'https://example.com/legal'); }, ), TextSpan( text: ' (Privacy Statement)', - style: const TextStyle(color: Colors.black), + style: const TextStyle( + color: Colors.black), recognizer: TapGestureRecognizer() ..onTap = () { - loginBloc.launchURL('https://example.com/privacy'); + loginBloc.launchURL( + 'https://example.com/privacy'); }, ), ], @@ -276,11 +294,14 @@ class LoginMobilePage extends StatelessWidget { : ColorsManager.grayColor, child: const Text('Sign in'), onPressed: () { - if (loginBloc.loginFormKey.currentState!.validate()) { + if (loginBloc.loginFormKey.currentState! + .validate()) { loginBloc.add( LoginButtonPressed( - username: loginBloc.loginEmailController.text, - password: loginBloc.loginPasswordController.text, + username: + loginBloc.loginEmailController.text, + password: loginBloc + .loginPasswordController.text, ), ); } @@ -295,10 +316,11 @@ class LoginMobilePage extends StatelessWidget { Flexible( child: Text( "Don't you have an account? ", - style: TextStyle(color: Colors.white, fontSize: 13), + style: TextStyle( + color: Colors.white, fontSize: 13), )), Text( - "Sign up", + 'Sign up', ), ], ), diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index a6de87cf..d7416b67 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -24,7 +24,8 @@ class LoginWebPage extends StatefulWidget { State createState() => _LoginWebPageState(); } -class _LoginWebPageState extends State with HelperResponsiveLayout { +class _LoginWebPageState extends State + with HelperResponsiveLayout { @override Widget build(BuildContext context) { return Scaffold( @@ -42,9 +43,7 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ); } }, - builder: (context, state) { - return _buildLoginForm(context, state); - }, + builder: _buildLoginForm, ), ), ); @@ -54,12 +53,12 @@ class _LoginWebPageState extends State with HelperResponsiveLayout final loginBloc = BlocProvider.of(context); final isSmallScreen = isSmallScreenSize(context); final isMediumScreen = isMediumScreenSize(context); - Size size = MediaQuery.of(context).size; + final size = MediaQuery.of(context).size; late ScrollController scrollController; scrollController = ScrollController(); void scrollToCenter() { - final double middlePosition = scrollController.position.maxScrollExtent / 2; + final middlePosition = scrollController.position.maxScrollExtent / 2; scrollController.animateTo( middlePosition, duration: const Duration(seconds: 1), @@ -84,7 +83,7 @@ class _LoginWebPageState extends State with HelperResponsiveLayout padding: EdgeInsets.all(size.width * 0.02), margin: EdgeInsets.all(size.width * 0.05), decoration: BoxDecoration( - color: Colors.black.withOpacity(0.3), + color: Colors.black.withValues(alpha: 0.3), borderRadius: const BorderRadius.all(Radius.circular(20)), ), child: Center( @@ -121,7 +120,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout const Spacer(), Expanded( flex: 2, - child: _buildLoginFormFields(context, loginBloc, size), + child: _buildLoginFormFields( + context, loginBloc, size), ), const Spacer(), ], @@ -132,23 +132,26 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ), ), ), - if (state is AuthLoading) const Center(child: CircularProgressIndicator()) + if (state is AuthLoading) + const Center(child: CircularProgressIndicator()) ], ); } - Widget _buildLoginFormFields(BuildContext context, AuthBloc loginBloc, Size size) { + Widget _buildLoginFormFields( + BuildContext context, AuthBloc loginBloc, Size size) { return Container( decoration: BoxDecoration( - color: Colors.white.withOpacity(0.1), + color: Colors.white.withValues(alpha: 0.1), borderRadius: const BorderRadius.all(Radius.circular(30)), - border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2)), + border: + Border.all(color: ColorsManager.graysColor.withValues(alpha: 0.2)), ), child: Form( key: loginBloc.loginFormKey, child: Padding( - padding: - EdgeInsets.symmetric(horizontal: size.width * 0.02, vertical: size.width * 0.003), + padding: EdgeInsets.symmetric( + horizontal: size.width * 0.02, vertical: size.width * 0.003), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, @@ -176,14 +179,15 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ); } - Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) { - final TextEditingController textEditingController = TextEditingController(); + Widget _buildDropdownField( + BuildContext context, AuthBloc loginBloc, Size size) { + final textEditingController = TextEditingController(); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Country/Region", + 'Country/Region', style: Theme.of(context).textTheme.bodySmall!.copyWith( fontSize: 14, fontWeight: FontWeight.w400, @@ -246,7 +250,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout searchInnerWidgetHeight: 50, searchInnerWidget: Container( height: 50, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: TextFormField( style: const TextStyle(color: Colors.black), controller: textEditingController, @@ -261,7 +266,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ), searchMatchFn: (item, searchValue) { // Use the item's child text (region name) for searching. - final regionName = (item.child as Text).data?.toLowerCase() ?? ''; + final regionName = + (item.child as Text).data?.toLowerCase() ?? ''; final search = searchValue.toLowerCase().trim(); // Debugging print statement to ensure values are captured correctly. // Return true if the region name contains the search term. @@ -286,7 +292,7 @@ class _LoginWebPageState extends State with HelperResponsiveLayout mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Email", + 'Email', style: Theme.of(context) .textTheme .bodySmall! @@ -303,10 +309,9 @@ class _LoginWebPageState extends State with HelperResponsiveLayout decoration: textBoxDecoration()!.copyWith( errorStyle: const TextStyle(height: 0), hintText: 'Enter your email address', - hintStyle: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400)), + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400)), style: const TextStyle(color: Colors.black), ), ), @@ -320,7 +325,7 @@ class _LoginWebPageState extends State with HelperResponsiveLayout mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Password", + 'Password', style: Theme.of(context) .textTheme .bodySmall! @@ -338,7 +343,7 @@ class _LoginWebPageState extends State with HelperResponsiveLayout controller: loginBloc.loginPasswordController, onFieldSubmitted: (value) { if (loginBloc.loginFormKey.currentState!.validate()) { - loginBloc.add(LoginButtonPressed( + loginBloc.add(LoginButtonPressed( username: loginBloc.loginEmailController.text, password: value, )); @@ -348,17 +353,18 @@ class _LoginWebPageState extends State with HelperResponsiveLayout }, decoration: textBoxDecoration()!.copyWith( hintText: 'At least 8 characters', - hintStyle: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400), + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, fontWeight: FontWeight.w400), suffixIcon: IconButton( onPressed: () { - loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText)); + loginBloc.add( + PasswordVisibleEvent(newValue: loginBloc.obscureText)); }, icon: SizedBox( child: SvgPicture.asset( - loginBloc.obscureText ? Assets.visiblePassword : Assets.invisiblePassword, + loginBloc.obscureText + ? Assets.visiblePassword + : Assets.invisiblePassword, height: 15, width: 15, ), @@ -385,11 +391,11 @@ class _LoginWebPageState extends State with HelperResponsiveLayout )); }, child: Text( - "Forgot Password?", - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.black, fontSize: 14, fontWeight: FontWeight.w400), + 'Forgot Password?', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.black, + fontSize: 14, + fontWeight: FontWeight.w400), ), ), ], @@ -453,7 +459,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout ); } - Widget _buildSignInButton(BuildContext context, AuthBloc loginBloc, Size size) { + Widget _buildSignInButton( + BuildContext context, AuthBloc loginBloc, Size size) { return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -467,7 +474,7 @@ class _LoginWebPageState extends State with HelperResponsiveLayout fontSize: 14, color: loginBloc.checkValidate ? ColorsManager.whiteColors - : ColorsManager.whiteColors.withOpacity(0.2), + : ColorsManager.whiteColors.withValues(alpha: 0.2), )), onPressed: () { if (loginBloc.loginFormKey.currentState!.validate()) { @@ -494,7 +501,8 @@ class _LoginWebPageState extends State with HelperResponsiveLayout SizedBox( child: Text( loginBloc.validate, - style: const TextStyle(fontWeight: FontWeight.w700, color: ColorsManager.red), + style: const TextStyle( + fontWeight: FontWeight.w700, color: ColorsManager.red), ), ) ], diff --git a/lib/pages/common/access_device_table.dart b/lib/pages/common/access_device_table.dart index 86d4a6b3..01aed542 100644 --- a/lib/pages/common/access_device_table.dart +++ b/lib/pages/common/access_device_table.dart @@ -108,66 +108,64 @@ class _DynamicTableState extends State { child: Row( children: [ if (widget.withCheckBox) _buildSelectAllCheckbox(), - ...widget.headers - .map((header) => _buildTableHeaderCell(header)), + ...widget.headers.map(_buildTableHeaderCell), ], ), ), - widget.isEmpty - ? Expanded( - child: Column( + if (widget.isEmpty) + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, + Column( children: [ - Column( - children: [ - SvgPicture.asset(Assets.emptyTable), - const SizedBox( - height: 15, - ), - Text( - // no password - widget.tableName == 'AccessManagement' - ? 'No Password ' - : 'No Devices', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - color: ColorsManager.grayColor), - ) - ], + SvgPicture.asset(Assets.emptyTable), + const SizedBox( + height: 15, ), + Text( + // no password + widget.tableName == 'AccessManagement' + ? 'No Password ' + : 'No Devices', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: ColorsManager.grayColor), + ) ], ), ], ), - ) - : Expanded( - child: Container( - color: Colors.white, - child: ListView.builder( - shrinkWrap: true, - itemCount: widget.data.length, - itemBuilder: (context, index) { - final row = widget.data[index]; - return Row( - children: [ - if (widget.withCheckBox) - _buildRowCheckbox( - index, widget.size.height * 0.10), - ...row.map((cell) => _buildTableCell( - cell.toString(), - widget.size.height * 0.10)), - ], - ); - }, - ), - ), + ], + ), + ) + else + Expanded( + child: ColoredBox( + color: Colors.white, + child: ListView.builder( + shrinkWrap: true, + itemCount: widget.data.length, + itemBuilder: (context, index) { + final row = widget.data[index]; + return Row( + children: [ + if (widget.withCheckBox) + _buildRowCheckbox( + index, widget.size.height * 0.10), + ...row.map((cell) => _buildTableCell( + cell.toString(), widget.size.height * 0.10)), + ], + ); + }, ), + ), + ), ], ), ), @@ -245,7 +243,7 @@ class _DynamicTableState extends State { } Widget _buildTableCell(String content, double size) { - bool isBatteryLevel = content.endsWith('%'); + final isBatteryLevel = content.endsWith('%'); double? batteryLevel; if (isBatteryLevel) { diff --git a/lib/pages/common/buttons/cancel_button.dart b/lib/pages/common/buttons/cancel_button.dart index da6dcdc7..2147760e 100644 --- a/lib/pages/common/buttons/cancel_button.dart +++ b/lib/pages/common/buttons/cancel_button.dart @@ -22,17 +22,21 @@ class CancelButton extends StatelessWidget { return ElevatedButton( onPressed: onPressed, style: ButtonStyle( - backgroundColor: WidgetStateProperty.all(ColorsManager.boxColor), // White background - foregroundColor: WidgetStateProperty.all(Colors.black), // Black text color + backgroundColor: + WidgetStateProperty.all(ColorsManager.boxColor), // White background + foregroundColor: + WidgetStateProperty.all(Colors.black), // Black text color shape: WidgetStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(borderRadius ?? 10), - side: const BorderSide(color: ColorsManager.boxColor), // Black border + side: + const BorderSide(color: ColorsManager.boxColor), // Black border ), ), - fixedSize: WidgetStateProperty.all(Size(width ?? 50, height ?? 40)), // Set button height + fixedSize: WidgetStateProperty.all( + Size(width ?? 50, height ?? 40)), // Set button height ), child: Text(label), // Dynamic label ); } -} \ No newline at end of file +} diff --git a/lib/pages/common/buttons/default_button.dart b/lib/pages/common/buttons/default_button.dart index ecca6138..61012434 100644 --- a/lib/pages/common/buttons/default_button.dart +++ b/lib/pages/common/buttons/default_button.dart @@ -64,7 +64,7 @@ class DefaultButton extends StatelessWidget { (Set states) { return enabled ? backgroundColor ?? ColorsManager.primaryColor - : Colors.black.withOpacity(0.2); + : Colors.black.withValues(alpha: 0.2); }), shape: WidgetStateProperty.all( RoundedRectangleBorder( diff --git a/lib/pages/common/curtain_toggle.dart b/lib/pages/common/curtain_toggle.dart index 7b1551c5..a1c99355 100644 --- a/lib/pages/common/curtain_toggle.dart +++ b/lib/pages/common/curtain_toggle.dart @@ -34,7 +34,7 @@ class CurtainToggle extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipOval( - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.curtainIcon, @@ -52,7 +52,7 @@ class CurtainToggle extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeColor: ColorsManager.dialogBlueTitle, + activeTrackColor: ColorsManager.dialogBlueTitle, onChanged: onChanged, ), ), diff --git a/lib/pages/common/custom_dialog.dart b/lib/pages/common/custom_dialog.dart index 9899bda4..78c4a43e 100644 --- a/lib/pages/common/custom_dialog.dart +++ b/lib/pages/common/custom_dialog.dart @@ -12,7 +12,7 @@ Future showCustomDialog({ double? iconWidth, VoidCallback? onOkPressed, bool barrierDismissible = false, - List? actions, + List? actions, }) { return showDialog( context: context, @@ -40,14 +40,20 @@ Future showCustomDialog({ style: Theme.of(context) .textTheme .headlineLarge! - .copyWith(fontSize: 20, fontWeight: FontWeight.w400, color: Colors.black), + .copyWith( + fontSize: 20, + fontWeight: FontWeight.w400, + color: Colors.black), ), ), Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( message, - style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.black), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.black), textAlign: TextAlign.center, ), ), diff --git a/lib/pages/common/custom_table.dart b/lib/pages/common/custom_table.dart index f23daa45..de6da949 100644 --- a/lib/pages/common/custom_table.dart +++ b/lib/pages/common/custom_table.dart @@ -20,8 +20,8 @@ class DynamicTable extends StatefulWidget { final void Function(int, bool, dynamic)? onRowSelected; final List? initialSelectedIds; final int uuidIndex; - final Function(dynamic selectedRows)? onSelectionChanged; - final Function(int rowIndex)? onSettingsPressed; + final void Function(dynamic selectedRows)? onSelectionChanged; + final void Function(int rowIndex)? onSettingsPressed; const DynamicTable({ super.key, required this.headers, @@ -79,10 +79,10 @@ class _DynamicTableState extends State { // Check if the old and new lists are the same if (oldList.length != newList.length) return false; - for (int i = 0; i < oldList.length; i++) { + for (var i = 0; i < oldList.length; i++) { if (oldList[i].length != newList[i].length) return false; - for (int j = 0; j < oldList[i].length; j++) { + for (var j = 0; j < oldList[i].length; j++) { if (oldList[i][j] != newList[i][j]) return false; } } @@ -162,7 +162,7 @@ class _DynamicTableState extends State { child: SingleChildScrollView( scrollDirection: Axis.horizontal, controller: _horizontalBodyScrollController, - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, child: SizedBox( width: widget.size.width, @@ -184,7 +184,7 @@ class _DynamicTableState extends State { rowIndex: rowIndex, columnIndex: entry.key, ); - }).toList(), + }), ], ); }), @@ -304,13 +304,13 @@ class _DynamicTableState extends State { required int rowIndex, required int columnIndex, }) { - bool isBatteryLevel = content.endsWith('%'); + final isBatteryLevel = content.endsWith('%'); double? batteryLevel; if (isBatteryLevel) { batteryLevel = double.tryParse(content.replaceAll('%', '').trim()); } - bool isSettingsColumn = widget.headers[columnIndex] == 'Settings'; + final isSettingsColumn = widget.headers[columnIndex] == 'Settings'; if (isSettingsColumn) { return buildSettingsIcon( @@ -404,7 +404,7 @@ class _DynamicTableState extends State { borderRadius: BorderRadius.circular(height / 2), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.17), + color: Colors.black.withValues(alpha: 0.17), blurRadius: 14, offset: const Offset(0, 4), ), @@ -416,11 +416,10 @@ class _DynamicTableState extends State { padding: const EdgeInsets.all(8.0), child: Center( child: SvgPicture.asset( - Assets.settings, // ضع المسار الصحيح هنا + Assets.settings, width: 40, height: 22, - color: ColorsManager - .primaryColor, // نفس لون الأيقونة في الصورة + color: ColorsManager.primaryColor, ), ), ), diff --git a/lib/pages/common/filter/filter_widget.dart b/lib/pages/common/filter/filter_widget.dart index 1af23045..afd98eef 100644 --- a/lib/pages/common/filter/filter_widget.dart +++ b/lib/pages/common/filter/filter_widget.dart @@ -36,7 +36,7 @@ class FilterWidget extends StatelessWidget { color: ColorsManager.boxColor, border: Border.all( color: isSelected - ? ColorsManager.blueColor.withOpacity(0.8) + ? ColorsManager.blueColor.withValues(alpha: 0.8) : Colors.transparent, width: 2.0, ), @@ -48,7 +48,7 @@ class FilterWidget extends StatelessWidget { tabs[index], style: TextStyle( color: isSelected - ? ColorsManager.blueColor.withOpacity(0.8) + ? ColorsManager.blueColor.withValues(alpha: 0.8) : Colors.black, ), ), diff --git a/lib/pages/common/hour_picker_dialog.dart b/lib/pages/common/hour_picker_dialog.dart index 01a87720..2c5be850 100644 --- a/lib/pages/common/hour_picker_dialog.dart +++ b/lib/pages/common/hour_picker_dialog.dart @@ -1,5 +1,3 @@ - - import 'package:flutter/material.dart'; class HourPickerDialog extends StatefulWidget { @@ -18,7 +16,7 @@ class _HourPickerDialogState extends State { void initState() { super.initState(); // Initialize the selectedHour with the initial time passed to the dialog - selectedHour = widget.initialTime.hour.toString().padLeft(2, '0') + ':00'; + selectedHour = '${widget.initialTime.hour.toString().padLeft(2, '0')}:00'; } @override @@ -28,7 +26,7 @@ class _HourPickerDialogState extends State { content: DropdownButton( value: selectedHour, // Show the currently selected hour items: List.generate(24, (index) { - String hour = index.toString().padLeft(2, '0'); + final hour = index.toString().padLeft(2, '0'); return DropdownMenuItem( value: '$hour:00', child: Text('$hour:00'), @@ -37,14 +35,16 @@ class _HourPickerDialogState extends State { onChanged: (String? newValue) { if (newValue != null) { setState(() { - selectedHour = newValue; // Update the selected hour without closing the dialog + selectedHour = + newValue; // Update the selected hour without closing the dialog }); } }, ), actions: [ TextButton( - onPressed: () => Navigator.of(context).pop(null), // Close the dialog without selection + onPressed: () => Navigator.of(context) + .pop(null), // Close the dialog without selection child: const Text('Cancel'), ), TextButton( diff --git a/lib/pages/common/info_dialog.dart b/lib/pages/common/info_dialog.dart index 97656418..f2062319 100644 --- a/lib/pages/common/info_dialog.dart +++ b/lib/pages/common/info_dialog.dart @@ -9,7 +9,8 @@ class InfoDialog extends StatelessWidget { final Size? size; final List? actions; - InfoDialog({ + const InfoDialog({ + super.key, required this.title, required this.content, this.actions, diff --git a/lib/pages/device_managment/ac/bloc/ac_bloc.dart b/lib/pages/device_managment/ac/bloc/ac_bloc.dart index af5a7b0a..d96a4714 100644 --- a/lib/pages/device_managment/ac/bloc/ac_bloc.dart +++ b/lib/pages/device_managment/ac/bloc/ac_bloc.dart @@ -45,7 +45,8 @@ class AcBloc extends Bloc { ) async { emit(AcsLoadingState()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status); if (deviceStatus.countdown1 != 0) { final totalMinutes = deviceStatus.countdown1 * 6; @@ -71,21 +72,20 @@ class AcBloc extends Bloc { void _listenToChanges(deviceId) { try { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; - - stream.listen((DatabaseEvent event) async { + ref.onValue.listen((DatabaseEvent event) async { if (event.snapshot.value == null) return; - Map usersMap = - event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; usersMap['status'].forEach((element) { - statusList.add(Status(code: element['code'], value: element['value'])); + statusList + .add(Status(code: element['code'], value: element['value'])); }); - deviceStatus = AcStatusModel.fromJson(usersMap['productUuid'], statusList); + deviceStatus = + AcStatusModel.fromJson(usersMap['productUuid'], statusList); if (!isClosed) { add(AcStatusUpdated(deviceStatus)); } @@ -129,8 +129,10 @@ class AcBloc extends Bloc { ) async { emit(AcsLoadingState()); try { - final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); - deviceStatus = AcStatusModel.fromJson(event.devicesIds.first, status.status); + final status = + await DevicesManagementApi().getBatchStatus(event.devicesIds); + deviceStatus = + AcStatusModel.fromJson(event.devicesIds.first, status.status); emit(ACStatusLoaded(status: deviceStatus)); } catch (e) { emit(AcsFailedState(error: e.toString())); @@ -190,8 +192,8 @@ class AcBloc extends Bloc { void _handleIncreaseTime(IncreaseTimeEvent event, Emitter emit) { if (state is! ACStatusLoaded) return; final currentState = state as ACStatusLoaded; - int newHours = scheduledHours; - int newMinutes = scheduledMinutes + 30; + var newHours = scheduledHours; + var newMinutes = scheduledMinutes + 30; newHours += newMinutes ~/ 60; newMinutes = newMinutes % 60; if (newHours > 23) { @@ -213,7 +215,7 @@ class AcBloc extends Bloc { ) { if (state is! ACStatusLoaded) return; final currentState = state as ACStatusLoaded; - int totalMinutes = (scheduledHours * 60) + scheduledMinutes; + var totalMinutes = (scheduledHours * 60) + scheduledMinutes; totalMinutes = (totalMinutes - 30).clamp(0, 1440); scheduledHours = totalMinutes ~/ 60; scheduledMinutes = totalMinutes % 60; @@ -286,7 +288,7 @@ class AcBloc extends Bloc { void _startCountdownTimer(Emitter emit) { _countdownTimer?.cancel(); - int totalSeconds = (scheduledHours * 3600) + (scheduledMinutes * 60); + var totalSeconds = (scheduledHours * 3600) + (scheduledMinutes * 60); _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (totalSeconds > 0) { @@ -336,32 +338,26 @@ class AcBloc extends Bloc { if (value is bool) { deviceStatus = deviceStatus.copyWith(acSwitch: value); } - break; case 'temp_set': if (value is int) { deviceStatus = deviceStatus.copyWith(tempSet: value); } - break; case 'mode': if (value is String) { deviceStatus = deviceStatus.copyWith(modeString: value); } - break; case 'level': if (value is String) { deviceStatus = deviceStatus.copyWith(fanSpeedsString: value); } - break; case 'child_lock': if (value is bool) { deviceStatus = deviceStatus.copyWith(childLock: value); } - break; case 'countdown_time': if (value is int) { deviceStatus = deviceStatus.copyWith(countdown1: value); } - break; default: break; } diff --git a/lib/pages/device_managment/ac/bloc/ac_event.dart b/lib/pages/device_managment/ac/bloc/ac_event.dart index 9764f3ed..217199ea 100644 --- a/lib/pages/device_managment/ac/bloc/ac_event.dart +++ b/lib/pages/device_managment/ac/bloc/ac_event.dart @@ -22,7 +22,7 @@ class AcFetchDeviceStatusEvent extends AcsEvent { class AcStatusUpdated extends AcsEvent { final AcStatusModel deviceStatus; - AcStatusUpdated(this.deviceStatus); + const AcStatusUpdated(this.deviceStatus); } class AcFetchBatchStatusEvent extends AcsEvent { @@ -77,8 +77,6 @@ class AcFactoryResetEvent extends AcsEvent { List get props => [deviceId, factoryResetModel]; } - - class OnClose extends AcsEvent {} class IncreaseTimeEvent extends AcsEvent { @@ -95,8 +93,7 @@ class ToggleScheduleEvent extends AcsEvent {} class TimerCompletedEvent extends AcsEvent {} -class UpdateTimerEvent extends AcsEvent { -} +class UpdateTimerEvent extends AcsEvent {} class ApiCountdownValueEvent extends AcsEvent { final int apiValue; diff --git a/lib/pages/device_managment/ac/bloc/ac_state.dart b/lib/pages/device_managment/ac/bloc/ac_state.dart index 3e1e2c68..a8985957 100644 --- a/lib/pages/device_managment/ac/bloc/ac_state.dart +++ b/lib/pages/device_managment/ac/bloc/ac_state.dart @@ -18,6 +18,7 @@ class ACStatusLoaded extends AcsState { final DateTime timestamp; final int scheduledHours; final int scheduledMinutes; + @override final bool isTimerActive; ACStatusLoaded({ @@ -72,5 +73,3 @@ class TimerRunInProgress extends AcsState { @override List get props => [remainingTime]; } - - diff --git a/lib/pages/device_managment/ac/model/ac_model.dart b/lib/pages/device_managment/ac/model/ac_model.dart index 6afc778d..32a7de0c 100644 --- a/lib/pages/device_managment/ac/model/ac_model.dart +++ b/lib/pages/device_managment/ac/model/ac_model.dart @@ -32,9 +32,9 @@ class AcStatusModel { late int currentTemp; late String fanSpeeds; late bool childLock; - late int _countdown1 = 0; + late var countdown1 = 0; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch': acSwitch = status.value ?? false; @@ -55,7 +55,7 @@ class AcStatusModel { childLock = status.value ?? false; break; case 'countdown_time': - _countdown1 = status.value ?? 0; + countdown1 = status.value ?? 0; break; } } @@ -68,7 +68,7 @@ class AcStatusModel { currentTemp: currentTemp, fanSpeedsString: fanSpeeds, childLock: childLock, - countdown1: _countdown1, + countdown1: countdown1, ); } diff --git a/lib/pages/device_managment/ac/view/ac_device_batch_control.dart b/lib/pages/device_managment/ac/view/ac_device_batch_control.dart index aad0669b..5b03ae3d 100644 --- a/lib/pages/device_managment/ac/view/ac_device_batch_control.dart +++ b/lib/pages/device_managment/ac/view/ac_device_batch_control.dart @@ -15,7 +15,8 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class AcDeviceBatchControlView extends StatelessWidget + with HelperResponsiveLayout { const AcDeviceBatchControlView({super.key, required this.devicesIds}); final List devicesIds; @@ -100,8 +101,8 @@ class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayo ), Text( 'h', - style: - context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor), + style: context.textTheme.bodySmall! + .copyWith(color: ColorsManager.blackColor), ), Text( '30', @@ -148,7 +149,8 @@ class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayo callFactoryReset: () { context.read().add(AcFactoryResetEvent( deviceId: state.status.uuid, - factoryResetModel: FactoryResetModel(devicesUuid: devicesIds), + factoryResetModel: + FactoryResetModel(devicesUuid: devicesIds), )); }, ), diff --git a/lib/pages/device_managment/ac/view/ac_device_control.dart b/lib/pages/device_managment/ac/view/ac_device_control.dart index a882e6d5..b779a5ca 100644 --- a/lib/pages/device_managment/ac/view/ac_device_control.dart +++ b/lib/pages/device_managment/ac/view/ac_device_control.dart @@ -14,7 +14,7 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout { - const AcDeviceControlsView({super.key, required this.device}); + const AcDeviceControlsView({super.key, required this.device}); final AllDevicesModel device; diff --git a/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart b/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart index be7441df..11724f1d 100644 --- a/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart +++ b/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart @@ -41,7 +41,7 @@ class _CurrentTempState extends State { double _initialAdjustedValue(dynamic value) { if (value is int || value is double) { - double doubleValue = value.toDouble(); + final double doubleValue = value.toDouble(); return doubleValue > 99 ? doubleValue / 10 : doubleValue; } else { throw ArgumentError('Invalid value type: Expected int or double'); @@ -75,35 +75,48 @@ class _CurrentTempState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - widget.isBatch == true - ? Text( - 'Set Temperature', - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), - ) - : Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + if (widget.isBatch == true) + Text( + 'Set Temperature', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey), + ) + else + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Current Temperature', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey), + ), + const SizedBox( + height: 5, + ), + Row( children: [ Text( - 'Current Temperature', - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), - ), - const SizedBox( - height: 5, - ), - Row( - children: [ - Text( - (widget.currentTemp > 99 ? widget.currentTemp / 10 : widget.currentTemp).toString(), - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), - ), - const CelsiusSymbol( - color: Colors.grey, - ) - ], + (widget.currentTemp > 99 + ? widget.currentTemp / 10 + : widget.currentTemp) + .toString(), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey), ), + const CelsiusSymbol( + color: Colors.grey, + ) ], ), + ], + ), const Spacer(), IncrementDecrementWidget( value: _adjustedValue.toString(), diff --git a/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart b/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart index 4e81ec09..8e592d48 100644 --- a/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart +++ b/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart @@ -52,7 +52,7 @@ class AcToggle extends StatelessWidget { height: 20, width: 35, child: CupertinoSwitch( - activeColor: ColorsManager.dialogBlueTitle, + activeTrackColor: ColorsManager.dialogBlueTitle, value: value, onChanged: (newValue) { context.read().add( diff --git a/lib/pages/device_managment/ac/view/control_list/current_temp.dart b/lib/pages/device_managment/ac/view/control_list/current_temp.dart index fdd51164..7c5f9494 100644 --- a/lib/pages/device_managment/ac/view/control_list/current_temp.dart +++ b/lib/pages/device_managment/ac/view/control_list/current_temp.dart @@ -39,7 +39,7 @@ class _CurrentTempState extends State { double _initialAdjustedValue(dynamic value) { if (value is int || value is double) { - double doubleValue = value.toDouble(); + final double doubleValue = value.toDouble(); return doubleValue > 99 ? doubleValue / 10 : doubleValue; } else { throw ArgumentError('Invalid value type: Expected int or double'); @@ -60,6 +60,7 @@ class _CurrentTempState extends State { ); }); } + @override void didUpdateWidget(CurrentTemp oldWidget) { super.didUpdateWidget(oldWidget); @@ -69,6 +70,7 @@ class _CurrentTempState extends State { }); } } + @override void dispose() { _debounce?.cancel(); @@ -87,7 +89,10 @@ class _CurrentTempState extends State { children: [ Text( 'Current Temperature', - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey), ), const SizedBox( height: 5, @@ -95,8 +100,14 @@ class _CurrentTempState extends State { Row( children: [ Text( - (widget.currentTemp > 99 ? widget.currentTemp / 10 : widget.currentTemp).toString(), - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), + (widget.currentTemp > 99 + ? widget.currentTemp / 10 + : widget.currentTemp) + .toString(), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.grey), ), const CelsiusSymbol( color: Colors.grey, diff --git a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart index 05e82f1f..0cf13036 100644 --- a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart +++ b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart @@ -16,7 +16,7 @@ class DeviceManagementBloc int _onlineCount = 0; int _offlineCount = 0; int _lowBatteryCount = 0; - List _selectedDevices = []; + final List _selectedDevices = []; List _filteredDevices = []; String currentProductName = ''; String? currentCommunity; @@ -37,20 +37,21 @@ class DeviceManagementBloc FetchDevices event, Emitter emit) async { emit(DeviceManagementLoading()); try { - List devices = []; + var devices = []; _devices.clear(); - var spaceBloc = event.context.read(); - final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + final spaceBloc = event.context.read(); + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; if (spaceBloc.state.selectedCommunities.isEmpty) { - devices = await DevicesManagementApi().fetchDevices('', '', projectUuid); + devices = + await DevicesManagementApi().fetchDevices('', '', projectUuid); } else { - for (var community in spaceBloc.state.selectedCommunities) { - List spacesList = + for (final community in spaceBloc.state.selectedCommunities) { + final spacesList = spaceBloc.state.selectedCommunityAndSpaces[community] ?? []; - for (var space in spacesList) { - devices.addAll(await DevicesManagementApi().fetchDevices( - community, space, projectUuid)); + for (final space in spacesList) { + devices.addAll(await DevicesManagementApi() + .fetchDevices(community, space, projectUuid)); } } } @@ -73,7 +74,7 @@ class DeviceManagementBloc } } - void _onFilterDevices( + Future _onFilterDevices( FilterDevices event, Emitter emit) async { if (_devices.isNotEmpty) { _filteredDevices = List.from(_devices.where((device) { @@ -165,9 +166,9 @@ class DeviceManagementBloc _selectedDevices.add(event.selectedDevice); } - List clonedSelectedDevices = List.from(_selectedDevices); + final clonedSelectedDevices = List.from(_selectedDevices); - bool isControlButtonEnabled = + final isControlButtonEnabled = _checkIfControlButtonEnabled(clonedSelectedDevices); if (state is DeviceManagementLoaded) { @@ -197,8 +198,8 @@ class DeviceManagementBloc void _onUpdateSelection( UpdateSelection event, Emitter emit) { - List selectedDevices = []; - List devicesToSelectFrom = []; + final selectedDevices = []; + var devicesToSelectFrom = []; if (state is DeviceManagementLoaded) { devicesToSelectFrom = (state as DeviceManagementLoaded).devices; @@ -206,7 +207,7 @@ class DeviceManagementBloc devicesToSelectFrom = (state as DeviceManagementFiltered).filteredDevices; } - for (int i = 0; i < event.selectedRows.length; i++) { + for (var i = 0; i < event.selectedRows.length; i++) { if (event.selectedRows[i]) { selectedDevices.add(devicesToSelectFrom[i]); } @@ -294,7 +295,7 @@ class DeviceManagementBloc currentCommunity = event.community; currentUnitName = event.unitName; - List devicesToSearch = _filteredDevices; + final devicesToSearch = _filteredDevices; if (devicesToSearch.isNotEmpty) { final filteredDevices = devicesToSearch.where((device) { diff --git a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart index 5586a310..25a8342b 100644 --- a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart +++ b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart @@ -18,6 +18,7 @@ import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dar import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart'; import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart'; +import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart'; import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart'; import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart'; @@ -39,8 +40,6 @@ import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heate import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_control_view.dart'; -import '../../one_g_glass_switch/view/one_gang_glass_switch_control_view.dart'; - mixin RouteControlsBasedCode { Widget routeControlsWidgets({required AllDevicesModel device}) { switch (device.productType) { @@ -107,7 +106,7 @@ mixin RouteControlsBasedCode { case 'SOS': return SosDeviceControlsView(device: device); - case 'NCPS': + case 'NCPS': return FlushMountedPresenceSensorControlView(device: device); default: return const SizedBox(); @@ -132,76 +131,133 @@ mixin RouteControlsBasedCode { switch (devices.first.productType) { case '1G': return WallLightBatchControlView( - deviceIds: devices.where((e) => (e.productType == '1G')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == '1G') + .map((e) => e.uuid!) + .toList(), ); case '2G': return TwoGangBatchControlView( - deviceIds: devices.where((e) => (e.productType == '2G')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == '2G') + .map((e) => e.uuid!) + .toList(), ); case '3G': return LivingRoomBatchControlsView( - deviceIds: devices.where((e) => (e.productType == '3G')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == '3G') + .map((e) => e.uuid!) + .toList(), ); case '1GT': return OneGangGlassSwitchBatchControlView( - deviceIds: devices.where((e) => (e.productType == '1GT')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == '1GT') + .map((e) => e.uuid!) + .toList(), ); case '2GT': return TwoGangGlassSwitchBatchControlView( - deviceIds: devices.where((e) => (e.productType == '2GT')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == '2GT') + .map((e) => e.uuid!) + .toList(), ); case '3GT': return ThreeGangGlassSwitchBatchControlView( - deviceIds: devices.where((e) => (e.productType == '3GT')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == '3GT') + .map((e) => e.uuid!) + .toList(), ); case 'GW': return GatewayBatchControlView( - gatewayIds: devices.where((e) => (e.productType == 'GW')).map((e) => e.uuid!).toList(), + gatewayIds: devices + .where((e) => e.productType == 'GW') + .map((e) => e.uuid!) + .toList(), ); case 'DL': return DoorLockBatchControlView( - devicesIds: devices.where((e) => (e.productType == 'DL')).map((e) => e.uuid!).toList()); + devicesIds: devices + .where((e) => e.productType == 'DL') + .map((e) => e.uuid!) + .toList()); case 'WPS': return WallSensorBatchControlView( - devicesIds: devices.where((e) => (e.productType == 'WPS')).map((e) => e.uuid!).toList()); + devicesIds: devices + .where((e) => e.productType == 'WPS') + .map((e) => e.uuid!) + .toList()); case 'CPS': return CeilingSensorBatchControlView( - devicesIds: devices.where((e) => (e.productType == 'CPS')).map((e) => e.uuid!).toList(), + devicesIds: devices + .where((e) => e.productType == 'CPS') + .map((e) => e.uuid!) + .toList(), ); case 'CUR': return CurtainBatchStatusView( - devicesIds: devices.where((e) => (e.productType == 'CUR')).map((e) => e.uuid!).toList(), + devicesIds: devices + .where((e) => e.productType == 'CUR') + .map((e) => e.uuid!) + .toList(), ); case 'AC': return AcDeviceBatchControlView( - devicesIds: devices.where((e) => (e.productType == 'AC')).map((e) => e.uuid!).toList()); + devicesIds: devices + .where((e) => e.productType == 'AC') + .map((e) => e.uuid!) + .toList()); case 'WH': return WaterHEaterBatchControlView( - deviceIds: devices.where((e) => (e.productType == 'WH')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == 'WH') + .map((e) => e.uuid!) + .toList(), ); case 'DS': return MainDoorSensorBatchView( - devicesIds: devices.where((e) => (e.productType == 'DS')).map((e) => e.uuid!).toList(), + devicesIds: devices + .where((e) => e.productType == 'DS') + .map((e) => e.uuid!) + .toList(), ); case 'GD': return GarageDoorBatchControlView( - deviceIds: devices.where((e) => (e.productType == 'GD')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == 'GD') + .map((e) => e.uuid!) + .toList(), ); case 'WL': return WaterLeakBatchControlView( - deviceIds: devices.where((e) => (e.productType == 'WL')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == 'WL') + .map((e) => e.uuid!) + .toList(), ); case 'PC': return PowerClampBatchControlView( - deviceIds: devices.where((e) => (e.productType == 'PC')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == 'PC') + .map((e) => e.uuid!) + .toList(), ); case 'SOS': return SOSBatchControlView( - deviceIds: devices.where((e) => (e.productType == 'SOS')).map((e) => e.uuid!).toList(), + deviceIds: devices + .where((e) => e.productType == 'SOS') + .map((e) => e.uuid!) + .toList(), ); case 'NCPS': return FlushMountedPresenceSensorBatchControlView( - devicesIds: devices.where((e) => (e.productType == 'NCPS')).map((e) => e.uuid!).toList(), + devicesIds: devices + .where((e) => e.productType == 'NCPS') + .map((e) => e.uuid!) + .toList(), ); default: return const SizedBox(); diff --git a/lib/pages/device_managment/all_devices/models/device_sub_space.dart b/lib/pages/device_managment/all_devices/models/device_sub_space.dart index 96195f76..bf94524b 100644 --- a/lib/pages/device_managment/all_devices/models/device_sub_space.dart +++ b/lib/pages/device_managment/all_devices/models/device_sub_space.dart @@ -5,7 +5,12 @@ class DeviceSubSpace { String? subspaceName; bool? disabled; - DeviceSubSpace({this.id, this.createdAt, this.updatedAt, this.subspaceName, this.disabled}); + DeviceSubSpace( + {this.id, + this.createdAt, + this.updatedAt, + this.subspaceName, + this.disabled}); DeviceSubSpace.fromJson(Map json) { id = json['uuid']?.toString() ?? ''; diff --git a/lib/pages/device_managment/all_devices/models/devices_model.dart b/lib/pages/device_managment/all_devices/models/devices_model.dart index 808a683f..a14b14d3 100644 --- a/lib/pages/device_managment/all_devices/models/devices_model.dart +++ b/lib/pages/device_managment/all_devices/models/devices_model.dart @@ -212,8 +212,8 @@ PC SOS */ - DeviceType type = devicesTypesMap[productType] ?? DeviceType.Other; - String tempIcon = ''; + final type = devicesTypesMap[productType] ?? DeviceType.Other; + var tempIcon = ''; if (type == DeviceType.LightBulb) { tempIcon = Assets.lightBulb; } else if (type == DeviceType.CeilingSensor || @@ -441,13 +441,9 @@ SOS VoltageCStatusFunction( deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), CurrentCStatusFunction( - deviceId: uuid ?? '', - deviceName: name ?? '', - type: 'IF'), + deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), PowerFactorCStatusFunction( - deviceId: uuid ?? '', - deviceName: name ?? '', - type: 'IF'), + deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), ]; default: @@ -565,23 +561,23 @@ SOS } Map devicesTypesMap = { - "AC": DeviceType.AC, - "GW": DeviceType.Gateway, - "CPS": DeviceType.CeilingSensor, - "DL": DeviceType.DoorLock, - "WPS": DeviceType.WallSensor, - "3G": DeviceType.ThreeGang, - "2G": DeviceType.TwoGang, - "1G": DeviceType.OneGang, - "CUR": DeviceType.Curtain, - "WH": DeviceType.WH, - "DS": DeviceType.DS, - "1GT": DeviceType.OneTouch, - "2GT": DeviceType.TowTouch, - "3GT": DeviceType.ThreeTouch, - "GD": DeviceType.GarageDoor, - "WL": DeviceType.WaterLeak, - "NCPS": DeviceType.NCPS, - "PC": DeviceType.PC, + 'AC': DeviceType.AC, + 'GW': DeviceType.Gateway, + 'CPS': DeviceType.CeilingSensor, + 'DL': DeviceType.DoorLock, + 'WPS': DeviceType.WallSensor, + '3G': DeviceType.ThreeGang, + '2G': DeviceType.TwoGang, + '1G': DeviceType.OneGang, + 'CUR': DeviceType.Curtain, + 'WH': DeviceType.WH, + 'DS': DeviceType.DS, + '1GT': DeviceType.OneTouch, + '2GT': DeviceType.TowTouch, + '3GT': DeviceType.ThreeTouch, + 'GD': DeviceType.GarageDoor, + 'WL': DeviceType.WaterLeak, + 'NCPS': DeviceType.NCPS, + 'PC': DeviceType.PC, }; } diff --git a/lib/pages/device_managment/all_devices/models/factory_reset_model.dart b/lib/pages/device_managment/all_devices/models/factory_reset_model.dart index 1b5685a1..decfa05f 100644 --- a/lib/pages/device_managment/all_devices/models/factory_reset_model.dart +++ b/lib/pages/device_managment/all_devices/models/factory_reset_model.dart @@ -6,13 +6,13 @@ class FactoryResetModel { FactoryResetModel({ required this.devicesUuid, - this.operationType = "RESET", + this.operationType = 'RESET', }); factory FactoryResetModel.fromJson(Map json) { return FactoryResetModel( devicesUuid: List.from(json['devicesUuid']), - operationType: "RESET", + operationType: 'RESET', ); } @@ -58,4 +58,3 @@ class FactoryResetModel { @override int get hashCode => devicesUuid.hashCode; } - diff --git a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart index f4baad0c..abd06cd0 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart @@ -24,13 +24,13 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - List devicesToShow = []; - int selectedIndex = 0; - int onlineCount = 0; - int offlineCount = 0; - int lowBatteryCount = 0; - bool isControlButtonEnabled = false; - List selectedDevices = []; + var devicesToShow = []; + var selectedIndex = 0; + var onlineCount = 0; + var offlineCount = 0; + var lowBatteryCount = 0; + var isControlButtonEnabled = false; + var selectedDevices = []; if (state is DeviceManagementLoaded) { devicesToShow = state.devices; @@ -194,18 +194,23 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { device.name ?? '', device.productName ?? '', device.uuid ?? '', - (device.spaces != null && - device.spaces!.isNotEmpty) - ? device.spaces![0].spaceName - : '', + if (device.spaces != null && + device.spaces!.isNotEmpty) + device.spaces![0].spaceName + else + '', combinedSpaceNames, - device.batteryLevel != null - ? '${device.batteryLevel}%' - : '-', + if (device.batteryLevel != null) + '${device.batteryLevel}%' + else + '-', formatDateTime( DateTime.fromMillisecondsSinceEpoch( (device.createTime ?? 0) * 1000)), - device.online == true ? 'Online' : 'Offline', + if (device.online == true) + 'Online' + else + 'Offline', formatDateTime( DateTime.fromMillisecondsSinceEpoch( (device.updateTime ?? 0) * 1000)), @@ -243,7 +248,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { showGeneralDialog( context: context, barrierDismissible: true, - barrierLabel: "Device Settings", + barrierLabel: 'Device Settings', transitionDuration: const Duration(milliseconds: 300), pageBuilder: (context, anim1, anim2) { return Align( diff --git a/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart b/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart index 6440d18f..99378a86 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart @@ -33,9 +33,9 @@ class _DeviceSearchFiltersState extends State spacing: 20, runSpacing: 10, children: [ - _buildSearchField("Space Name", _unitNameController, 200), + _buildSearchField('Space Name', _unitNameController, 200), _buildSearchField( - "Device Name / Product Name", _productNameController, 300), + 'Device Name / Product Name', _productNameController, 300), _buildSearchResetButtons(), ], ); diff --git a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart index 42387e57..0d5e59b2 100644 --- a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart +++ b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart @@ -37,7 +37,8 @@ class CeilingSensorBloc extends Bloc { ) async { emit(CeilingLoadingInitialState()); try { - final response = await DevicesManagementApi().getDeviceStatus(event.deviceId); + final response = + await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); _listenToChanges(event.deviceId); @@ -54,11 +55,12 @@ class CeilingSensorBloc extends Bloc { stream.listen((DatabaseEvent event) { if (event.snapshot.value == null) return; - final usersMap = event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; final statusList = []; usersMap['status'].forEach((element) { - statusList.add(Status(code: element['code'], value: element['value'])); + statusList + .add(Status(code: element['code'], value: element['value'])); }); deviceStatus = CeilingSensorModel.fromJson(statusList); @@ -178,7 +180,8 @@ class CeilingSensorBloc extends Bloc { ) async { emit(CeilingLoadingInitialState()); try { - final response = await DevicesManagementApi().getBatchStatus(event.devicesIds); + final response = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); } catch (e) { diff --git a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart index 1dc7d8d7..e296e1b9 100644 --- a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart +++ b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart @@ -85,8 +85,6 @@ class CeilingFactoryResetEvent extends CeilingSensorEvent { List get props => [devicesId, factoryResetModel]; } - - class StatusUpdated extends CeilingSensorEvent { final CeilingSensorModel deviceStatus; const StatusUpdated(this.deviceStatus); diff --git a/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart b/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart index 08a65a11..c05b4e09 100644 --- a/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart +++ b/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart @@ -26,48 +26,53 @@ class CeilingSensorModel { }); factory CeilingSensorModel.fromJson(List jsonList) { - late String _presenceState = 'none'; - late int _sensitivity = 1; - late String _checkingResult = ''; - int _presenceRange = 1; - int _sportsPara = 1; - String _bodyMovement = 'none'; - String _noBodyTime = 'none'; - int _maxDis = 0; - SpaceTypes _spaceType = SpaceTypes.none; + late var presenceState = 'none'; + late var sensitivity = 1; + late var checkingResult = ''; + var presenceRange = 1; + var sportsPara = 1; + var bodyMovement = 'none'; + var noBodyTime = 'none'; + var maxDis = 0; + var spaceType = SpaceTypes.none; try { - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'presence_state': - _presenceState = status.value ?? 'none'; + presenceState = status.value ?? 'none'; break; case 'scene': - _spaceType = getSpaceType(status.value ?? 'none'); + spaceType = getSpaceType(status.value ?? 'none'); break; case 'sensitivity': - _sensitivity = - status.value is int ? status.value : int.tryParse(status.value ?? '1') ?? 1; + sensitivity = status.value is int + ? status.value + : int.tryParse(status.value ?? '1') ?? 1; break; case 'checking_result': - _checkingResult = status.value ?? ''; + checkingResult = status.value ?? ''; break; case 'presence_range': - _presenceRange = - status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0; + presenceRange = status.value is int + ? status.value + : int.tryParse(status.value ?? '0') ?? 0; break; case 'sports_para': - _sportsPara = - status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0; + sportsPara = status.value is int + ? status.value + : int.tryParse(status.value ?? '0') ?? 0; break; case 'body_movement': - _bodyMovement = status.value ?? ''; + bodyMovement = status.value ?? ''; break; case 'nobody_time': - _noBodyTime = status.value ?? 'none'; + noBodyTime = status.value ?? 'none'; break; case 'moving_max_dis': - _maxDis = status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0; + maxDis = status.value is int + ? status.value + : int.tryParse(status.value ?? '0') ?? 0; break; } } @@ -76,15 +81,15 @@ class CeilingSensorModel { } return CeilingSensorModel( - presenceState: _presenceState, - sensitivity: _sensitivity, - checkingResult: _checkingResult, - presenceRange: _presenceRange, - sportsPara: _sportsPara, - bodyMovement: _bodyMovement, - noBodyTime: _noBodyTime, - maxDistance: _maxDis, - spaceType: _spaceType, + presenceState: presenceState, + sensitivity: sensitivity, + checkingResult: checkingResult, + presenceRange: presenceRange, + sportsPara: sportsPara, + bodyMovement: bodyMovement, + noBodyTime: noBodyTime, + maxDistance: maxDis, + spaceType: spaceType, ); } diff --git a/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart b/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart index 9b5ab360..3f57e7a1 100644 --- a/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart +++ b/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart @@ -12,7 +12,8 @@ import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presen import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class CeilingSensorBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class CeilingSensorBatchControlView extends StatelessWidget + with HelperResponsiveLayout { const CeilingSensorBatchControlView({super.key, required this.devicesIds}); final List devicesIds; @@ -28,11 +29,12 @@ class CeilingSensorBatchControlView extends StatelessWidget with HelperResponsiv )..add(CeilingFetchDeviceStatusEvent(devicesIds)), child: BlocBuilder( builder: (context, state) { - if (state is CeilingLoadingInitialState || state is CeilingReportsLoadingState) { + if (state is CeilingLoadingInitialState || + state is CeilingReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is CeilingUpdateState) { - return _buildGridView( - context, state.ceilingSensorModel, isExtraLarge, isLarge, isMedium); + return _buildGridView(context, state.ceilingSensorModel, + isExtraLarge, isLarge, isMedium); } return const Center(child: Text('Error fetching status')); }, @@ -40,8 +42,8 @@ class CeilingSensorBatchControlView extends StatelessWidget with HelperResponsiv ); } - Widget _buildGridView(BuildContext context, CeilingSensorModel model, bool isExtraLarge, - bool isLarge, bool isMedium) { + Widget _buildGridView(BuildContext context, CeilingSensorModel model, + bool isExtraLarge, bool isLarge, bool isMedium) { return GridView( padding: const EdgeInsets.symmetric(horizontal: 50), shrinkWrap: true, @@ -116,7 +118,8 @@ class CeilingSensorBatchControlView extends StatelessWidget with HelperResponsiv context.read().add( CeilingFactoryResetEvent( devicesId: devicesIds.first, - factoryResetModel: FactoryResetModel(devicesUuid: devicesIds), + factoryResetModel: + FactoryResetModel(devicesUuid: devicesIds), ), ); }, diff --git a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart index 749a7729..f75ff8b4 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart @@ -34,7 +34,8 @@ class CurtainBloc extends Bloc { ) async { emit(CurtainStatusLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(event.deviceId, emit); deviceStatus = _checkStatus(status.status[0].value); emit(CurtainStatusLoaded(deviceStatus)); @@ -54,7 +55,7 @@ class CurtainBloc extends Bloc { final statusList = []; if (data['status'] != null) { - for (var element in data['status']) { + for (final element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -121,7 +122,8 @@ class CurtainBloc extends Bloc { ) async { emit(CurtainStatusLoading()); try { - final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); + final status = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = _checkStatus(status.status[0].value); emit(CurtainStatusLoaded(deviceStatus)); } catch (e) { diff --git a/lib/pages/device_managment/curtain/bloc/curtain_event.dart b/lib/pages/device_managment/curtain/bloc/curtain_event.dart index dd6700f9..d8c85ccd 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_event.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_event.dart @@ -60,7 +60,8 @@ class CurtainFactoryReset extends CurtainEvent { @override List get props => [deviceId, factoryReset]; } + class StatusUpdated extends CurtainEvent { final bool deviceStatus; const StatusUpdated(this.deviceStatus); -} \ No newline at end of file +} diff --git a/lib/pages/device_managment/curtain/bloc/curtain_state.dart b/lib/pages/device_managment/curtain/bloc/curtain_state.dart index dfe11c2a..72d974f1 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_state.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_state.dart @@ -1,7 +1,6 @@ - import 'package:equatable/equatable.dart'; -sealed class CurtainState extends Equatable { +sealed class CurtainState extends Equatable { const CurtainState(); @override diff --git a/lib/pages/device_managment/curtain/model/curtain_model.dart b/lib/pages/device_managment/curtain/model/curtain_model.dart index 908415d5..0a400c38 100644 --- a/lib/pages/device_managment/curtain/model/curtain_model.dart +++ b/lib/pages/device_managment/curtain/model/curtain_model.dart @@ -12,8 +12,8 @@ class CurtainModel { }); factory CurtainModel.fromJson(dynamic json) { - var statusList = json['status'] as List; - List status = statusList.map((i) => Status.fromJson(i)).toList(); + final statusList = json['status'] as List; + final status = statusList.map((i) => Status.fromJson(i)).toList(); return CurtainModel( productUuid: json['productUuid'], diff --git a/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart b/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart index 41dcaf9e..ccb9613d 100644 --- a/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart +++ b/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart @@ -10,7 +10,8 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class CurtainBatchStatusView extends StatelessWidget with HelperResponsiveLayout { +class CurtainBatchStatusView extends StatelessWidget + with HelperResponsiveLayout { const CurtainBatchStatusView({super.key, required this.devicesIds}); final List devicesIds; @@ -18,8 +19,8 @@ class CurtainBatchStatusView extends StatelessWidget with HelperResponsiveLayout @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - CurtainBlocFactory.create(deviceId: devicesIds.first)..add(CurtainFetchBatchStatus(devicesIds)), + create: (context) => CurtainBlocFactory.create(deviceId: devicesIds.first) + ..add(CurtainFetchBatchStatus(devicesIds)), child: BlocBuilder( builder: (context, state) { if (state is CurtainStatusLoading) { diff --git a/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart b/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart index c996cf72..73e31f89 100644 --- a/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart +++ b/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart @@ -2,12 +2,13 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; -import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart'; +import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; + part 'setting_bloc_event.dart'; class SettingDeviceBloc extends Bloc { @@ -37,7 +38,7 @@ class SettingDeviceBloc extends Bloc { String? _fullNameValidator(String? value) { if (value == null) return 'name is required'; - final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); + final withoutExtraSpaces = value.replaceAll(RegExp(r'\s+'), ' ').trim(); if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { return 'name must be between 2 and 30 characters long'; } @@ -66,8 +67,8 @@ class SettingDeviceBloc extends Bloc { DeviceSettingInitialInfo event, Emitter emit) async { try { emit(DeviceSettingsLoading()); - var response = await DevicesManagementApi.getDeviceInfo(deviceId); - DeviceInfoModel deviceInfo = DeviceInfoModel.fromJson(response); + final response = await DevicesManagementApi.getDeviceInfo(deviceId); + final deviceInfo = DeviceInfoModel.fromJson(response); nameController.text = deviceInfo.name; emit(DeviceSettingsUpdate( deviceName: nameController.text, @@ -92,9 +93,7 @@ class SettingDeviceBloc extends Bloc { )); editName = event.value!; if (editName) { - Future.delayed(const Duration(milliseconds: 500), () { - focusNode.requestFocus(); - }); + Future.delayed(const Duration(milliseconds: 500), focusNode.requestFocus); } else { add(const SettingBlocSaveName()); focusNode.unfocus(); @@ -106,7 +105,7 @@ class SettingDeviceBloc extends Bloc { )); } - void _deleteDevice( + Future _deleteDevice( SettingBlocDeleteDevice event, Emitter emit) async { try { emit(DeviceSettingsLoading()); @@ -123,7 +122,7 @@ class SettingDeviceBloc extends Bloc { } } - void _onAssignDevice( + Future _onAssignDevice( SettingBlocAssignRoom event, Emitter emit) async { try { emit(DeviceSettingsLoading()); @@ -143,7 +142,7 @@ class SettingDeviceBloc extends Bloc { } } - void _fetchRooms( + Future _fetchRooms( SettingBlocFetchRooms event, Emitter emit) async { try { emit(DeviceSettingsLoading()); diff --git a/lib/pages/device_managment/device_setting/device_settings_panel.dart b/lib/pages/device_managment/device_setting/device_settings_panel.dart index 48458b3b..cea5bea6 100644 --- a/lib/pages/device_managment/device_setting/device_settings_panel.dart +++ b/lib/pages/device_managment/device_setting/device_settings_panel.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/device_icon_type_helper.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/device_management_content.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/remove_device_widget.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart'; -import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart'; -import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -38,7 +38,7 @@ class DeviceSettingsPanel extends StatelessWidget { builder: (context) { return BlocBuilder( builder: (context, state) { - final _bloc = context.read(); + final bloc = context.read(); final iconPath = DeviceIconTypeHelper.getDeviceIconByTypeCode( device.productType); final deviceInfo = state is DeviceSettingsUpdate @@ -73,7 +73,7 @@ class DeviceSettingsPanel extends StatelessWidget { .copyWith( fontWeight: FontWeight.w700, color: ColorsManager.vividBlue - .withOpacity(0.7), + .withValues(alpha: 0.7), fontSize: 24), ), ], @@ -87,8 +87,8 @@ class DeviceSettingsPanel extends StatelessWidget { padding: const EdgeInsets.only(left: 15), child: CircleAvatar( radius: 38, - backgroundColor: - ColorsManager.grayBorder.withOpacity(0.5), + backgroundColor: ColorsManager.grayBorder + .withValues(alpha: 0.5), child: CircleAvatar( backgroundColor: ColorsManager.whiteColors, radius: 36, @@ -128,14 +128,14 @@ class DeviceSettingsPanel extends StatelessWidget { fontSize: 16, ), textAlign: TextAlign.start, - focusNode: _bloc.focusNode, - controller: _bloc.nameController, - enabled: _bloc.editName, + focusNode: bloc.focusNode, + controller: bloc.nameController, + enabled: bloc.editName, onFieldSubmitted: (value) { - _bloc.add(const ChangeNameEvent( + bloc.add(const ChangeNameEvent( value: false)); }, - decoration: InputDecoration( + decoration: const InputDecoration( isDense: true, contentPadding: EdgeInsets.zero, border: InputBorder.none, @@ -151,11 +151,11 @@ class DeviceSettingsPanel extends StatelessWidget { height: 25, child: Visibility( visible: - _bloc.editName != true, + bloc.editName != true, replacement: const SizedBox(), child: InkWell( onTap: () { - _bloc.add( + bloc.add( const ChangeNameEvent( value: true)); }, @@ -192,14 +192,14 @@ class DeviceSettingsPanel extends StatelessWidget { deviceInfo: deviceInfo, ), const SizedBox(height: 32), - RemoveDeviceWidget(bloc: _bloc), + RemoveDeviceWidget(bloc: bloc), ], ), ), if (state is DeviceSettingsLoading) Positioned.fill( - child: Container( - color: Colors.black.withOpacity(0.1), + child: ColoredBox( + color: Colors.black.withValues(alpha: 0.1), child: const Center( child: CircularProgressIndicator( color: ColorsManager.primaryColor, diff --git a/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart b/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart index 9d3f4036..f4ab1cd0 100644 --- a/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart +++ b/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart @@ -20,9 +20,9 @@ class SubSpaceModel { } factory SubSpaceModel.fromJson(Map json) { - List devices = []; + final devices = []; if (json['devices'] != null) { - for (var device in json['devices']) { + for (final device in json['devices']) { devices.add(DeviceModel.fromJson(device)); } } diff --git a/lib/pages/device_managment/device_setting/sub_space_dialog.dart b/lib/pages/device_managment/device_setting/sub_space_dialog.dart index 28350d4d..2b909a85 100644 --- a/lib/pages/device_managment/device_setting/sub_space_dialog.dart +++ b/lib/pages/device_managment/device_setting/sub_space_dialog.dart @@ -12,11 +12,11 @@ class SubSpaceDialog extends StatefulWidget { final void Function(SubSpaceModel?) onConfirmed; const SubSpaceDialog({ - Key? key, + super.key, required this.subSpaces, this.selected, required this.onConfirmed, - }) : super(key: key); + }); @override State createState() => _SubSpaceDialogState(); @@ -63,7 +63,7 @@ class _SubSpaceDialogState extends State { _selectedId = value; }); }, - activeColor: Color(0xFF2962FF), + activeColor: const Color(0xFF2962FF), title: Text( space.name ?? 'Unnamed Sub-Space', style: context.textTheme.bodyMedium?.copyWith( @@ -75,7 +75,7 @@ class _SubSpaceDialogState extends State { controlAffinity: ListTileControlAffinity.trailing, contentPadding: const EdgeInsets.symmetric(horizontal: 24), ); - }).toList(), + }), const SizedBox(height: 12), const Divider(height: 1, thickness: 1), SubSpaceDialogButtons(selectedId: _selectedId, widget: widget), diff --git a/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart b/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart index f83ced1a..a42f4352 100644 --- a/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart +++ b/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart @@ -22,17 +22,15 @@ class DoorLockBloc extends Bloc { on(_onStatusUpdated); } - _listenToChanges(deviceId) { + void _listenToChanges(deviceId) { try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$deviceId'); - Stream stream = ref.onValue; + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + final stream = ref.onValue; stream.listen((DatabaseEvent event) { - Map usersMap = - event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); diff --git a/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart b/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart index 39c4ca16..8bbb3c03 100644 --- a/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart +++ b/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart @@ -1,4 +1,3 @@ - import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/device_managment/door_lock/models/door_lock_status_model.dart'; diff --git a/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart b/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart index cda512c5..9dca688b 100644 --- a/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart +++ b/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart @@ -60,7 +60,7 @@ class DoorLockStatusModel { late String remoteNoDpKey; late bool normalOpenSwitch; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'unlock_fingerprint': unlockFingerprint = status.value ?? 0; diff --git a/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart b/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart index b28737fc..e2d85df9 100644 --- a/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart +++ b/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart @@ -7,7 +7,8 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class DoorLockBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class DoorLockBatchControlView extends StatelessWidget + with HelperResponsiveLayout { const DoorLockBatchControlView({super.key, required this.devicesIds}); final List devicesIds; diff --git a/lib/pages/device_managment/door_lock/widget/door_button.dart b/lib/pages/device_managment/door_lock/widget/door_button.dart index e8e3066e..6bf8acf6 100644 --- a/lib/pages/device_managment/door_lock/widget/door_button.dart +++ b/lib/pages/device_managment/door_lock/widget/door_button.dart @@ -90,7 +90,7 @@ class _DoorLockButtonState extends State shape: BoxShape.circle, boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.5), + color: Colors.grey.withValues(alpha: 0.5), blurRadius: 18, blurStyle: BlurStyle.outer, ), diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart index aea800dd..f4b933ae 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart @@ -15,8 +15,8 @@ import 'package:syncrow_web/services/devices_mang_api.dart'; part 'flush_mounted_presence_sensor_event.dart'; part 'flush_mounted_presence_sensor_state.dart'; -class FlushMountedPresenceSensorBloc - extends Bloc { +class FlushMountedPresenceSensorBloc extends Bloc< + FlushMountedPresenceSensorEvent, FlushMountedPresenceSensorState> { final String deviceId; final ControlDeviceService controlDeviceService; final BatchControlDevicesService batchControlDevicesService; @@ -54,7 +54,7 @@ class FlushMountedPresenceSensorBloc ); } - void _onFlushMountedPresenceSensorFetchStatusEvent( + Future _onFlushMountedPresenceSensorFetchStatusEvent( FlushMountedPresenceSensorFetchStatusEvent event, Emitter emit, ) async { @@ -76,7 +76,8 @@ class FlushMountedPresenceSensorBloc ) async { emit(FlushMountedPresenceSensorLoadingInitialState()); try { - final response = await DevicesManagementApi().getBatchStatus(event.devicesIds); + final response = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = FlushMountedPresenceSensorModel.fromJson(response.status); emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); } catch (e) { @@ -91,9 +92,9 @@ class FlushMountedPresenceSensorBloc ); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value as Map; + final eventsMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), @@ -113,7 +114,7 @@ class FlushMountedPresenceSensorBloc } } - void _onFlushMountedPresenceSensorChangeValueEvent( + Future _onFlushMountedPresenceSensorChangeValueEvent( FlushMountedPresenceSensorChangeValueEvent event, Emitter emit, ) async { @@ -196,7 +197,8 @@ class FlushMountedPresenceSensorBloc deviceReport: value, code: event.code)); }); } catch (e) { - emit(FlushMountedPresenceSensorDeviceReportsFailedState(error: e.toString())); + emit(FlushMountedPresenceSensorDeviceReportsFailedState( + error: e.toString())); return; } } diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart index 08a01615..e7fe8156 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart @@ -59,7 +59,8 @@ class FlushMountedPresenceSensorGetDeviceReportsEvent class FlushMountedPresenceSensorShowDescriptionEvent extends FlushMountedPresenceSensorEvent { final String description; - const FlushMountedPresenceSensorShowDescriptionEvent({required this.description}); + const FlushMountedPresenceSensorShowDescriptionEvent( + {required this.description}); } class FlushMountedPresenceSensorBackToGridViewEvent diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart index 0fef07f2..e88a9ad8 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart @@ -13,7 +13,8 @@ class FlushMountedPresenceSensorInitialState class FlushMountedPresenceSensorLoadingInitialState extends FlushMountedPresenceSensorState {} -class FlushMountedPresenceSensorUpdateState extends FlushMountedPresenceSensorState { +class FlushMountedPresenceSensorUpdateState + extends FlushMountedPresenceSensorState { final FlushMountedPresenceSensorModel model; const FlushMountedPresenceSensorUpdateState({required this.model}); @@ -30,7 +31,8 @@ class FlushMountedPresenceSensorLoadingNewSate List get props => [model]; } -class FlushMountedPresenceSensorFailedState extends FlushMountedPresenceSensorState { +class FlushMountedPresenceSensorFailedState + extends FlushMountedPresenceSensorState { final String error; const FlushMountedPresenceSensorFailedState({required this.error}); @@ -58,7 +60,8 @@ class FlushMountedPresenceSensorDeviceReportsState class FlushMountedPresenceSensorDeviceReportsFailedState extends FlushMountedPresenceSensorState { - const FlushMountedPresenceSensorDeviceReportsFailedState({required this.error}); + const FlushMountedPresenceSensorDeviceReportsFailedState( + {required this.error}); final String error; @@ -68,7 +71,8 @@ class FlushMountedPresenceSensorDeviceReportsFailedState class FlushMountedPresenceSensorShowDescriptionState extends FlushMountedPresenceSensorState { - const FlushMountedPresenceSensorShowDescriptionState({required this.description}); + const FlushMountedPresenceSensorShowDescriptionState( + {required this.description}); final String description; @override diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart index e842f36b..e1458dc9 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart @@ -9,8 +9,10 @@ abstract final class FlushMountedPresenceSensorBlocFactory { }) { return FlushMountedPresenceSensorBloc( deviceId: deviceId, - controlDeviceService: DeviceBlocDependenciesFactory.createControlDeviceService(), - batchControlDevicesService: DeviceBlocDependenciesFactory.createBatchControlDevicesService(), + controlDeviceService: + DeviceBlocDependenciesFactory.createControlDeviceService(), + batchControlDevicesService: + DeviceBlocDependenciesFactory.createBatchControlDevicesService(), ); } } diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart index bf97005d..106a9942 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart @@ -37,18 +37,18 @@ class FlushMountedPresenceSensorModel { int sensiReduce; factory FlushMountedPresenceSensorModel.fromJson(List jsonList) { - String presenceState = 'none'; - int sensitivity = 0; - int nearDetection = 0; - int farDetection = 0; - String checkingResult = 'none'; - int presenceDelay = 0; - int noneDelay = 0; - int occurDistReduce = 0; - int illuminance = 0; - int sensiReduce = 0; + var presenceState = 'none'; + var sensitivity = 0; + var nearDetection = 0; + var farDetection = 0; + var checkingResult = 'none'; + var presenceDelay = 0; + var noneDelay = 0; + var occurDistReduce = 0; + var illuminance = 0; + var sensiReduce = 0; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case codePresenceState: presenceState = status.value ?? 'presence'; @@ -97,7 +97,3 @@ class FlushMountedPresenceSensorModel { ); } } - - - - diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart index 2860e5cc..589b6b0e 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart @@ -66,13 +66,14 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget minValue: 0, maxValue: 9, steps: 1, - action: (int value) => context.read().add( - FlushMountedPresenceSensorBatchControlEvent( - deviceIds: devicesIds, - code: FlushMountedPresenceSensorModel.codeSensitivity, - value: value, - ), - ), + action: (int value) => + context.read().add( + FlushMountedPresenceSensorBatchControlEvent( + deviceIds: devicesIds, + code: FlushMountedPresenceSensorModel.codeSensitivity, + value: value, + ), + ), ), PresenceUpdateData( value: (model.nearDetection / 100).clamp(0.0, double.infinity), @@ -114,13 +115,14 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => context.read().add( - FlushMountedPresenceSensorBatchControlEvent( - deviceIds: devicesIds, - code: FlushMountedPresenceSensorModel.codeSensiReduce, - value: value, - ), - ), + action: (int value) => + context.read().add( + FlushMountedPresenceSensorBatchControlEvent( + deviceIds: devicesIds, + code: FlushMountedPresenceSensorModel.codeSensiReduce, + value: value, + ), + ), ), PresenceUpdateData( value: model.occurDistReduce.toDouble(), @@ -128,16 +130,17 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => context.read().add( - FlushMountedPresenceSensorBatchControlEvent( - deviceIds: devicesIds, - code: FlushMountedPresenceSensorModel.codeOccurDistReduce, - value: value, - ), - ), + action: (int value) => + context.read().add( + FlushMountedPresenceSensorBatchControlEvent( + deviceIds: devicesIds, + code: FlushMountedPresenceSensorModel.codeOccurDistReduce, + value: value, + ), + ), ), PresenceUpdateData( - value: (model.presenceDelay / 10).toDouble(), + value: model.presenceDelay / 10, title: 'Target Confirm Time:', description: 's', minValue: 0.0, @@ -154,7 +157,7 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget ), ), PresenceUpdateData( - value: ((model.noneDelay / 10).toDouble()), + value: model.noneDelay / 10, description: 's', title: 'Disappe Delay:', minValue: 20, diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart index 08ad809d..098dbb61 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart @@ -15,7 +15,8 @@ import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_la class FlushMountedPresenceSensorControlView extends StatelessWidget with HelperResponsiveLayout { - const FlushMountedPresenceSensorControlView({required this.device, super.key}); + const FlushMountedPresenceSensorControlView( + {required this.device, super.key}); final AllDevicesModel device; @@ -37,9 +38,9 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget return ReportsTable( report: state.deviceReport, thirdColumnTitle: - state.code == 'illuminance_value' ? "Value" : 'Status', + state.code == 'illuminance_value' ? 'Value' : 'Status', thirdColumnDescription: - state.code == 'illuminance_value' ? "Lux" : null, + state.code == 'illuminance_value' ? 'Lux' : null, onRowTap: (index) {}, onClose: () { context @@ -56,7 +57,8 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget .add(FlushMountedPresenceSensorBackToGridViewEvent()); }, ); - } else if (state is FlushMountedPresenceSensorDeviceReportsFailedState) { + } else if (state + is FlushMountedPresenceSensorDeviceReportsFailedState) { final model = context.read().deviceStatus; return _buildGridView(context, model); @@ -105,12 +107,13 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget minValue: 0, maxValue: 9, steps: 1, - action: (int value) => context.read().add( - FlushMountedPresenceSensorChangeValueEvent( - code: FlushMountedPresenceSensorModel.codeSensitivity, - value: value, - ), - ), + action: (int value) => + context.read().add( + FlushMountedPresenceSensorChangeValueEvent( + code: FlushMountedPresenceSensorModel.codeSensitivity, + value: value, + ), + ), ), PresenceUpdateData( value: (model.nearDetection / 100).clamp(0.0, double.infinity), @@ -150,12 +153,13 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => context.read().add( - FlushMountedPresenceSensorChangeValueEvent( - code: FlushMountedPresenceSensorModel.codeSensiReduce, - value: value, - ), - ), + action: (int value) => + context.read().add( + FlushMountedPresenceSensorChangeValueEvent( + code: FlushMountedPresenceSensorModel.codeSensiReduce, + value: value, + ), + ), ), PresenceUpdateData( value: model.occurDistReduce.toDouble(), @@ -163,15 +167,16 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => context.read().add( - FlushMountedPresenceSensorChangeValueEvent( - code: FlushMountedPresenceSensorModel.codeOccurDistReduce, - value: value, - ), - ), + action: (int value) => + context.read().add( + FlushMountedPresenceSensorChangeValueEvent( + code: FlushMountedPresenceSensorModel.codeOccurDistReduce, + value: value, + ), + ), ), PresenceUpdateData( - value: (model.presenceDelay / 10).toDouble(), + value: model.presenceDelay / 10, valuesPercision: 1, title: 'Target Confirm Time:', description: 's', @@ -187,7 +192,7 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget ), ), PresenceUpdateData( - value: (model.noneDelay / 10).toDouble(), + value: model.noneDelay / 10, description: 's', title: 'Disappe Delay:', minValue: 20, diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart index 28a7e33b..48fd146b 100644 --- a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart +++ b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart @@ -2,7 +2,6 @@ import 'dart:async'; 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_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_state.dart'; @@ -42,17 +41,15 @@ class GarageDoorBloc extends Bloc { on(_onEditSchedule); on(_onStatusUpdated); } - _listenToChanges(deviceId) { + void _listenToChanges(deviceId) { try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$deviceId'); - Stream stream = ref.onValue; + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + final stream = ref.onValue; stream.listen((DatabaseEvent event) { - Map usersMap = - event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); @@ -72,11 +69,11 @@ class GarageDoorBloc extends Bloc { emit(GarageDoorLoadedState(status: deviceStatus)); } - void _fetchGarageDoorStatus( + Future _fetchGarageDoorStatus( GarageDoorInitialEvent event, Emitter emit) async { emit(GarageDoorLoadingState()); try { - var response = + final response = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status); _listenToChanges(deviceId); @@ -103,13 +100,13 @@ class GarageDoorBloc extends Bloc { Future _addSchedule( AddGarageDoorScheduleEvent event, Emitter emit) async { try { - ScheduleEntry newSchedule = ScheduleEntry( + final newSchedule = ScheduleEntry( category: event.category, time: formatTimeOfDayToISO(event.time), function: Status(code: 'doorcontact_state', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - bool success = + final success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId); if (success) { add(FetchGarageDoorSchedulesEvent( @@ -156,7 +153,7 @@ class GarageDoorBloc extends Bloc { } return schedule; }).toList(); - bool success = await DevicesManagementApi().updateScheduleRecord( + final success = await DevicesManagementApi().updateScheduleRecord( enable: event.enable, uuid: deviceStatus.uuid, scheduleId: event.scheduleId, @@ -175,7 +172,7 @@ class GarageDoorBloc extends Bloc { Future _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter emit) async { try { - bool success = await DevicesManagementApi() + final success = await DevicesManagementApi() .deleteScheduleRecord(deviceStatus.uuid, event.scheduleId); if (success) { final updatedSchedules = deviceStatus.schedules @@ -195,7 +192,7 @@ class GarageDoorBloc extends Bloc { Emitter emit) async { emit(ScheduleGarageLoadingState()); try { - List schedules = await DevicesManagementApi() + final schedules = await DevicesManagementApi() .getDeviceSchedules(deviceStatus.uuid, event.category); deviceStatus = deviceStatus.copyWith(schedules: schedules); emit( @@ -226,7 +223,7 @@ class GarageDoorBloc extends Bloc { UpdateSelectedDayEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { - List updatedDays = List.from(currentState.selectedDays); + final updatedDays = List.from(currentState.selectedDays); updatedDays[event.dayIndex] = event.isSelected; emit(currentState.copyWith( selectedDays: updatedDays, selectedTime: currentState.selectedTime)); @@ -264,9 +261,8 @@ class GarageDoorBloc extends Bloc { .subtract(const Duration(days: 30)) .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final DeviceReport records = - await DevicesManagementApi.getDeviceReportsByDate( - event.deviceId, 'switch_1', from.toString(), to.toString()); + final records = await DevicesManagementApi.getDeviceReportsByDate( + event.deviceId, 'switch_1', from.toString(), to.toString()); emit(GarageDoorReportsState(deviceReport: records)); } catch (e) { emit(GarageDoorReportsFailedState(error: e.toString())); @@ -352,12 +348,12 @@ class GarageDoorBloc extends Bloc { } } - void _increaseDelay( + Future _increaseDelay( IncreaseGarageDoorDelayEvent event, Emitter emit) async { // if (deviceStatus.countdown1 != 0) { try { deviceStatus = deviceStatus.copyWith( - delay: deviceStatus.delay + Duration(minutes: 10)); + delay: deviceStatus.delay + const Duration(minutes: 10)); emit(GarageDoorLoadedState(status: deviceStatus)); add(GarageDoorControlEvent( deviceId: deviceId, @@ -369,13 +365,13 @@ class GarageDoorBloc extends Bloc { // } } - void _decreaseDelay( + Future _decreaseDelay( DecreaseGarageDoorDelayEvent event, Emitter emit) async { // if (deviceStatus.countdown1 != 0) { try { if (deviceStatus.delay.inMinutes > 10) { deviceStatus = deviceStatus.copyWith( - delay: deviceStatus.delay - Duration(minutes: 10)); + delay: deviceStatus.delay - const Duration(minutes: 10)); } emit(GarageDoorLoadedState(status: deviceStatus)); add(GarageDoorControlEvent( @@ -388,7 +384,7 @@ class GarageDoorBloc extends Bloc { //} } - void _garageDoorControlEvent( + Future _garageDoorControlEvent( GarageDoorControlEvent event, Emitter emit) async { final oldValue = event.code == 'countdown_1' ? deviceStatus.countdown1 @@ -489,14 +485,14 @@ class GarageDoorBloc extends Bloc { FutureOr _onEditSchedule( EditGarageDoorScheduleEvent event, Emitter emit) async { try { - ScheduleEntry newSchedule = ScheduleEntry( + final newSchedule = ScheduleEntry( scheduleId: event.scheduleId, category: event.category, time: formatTimeOfDayToISO(event.time), function: Status(code: 'doorcontact_state', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - bool success = await DevicesManagementApi() + final success = await DevicesManagementApi() .editScheduleRecord(deviceId, newSchedule); if (success) { add(FetchGarageDoorSchedulesEvent( diff --git a/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart b/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart index 7b133d45..4600a685 100644 --- a/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart +++ b/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart @@ -18,7 +18,7 @@ class GarageDoorDialogHelper { final bloc = context.read(); if (schedule == null) { - bloc.add((const UpdateSelectedTimeEvent(null))); + bloc.add(const UpdateSelectedTimeEvent(null)); bloc.add(InitializeAddScheduleEvent( selectedTime: null, selectedDays: List.filled(7, false), @@ -77,9 +77,10 @@ class GarageDoorDialogHelper { backgroundColor: ColorsManager.boxColor, borderRadius: 15, onPressed: () async { - TimeOfDay? time = await showTimePicker( + final time = await showTimePicker( context: context, - initialTime: state.selectedTime ?? TimeOfDay.now(), + initialTime: + state.selectedTime ?? TimeOfDay.now(), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( @@ -99,7 +100,9 @@ class GarageDoorDialogHelper { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - state.selectedTime == null ? 'Time' : state.selectedTime!.format(context), + state.selectedTime == null + ? 'Time' + : state.selectedTime!.format(context), style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.grayColor, ), @@ -114,7 +117,8 @@ class GarageDoorDialogHelper { ), ), const SizedBox(height: 16), - _buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit), + _buildDayCheckboxes(context, state.selectedDays, + isEdit: isEdit), const SizedBox(height: 16), _buildFunctionSwitch(context, state.functionOn, isEdit), ], @@ -188,9 +192,9 @@ class GarageDoorDialogHelper { static List _convertDaysStringToBooleans(List selectedDays) { final daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - List daysBoolean = List.filled(7, false); + final daysBoolean = List.filled(7, false); - for (int i = 0; i < daysOfWeek.length; i++) { + for (var i = 0; i < daysOfWeek.length; i++) { if (selectedDays.contains(daysOfWeek[i])) { daysBoolean[i] = true; } @@ -199,7 +203,9 @@ class GarageDoorDialogHelper { return daysBoolean; } - static Widget _buildDayCheckboxes(BuildContext context, List selectedDays, {bool? isEdit}) { + static Widget _buildDayCheckboxes( + BuildContext context, List selectedDays, + {bool? isEdit}) { final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; return Row( @@ -209,7 +215,9 @@ class GarageDoorDialogHelper { Checkbox( value: selectedDays[index], onChanged: (bool? value) { - context.read().add(UpdateSelectedDayEvent(index, value!)); + context + .read() + .add(UpdateSelectedDayEvent(index, value!)); }, ), Text(dayLabels[index]), @@ -219,19 +227,23 @@ class GarageDoorDialogHelper { ); } - static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) { + static Widget _buildFunctionSwitch( + BuildContext context, bool isOn, bool? isEdit) { return Row( children: [ Text( 'Function:', - style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor), + style: context.textTheme.bodySmall! + .copyWith(color: ColorsManager.grayColor), ), const SizedBox(width: 10), Radio( value: true, groupValue: isOn, onChanged: (bool? value) { - context.read().add(const UpdateFunctionOnEvent(functionOn: true)); + context + .read() + .add(const UpdateFunctionOnEvent(functionOn: true)); }, ), const Text('On'), @@ -240,7 +252,9 @@ class GarageDoorDialogHelper { value: false, groupValue: isOn, onChanged: (bool? value) { - context.read().add(const UpdateFunctionOnEvent(functionOn: false)); + context + .read() + .add(const UpdateFunctionOnEvent(functionOn: false)); }, ), const Text('Off'), @@ -297,13 +311,17 @@ class GarageDoorDialogHelper { alertBody: TimeOutAlarmDialogBody(bloc), title: 'Time Out Alarm', onConfirm: () { - final updatedState = context.read().state; - if (updatedState is GarageDoorLoadedState) { + final updatedState = + context.read().state; + if (updatedState + is GarageDoorLoadedState) { context.read().add( GarageDoorControlEvent( - deviceId: updatedState.status.uuid, + deviceId: + updatedState.status.uuid, code: 'countdown_alarm', - value: updatedState.status.countdownAlarm, + value: updatedState + .status.countdownAlarm, ), ); Navigator.pop(context); @@ -311,8 +329,11 @@ class GarageDoorDialogHelper { }); }, child: ToggleWidget( - icon: "-1", - value: state.status.doorState1 == "close_time_alarm" ? false : true, + icon: '-1', + value: state.status.doorState1 == + 'close_time_alarm' + ? false + : true, code: 'door_state_1', deviceId: bloc.deviceId, label: 'Alarm when door is open', @@ -321,9 +342,10 @@ class GarageDoorDialogHelper { GarageDoorControlEvent( deviceId: bloc.deviceId, code: 'door_state_1', - value: state.status.doorState1 == "close_time_alarm" - ? "unclosed_time" - : "close_time_alarm", + value: state.status.doorState1 == + 'close_time_alarm' + ? 'unclosed_time' + : 'close_time_alarm', ), ); }), @@ -348,13 +370,17 @@ class GarageDoorDialogHelper { ), title: 'Opening and Closing Time', onConfirm: () { - final updatedState = context.read().state; - if (updatedState is GarageDoorLoadedState) { + final updatedState = + context.read().state; + if (updatedState + is GarageDoorLoadedState) { context.read().add( GarageDoorControlEvent( - deviceId: updatedState.status.uuid, + deviceId: + updatedState.status.uuid, code: 'tr_timecon', - value: updatedState.status.trTimeCon, + value: updatedState + .status.trTimeCon, ), ); Navigator.pop(context); diff --git a/lib/pages/device_managment/garage_door/models/garage_door_model.dart b/lib/pages/device_managment/garage_door/models/garage_door_model.dart index 60d37d9f..4c991a9f 100644 --- a/lib/pages/device_managment/garage_door/models/garage_door_model.dart +++ b/lib/pages/device_managment/garage_door/models/garage_door_model.dart @@ -39,9 +39,9 @@ class GarageDoorStatusModel { late String doorControl1; late bool voiceControl1; late String doorState1; - List schedules = []; // Initialize schedules + final schedules = []; // Initialize schedules - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; diff --git a/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart b/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart index 9b3159bb..d21db9db 100644 --- a/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart +++ b/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart @@ -11,10 +11,11 @@ import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class GarageDoorBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class GarageDoorBatchControlView extends StatelessWidget + with HelperResponsiveLayout { final List deviceIds; - const GarageDoorBatchControlView({Key? key, required this.deviceIds}) : super(key: key); + const GarageDoorBatchControlView({super.key, required this.deviceIds}); @override Widget build(BuildContext context) { @@ -37,7 +38,8 @@ class GarageDoorBatchControlView extends StatelessWidget with HelperResponsiveLa ); } - Widget _buildStatusControls(BuildContext context, GarageDoorStatusModel status) { + Widget _buildStatusControls( + BuildContext context, GarageDoorStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart b/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart index 843bac9b..403beb85 100644 --- a/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart +++ b/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart'; import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart'; @@ -8,7 +7,8 @@ class OpeningAndClosingTimeDialogBody extends StatefulWidget { final ValueChanged onDurationChanged; final GarageDoorBloc bloc; - OpeningAndClosingTimeDialogBody({ + const OpeningAndClosingTimeDialogBody({ + super.key, required this.onDurationChanged, required this.bloc, }); diff --git a/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart b/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart index 07cd9c7a..238b7ad7 100644 --- a/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart +++ b/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart @@ -26,7 +26,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { Table( border: TableBorder.all( color: ColorsManager.graysColor, - borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), topRight: Radius.circular(20)), ), children: [ TableRow( @@ -50,17 +51,21 @@ class ScheduleGarageTableWidget extends StatelessWidget { BlocBuilder( builder: (context, state) { if (state is ScheduleGarageLoadingState) { - return const SizedBox(height: 200, child: Center(child: CircularProgressIndicator())); + return const SizedBox( + height: 200, + child: Center(child: CircularProgressIndicator())); } - if (state is GarageDoorLoadedState && state.status.schedules?.isEmpty == true) { + if (state is GarageDoorLoadedState && + state.status.schedules?.isEmpty == true) { return _buildEmptyState(context); } else if (state is GarageDoorLoadedState) { return Container( height: 200, decoration: BoxDecoration( border: Border.all(color: ColorsManager.graysColor), - borderRadius: - const BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(20), + bottomRight: Radius.circular(20)), ), child: _buildTableBody(state, context)); } @@ -78,7 +83,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { height: 200, decoration: BoxDecoration( border: Border.all(color: ColorsManager.graysColor), - borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), ), child: Center( child: Column( @@ -112,7 +118,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { children: [ if (state.status.schedules != null) for (int i = 0; i < state.status.schedules!.length; i++) - _buildScheduleRow(state.status.schedules![i], i, context, state), + _buildScheduleRow( + state.status.schedules![i], i, context, state), ], ), ), @@ -134,7 +141,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { ); } - TableRow _buildScheduleRow(ScheduleModel schedule, int index, BuildContext context, GarageDoorLoadedState state) { + TableRow _buildScheduleRow(ScheduleModel schedule, int index, + BuildContext context, GarageDoorLoadedState state) { return TableRow( children: [ Center( @@ -152,7 +160,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { width: 24, height: 24, child: schedule.enable - ? const Icon(Icons.radio_button_checked, color: ColorsManager.blueColor) + ? const Icon(Icons.radio_button_checked, + color: ColorsManager.blueColor) : const Icon( Icons.radio_button_unchecked, color: ColorsManager.grayColor, @@ -160,7 +169,9 @@ class ScheduleGarageTableWidget extends StatelessWidget { ), ), ), - Center(child: Text(_getSelectedDays(ScheduleModel.parseSelectedDays(schedule.days)))), + Center( + child: Text(_getSelectedDays( + ScheduleModel.parseSelectedDays(schedule.days)))), Center(child: Text(formatIsoStringToTime(schedule.time, context))), Center(child: Text(schedule.function.value ? 'On' : 'Off')), Center( @@ -170,18 +181,24 @@ class ScheduleGarageTableWidget extends StatelessWidget { TextButton( style: TextButton.styleFrom(padding: EdgeInsets.zero), onPressed: () { - GarageDoorDialogHelper.showAddGarageDoorScheduleDialog(context, - schedule: schedule, index: index, isEdit: true); + GarageDoorDialogHelper.showAddGarageDoorScheduleDialog( + context, + schedule: schedule, + index: index, + isEdit: true); }, child: Text( 'Edit', - style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blueColor), + style: context.textTheme.bodySmall! + .copyWith(color: ColorsManager.blueColor), ), ), TextButton( style: TextButton.styleFrom(padding: EdgeInsets.zero), onPressed: () { - context.read().add(DeleteGarageDoorScheduleEvent( + context + .read() + .add(DeleteGarageDoorScheduleEvent( index: index, scheduleId: schedule.scheduleId, deviceId: state.status.uuid, @@ -189,7 +206,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { }, child: Text( 'Delete', - style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blueColor), + style: context.textTheme.bodySmall! + .copyWith(color: ColorsManager.blueColor), ), ), ], @@ -201,8 +219,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { String _getSelectedDays(List selectedDays) { final days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - List selectedDaysStr = []; - for (int i = 0; i < selectedDays.length; i++) { + final selectedDaysStr = []; + for (var i = 0; i < selectedDays.length; i++) { if (selectedDays[i]) { selectedDaysStr.add(days[i]); } diff --git a/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart b/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart index e5819e89..786b3fa6 100644 --- a/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart +++ b/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart @@ -28,7 +28,7 @@ class ScheduleGarageManagementUI extends StatelessWidget { padding: 2, backgroundColor: ColorsManager.graysColor, borderRadius: 15, - onPressed: () => onAddSchedule(), + onPressed: onAddSchedule, child: Row( children: [ const Icon(Icons.add, color: ColorsManager.primaryColor), diff --git a/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart b/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart index 7b6e4690..3f8939dd 100644 --- a/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart +++ b/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart @@ -35,7 +35,8 @@ class ScheduleGarageDoorModeSelector extends StatelessWidget { ); } - Widget _buildRadioTile(BuildContext context, String label, ScheduleModes mode, GarageDoorLoadedState state) { + Widget _buildRadioTile(BuildContext context, String label, ScheduleModes mode, + GarageDoorLoadedState state) { return Flexible( child: ListTile( contentPadding: EdgeInsets.zero, diff --git a/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart b/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart index 491be37b..f2805d39 100644 --- a/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart +++ b/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart @@ -4,7 +4,8 @@ class SecondsPicker extends StatefulWidget { final int initialSeconds; final ValueChanged onSecondsChanged; - SecondsPicker({ + const SecondsPicker({ + super.key, required this.initialSeconds, required this.onSecondsChanged, }); diff --git a/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart b/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart index 541ab9e4..2eff275d 100644 --- a/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart +++ b/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart @@ -5,7 +5,7 @@ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart'; class TimeOutAlarmDialogBody extends StatefulWidget { - TimeOutAlarmDialogBody(this.bloc); + const TimeOutAlarmDialogBody(this.bloc, {super.key}); final GarageDoorBloc bloc; @override diff --git a/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart b/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart index e14672ae..66c33fbe 100644 --- a/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart +++ b/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart @@ -16,10 +16,12 @@ class GateWayBloc extends Bloc { on(_onFactoryReset); } - FutureOr _getGatWayById(GatWayById event, Emitter emit) async { + FutureOr _getGatWayById( + GatWayById event, Emitter emit) async { emit(GatewayLoadingState()); try { - List devicesList = await DevicesManagementApi.getDevicesByGatewayId(event.getWayId); + final devicesList = + await DevicesManagementApi.getDevicesByGatewayId(event.getWayId); emit(UpdateGatewayState(list: devicesList)); } catch (e) { @@ -28,7 +30,8 @@ class GateWayBloc extends Bloc { } } - FutureOr _onFactoryReset(GateWayFactoryReset event, Emitter emit) async { + FutureOr _onFactoryReset( + GateWayFactoryReset event, Emitter emit) async { emit(GatewayLoadingState()); try { final response = await DevicesManagementApi().factoryReset( diff --git a/lib/pages/device_managment/gateway/view/gateway_batch_control.dart b/lib/pages/device_managment/gateway/view/gateway_batch_control.dart index f3a08a18..a9fe13ba 100644 --- a/lib/pages/device_managment/gateway/view/gateway_batch_control.dart +++ b/lib/pages/device_managment/gateway/view/gateway_batch_control.dart @@ -6,7 +6,8 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class GatewayBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class GatewayBatchControlView extends StatelessWidget + with HelperResponsiveLayout { const GatewayBatchControlView({super.key, required this.gatewayIds}); final List gatewayIds; @@ -38,7 +39,8 @@ class GatewayBatchControlView extends StatelessWidget with HelperResponsiveLayou context.read().add( GateWayFactoryReset( deviceId: gatewayIds.first, - factoryReset: FactoryResetModel(devicesUuid: gatewayIds), + factoryReset: + FactoryResetModel(devicesUuid: gatewayIds), ), ); }, diff --git a/lib/pages/device_managment/gateway/view/gateway_view.dart b/lib/pages/device_managment/gateway/view/gateway_view.dart index d674e4d8..8f5d0674 100644 --- a/lib/pages/device_managment/gateway/view/gateway_view.dart +++ b/lib/pages/device_managment/gateway/view/gateway_view.dart @@ -37,21 +37,21 @@ class GateWayControlsView extends StatelessWidget with HelperResponsiveLayout { mainAxisSize: MainAxisSize.min, children: [ Text( - "Bluetooth Devices:", + 'Bluetooth Devices:', style: context.textTheme.bodyMedium!.copyWith( color: ColorsManager.grayColor, ), ), const SizedBox(height: 12), Text( - "No devices found", + 'No devices found', style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.blackColor, ), ), const SizedBox(height: 30), Text( - "ZigBee Devices:", + 'ZigBee Devices:', style: context.textTheme.bodyMedium!.copyWith( color: ColorsManager.grayColor, ), diff --git a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart index 493e3037..1a2d0ab1 100644 --- a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart +++ b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart @@ -159,17 +159,15 @@ class MainDoorSensorBloc } } - _listenToChanges(deviceId) { + void _listenToChanges(deviceId) { try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$deviceId'); - Stream stream = ref.onValue; + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + final stream = ref.onValue; stream.listen((DatabaseEvent event) { - Map usersMap = - event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); diff --git a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart index 569cfa11..8dcc221a 100644 --- a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart +++ b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart @@ -1,8 +1,7 @@ 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/main_door_sensor/models/main_door_status_model.dart'; -import '../../all_devices/models/factory_reset_model.dart'; - class MainDoorSensorEvent extends Equatable { @override List get props => []; @@ -75,7 +74,7 @@ class MainDoorSensorFactoryReset extends MainDoorSensorEvent { class StatusUpdated extends MainDoorSensorEvent { final MainDoorSensorStatusModel deviceStatus; - StatusUpdated(this.deviceStatus); + StatusUpdated(this.deviceStatus); @override List get props => [deviceStatus]; } diff --git a/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart b/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart index 52dda7a3..65518938 100644 --- a/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart +++ b/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart @@ -12,10 +12,10 @@ class MainDoorSensorStatusModel { }); factory MainDoorSensorStatusModel.fromJson(String id, List jsonList) { - late bool doorContactState = false; - late int batteryPercentage = 0; + late var doorContactState = false; + late var batteryPercentage = 0; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'doorcontact_state': doorContactState = status.value ?? false; diff --git a/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart b/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart index ecdb367a..723cb2f0 100644 --- a/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart +++ b/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart @@ -12,7 +12,8 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLayout { +class MainDoorSensorControlView extends StatelessWidget + with HelperResponsiveLayout { const MainDoorSensorControlView({super.key, required this.device}); final AllDevicesModel device; @@ -20,10 +21,12 @@ class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLay @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => MainDoorSensorBloc()..add(MainDoorSensorFetchDeviceEvent(device.uuid!)), + create: (context) => MainDoorSensorBloc() + ..add(MainDoorSensorFetchDeviceEvent(device.uuid!)), child: BlocBuilder( builder: (context, state) { - if (state is MainDoorSensorLoadingState || state is MainDoorSensorReportsLoadingState) { + if (state is MainDoorSensorLoadingState || + state is MainDoorSensorReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is MainDoorSensorDeviceStatusLoaded) { return _buildStatusControls(context, state.status); @@ -32,12 +35,15 @@ class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLay report: state.deviceReport, onRowTap: (index) {}, onClose: () { - context.read().add(MainDoorSensorFetchDeviceEvent(device.uuid!)); + context + .read() + .add(MainDoorSensorFetchDeviceEvent(device.uuid!)); }, hideValueShowDescription: true, mainDoorSensor: true, ); - } else if (state is MainDoorSensorFailedState || state is MainDoorSensorBatchFailedState) { + } else if (state is MainDoorSensorFailedState || + state is MainDoorSensorBatchFailedState) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); @@ -46,7 +52,8 @@ class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLay )); } - Widget _buildStatusControls(BuildContext context, MainDoorSensorStatusModel status) { + Widget _buildStatusControls( + BuildContext context, MainDoorSensorStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -71,7 +78,9 @@ class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLay icon: Assets.openCloseDoor, onTap: () {}, status: status.doorContactState, - textColor: status.doorContactState ? ColorsManager.red : ColorsManager.blackColor, + textColor: status.doorContactState + ? ColorsManager.red + : ColorsManager.blackColor, paddingAmount: 8, ), IconNameStatusContainer( @@ -79,7 +88,9 @@ class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLay name: 'Open/Close\nRecord', icon: Assets.openCloseRecords, onTap: () { - final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; + final from = DateTime.now() + .subtract(const Duration(days: 30)) + .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; context.read().add( MainDoorSensorReportsEvent( diff --git a/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart b/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart index bbebabaa..e14321dd 100644 --- a/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart +++ b/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart @@ -27,7 +27,8 @@ class MainDoorSensorBatchView extends StatelessWidget { BlocProvider.of(innerContext).add( MainDoorSensorFactoryReset( deviceId: devicesIds.first, - factoryReset: FactoryResetModel(devicesUuid: devicesIds), + factoryReset: + FactoryResetModel(devicesUuid: devicesIds), ), ); }, diff --git a/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart b/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart index ac66b315..8e9cc8cd 100644 --- a/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart +++ b/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart @@ -53,7 +53,7 @@ class _NotificationDialogState extends State { ), ), child: IconButton( - padding: EdgeInsets.all(1), + padding: const EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, diff --git a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart index c1e976ab..8de84264 100644 --- a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart @@ -39,9 +39,11 @@ class OneGangGlassSwitchBloc ) async { emit(OneGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(event.deviceId, emit); - deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status); + deviceStatus = + OneGangGlassStatusModel.fromJson(event.deviceId, status.status); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(OneGangGlassSwitchError(e.toString())); @@ -62,7 +64,7 @@ class OneGangGlassSwitchBloc final statusList = []; if (data['status'] != null) { - for (var element in data['status']) { + for (final element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -72,7 +74,8 @@ class OneGangGlassSwitchBloc } } if (statusList.isNotEmpty) { - final newStatus = OneGangGlassStatusModel.fromJson(deviceId, statusList); + final newStatus = + OneGangGlassStatusModel.fromJson(deviceId, statusList); if (newStatus != deviceStatus) { deviceStatus = newStatus; if (!isClosed) { @@ -140,9 +143,10 @@ class OneGangGlassSwitchBloc ) async { emit(OneGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = - OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status); + final status = + await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = OneGangGlassStatusModel.fromJson( + event.deviceIds.first, status.status); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(OneGangGlassSwitchError(e.toString())); diff --git a/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart b/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart index 39c96dd0..dd8a1140 100644 --- a/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart +++ b/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart @@ -15,7 +15,7 @@ class OneGangGlassStatusModel { late bool switch1; late int countDown; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; @@ -46,5 +46,6 @@ class OneGangGlassStatusModel { } @override - String toString() => 'OneGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown: $countDown)'; + String toString() => + 'OneGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown: $countDown)'; } diff --git a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart index 307e61da..5f88768a 100644 --- a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart +++ b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart @@ -8,16 +8,19 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class OneGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class OneGangGlassSwitchBatchControlView extends StatelessWidget + with HelperResponsiveLayout { final List deviceIds; - const OneGangGlassSwitchBatchControlView({required this.deviceIds, super.key}); + const OneGangGlassSwitchBatchControlView( + {required this.deviceIds, super.key}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => OneGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(OneGangGlassSwitchFetchBatchStatusEvent(deviceIds)), + create: (context) => + OneGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(OneGangGlassSwitchFetchBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is OneGangGlassSwitchLoading) { @@ -34,7 +37,8 @@ class OneGangGlassSwitchBatchControlView extends StatelessWidget with HelperResp ); } - Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) { + Widget _buildStatusControls( + BuildContext context, OneGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart index 997be513..2c376ad6 100644 --- a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart @@ -7,7 +7,8 @@ import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout { +class OneGangGlassSwitchControlView extends StatelessWidget + with HelperResponsiveLayout { final String deviceId; const OneGangGlassSwitchControlView({required this.deviceId, super.key}); @@ -16,7 +17,8 @@ class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiv Widget build(BuildContext context) { return BlocProvider( create: (context) => - OneGangGlassSwitchBlocFactory.create(deviceId: deviceId)..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)), + OneGangGlassSwitchBlocFactory.create(deviceId: deviceId) + ..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is OneGangGlassSwitchLoading) { @@ -33,7 +35,8 @@ class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiv ); } - Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) { + Widget _buildStatusControls( + BuildContext context, OneGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -56,7 +59,7 @@ class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiv value: status.switch1, code: 'switch_1', deviceId: deviceId, - label: "Wall Light", + label: 'Wall Light', onChange: (value) { context.read().add( OneGangGlassSwitchControl( diff --git a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart index 59eccfe9..cf22faba 100644 --- a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart +++ b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart @@ -10,7 +10,8 @@ import 'package:syncrow_web/services/batch_control_devices_service.dart'; import 'package:syncrow_web/services/control_device_service.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; -class WallLightSwitchBloc extends Bloc { +class WallLightSwitchBloc + extends Bloc { late WallLightStatusModel deviceStatus; final String deviceId; final ControlDeviceService controlDeviceService; @@ -35,9 +36,11 @@ class WallLightSwitchBloc extends Bloc[]; if (data['status'] != null) { - for (var element in data['status']) { + for (final element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -136,7 +139,8 @@ class WallLightSwitchBloc extends Bloc deviceIds; @@ -18,15 +19,17 @@ class WallLightBatchControlView extends StatelessWidget with HelperResponsiveLay @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => WallLightSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(WallLightSwitchFetchBatchEvent(deviceIds)), + create: (context) => + WallLightSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(WallLightSwitchFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is WallLightSwitchLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is WallLightSwitchStatusLoaded) { return _buildStatusControls(context, state.status); - } else if (state is WallLightSwitchError || state is WallLightSwitchControlError) { + } else if (state is WallLightSwitchError || + state is WallLightSwitchControlError) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); @@ -36,7 +39,8 @@ class WallLightBatchControlView extends StatelessWidget with HelperResponsiveLay ); } - Widget _buildStatusControls(BuildContext context, WallLightStatusModel status) { + Widget _buildStatusControls( + BuildContext context, WallLightStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -78,7 +82,8 @@ class WallLightBatchControlView extends StatelessWidget with HelperResponsiveLay FactoryResetWidget( callFactoryReset: () { context.read().add(WallLightFactoryReset( - deviceId: status.uuid, factoryReset: FactoryResetModel(devicesUuid: deviceIds))); + deviceId: status.uuid, + factoryReset: FactoryResetModel(devicesUuid: deviceIds))); }, ), ], diff --git a/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart b/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart index 24c5138f..4cc0dbf3 100644 --- a/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart +++ b/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart @@ -215,33 +215,46 @@ class SmartPowerBloc extends Bloc { SmartPowerFetchDeviceEvent event, Emitter emit) async { emit(SmartPowerLoading()); try { - var status = + final status = await DevicesManagementApi().getPowerClampInfo(event.deviceId); - deviceStatus = PowerClampModel.fromJson(status as Map? ??{}); + deviceStatus = + PowerClampModel.fromJson(status as Map? ?? {}); final phaseADataPoints = deviceStatus.status.phaseA.dataPoints; final phaseBDataPoints = deviceStatus.status.phaseB.dataPoints; final phaseCDataPoints = deviceStatus.status.phaseC.dataPoints; phaseData = [ { 'name': 'Phase A', - 'voltage': '${(phaseADataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', - 'current': '${(phaseADataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', - 'activePower': '${phaseADataPoints.elementAtOrNull(2)?.value??'N/A'} W', - 'powerFactor': '${phaseADataPoints.elementAtOrNull(3)?.value??'N/A'}', + 'voltage': + '${(phaseADataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', + 'current': + '${(phaseADataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', + 'activePower': + '${phaseADataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', + 'powerFactor': + '${phaseADataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', }, { 'name': 'Phase B', - 'voltage': '${(phaseBDataPoints .elementAtOrNull(0)?.value as num? ?? 0) / 10} V', - 'current': '${(phaseBDataPoints .elementAtOrNull(1)?.value as num? ?? 0) / 10} A', - 'activePower': '${phaseBDataPoints.elementAtOrNull(2)?.value??'N/A'} W', - 'powerFactor': '${phaseBDataPoints.elementAtOrNull(3)?.value??'N/A'}', + 'voltage': + '${(phaseBDataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', + 'current': + '${(phaseBDataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', + 'activePower': + '${phaseBDataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', + 'powerFactor': + '${phaseBDataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', }, { 'name': 'Phase C', - 'voltage': '${(phaseCDataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', - 'current': '${(phaseCDataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', - 'activePower': '${phaseCDataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', - 'powerFactor': '${phaseCDataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', + 'voltage': + '${(phaseCDataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', + 'current': + '${(phaseCDataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', + 'activePower': + '${phaseCDataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', + 'powerFactor': + '${phaseCDataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', }, ]; emit(GetDeviceStatus()); @@ -305,8 +318,7 @@ class SmartPowerBloc extends Bloc { try { final response = await DevicesManagementApi().getPowerStatus(event.devicesIds); - PowerClampBatchModel deviceStatus = - PowerClampBatchModel.fromJson(response); + final deviceStatus = PowerClampBatchModel.fromJson(response); emit(SmartPowerLoadBatchControll(deviceStatus)); } catch (e) { @@ -417,15 +429,15 @@ class SmartPowerBloc extends Bloc { } Future selectMonthAndYear(BuildContext context) async { - int selectedYear = DateTime.now().year; - int selectedMonth = DateTime.now().month; + var selectedYear = DateTime.now().year; + var selectedMonth = DateTime.now().month; - FixedExtentScrollController yearController = + final yearController = FixedExtentScrollController(initialItem: selectedYear - 1905); - FixedExtentScrollController monthController = + final monthController = FixedExtentScrollController(initialItem: selectedMonth - 1); - return await showDialog( + return showDialog( context: context, builder: (BuildContext context) { return Column( @@ -537,11 +549,11 @@ class SmartPowerBloc extends Bloc { } Future selectYear(BuildContext context) async { - int selectedYear = DateTime.now().year; - FixedExtentScrollController yearController = + var selectedYear = DateTime.now().year; + final yearController = FixedExtentScrollController(initialItem: selectedYear - 1905); - return await showDialog( + return showDialog( context: context, builder: (BuildContext context) { return Column( @@ -622,9 +634,9 @@ class SmartPowerBloc extends Bloc { Future dayMonthYearPicker({ required BuildContext context, }) async { - DateTime selectedDate = DateTime.now(); + var selectedDate = DateTime.now(); - return await showDialog( + return showDialog( context: context, builder: (BuildContext context) { return Column( @@ -686,7 +698,7 @@ class SmartPowerBloc extends Bloc { String formattedDate = DateFormat('yyyy/MM/dd').format(DateTime.now()); - void checkDayMonthYearSelected( + Future checkDayMonthYearSelected( SelectDateEvent event, Emitter emit) async { Future Function(BuildContext context)? dateSelector; String dateFormat; @@ -698,15 +710,11 @@ class SmartPowerBloc extends Bloc { dateFormat = 'yyyy/MM/dd'; break; case 1: - dateSelector = (context) { - return selectMonthAndYear(context); - }; + dateSelector = selectMonthAndYear; dateFormat = 'yyyy-MM'; break; case 2: - dateSelector = (context) { - return selectYear(context); - }; + dateSelector = selectYear; dateFormat = 'yyyy'; break; default: @@ -743,7 +751,7 @@ class SmartPowerBloc extends Bloc { .toList(); } else if (event.viewType == 'Month') { formattedDate = - "${event.selectedDate.year.toString()}-${getMonthShortName(event.selectedDate.month)}"; + '${event.selectedDate.year}-${getMonthShortName(event.selectedDate.month)}'; filteredRecords = record .where((record) => @@ -752,7 +760,7 @@ class SmartPowerBloc extends Bloc { .toList(); } else if (event.viewType == 'Day') { formattedDate = - "${event.selectedDate.year.toString()}-${getMonthShortName(event.selectedDate.month)}-${event.selectedDate.day}"; + '${event.selectedDate.year}-${getMonthShortName(event.selectedDate.month)}-${event.selectedDate.day}'; filteredRecords = record .where((record) => @@ -784,11 +792,11 @@ class SmartPowerBloc extends Bloc { String endChartDate = ''; - void selectDateRange() async { - DateTime startDate = dateTime!; - DateTime endDate = DateTime(startDate.year, startDate.month + 1, 1) + Future selectDateRange() async { + final startDate = dateTime!; + final endDate = DateTime(startDate.year, startDate.month + 1, 1) .subtract(const Duration(days: 1)); - String formattedEndDate = DateFormat('dd/MM/yyyy').format(endDate); + final formattedEndDate = DateFormat('dd/MM/yyyy').format(endDate); endChartDate = ' - $formattedEndDate'; } } diff --git a/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart b/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart index 1985c67c..c6cca576 100644 --- a/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart +++ b/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart @@ -95,16 +95,18 @@ class FilterRecordsByDateEvent extends SmartPowerEvent { class FetchPowerClampBatchStatusEvent extends SmartPowerEvent { final List deviceIds; - FetchPowerClampBatchStatusEvent(this.deviceIds); + FetchPowerClampBatchStatusEvent(this.deviceIds); @override List get props => [deviceIds]; -}class PowerBatchControlEvent extends SmartPowerEvent { +} + +class PowerBatchControlEvent extends SmartPowerEvent { final List deviceIds; final String code; final dynamic value; - PowerBatchControlEvent({ + PowerBatchControlEvent({ required this.deviceIds, required this.code, required this.value, @@ -112,4 +114,4 @@ class FetchPowerClampBatchStatusEvent extends SmartPowerEvent { @override List get props => [deviceIds, code, value]; -} \ No newline at end of file +} diff --git a/lib/pages/device_managment/power_clamp/models/device_event.dart b/lib/pages/device_managment/power_clamp/models/device_event.dart index 09f7b46e..8ef43961 100644 --- a/lib/pages/device_managment/power_clamp/models/device_event.dart +++ b/lib/pages/device_managment/power_clamp/models/device_event.dart @@ -1,4 +1,3 @@ - class EventDevice { final String? code; final DateTime? eventTime; @@ -12,7 +11,7 @@ class EventDevice { EventDevice.fromJson(Map json) : code = json['code'] as String?, - eventTime = json['eventTime'] , + eventTime = json['eventTime'], value = json['value'] as String?; Map toJson() => { diff --git a/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart b/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart index 1812d1c9..10ea3a11 100644 --- a/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart +++ b/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart @@ -19,10 +19,10 @@ class PowerClampBatchModel extends PowerClampModel1 { }); factory PowerClampBatchModel.fromJson(Map json) { - String productUuid = json['productUuid'] ?? ''; - String productType = json['productType'] ?? ''; + final String productUuid = json['productUuid'] ?? ''; + final String productType = json['productType'] ?? ''; - List statusList = []; + var statusList = []; if (json['status'] != null && json['status'] is List) { statusList = (json['status'] as List).map((e) => Status.fromJson(e)).toList(); diff --git a/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart b/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart index b6592f4d..424c940f 100644 --- a/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart +++ b/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart @@ -16,7 +16,8 @@ class PowerClampModel { return PowerClampModel( productUuid: json['productUuid'] as String? ?? '', productType: json['productType'] as String? ?? '', - status: PowerStatus.fromJson(json['status'] as Map? ?? {}), + status: + PowerStatus.fromJson(json['status'] as Map? ?? {}), ); } diff --git a/lib/pages/device_managment/power_clamp/view/phase_widget.dart b/lib/pages/device_managment/power_clamp/view/phase_widget.dart index 223acd95..ab70237e 100644 --- a/lib/pages/device_managment/power_clamp/view/phase_widget.dart +++ b/lib/pages/device_managment/power_clamp/view/phase_widget.dart @@ -5,7 +5,8 @@ import 'package:syncrow_web/utils/constants/assets.dart'; class PhaseWidget extends StatefulWidget { final List> phaseData; - PhaseWidget({ + const PhaseWidget({ + super.key, required this.phaseData, }); @override @@ -19,7 +20,7 @@ class _PhaseWidgetState extends State { Widget build(BuildContext context) { return Column( children: [ - SizedBox(height: 10), + const SizedBox(height: 10), Row( children: List.generate(widget.phaseData.length, (index) { return InkWell( @@ -43,27 +44,28 @@ class _PhaseWidgetState extends State { ); }), ), - SizedBox(height: 10), - _selectedPhaseIndex == 0 - ? phase( - totalActive: widget.phaseData[0]['activePower'] ?? '0', - totalCurrent: widget.phaseData[0]['current'] ?? '0', - totalFactor: widget.phaseData[0]['powerFactor'] ?? '0', - totalVoltage: widget.phaseData[0]['voltage'] ?? '0', - ) - : _selectedPhaseIndex == 1 - ? phase( - totalActive: widget.phaseData[1]['activePower'] ?? '0', - totalCurrent: widget.phaseData[1]['current'] ?? '0', - totalFactor: widget.phaseData[1]['powerFactor'] ?? '0', - totalVoltage: widget.phaseData[1]['voltage'] ?? '0', - ) - : phase( - totalActive: widget.phaseData[2]['activePower'] ?? '0', - totalCurrent: widget.phaseData[2]['current'] ?? '0', - totalFactor: widget.phaseData[2]['powerFactor'] ?? '0', - totalVoltage: widget.phaseData[2]['voltage'] ?? '0', - ), + const SizedBox(height: 10), + if (_selectedPhaseIndex == 0) + phase( + totalActive: widget.phaseData[0]['activePower'] ?? '0', + totalCurrent: widget.phaseData[0]['current'] ?? '0', + totalFactor: widget.phaseData[0]['powerFactor'] ?? '0', + totalVoltage: widget.phaseData[0]['voltage'] ?? '0', + ) + else + _selectedPhaseIndex == 1 + ? phase( + totalActive: widget.phaseData[1]['activePower'] ?? '0', + totalCurrent: widget.phaseData[1]['current'] ?? '0', + totalFactor: widget.phaseData[1]['powerFactor'] ?? '0', + totalVoltage: widget.phaseData[1]['voltage'] ?? '0', + ) + : phase( + totalActive: widget.phaseData[2]['activePower'] ?? '0', + totalCurrent: widget.phaseData[2]['current'] ?? '0', + totalFactor: widget.phaseData[2]['powerFactor'] ?? '0', + totalVoltage: widget.phaseData[2]['voltage'] ?? '0', + ), ], ); } diff --git a/lib/pages/device_managment/power_clamp/view/power_chart.dart b/lib/pages/device_managment/power_clamp/view/power_chart.dart index 7d6371f4..bbdcd87d 100644 --- a/lib/pages/device_managment/power_clamp/view/power_chart.dart +++ b/lib/pages/device_managment/power_clamp/view/power_chart.dart @@ -35,7 +35,7 @@ class _EnergyConsumptionPageState extends State { @override Widget build(BuildContext context) { - return Container( + return ColoredBox( color: ColorsManager.whiteColors, child: Column( children: [ @@ -146,7 +146,7 @@ class _EnergyConsumptionPageState extends State { showTitles: false, reservedSize: 70, getTitlesWidget: (value, meta) { - int index = value.toInt(); + final index = value.toInt(); if (index >= 0 && index < _chartData.length) { return Padding( padding: const EdgeInsets.all(8.0), @@ -169,14 +169,14 @@ class _EnergyConsumptionPageState extends State { verticalInterval: 1, getDrawingVerticalLine: (value) { return FlLine( - color: Colors.grey.withOpacity(0.2), + color: Colors.grey.withValues(alpha: 0.2), dashArray: [8, 8], strokeWidth: 1, ); }, getDrawingHorizontalLine: (value) { return FlLine( - color: Colors.grey.withOpacity(0.2), + color: Colors.grey.withValues(alpha: 0.2), dashArray: [5, 5], strokeWidth: 1, ); @@ -192,19 +192,21 @@ class _EnergyConsumptionPageState extends State { spots: _chartData .asMap() .entries - .map((entry) => FlSpot( - entry.key.toDouble(), entry.value.consumption)) + .map((entry) => FlSpot(entry.key.toDouble(), + entry.value.consumption)) .toList(), isCurved: true, - color: ColorsManager.primaryColor.withOpacity(0.6), + color: + ColorsManager.primaryColor.withValues(alpha: 0.6), show: true, shadow: const Shadow(color: Colors.black12), belowBarData: BarAreaData( show: true, gradient: LinearGradient( colors: [ - ColorsManager.primaryColor.withOpacity(0.5), - Colors.blue.withOpacity(0.1), + ColorsManager.primaryColor + .withValues(alpha: 0.5), + Colors.blue.withValues(alpha: 0.1), ], begin: Alignment.center, end: Alignment.bottomCenter, @@ -220,7 +222,7 @@ class _EnergyConsumptionPageState extends State { borderData: FlBorderData( show: false, border: Border.all( - color: const Color(0xff023DFE).withOpacity(0.7), + color: const Color(0xff023DFE).withValues(alpha: 0.7), width: 10, ), ), diff --git a/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart b/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart index 7f6a4b64..2032cd90 100644 --- a/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart +++ b/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart @@ -9,16 +9,17 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class PowerClampBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class PowerClampBatchControlView extends StatelessWidget + with HelperResponsiveLayout { final List deviceIds; - const PowerClampBatchControlView({Key? key, required this.deviceIds}) : super(key: key); + const PowerClampBatchControlView({super.key, required this.deviceIds}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - SmartPowerBloc(deviceId: deviceIds.first)..add(SmartPowerFetchBatchEvent(deviceIds)), + create: (context) => SmartPowerBloc(deviceId: deviceIds.first) + ..add(SmartPowerFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is SmartPowerLoading) { @@ -35,7 +36,8 @@ class PowerClampBatchControlView extends StatelessWidget with HelperResponsiveLa ); } - Widget _buildStatusControls(BuildContext context, PowerClampBatchModel status) { + Widget _buildStatusControls( + BuildContext context, PowerClampBatchModel status) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/pages/device_managment/power_clamp/view/power_info_card.dart b/lib/pages/device_managment/power_clamp/view/power_info_card.dart index 601b6346..b06bd1c3 100644 --- a/lib/pages/device_managment/power_clamp/view/power_info_card.dart +++ b/lib/pages/device_managment/power_clamp/view/power_info_card.dart @@ -9,12 +9,12 @@ class PowerClampInfoCard extends StatelessWidget { final String unit; const PowerClampInfoCard({ - Key? key, + super.key, required this.iconPath, required this.title, required this.value, required this.unit, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart b/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart index 67313802..3f67a027 100644 --- a/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart +++ b/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart @@ -12,7 +12,8 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; //Smart Power Clamp -class SmartPowerDeviceControl extends StatelessWidget with HelperResponsiveLayout { +class SmartPowerDeviceControl extends StatelessWidget + with HelperResponsiveLayout { final String deviceId; const SmartPowerDeviceControl({super.key, required this.deviceId}); @@ -59,7 +60,7 @@ class SmartPowerDeviceControl extends StatelessWidget with HelperResponsiveLayou required SmartPowerBloc blocProvider, required int currentPage, }) { - PageController pageController = PageController(initialPage: currentPage); + final pageController = PageController(initialPage: currentPage); return Container( padding: const EdgeInsets.symmetric(horizontal: 50), child: DeviceControlsContainer( @@ -195,8 +196,8 @@ class SmartPowerDeviceControl extends StatelessWidget with HelperResponsiveLayou blocProvider.add(SelectDateEvent(context: context)); blocProvider.add(FilterRecordsByDateEvent( selectedDate: blocProvider.dateTime!, - viewType: - blocProvider.views[blocProvider.currentIndex])); + viewType: blocProvider + .views[blocProvider.currentIndex])); }, widget: blocProvider.dateSwitcher(), chartData: blocProvider.energyDataList.isNotEmpty diff --git a/lib/pages/device_managment/shared/device_batch_control_dialog.dart b/lib/pages/device_managment/shared/device_batch_control_dialog.dart index f2dc68f5..c99b0028 100644 --- a/lib/pages/device_managment/shared/device_batch_control_dialog.dart +++ b/lib/pages/device_managment/shared/device_batch_control_dialog.dart @@ -4,7 +4,8 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; -class DeviceBatchControlDialog extends StatelessWidget with RouteControlsBasedCode { +class DeviceBatchControlDialog extends StatelessWidget + with RouteControlsBasedCode { final List devices; const DeviceBatchControlDialog({super.key, required this.devices}); @@ -43,7 +44,7 @@ class DeviceBatchControlDialog extends StatelessWidget with RouteControlsBasedCo height: 8, ), Text( - "Batch Control", + 'Batch Control', style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.dialogBlueTitle, ), @@ -104,39 +105,39 @@ String getBatchDialogName(AllDevicesModel device) { */ switch (device.productType) { case '1G': - return "Smart Light Switch"; + return 'Smart Light Switch'; case '2G': - return "Smart Light Switch"; + return 'Smart Light Switch'; case '3G': - return "Smart Light Switch"; + return 'Smart Light Switch'; case 'GW': - return "Gateway"; + return 'Gateway'; case 'DL': - return "Door Lock"; + return 'Door Lock'; case 'WPS': - return "White Presence Sensor"; + return 'White Presence Sensor'; case 'CPS': - return "Black Presence Sensor"; + return 'Black Presence Sensor'; case 'CUR': - return "Smart Curtains"; + return 'Smart Curtains'; case 'WH': - return "Smart Water Heater"; + return 'Smart Water Heater'; case 'AC': - return "Smart AC"; + return 'Smart AC'; case 'DS': - return "Door / Window Sensor"; + return 'Door / Window Sensor'; case '1GT': - return "Touch Switch"; + return 'Touch Switch'; case '2GT': - return "Touch Switch"; + return 'Touch Switch'; case '3GT': - return "Touch Switch"; + return 'Touch Switch'; case 'GD': - return "Garage Door Opener"; + return 'Garage Door Opener'; case 'WL': - return "Water Leak Sensor"; + return 'Water Leak Sensor'; case 'SOS': - return "SOS"; + return 'SOS'; default: return device.categoryName ?? 'Device Control'; } diff --git a/lib/pages/device_managment/shared/device_control_dialog.dart b/lib/pages/device_managment/shared/device_control_dialog.dart index beb3b52c..0c9c4398 100644 --- a/lib/pages/device_managment/shared/device_control_dialog.dart +++ b/lib/pages/device_managment/shared/device_control_dialog.dart @@ -50,7 +50,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { ), ), child: IconButton( - padding: EdgeInsets.all(1), + padding: const EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, @@ -107,7 +107,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { 'Installation Date and Time:', formatDateTime( DateTime.fromMillisecondsSinceEpoch( - ((device.createTime ?? 0) * 1000), + (device.createTime ?? 0) * 1000, ), ), ), @@ -115,7 +115,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { 'Battery Level:', device.batteryLevel != null ? '${device.batteryLevel ?? 0}%' - : "-", + : '-', statusColor: device.batteryLevel != null ? (device.batteryLevel! < 20 ? ColorsManager.red @@ -131,7 +131,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { 'Last Offline Date and Time:', formatDateTime( DateTime.fromMillisecondsSinceEpoch( - ((device.updateTime ?? 0) * 1000), + (device.updateTime ?? 0) * 1000, ), ), ), diff --git a/lib/pages/device_managment/shared/device_controls_container.dart b/lib/pages/device_managment/shared/device_controls_container.dart index 888563da..5ee8a978 100644 --- a/lib/pages/device_managment/shared/device_controls_container.dart +++ b/lib/pages/device_managment/shared/device_controls_container.dart @@ -18,8 +18,9 @@ class DeviceControlsContainer extends StatelessWidget { color: Colors.grey.shade100, borderRadius: BorderRadius.circular(20), ), - padding: - EdgeInsets.symmetric(vertical: padding ?? 10, horizontal: padding ?? 16), //EdgeInsets.all(padding ?? 12), + padding: EdgeInsets.symmetric( + vertical: padding ?? 10, + horizontal: padding ?? 16), //EdgeInsets.all(padding ?? 12), child: child, ), ); diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart index aac34b77..ba84bd87 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart @@ -4,7 +4,10 @@ import 'package:syncrow_web/utils/color_manager.dart'; class PresenceDisplayValue extends StatelessWidget { const PresenceDisplayValue( - {super.key, required this.value, required this.postfix, required this.description}); + {super.key, + required this.value, + required this.postfix, + required this.description}); final String value; final String postfix; @@ -32,7 +35,9 @@ class PresenceDisplayValue extends StatelessWidget { child: Text( postfix, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, fontSize: 16, fontWeight: FontWeight.w700), + color: ColorsManager.blackColor, + fontSize: 16, + fontWeight: FontWeight.w700), ), ), ], @@ -40,7 +45,9 @@ class PresenceDisplayValue extends StatelessWidget { Text( description, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 16), + color: ColorsManager.blackColor, + fontWeight: FontWeight.w400, + fontSize: 16), ), ], ), diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart index e1ca0586..c33ac15c 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_web/utils/constants/assets.dart'; -import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart'; import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; class PresenceSpaceType extends StatelessWidget { const PresenceSpaceType({ @@ -20,7 +20,7 @@ class PresenceSpaceType extends StatelessWidget { @override Widget build(BuildContext context) { - final Map spaceTypeIcons = { + final spaceTypeIcons = { SpaceTypes.none: Assets.office, SpaceTypes.parlour: Assets.parlour, SpaceTypes.area: Assets.dyi, diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart index d2d48b78..b46bbcc5 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart @@ -4,7 +4,8 @@ import 'package:syncrow_web/pages/device_managment/shared/device_controls_contai import 'package:syncrow_web/utils/color_manager.dart'; class PresenceStaticWidget extends StatelessWidget { - const PresenceStaticWidget({required this.icon, required this.description, super.key}); + const PresenceStaticWidget( + {required this.icon, required this.description, super.key}); final String icon; final String description; @@ -23,7 +24,9 @@ class PresenceStaticWidget extends StatelessWidget { Text( description, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 16), + color: ColorsManager.blackColor, + fontWeight: FontWeight.w400, + fontSize: 16), ), ], ), diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart index 26e47c8b..4ec7737a 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart @@ -25,7 +25,9 @@ class PresenceState extends StatelessWidget { Text( 'Status:', style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 10), + color: ColorsManager.blackColor, + fontWeight: FontWeight.w400, + fontSize: 10), ), ], ), @@ -41,7 +43,9 @@ class PresenceState extends StatelessWidget { Text( value, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 16), + color: ColorsManager.blackColor, + fontWeight: FontWeight.w400, + fontSize: 16), ), ], ), diff --git a/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart b/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart index 9cc23505..cda019ea 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart @@ -48,7 +48,7 @@ class _PresenceUpdateDataState extends State { String _extractNumericValue(String value) { if (value == 'none') return '0'; - return value.replaceAll(RegExp(r'[a-zA-Z]'), '').trim(); + return value.replaceAll(RegExp('[a-zA-Z]'), '').trim(); } String _extractUnit(String value) { @@ -69,17 +69,17 @@ class _PresenceUpdateDataState extends State { } void _incrementValue() { - int currentIndex = nobodyTimeRange.indexOf(_currentValue); + final currentIndex = nobodyTimeRange.indexOf(_currentValue); if (currentIndex < nobodyTimeRange.length - 1) { - String newValue = nobodyTimeRange[currentIndex + 1]; + final newValue = nobodyTimeRange[currentIndex + 1]; _onValueChanged(newValue); } } void _decrementValue() { - int currentIndex = nobodyTimeRange.indexOf(_currentValue); + final currentIndex = nobodyTimeRange.indexOf(_currentValue); if (currentIndex > 0) { - String newValue = nobodyTimeRange[currentIndex - 1]; + final newValue = nobodyTimeRange[currentIndex - 1]; _onValueChanged(newValue); } } diff --git a/lib/pages/device_managment/shared/table/report_table.dart b/lib/pages/device_managment/shared/table/report_table.dart index 11385080..72a98f56 100644 --- a/lib/pages/device_managment/shared/table/report_table.dart +++ b/lib/pages/device_managment/shared/table/report_table.dart @@ -41,7 +41,8 @@ class ReportsTable extends StatelessWidget { height: 100, child: Text( 'No reports found', - style: context.textTheme.bodyLarge!.copyWith(color: ColorsManager.grayColor), + style: context.textTheme.bodyLarge! + .copyWith(color: ColorsManager.grayColor), ), ) : Stack( @@ -49,7 +50,8 @@ class ReportsTable extends StatelessWidget { Padding( padding: const EdgeInsets.all(20.0), child: Table( - border: TableBorder.all(color: Colors.grey.shade300, width: 1), + border: + TableBorder.all(color: Colors.grey.shade300, width: 1), columnWidths: const { 0: FlexColumnWidth(), 1: FlexColumnWidth(), @@ -66,28 +68,36 @@ class ReportsTable extends StatelessWidget { ), if (report.data != null) ...report.data!.asMap().entries.map((entry) { - int index = entry.key; - DeviceEvent data = entry.value; + final index = entry.key; + final data = entry.value; // Parse eventTime into Date and Time - DateTime eventDateTime = - DateTime.fromMillisecondsSinceEpoch(data.eventTime!); - String date = DateFormat('dd/MM/yyyy').format(eventDateTime); - String time = DateFormat('HH:mm').format(eventDateTime); + final eventDateTime = + DateTime.fromMillisecondsSinceEpoch( + data.eventTime!); + final date = + DateFormat('dd/MM/yyyy').format(eventDateTime); + final time = DateFormat('HH:mm').format(eventDateTime); String value; if (hideValueShowDescription == true) { - if (mainDoorSensor != null && mainDoorSensor == true) { + if (mainDoorSensor != null && + mainDoorSensor == true) { value = data.value == 'true' ? 'Open' : 'Close'; - } else if (garageDoorSensor != null && garageDoorSensor == true) { + } else if (garageDoorSensor != null && + garageDoorSensor == true) { value = data.value == 'true' ? 'Opened' : 'Closed'; } else if (waterLeak != null && waterLeak == true) { - value = data.value == 'normal' ? 'Normal' : 'Leak Detected'; + value = data.value == 'normal' + ? 'Normal' + : 'Leak Detected'; } else { - value = '${data.value!} ${thirdColumnDescription ?? ''}'; + value = + '${data.value!} ${thirdColumnDescription ?? ''}'; } } else { - value = '${data.value!} ${thirdColumnDescription ?? ''}'; + value = + '${data.value!} ${thirdColumnDescription ?? ''}'; } return TableRow( diff --git a/lib/pages/device_managment/shared/toggle_widget.dart b/lib/pages/device_managment/shared/toggle_widget.dart index 4888572f..0e8cff37 100644 --- a/lib/pages/device_managment/shared/toggle_widget.dart +++ b/lib/pages/device_managment/shared/toggle_widget.dart @@ -42,29 +42,30 @@ class ToggleWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - icon == '-1' - ? const SizedBox( - height: 60, - width: 60, - ) - : ClipOval( - child: Container( - height: 60, - width: 60, - padding: const EdgeInsets.all(8), - color: ColorsManager.whiteColors, - child: SvgPicture.asset( - icon ?? Assets.lightPulp, - width: 35, - height: 35, - fit: BoxFit.contain, - ), - )), + if (icon == '-1') + const SizedBox( + height: 60, + width: 60, + ) + else + ClipOval( + child: Container( + height: 60, + width: 60, + padding: const EdgeInsets.all(8), + color: ColorsManager.whiteColors, + child: SvgPicture.asset( + icon ?? Assets.lightPulp, + width: 35, + height: 35, + fit: BoxFit.contain, + ), + )), if (showToggle) Container( child: CupertinoSwitch( value: value, - activeColor: ColorsManager.dialogBlueTitle, + activeTrackColor: ColorsManager.dialogBlueTitle, onChanged: onChange, ), ), diff --git a/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart b/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart index 14fdf61c..9334a039 100644 --- a/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart +++ b/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart @@ -22,7 +22,8 @@ class SosDeviceBloc extends Bloc { late SosStatusModel deviceStatus; - FutureOr _getDeviceStatus(GetDeviceStatus event, Emitter emit) async { + FutureOr _getDeviceStatus( + GetDeviceStatus event, Emitter emit) async { emit(SosDeviceLoadingState()); try { final status = await DevicesManagementApi().getDeviceStatus(event.uuid); @@ -33,7 +34,8 @@ class SosDeviceBloc extends Bloc { } } - FutureOr _getBatchStatus(GetBatchStatus event, Emitter emit) async { + FutureOr _getBatchStatus( + GetBatchStatus event, Emitter emit) async { emit(SosDeviceLoadingState()); try { final status = await DevicesManagementApi().getBatchStatus(event.uuids); @@ -44,25 +46,31 @@ class SosDeviceBloc extends Bloc { } } - FutureOr _getDeviceRecords(GetDeviceRecords event, Emitter emit) async { + FutureOr _getDeviceRecords( + GetDeviceRecords event, Emitter emit) async { emit(SosReportLoadingState()); try { - final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; + final from = DateTime.now() + .subtract(const Duration(days: 30)) + .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final DeviceReport records = - await DevicesManagementApi.getDeviceReportsByDate(event.uuid, 'sos', from.toString(), to.toString()); + final records = await DevicesManagementApi.getDeviceReportsByDate( + event.uuid, 'sos', from.toString(), to.toString()); emit(SosReportLoadedState(records)); } catch (e) { emit(SosReportErrorState(e.toString())); } } - FutureOr _getDeviceAutomationRecords(GetDeviceAutomationRecords event, Emitter emit) async { + FutureOr _getDeviceAutomationRecords( + GetDeviceAutomationRecords event, Emitter emit) async { emit(SosAutomationReportLoadingState()); try { - final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; + final from = DateTime.now() + .subtract(const Duration(days: 30)) + .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final DeviceReport records = await DevicesManagementApi.getDeviceReportsByDate( + final records = await DevicesManagementApi.getDeviceReportsByDate( event.uuid, 'sos_automation', from.toString(), to.toString()); emit(SosAutomationReportLoadedState(records)); } catch (e) { @@ -70,14 +78,17 @@ class SosDeviceBloc extends Bloc { } } - FutureOr _backToSosStatusView(BackToSosStatusView event, Emitter emit) { + FutureOr _backToSosStatusView( + BackToSosStatusView event, Emitter emit) { emit(SosDeviceLoadedState(deviceStatus)); } - FutureOr _sosFactoryReset(SosFactoryReset event, Emitter emit) async { + FutureOr _sosFactoryReset( + SosFactoryReset event, Emitter emit) async { emit(SosDeviceLoadingState()); try { - final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId); + final response = await DevicesManagementApi() + .factoryReset(event.factoryReset, event.deviceId); if (response) { emit(SosDeviceLoadedState(deviceStatus)); } else { diff --git a/lib/pages/device_managment/sos/models/sos_status_model.dart b/lib/pages/device_managment/sos/models/sos_status_model.dart index ac0de3b0..4a9f2114 100644 --- a/lib/pages/device_managment/sos/models/sos_status_model.dart +++ b/lib/pages/device_managment/sos/models/sos_status_model.dart @@ -15,7 +15,7 @@ class SosStatusModel { late int batteryLevel; late String sosStatus; - for (var status in statuses) { + for (final status in statuses) { switch (status.code) { case 'battery_percentage': batteryLevel = status.value; diff --git a/lib/pages/device_managment/sos/view/sos_device_control_view.dart b/lib/pages/device_managment/sos/view/sos_device_control_view.dart index dde4512b..631a7424 100644 --- a/lib/pages/device_managment/sos/view/sos_device_control_view.dart +++ b/lib/pages/device_managment/sos/view/sos_device_control_view.dart @@ -6,13 +6,12 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart'; import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart'; import 'package:syncrow_web/pages/device_managment/sos/bloc/sos_device_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/sos/models/sos_status_model.dart'; import 'package:syncrow_web/pages/device_managment/sos/widgets/sos_notification_dialog.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -import '../models/sos_status_model.dart'; - class SosDeviceControlsView extends StatelessWidget with HelperResponsiveLayout { const SosDeviceControlsView({ @@ -56,9 +55,9 @@ class SosDeviceControlsView extends StatelessWidget } else if (state is SosDeviceErrorState) { return const Center(child: Text('Error fetching status')); } else if (state is SosAutomationReportErrorState) { - return Center(child: Text('Error: ${state.message.toString()}')); + return Center(child: Text('Error: ${state.message}')); } else if (state is SosReportErrorState) { - return Center(child: Text('Error: ${state.message.toString()}')); + return Center(child: Text('Error: ${state.message}')); } return const Center(child: CircularProgressIndicator()); }, diff --git a/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart b/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart index 55428107..bbdeaa3d 100644 --- a/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart +++ b/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart @@ -52,7 +52,7 @@ class _NotificationDialogState extends State { ), ), child: IconButton( - padding: EdgeInsets.all(1), + padding: const EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, diff --git a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart index 766c3163..7ab5567d 100644 --- a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart @@ -40,7 +40,8 @@ class ThreeGangGlassSwitchBloc ) async { emit(ThreeGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(event.deviceId, emit); deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status); @@ -64,7 +65,7 @@ class ThreeGangGlassSwitchBloc final statusList = []; if (data['status'] != null) { - for (var element in data['status']) { + for (final element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -74,7 +75,8 @@ class ThreeGangGlassSwitchBloc } } if (statusList.isNotEmpty) { - final newStatus = ThreeGangGlassStatusModel.fromJson(deviceId, statusList); + final newStatus = + ThreeGangGlassStatusModel.fromJson(deviceId, statusList); if (newStatus != deviceStatus) { deviceStatus = newStatus; if (!isClosed) { @@ -142,9 +144,10 @@ class ThreeGangGlassSwitchBloc ) async { emit(ThreeGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = - ThreeGangGlassStatusModel.fromJson(event.deviceIds.first, status.status); + final status = + await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = ThreeGangGlassStatusModel.fromJson( + event.deviceIds.first, status.status); emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus)); } catch (e) { emit(ThreeGangGlassSwitchError(e.toString())); diff --git a/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart b/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart index cec12b7f..e439a434 100644 --- a/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart +++ b/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart @@ -27,7 +27,7 @@ class ThreeGangGlassStatusModel { late bool switch3; late int countDown3; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; diff --git a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart index 93fbe53e..22b5ff53 100644 --- a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart +++ b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart @@ -9,16 +9,19 @@ import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/factorie import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class ThreeGangGlassSwitchBatchControlView extends StatelessWidget + with HelperResponsiveLayout { final List deviceIds; - const ThreeGangGlassSwitchBatchControlView({required this.deviceIds, super.key}); + const ThreeGangGlassSwitchBatchControlView( + {required this.deviceIds, super.key}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(ThreeGangGlassSwitchFetchBatchStatusEvent(deviceIds)), + create: (context) => + ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(ThreeGangGlassSwitchFetchBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is ThreeGangGlassSwitchLoading) { @@ -35,7 +38,8 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe ); } - Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel status) { + Widget _buildStatusControls( + BuildContext context, ThreeGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -58,7 +62,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe value: status.switch1, code: 'switch_1', deviceId: deviceIds.first, - label: "Wall Light", + label: 'Wall Light', onChange: (value) { context.read().add( ThreeGangGlassSwitchBatchControl( @@ -73,7 +77,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe value: status.switch2, code: 'switch_2', deviceId: deviceIds.first, - label: "Ceiling Light", + label: 'Ceiling Light', onChange: (value) { context.read().add( ThreeGangGlassSwitchBatchControl( @@ -88,7 +92,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe value: status.switch3, code: 'switch_3', deviceId: deviceIds.first, - label: "SpotLight", + label: 'SpotLight', onChange: (value) { context.read().add( ThreeGangGlassSwitchBatchControl( diff --git a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart index 21a81df0..019f17f2 100644 --- a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart @@ -3,12 +3,12 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/factories/three_gang_glass_switch_bloc_factory.dart'; +import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -import '../models/three_gang_glass_switch.dart'; - -class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout { +class ThreeGangGlassSwitchControlView extends StatelessWidget + with HelperResponsiveLayout { final String deviceId; const ThreeGangGlassSwitchControlView({required this.deviceId, super.key}); @@ -17,7 +17,8 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons Widget build(BuildContext context) { return BlocProvider( create: (context) => - ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceId)..add(ThreeGangGlassSwitchFetchDeviceEvent(deviceId)), + ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceId) + ..add(ThreeGangGlassSwitchFetchDeviceEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is ThreeGangGlassSwitchLoading) { @@ -34,7 +35,8 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons ); } - Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel status) { + Widget _buildStatusControls( + BuildContext context, ThreeGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -57,7 +59,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons value: status.switch1, code: 'switch_1', deviceId: deviceId, - label: "Wall Light", + label: 'Wall Light', onChange: (value) { context.read().add( ThreeGangGlassSwitchControl( @@ -72,7 +74,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons value: status.switch2, code: 'switch_2', deviceId: deviceId, - label: "Ceiling Light", + label: 'Ceiling Light', onChange: (value) { context.read().add( ThreeGangGlassSwitchControl( @@ -87,7 +89,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperRespons value: status.switch3, code: 'switch_3', deviceId: deviceId, - label: "SpotLight", + label: 'SpotLight', onChange: (value) { context.read().add( ThreeGangGlassSwitchControl( diff --git a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart index bec1314c..be51b1d2 100644 --- a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart +++ b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart @@ -39,9 +39,11 @@ class LivingRoomBloc extends Bloc { ) async { emit(LivingRoomDeviceStatusLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(deviceId); - deviceStatus = LivingRoomStatusModel.fromJson(event.deviceId, status.status); + deviceStatus = + LivingRoomStatusModel.fromJson(event.deviceId, status.status); emit(LivingRoomDeviceStatusLoaded(deviceStatus)); } catch (e) { emit(LivingRoomDeviceManagementError(e.toString())); @@ -52,9 +54,9 @@ class LivingRoomBloc extends Bloc { try { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value as Map; + final eventsMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), @@ -122,7 +124,8 @@ class LivingRoomBloc extends Bloc { ) async { emit(LivingRoomDeviceStatusLoading()); try { - final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); + final status = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = LivingRoomStatusModel.fromJson(event.devicesIds.first, status.status); emit(LivingRoomDeviceStatusLoaded(deviceStatus)); diff --git a/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart b/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart index 4bb5eada..60ea3d12 100644 --- a/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart +++ b/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart @@ -18,7 +18,7 @@ class LivingRoomStatusModel { late bool switch2; late bool switch3; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; // default to false if null diff --git a/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart b/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart index 0b1a2f06..77647078 100644 --- a/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart +++ b/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart @@ -2,14 +2,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; +import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/factories/living_room_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; -import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class LivingRoomBatchControlsView extends StatelessWidget with HelperResponsiveLayout { +class LivingRoomBatchControlsView extends StatelessWidget + with HelperResponsiveLayout { const LivingRoomBatchControlsView({super.key, required this.deviceIds}); final List deviceIds; @@ -18,14 +19,16 @@ class LivingRoomBatchControlsView extends StatelessWidget with HelperResponsiveL Widget build(BuildContext context) { return BlocProvider( create: (context) => - LivingRoomBlocFactory.create(deviceId: deviceIds.first)..add(LivingRoomFetchBatchEvent(deviceIds)), + LivingRoomBlocFactory.create(deviceId: deviceIds.first) + ..add(LivingRoomFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is LivingRoomDeviceStatusLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is LivingRoomDeviceStatusLoaded) { return _buildStatusControls(context, state.status); - } else if (state is LivingRoomDeviceManagementError || state is LivingRoomControlError) { + } else if (state is LivingRoomDeviceManagementError || + state is LivingRoomControlError) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); @@ -35,7 +38,8 @@ class LivingRoomBatchControlsView extends StatelessWidget with HelperResponsiveL ); } - Widget _buildStatusControls(BuildContext context, LivingRoomStatusModel status) { + Widget _buildStatusControls( + BuildContext context, LivingRoomStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart b/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart index 731b354c..7d0faf7f 100644 --- a/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart +++ b/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/factories/living_room_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; -import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; class LivingRoomDeviceControlsView extends StatelessWidget diff --git a/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart b/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart index 629c131b..ed0896fa 100644 --- a/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart +++ b/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart @@ -1,5 +1,4 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; @@ -7,7 +6,11 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class CeilingLight extends StatelessWidget { - const CeilingLight({super.key, required this.value, required this.code, required this.deviceId}); + const CeilingLight( + {super.key, + required this.value, + required this.code, + required this.deviceId}); final bool value; final String code; @@ -23,7 +26,7 @@ class CeilingLight extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.lightPulp, @@ -37,7 +40,7 @@ class CeilingLight extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeColor: ColorsManager.dialogBlueTitle, + activeTrackColor: ColorsManager.dialogBlueTitle, onChanged: (newValue) { context.read().add( LivingRoomControl( diff --git a/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart b/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart index 6ac71a38..ea635247 100644 --- a/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart +++ b/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart @@ -1,5 +1,4 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; @@ -7,7 +6,11 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class SpotLight extends StatelessWidget { - const SpotLight({super.key, required this.value, required this.code, required this.deviceId}); + const SpotLight( + {super.key, + required this.value, + required this.code, + required this.deviceId}); final bool value; final String code; @@ -23,7 +26,7 @@ class SpotLight extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.lightPulp, @@ -37,7 +40,7 @@ class SpotLight extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeColor: ColorsManager.dialogBlueTitle, + activeTrackColor: ColorsManager.dialogBlueTitle, onChanged: (newValue) { context.read().add( LivingRoomControl( diff --git a/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart b/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart index 12c814ac..8844cb1e 100644 --- a/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart +++ b/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart @@ -1,5 +1,4 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; @@ -7,7 +6,11 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class WallLight extends StatelessWidget { - const WallLight({super.key, required this.value, required this.code, required this.deviceId}); + const WallLight( + {super.key, + required this.value, + required this.code, + required this.deviceId}); final bool value; final String code; @@ -23,7 +26,7 @@ class WallLight extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.lightPulp, @@ -37,7 +40,7 @@ class WallLight extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeColor: ColorsManager.dialogBlueTitle, + activeTrackColor: ColorsManager.dialogBlueTitle, onChanged: (newValue) { context.read().add( LivingRoomControl( diff --git a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart index 8f82c198..2a71f477 100644 --- a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart @@ -42,8 +42,10 @@ class TwoGangGlassSwitchBloc ) async { emit(TwoGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceId, status.status); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = + TwoGangGlassStatusModel.fromJson(event.deviceId, status.status); _listenToChanges(event.deviceId); emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { @@ -58,11 +60,12 @@ class TwoGangGlassSwitchBloc ); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value as Map; + final eventsMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; eventsMap['status'].forEach((element) { - statusList.add(Status(code: element['code'], value: element['value'])); + statusList + .add(Status(code: element['code'], value: element['value'])); }); deviceStatus = TwoGangGlassStatusModel.fromJson(deviceId, statusList); @@ -121,7 +124,8 @@ class TwoGangGlassSwitchBloc ) async { emit(TwoGangGlassSwitchLoading()); try { - final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); + final status = + await DevicesManagementApi().getBatchStatus(event.deviceIds); deviceStatus = TwoGangGlassStatusModel.fromJson( event.deviceIds.first, status.status, diff --git a/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart b/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart index 54d99d74..1d407ab6 100644 --- a/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart +++ b/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart @@ -21,7 +21,7 @@ class TwoGangGlassStatusModel { late bool switch2; late int countDown2; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; diff --git a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart index 9d120ad6..a70f1dfe 100644 --- a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart +++ b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart @@ -9,16 +9,19 @@ import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/factories/ import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class TwoGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class TwoGangGlassSwitchBatchControlView extends StatelessWidget + with HelperResponsiveLayout { final List deviceIds; - const TwoGangGlassSwitchBatchControlView({required this.deviceIds, super.key}); + const TwoGangGlassSwitchBatchControlView( + {required this.deviceIds, super.key}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => TwoGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)), + create: (context) => + TwoGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is TwoGangGlassSwitchLoading) { @@ -35,7 +38,8 @@ class TwoGangGlassSwitchBatchControlView extends StatelessWidget with HelperResp ); } - Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) { + Widget _buildStatusControls( + BuildContext context, TwoGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart index 575deeac..34e96c2b 100644 --- a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart @@ -16,8 +16,9 @@ class TwoGangGlassSwitchControlView extends StatelessWidget @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => TwoGangGlassSwitchBlocFactory.create(deviceId: deviceId) - ..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)), + create: (context) => + TwoGangGlassSwitchBlocFactory.create(deviceId: deviceId) + ..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is TwoGangGlassSwitchLoading) { diff --git a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart index 2e3a8633..1d959ffb 100644 --- a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart +++ b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart @@ -37,7 +37,8 @@ class TwoGangSwitchBloc extends Bloc { ) async { emit(TwoGangSwitchLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = TwoGangStatusModel.fromJson(event.deviceId, status.status); _listenToChanges(event.deviceId); emit(TwoGangSwitchStatusLoaded(deviceStatus)); @@ -51,9 +52,9 @@ class TwoGangSwitchBloc extends Bloc { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value as Map; + final eventsMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), @@ -116,7 +117,8 @@ class TwoGangSwitchBloc extends Bloc { ) async { emit(TwoGangSwitchLoading()); try { - final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); + final status = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = TwoGangStatusModel.fromJson( event.devicesIds.first, status.status, diff --git a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart index b9208211..f4596d8c 100644 --- a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart +++ b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart @@ -22,7 +22,7 @@ class TwoGangSwitchStatusLoaded extends TwoGangSwitchState { class TwoGangSwitchError extends TwoGangSwitchState { final String message; - TwoGangSwitchError(this.message); + TwoGangSwitchError(this.message); @override List get props => [message]; diff --git a/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart b/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart index 58094a71..78794d72 100644 --- a/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart +++ b/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart @@ -21,7 +21,7 @@ class TwoGangStatusModel { late int countDown; late int countDown2; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch_1': switch1 = bool.tryParse(status.value.toString()) ?? false; diff --git a/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart b/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart index e8346cb2..1284a93b 100644 --- a/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart +++ b/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart @@ -10,7 +10,8 @@ import 'package:syncrow_web/pages/device_managment/two_gang_switch/factories/two import 'package:syncrow_web/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class TwoGangBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class TwoGangBatchControlView extends StatelessWidget + with HelperResponsiveLayout { const TwoGangBatchControlView({super.key, required this.deviceIds}); final List deviceIds; @@ -18,15 +19,17 @@ class TwoGangBatchControlView extends StatelessWidget with HelperResponsiveLayou @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => TwoGangSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(TwoGangSwitchFetchBatchEvent(deviceIds)), + create: (context) => + TwoGangSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(TwoGangSwitchFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is TwoGangSwitchLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is TwoGangSwitchStatusLoaded) { return _buildStatusControls(context, state.status); - } else if (state is TwoGangSwitchError || state is TwoGangSwitchControlError) { + } else if (state is TwoGangSwitchError || + state is TwoGangSwitchControlError) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); diff --git a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart index 630a132b..4db3798e 100644 --- a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart +++ b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart @@ -55,7 +55,8 @@ class WallSensorBloc extends Bloc { ) async { emit(WallSensorLoadingInitialState()); try { - final response = await DevicesManagementApi().getBatchStatus(event.devicesIds); + final response = + await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = WallSensorModel.fromJson(response.status); emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); } catch (e) { @@ -68,9 +69,9 @@ class WallSensorBloc extends Bloc { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value as Map; + final eventsMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), diff --git a/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart b/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart index 92b1842e..d193df93 100644 --- a/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart +++ b/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart @@ -23,46 +23,46 @@ class WallSensorModel { required this.noBodyTime}); factory WallSensorModel.fromJson(List jsonList) { - late String _presenceState; - late int _farDetection; - late int _presenceTime; - late int _motionSensitivity; - late int _motionlessSensitivity; - late int _currentDistance; - late int _illuminance; - late bool _indicator; - late int _noBodyTime; + late String presenceState; + late int farDetection; + late int presenceTime; + late int motionSensitivity; + late int motionlessSensitivity; + late int currentDistance; + late int illuminance; + late bool indicator; + late int noBodyTime; - for (int i = 0; i < jsonList.length; i++) { + for (var i = 0; i < jsonList.length; i++) { if (jsonList[i].code == 'presence_state') { - _presenceState = jsonList[i].value ?? 'none'; + presenceState = jsonList[i].value ?? 'none'; } else if (jsonList[i].code == 'far_detection') { - _farDetection = jsonList[i].value ?? 0; + farDetection = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'presence_time') { - _presenceTime = jsonList[i].value ?? 0; + presenceTime = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'motion_sensitivity_value') { - _motionSensitivity = jsonList[i].value ?? 0; + motionSensitivity = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'motionless_sensitivity') { - _motionlessSensitivity = jsonList[i].value ?? 0; + motionlessSensitivity = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'dis_current') { - _currentDistance = jsonList[i].value ?? 0; + currentDistance = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'illuminance_value') { - _illuminance = jsonList[i].value ?? 0; + illuminance = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'indicator') { - _indicator = jsonList[i].value ?? false; + indicator = jsonList[i].value ?? false; } else if (jsonList[i].code == 'no_one_time') { - _noBodyTime = jsonList[i].value ?? 0; + noBodyTime = jsonList[i].value ?? 0; } } return WallSensorModel( - presenceState: _presenceState, - farDetection: _farDetection, - presenceTime: _presenceTime, - motionSensitivity: _motionSensitivity, - motionlessSensitivity: _motionlessSensitivity, - currentDistance: _currentDistance, - illuminance: _illuminance, - indicator: _indicator, - noBodyTime: _noBodyTime); + presenceState: presenceState, + farDetection: farDetection, + presenceTime: presenceTime, + motionSensitivity: motionSensitivity, + motionlessSensitivity: motionlessSensitivity, + currentDistance: currentDistance, + illuminance: illuminance, + indicator: indicator, + noBodyTime: noBodyTime); } } diff --git a/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart b/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart index 61108387..6d15ba37 100644 --- a/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart +++ b/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart @@ -11,7 +11,8 @@ import 'package:syncrow_web/pages/device_managment/wall_sensor/factories/wall_se import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WallSensorBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class WallSensorBatchControlView extends StatelessWidget + with HelperResponsiveLayout { const WallSensorBatchControlView({super.key, required this.devicesIds}); final List devicesIds; @@ -22,17 +23,21 @@ class WallSensorBatchControlView extends StatelessWidget with HelperResponsiveLa final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => WallSensorBlocFactory.create(deviceId: devicesIds.first) - ..add(WallSensorFetchBatchStatusEvent(devicesIds)), + create: (context) => + WallSensorBlocFactory.create(deviceId: devicesIds.first) + ..add(WallSensorFetchBatchStatusEvent(devicesIds)), child: BlocBuilder( builder: (context, state) { - if (state is WallSensorLoadingInitialState || state is DeviceReportsLoadingState) { + if (state is WallSensorLoadingInitialState || + state is DeviceReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is WallSensorUpdateState) { - return _buildGridView(context, state.wallSensorModel, isExtraLarge, isLarge, isMedium); + return _buildGridView(context, state.wallSensorModel, isExtraLarge, + isLarge, isMedium); } else if (state is DeviceReportsFailedState) { final model = context.read().deviceStatus; - return _buildGridView(context, model, isExtraLarge, isLarge, isMedium); + return _buildGridView( + context, model, isExtraLarge, isLarge, isMedium); } return const Center(child: Text('Error fetching status')); }, @@ -40,8 +45,8 @@ class WallSensorBatchControlView extends StatelessWidget with HelperResponsiveLa ); } - Widget _buildGridView( - BuildContext context, WallSensorModel model, bool isExtraLarge, bool isLarge, bool isMedium) { + Widget _buildGridView(BuildContext context, WallSensorModel model, + bool isExtraLarge, bool isLarge, bool isMedium) { return GridView( padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20), shrinkWrap: true, @@ -94,11 +99,12 @@ class WallSensorBatchControlView extends StatelessWidget with HelperResponsiveLa maxValue: 10000, steps: 1, description: 'sec', - action: (int value) => context.read().add(WallSensorBatchControlEvent( - deviceIds: devicesIds, - code: 'no_one_time', - value: value, - ))), + action: (int value) => + context.read().add(WallSensorBatchControlEvent( + deviceIds: devicesIds, + code: 'no_one_time', + value: value, + ))), PresenceUpdateData( value: model.farDetection.toDouble(), title: 'Far Detection:', diff --git a/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart b/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart index def8ed93..b6279b07 100644 --- a/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart +++ b/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart @@ -1,21 +1,22 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_status.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart'; import 'package:syncrow_web/pages/device_managment/shared/table/description_view.dart'; import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_bloc.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_state.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_status.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/factories/wall_sensor_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_model.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout { +class WallSensorControlsView extends StatelessWidget + with HelperResponsiveLayout { const WallSensorControlsView({super.key, required this.device}); final AllDevicesModel device; @@ -26,19 +27,23 @@ class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => - WallSensorBlocFactory.create(deviceId: device.uuid!)..add(WallSensorFetchStatusEvent()), + create: (context) => WallSensorBlocFactory.create(deviceId: device.uuid!) + ..add(WallSensorFetchStatusEvent()), child: BlocBuilder( builder: (context, state) { - if (state is WallSensorLoadingInitialState || state is DeviceReportsLoadingState) { + if (state is WallSensorLoadingInitialState || + state is DeviceReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is WallSensorUpdateState) { - return _buildGridView(context, state.wallSensorModel, isExtraLarge, isLarge, isMedium); + return _buildGridView(context, state.wallSensorModel, isExtraLarge, + isLarge, isMedium); } else if (state is DeviceReportsState) { return ReportsTable( report: state.deviceReport, - thirdColumnTitle: state.code == 'illuminance_value' ? "Value" : 'Status', - thirdColumnDescription: state.code == 'illuminance_value' ? "Lux" : null, + thirdColumnTitle: + state.code == 'illuminance_value' ? 'Value' : 'Status', + thirdColumnDescription: + state.code == 'illuminance_value' ? 'Lux' : null, onRowTap: (index) {}, onClose: () { context.read().add(BackToGridViewEvent()); @@ -53,7 +58,8 @@ class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout ); } else if (state is DeviceReportsFailedState) { final model = context.read().deviceStatus; - return _buildGridView(context, model, isExtraLarge, isLarge, isMedium); + return _buildGridView( + context, model, isExtraLarge, isLarge, isMedium); } return const Center(child: Text('Error fetching status')); }, @@ -61,8 +67,8 @@ class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout ); } - Widget _buildGridView( - BuildContext context, WallSensorModel model, bool isExtraLarge, bool isLarge, bool isMedium) { + Widget _buildGridView(BuildContext context, WallSensorModel model, + bool isExtraLarge, bool isLarge, bool isMedium) { return GridView( padding: const EdgeInsets.symmetric(horizontal: 50), shrinkWrap: true, @@ -131,10 +137,11 @@ class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout maxValue: 10000, steps: 1, description: 'sec', - action: (int value) => context.read().add(WallSensorChangeValueEvent( - code: 'no_one_time', - value: value, - ))), + action: (int value) => + context.read().add(WallSensorChangeValueEvent( + code: 'no_one_time', + value: value, + ))), PresenceUpdateData( value: model.farDetection.toDouble(), title: 'Far Detection:', @@ -151,9 +158,8 @@ class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout ), GestureDetector( onTap: () { - context - .read() - .add(GetDeviceReportsEvent(code: 'illuminance_value', deviceUuid: device.uuid!)); + context.read().add(GetDeviceReportsEvent( + code: 'illuminance_value', deviceUuid: device.uuid!)); }, child: const PresenceStaticWidget( icon: Assets.illuminanceRecordIcon, @@ -162,9 +168,8 @@ class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout ), GestureDetector( onTap: () { - context - .read() - .add(GetDeviceReportsEvent(code: 'presence_state', deviceUuid: device.uuid!)); + context.read().add(GetDeviceReportsEvent( + code: 'presence_state', deviceUuid: device.uuid!)); }, child: const PresenceStaticWidget( icon: Assets.presenceRecordIcon, diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart index 560a61e1..69b49e4c 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart @@ -123,11 +123,13 @@ class WaterHeaterBloc extends Bloc { countdownRemaining: countdownRemaining, )); - if (!currentState.isCountdownActive! && countdownRemaining > Duration.zero) { + if (!currentState.isCountdownActive! && + countdownRemaining > Duration.zero) { _startCountdownTimer(emit, countdownRemaining); } } else if (event.scheduleMode == ScheduleModes.inching) { - final inchingDuration = Duration(hours: event.hours, minutes: event.minutes); + final inchingDuration = + Duration(hours: event.hours, minutes: event.minutes); emit( currentState.copyWith( @@ -165,7 +167,7 @@ class WaterHeaterBloc extends Bloc { ); if (success) { - if (event.code == "countdown_1") { + if (event.code == 'countdown_1') { final countdownDuration = Duration(seconds: event.value); emit( @@ -190,7 +192,7 @@ class WaterHeaterBloc extends Bloc { ), ); } - } else if (event.code == "switch_inching") { + } else if (event.code == 'switch_inching') { final inchingDuration = Duration(seconds: event.value); emit( currentState.copyWith( @@ -236,7 +238,8 @@ class WaterHeaterBloc extends Bloc { try { final status = await DevicesManagementApi().deviceControl( event.deviceId, - Status(code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), + Status( + code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), ); if (!status) { emit(const WaterHeaterFailedState(error: 'Failed to stop schedule.')); @@ -254,8 +257,10 @@ class WaterHeaterBloc extends Bloc { emit(WaterHeaterLoadingState()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = WaterHeaterStatusModel.fromJson(event.deviceId, status.status); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = + WaterHeaterStatusModel.fromJson(event.deviceId, status.status); if (deviceStatus.scheduleMode == ScheduleModes.countdown) { final countdownRemaining = Duration( @@ -326,21 +331,20 @@ class WaterHeaterBloc extends Bloc { void _listenToChanges(deviceId) { try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$deviceId'); - Stream stream = ref.onValue; + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + final stream = ref.onValue; stream.listen((DatabaseEvent event) { - Map usersMap = - event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; usersMap['status'].forEach((element) { - statusList.add(Status(code: element['code'], value: element['value'])); + statusList + .add(Status(code: element['code'], value: element['value'])); }); - deviceStatus = - WaterHeaterStatusModel.fromJson(usersMap['productUuid'], statusList); + deviceStatus = WaterHeaterStatusModel.fromJson( + usersMap['productUuid'], statusList); if (!isClosed) { add(StatusUpdated(deviceStatus)); } @@ -475,14 +479,14 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - ScheduleEntry newSchedule = ScheduleEntry( + final newSchedule = ScheduleEntry( category: event.category, time: formatTimeOfDayToISO(event.time), function: Status(code: 'switch_1', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - bool success = await DevicesManagementApi() + final success = await DevicesManagementApi() .addScheduleRecord(newSchedule, currentState.status.uuid); if (success) { @@ -500,7 +504,7 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - ScheduleEntry newSchedule = ScheduleEntry( + final newSchedule = ScheduleEntry( scheduleId: event.scheduleId, category: event.category, time: formatTimeOfDayToISO(event.time), @@ -508,7 +512,7 @@ class WaterHeaterBloc extends Bloc { days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - bool success = await DevicesManagementApi().editScheduleRecord( + final success = await DevicesManagementApi().editScheduleRecord( currentState.status.uuid, newSchedule, ); @@ -538,7 +542,7 @@ class WaterHeaterBloc extends Bloc { return schedule; }).toList(); - bool success = await DevicesManagementApi().updateScheduleRecord( + final success = await DevicesManagementApi().updateScheduleRecord( enable: event.enable, uuid: currentState.status.uuid, scheduleId: event.scheduleId, @@ -559,7 +563,7 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - bool success = await DevicesManagementApi() + final success = await DevicesManagementApi() .deleteScheduleRecord(currentState.status.uuid, event.scheduleId); if (success) { @@ -584,8 +588,8 @@ class WaterHeaterBloc extends Bloc { final status = await DevicesManagementApi().getBatchStatus( event.devicesUuid, ); - deviceStatus = - WaterHeaterStatusModel.fromJson(event.devicesUuid.first, status.status); + deviceStatus = WaterHeaterStatusModel.fromJson( + event.devicesUuid.first, status.status); emit(WaterHeaterDeviceStatusLoaded(deviceStatus)); } catch (e) { @@ -593,8 +597,8 @@ class WaterHeaterBloc extends Bloc { } } - Future _batchControlWaterHeater( - ControlWaterHeaterBatchEvent event, Emitter emit) async { + Future _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, + Emitter emit) async { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; @@ -613,7 +617,7 @@ class WaterHeaterBloc extends Bloc { ); if (success) { - if (event.code == "switch_1") { + if (event.code == 'switch_1') { emit(currentState.copyWith( status: deviceStatus, )); diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart index e4cc8474..92c5c293 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart @@ -54,7 +54,6 @@ final class WaterHeaterFetchStatusEvent extends WaterHeaterEvent { final class DecrementCountdownEvent extends WaterHeaterEvent {} - class StatusUpdated extends WaterHeaterEvent { final WaterHeaterStatusModel deviceStatus; const StatusUpdated(this.deviceStatus); @@ -62,7 +61,6 @@ class StatusUpdated extends WaterHeaterEvent { List get props => [deviceStatus]; } - final class AddScheduleEvent extends WaterHeaterEvent { final List selectedDays; final TimeOfDay time; diff --git a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart index 9278e396..27df3a9e 100644 --- a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart +++ b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart @@ -7,11 +7,12 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class ScheduleDialogHelper { - static void showAddScheduleDialog(BuildContext context, {ScheduleModel? schedule, int? index, bool? isEdit}) { + static void showAddScheduleDialog(BuildContext context, + {ScheduleModel? schedule, int? index, bool? isEdit}) { final bloc = context.read(); if (schedule == null) { - bloc.add((const UpdateSelectedTimeEvent(null))); + bloc.add(const UpdateSelectedTimeEvent(null)); bloc.add(InitializeAddScheduleEvent( selectedTime: null, selectedDays: List.filled(7, false), @@ -70,9 +71,10 @@ class ScheduleDialogHelper { backgroundColor: ColorsManager.boxColor, borderRadius: 15, onPressed: () async { - TimeOfDay? time = await showTimePicker( + final time = await showTimePicker( context: context, - initialTime: state.selectedTime ?? TimeOfDay.now(), + initialTime: + state.selectedTime ?? TimeOfDay.now(), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( @@ -92,7 +94,9 @@ class ScheduleDialogHelper { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - state.selectedTime == null ? 'Time' : state.selectedTime!.format(context), + state.selectedTime == null + ? 'Time' + : state.selectedTime!.format(context), style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.grayColor, ), @@ -107,7 +111,8 @@ class ScheduleDialogHelper { ), ), const SizedBox(height: 16), - _buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit), + _buildDayCheckboxes(context, state.selectedDays, + isEdit: isEdit), const SizedBox(height: 16), _buildFunctionSwitch(context, state.functionOn, isEdit), ], @@ -181,9 +186,9 @@ class ScheduleDialogHelper { static List _convertDaysStringToBooleans(List selectedDays) { final daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - List daysBoolean = List.filled(7, false); + final daysBoolean = List.filled(7, false); - for (int i = 0; i < daysOfWeek.length; i++) { + for (var i = 0; i < daysOfWeek.length; i++) { if (selectedDays.contains(daysOfWeek[i])) { daysBoolean[i] = true; } @@ -192,7 +197,9 @@ class ScheduleDialogHelper { return daysBoolean; } - static Widget _buildDayCheckboxes(BuildContext context, List selectedDays, {bool? isEdit}) { + static Widget _buildDayCheckboxes( + BuildContext context, List selectedDays, + {bool? isEdit}) { final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; return Row( @@ -202,7 +209,9 @@ class ScheduleDialogHelper { Checkbox( value: selectedDays[index], onChanged: (bool? value) { - context.read().add(UpdateSelectedDayEvent(index, value!)); + context + .read() + .add(UpdateSelectedDayEvent(index, value!)); }, ), Text(dayLabels[index]), @@ -212,19 +221,23 @@ class ScheduleDialogHelper { ); } - static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) { + static Widget _buildFunctionSwitch( + BuildContext context, bool isOn, bool? isEdit) { return Row( children: [ Text( 'Function:', - style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor), + style: context.textTheme.bodySmall! + .copyWith(color: ColorsManager.grayColor), ), const SizedBox(width: 10), Radio( value: true, groupValue: isOn, onChanged: (bool? value) { - context.read().add(const UpdateFunctionOnEvent(true)); + context + .read() + .add(const UpdateFunctionOnEvent(true)); }, ), const Text('On'), @@ -233,7 +246,9 @@ class ScheduleDialogHelper { value: false, groupValue: isOn, onChanged: (bool? value) { - context.read().add(const UpdateFunctionOnEvent(false)); + context + .read() + .add(const UpdateFunctionOnEvent(false)); }, ), const Text('Off'), diff --git a/lib/pages/device_managment/water_heater/models/schedule_entry.dart b/lib/pages/device_managment/water_heater/models/schedule_entry.dart index a2a109af..4a379009 100644 --- a/lib/pages/device_managment/water_heater/models/schedule_entry.dart +++ b/lib/pages/device_managment/water_heater/models/schedule_entry.dart @@ -58,7 +58,8 @@ class ScheduleEntry { String toJson() => json.encode(toMap()); - factory ScheduleEntry.fromJson(String source) => ScheduleEntry.fromMap(json.decode(source)); + factory ScheduleEntry.fromJson(String source) => + ScheduleEntry.fromMap(json.decode(source)); @override bool operator ==(Object other) { @@ -73,6 +74,9 @@ class ScheduleEntry { @override int get hashCode { - return category.hashCode ^ time.hashCode ^ function.hashCode ^ days.hashCode; + return category.hashCode ^ + time.hashCode ^ + function.hashCode ^ + days.hashCode; } } diff --git a/lib/pages/device_managment/water_heater/models/schedule_model.dart b/lib/pages/device_managment/water_heater/models/schedule_model.dart index 3d05a3e0..b90cf921 100644 --- a/lib/pages/device_managment/water_heater/models/schedule_model.dart +++ b/lib/pages/device_managment/water_heater/models/schedule_model.dart @@ -1,7 +1,8 @@ import 'dart:convert'; + +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; -import 'package:flutter/foundation.dart'; class ScheduleModel { final String scheduleId; @@ -93,8 +94,8 @@ class ScheduleModel { static List convertSelectedDaysToStrings(List selectedDays) { const allDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - List result = []; - for (int i = 0; i < selectedDays.length; i++) { + final result = []; + for (var i = 0; i < selectedDays.length; i++) { if (selectedDays[i]) { result.add(allDays[i]); } diff --git a/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart b/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart index c535bda2..e4b48b5d 100644 --- a/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart +++ b/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart @@ -16,7 +16,7 @@ class WaterHeaterStatusModel extends Equatable { final String cycleTiming; final List schedules; - const WaterHeaterStatusModel({ + const WaterHeaterStatusModel({ required this.uuid, required this.heaterSwitch, required this.countdownHours, @@ -30,13 +30,13 @@ class WaterHeaterStatusModel extends Equatable { }); factory WaterHeaterStatusModel.fromJson(String id, List jsonList) { - late bool heaterSwitch = false; - late int countdownInSeconds = 0; - late String relayStatus = ''; - late String cycleTiming = ''; - late ScheduleModes scheduleMode = ScheduleModes.countdown; + late var heaterSwitch = false; + late var countdownInSeconds = 0; + late var relayStatus = ''; + late var cycleTiming = ''; + late var scheduleMode = ScheduleModes.countdown; - for (var status in jsonList) { + for (final status in jsonList) { switch (status.code) { case 'switch_1': heaterSwitch = status.value ?? false; diff --git a/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart b/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart index 3c8a3858..97ef6302 100644 --- a/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart +++ b/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart @@ -37,7 +37,8 @@ class WaterHEaterBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls(BuildContext context, WaterHeaterStatusModel status) { + Widget _buildStatusControls( + BuildContext context, WaterHeaterStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart index f1e56136..f654e62c 100644 --- a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart +++ b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart @@ -35,7 +35,8 @@ class WaterHeaterDeviceControlView extends StatelessWidget state is WaterHeaterBatchFailedState) { return const Center(child: Text('Error fetching status')); } else { - return const SizedBox(height: 200, child: Center(child: SizedBox())); + return const SizedBox( + height: 200, child: Center(child: SizedBox())); } }, )); diff --git a/lib/pages/device_managment/water_heater/widgets/count_down_button.dart b/lib/pages/device_managment/water_heater/widgets/count_down_button.dart index e60c7def..4107b6ce 100644 --- a/lib/pages/device_managment/water_heater/widgets/count_down_button.dart +++ b/lib/pages/device_managment/water_heater/widgets/count_down_button.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class CountdownModeButtons extends StatelessWidget { diff --git a/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart b/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart index 8eec5cca..5257dddc 100644 --- a/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart +++ b/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class InchingModeButtons extends StatelessWidget { @@ -12,12 +12,12 @@ class InchingModeButtons extends StatelessWidget { final int minutes; const InchingModeButtons({ - Key? key, + super.key, required this.isActive, required this.deviceId, required this.hours, required this.minutes, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart b/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart index 1710c439..0b2657c5 100644 --- a/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart +++ b/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart @@ -28,7 +28,7 @@ class ScheduleManagementUI extends StatelessWidget { padding: 2, backgroundColor: ColorsManager.graysColor, borderRadius: 15, - onPressed: () => onAddSchedule(), + onPressed: onAddSchedule, child: Row( children: [ const Icon(Icons.add, color: ColorsManager.primaryColor), diff --git a/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart b/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart index bb9ddc8f..fb73eaf4 100644 --- a/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart +++ b/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; -import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; class ScheduleModeSelector extends StatelessWidget { final WaterHeaterDeviceStatusLoaded state; diff --git a/lib/pages/device_managment/water_heater/widgets/schedule_table.dart b/lib/pages/device_managment/water_heater/widgets/schedule_table.dart index 18cbbe5a..576ebc2b 100644 --- a/lib/pages/device_managment/water_heater/widgets/schedule_table.dart +++ b/lib/pages/device_managment/water_heater/widgets/schedule_table.dart @@ -2,14 +2,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/format_date_time.dart'; -import '../helper/add_schedule_dialog_helper.dart'; - class ScheduleTableWidget extends StatelessWidget { final WaterHeaterDeviceStatusLoaded state; @@ -211,8 +210,8 @@ class ScheduleTableWidget extends StatelessWidget { String _getSelectedDays(List selectedDays) { final days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - List selectedDaysStr = []; - for (int i = 0; i < selectedDays.length; i++) { + final selectedDaysStr = []; + for (var i = 0; i < selectedDays.length; i++) { if (selectedDays[i]) { selectedDaysStr.add(days[i]); } diff --git a/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart b/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart index 6d3ca9a6..ee1390a7 100644 --- a/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart +++ b/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart @@ -1,13 +1,11 @@ +import 'dart:async'; + 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_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_state.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart'; - -import 'dart:async'; - import 'package:syncrow_web/services/devices_mang_api.dart'; class WaterLeakBloc extends Bloc { @@ -39,17 +37,15 @@ class WaterLeakBloc extends Bloc { } } - _listenToChanges() { + void _listenToChanges() { try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$deviceId'); - Stream stream = ref.onValue; + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + final stream = ref.onValue; stream.listen((DatabaseEvent event) { - Map usersMap = - event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); @@ -195,9 +191,8 @@ class WaterLeakBloc extends Bloc { .subtract(const Duration(days: 30)) .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final DeviceReport records = - await DevicesManagementApi.getDeviceReportsByDate( - event.deviceId, event.code, from.toString(), to.toString()); + final records = await DevicesManagementApi.getDeviceReportsByDate( + event.deviceId, event.code, from.toString(), to.toString()); emit(WaterLeakReportsLoadedState(records)); } catch (e) { emit(WaterLeakReportsFailedState(e.toString())); diff --git a/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart b/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart index 1eb795e5..30b077bf 100644 --- a/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart +++ b/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart @@ -10,16 +10,17 @@ import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_st import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WaterLeakBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class WaterLeakBatchControlView extends StatelessWidget + with HelperResponsiveLayout { final List deviceIds; - const WaterLeakBatchControlView({Key? key, required this.deviceIds}) : super(key: key); + const WaterLeakBatchControlView({super.key, required this.deviceIds}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - WaterLeakBloc(deviceIds.first)..add(FetchWaterLeakBatchStatusEvent(deviceIds)), + create: (context) => WaterLeakBloc(deviceIds.first) + ..add(FetchWaterLeakBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is WaterLeakLoadingState) { @@ -36,7 +37,8 @@ class WaterLeakBatchControlView extends StatelessWidget with HelperResponsiveLay ); } - Widget _buildStatusControls(BuildContext context, WaterLeakStatusModel status) { + Widget _buildStatusControls( + BuildContext context, WaterLeakStatusModel status) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart b/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart index 6b9dc564..51fd5880 100644 --- a/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart +++ b/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart @@ -13,7 +13,7 @@ import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_la class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { final String deviceId; - const WaterLeakView({Key? key, required this.deviceId}) : super(key: key); + const WaterLeakView({super.key, required this.deviceId}); @override Widget build(BuildContext context) { @@ -21,7 +21,8 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => WaterLeakBloc(deviceId)..add(FetchWaterLeakStatusEvent(deviceId)), + create: (context) => + WaterLeakBloc(deviceId)..add(FetchWaterLeakStatusEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is WaterLeakLoadingState) { @@ -44,21 +45,31 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { children: [ IconNameStatusContainer( isFullIcon: false, - name: state.status.watersensorState == 'normal' ? 'Normal' : 'Leak Detection', - icon: state.status.watersensorState == 'normal' ? Assets.waterLeakNormal : Assets.waterLeakDetected, + name: state.status.watersensorState == 'normal' + ? 'Normal' + : 'Leak Detection', + icon: state.status.watersensorState == 'normal' + ? Assets.waterLeakNormal + : Assets.waterLeakDetected, onTap: () {}, status: state.status.watersensorState == 'normal', - textColor: state.status.watersensorState == 'normal' ? ColorsManager.blackColor : ColorsManager.red, + textColor: state.status.watersensorState == 'normal' + ? ColorsManager.blackColor + : ColorsManager.red, ), IconNameStatusContainer( isFullIcon: false, name: 'Records', icon: Assets.records, onTap: () { - context.read().add(FetchWaterLeakReportsEvent( + context + .read() + .add(FetchWaterLeakReportsEvent( deviceId: deviceId, code: 'watersensor_state', - from: DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch, + from: DateTime.now() + .subtract(const Duration(days: 30)) + .millisecondsSinceEpoch, to: DateTime.now().millisecondsSinceEpoch, )); }, @@ -98,7 +109,9 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { waterLeak: true, onRowTap: (index) {}, onClose: () { - context.read().add(FetchWaterLeakStatusEvent(deviceId)); + context + .read() + .add(FetchWaterLeakStatusEvent(deviceId)); }, ); } else if (state is WaterLeakReportsFailedState) { diff --git a/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart b/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart index 0e3e325f..924973c5 100644 --- a/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart +++ b/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart @@ -6,7 +6,8 @@ class WaterLeakNotificationDialog extends StatefulWidget { const WaterLeakNotificationDialog({super.key}); @override - State createState() => _NotificationDialogState(); + State createState() => + _NotificationDialogState(); } class _NotificationDialogState extends State { @@ -53,7 +54,7 @@ class _NotificationDialogState extends State { ), ), child: IconButton( - padding: EdgeInsets.all(1), + padding: const EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index ad6ed4d8..d422f318 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -13,14 +13,13 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/services/home_api.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/routes_const.dart'; -import 'package:syncrow_web/utils/navigation_service.dart'; class HomeBloc extends Bloc { UserModel? user; String terms = ''; String policy = ''; - HomeBloc() : super((HomeInitial())) { + HomeBloc() : super(HomeInitial()) { // on(_createNode); on(_fetchUserInfo); on(_fetchTerms); @@ -30,13 +29,12 @@ class HomeBloc extends Bloc { Future _fetchUserInfo(FetchUserInfo event, Emitter emit) async { try { - var uuid = + final uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); user = await HomeApi().fetchUserInfo(uuid); if (user != null && user!.project != null) { await ProjectManager.setProjectUUID(user!.project!.uuid); - } add(FetchTermEvent()); add(FetchPolicyEvent()); @@ -63,7 +61,7 @@ class HomeBloc extends Bloc { policy = await HomeApi().fetchPolicy(); emit(HomeInitial()); } catch (e) { - debugPrint("Error fetching policy: $e"); + debugPrint('Error fetching policy: $e'); return; } } @@ -72,7 +70,7 @@ class HomeBloc extends Bloc { ConfirmUserAgreementEvent event, Emitter emit) async { try { emit(LoadingHome()); - var uuid = + final uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); policy = await HomeApi().confirmUserAgreements(uuid); emit(PolicyAgreement()); @@ -146,21 +144,21 @@ class HomeBloc extends Bloc { // icon: Assets.energyIcon, // active: false, // onPress: (context) {}, - // color: ColorsManager.slidingBlueColor.withOpacity(0.2), + // color: ColorsManager.slidingBlueColor.withValues(alpha:0.2), // ), // HomeItemModel( // title: 'Integrations', // icon: Assets.integrationsIcon, // active: false, // onPress: (context) {}, - // color: ColorsManager.slidingBlueColor.withOpacity(0.2), + // color: ColorsManager.slidingBlueColor.withValues(alpha:0.2), // ), // HomeItemModel( // title: 'Asset', // icon: Assets.assetIcon, // active: false, // onPress: (context) {}, - // color: ColorsManager.slidingBlueColor.withOpacity(0.2), + // color: ColorsManager.slidingBlueColor.withValues(alpha:0.2), // ), ]; } diff --git a/lib/pages/home/view/agreement_and_privacy_dialog.dart b/lib/pages/home/view/agreement_and_privacy_dialog.dart index 6b72c300..61e8a150 100644 --- a/lib/pages/home/view/agreement_and_privacy_dialog.dart +++ b/lib/pages/home/view/agreement_and_privacy_dialog.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:go_router/go_router.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/routes_const.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -89,7 +87,7 @@ class _AgreementAndPrivacyDialogState extends State { controller: _scrollController, padding: const EdgeInsets.all(25), child: Html( - data: "$_dialogContent $staticText", + data: '$_dialogContent $staticText', onLinkTap: (url, attributes, element) async { if (url != null) { final uri = Uri.parse(url); @@ -97,10 +95,10 @@ class _AgreementAndPrivacyDialogState extends State { } }, style: { - "body": Style( + 'body': Style( fontSize: FontSize(14), color: Colors.black87, - lineHeight: LineHeight(1.5), + lineHeight: const LineHeight(1.5), ), }, ), @@ -110,7 +108,7 @@ class _AgreementAndPrivacyDialogState extends State { } Widget _buildActionButton() { - final String buttonText = _currentPage == 2 ? "I Agree" : "Next"; + final buttonText = _currentPage == 2 ? 'I Agree' : 'Next'; return InkWell( onTap: _isAtEnd @@ -167,7 +165,7 @@ class _AgreementAndPrivacyDialogState extends State { AuthBloc.logout(context); context.go(RoutesConst.auth); }, - child: const Text("Cancel"), + child: const Text('Cancel'), ), _buildActionButton(), ], diff --git a/lib/pages/home/view/home_page.dart b/lib/pages/home/view/home_page.dart index 9159011f..9652f0b6 100644 --- a/lib/pages/home/view/home_page.dart +++ b/lib/pages/home/view/home_page.dart @@ -11,7 +11,7 @@ class HomePage extends StatelessWidget with HelperResponsiveLayout { final isSmallScreen = isSmallScreenSize(context); final isMediumScreen = isMediumScreenSize(context); return isSmallScreen || isMediumScreen - ? HomeMobilePage() + ? const HomeMobilePage() : const HomeWebPage(); } } diff --git a/lib/pages/home/view/home_page_mobile.dart b/lib/pages/home/view/home_page_mobile.dart index ad019ea8..2b1d502b 100644 --- a/lib/pages/home/view/home_page_mobile.dart +++ b/lib/pages/home/view/home_page_mobile.dart @@ -4,16 +4,15 @@ import 'package:flutter_svg/svg.dart'; 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/view/home_card.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; class HomeMobilePage extends StatelessWidget { - HomeMobilePage({super.key}); + const HomeMobilePage({super.key}); @override Widget build(BuildContext context) { - Size size = MediaQuery.of(context).size; + final size = MediaQuery.of(context).size; return PopScope( canPop: false, onPopInvoked: (didPop) => false, @@ -41,7 +40,8 @@ class HomeMobilePage extends StatelessWidget { SizedBox(height: size.height * 0.05), const Text( 'ACCESS YOUR APPS', - style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700), + style: + TextStyle(fontSize: 20, fontWeight: FontWeight.w700), ), const SizedBox(height: 30), Expanded( @@ -63,8 +63,8 @@ class HomeMobilePage extends StatelessWidget { index: index, active: true, color: homeBloc.homeItems[index].color, - name: homeBloc.homeItems[index].title!, - img: homeBloc.homeItems[index].icon!, + name: homeBloc.homeItems[index].title!, + img: homeBloc.homeItems[index].icon!, onTap: () => homeBloc.homeItems[index].onPress(context), ); diff --git a/lib/pages/home/view/home_page_web.dart b/lib/pages/home/view/home_page_web.dart index 53a994f6..5adb5a12 100644 --- a/lib/pages/home/view/home_page_web.dart +++ b/lib/pages/home/view/home_page_web.dart @@ -20,11 +20,9 @@ class _HomeWebPageState extends State { // Flag to track whether the dialog is already shown. bool _dialogShown = false; - - @override Widget build(BuildContext context) { - Size size = MediaQuery.of(context).size; + final size = MediaQuery.of(context).size; final homeBloc = BlocProvider.of(context); return PopScope( diff --git a/lib/pages/home/view/tree_page.dart b/lib/pages/home/view/tree_page.dart index 9458e361..f8dc9c33 100644 --- a/lib/pages/home/view/tree_page.dart +++ b/lib/pages/home/view/tree_page.dart @@ -144,7 +144,7 @@ // borderRadius: BorderRadius.circular(10.0), // boxShadow: [ // BoxShadow( -// color: Colors.grey.withOpacity(0.5), +// color: Colors.grey.withValues(alpha:0.5), // spreadRadius: 2, // blurRadius: 5, // offset: Offset(0, 3), // changes position of shadow diff --git a/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart b/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart index 4f4988b3..15787fd7 100644 --- a/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart +++ b/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart @@ -29,7 +29,7 @@ class RolesPermissionBloc bool tapSelect = true; - changeTapSelected( + void changeTapSelected( ChangeTapSelected event, Emitter emit) { try { emit(RolesLoadingState()); diff --git a/lib/pages/roles_and_permission/model/role_type_model.dart b/lib/pages/roles_and_permission/model/role_type_model.dart index 16b24ec5..61a52f9d 100644 --- a/lib/pages/roles_and_permission/model/role_type_model.dart +++ b/lib/pages/roles_and_permission/model/role_type_model.dart @@ -16,7 +16,7 @@ class RoleTypeModel { uuid: json['uuid'], createdAt: json['createdAt'], updatedAt: json['updatedAt'], - type: json['type'].toString().toLowerCase().replaceAll("_", " "), + type: json['type'].toString().toLowerCase().replaceAll('_', ' '), ); } } diff --git a/lib/pages/roles_and_permission/model/roles_user_model.dart b/lib/pages/roles_and_permission/model/roles_user_model.dart index e502370a..98049bcb 100644 --- a/lib/pages/roles_and_permission/model/roles_user_model.dart +++ b/lib/pages/roles_and_permission/model/roles_user_model.dart @@ -36,14 +36,14 @@ class RolesUserModel { email: json['email'], firstName: json['firstName'], lastName: json['lastName'], - roleType: json['roleType'].toString().toLowerCase().replaceAll("_", " "), + roleType: json['roleType'].toString().toLowerCase().replaceAll('_', ' '), status: json['status'], isEnabled: json['isEnabled'], invitedBy: - json['invitedBy'].toString().toLowerCase().replaceAll("_", " "), + json['invitedBy'].toString().toLowerCase().replaceAll('_', ' '), phoneNumber: json['phoneNumber'], - jobTitle: json['jobTitle'] == null || json['jobTitle'] == " " - ? "_" + jobTitle: json['jobTitle'] == null || json['jobTitle'] == ' ' + ? '_' : json['jobTitle'], createdDate: json['createdDate'], createdTime: json['createdTime'], diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart index 54187152..00e8605d 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart @@ -1,4 +1,3 @@ -import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; @@ -11,7 +10,6 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialo import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/user_permission.dart'; @@ -66,7 +64,7 @@ class UsersBloc extends Bloc { void isCompleteSpacesFun( CheckSpacesStepStatus event, Emitter emit) { emit(UsersLoadingState()); - var spaceBloc = + final spaceBloc = NavigationService.navigatorKey.currentContext!.read(); isCompleteSpaces = spaceBloc.state.selectedCommunities.isNotEmpty; @@ -83,26 +81,25 @@ class UsersBloc extends Bloc { String communityUuid) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - return await CommunitySpaceManagementApi() + return CommunitySpaceManagementApi() .getSpaceHierarchy(communityUuid, projectUuid); } List updatedCommunities = []; List spacesNodes = []; List communityIds = []; - _onLoadCommunityAndSpaces( + Future _onLoadCommunityAndSpaces( LoadCommunityAndSpacesEvent event, Emitter emit) async { try { emit(UsersLoadingState()); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - List communities = + final communities = await CommunitySpaceManagementApi().fetchCommunities(projectUuid); communityIds = communities.map((community) => community.uuid).toList(); updatedCommunities = await Future.wait( communities.map((community) async { - List spaces = - await _fetchSpacesForCommunity(community.uuid); + final spaces = await _fetchSpacesForCommunity(community.uuid); spacesNodes = _buildTreeNodes(spaces); return TreeNode( uuid: community.uuid, @@ -129,7 +126,7 @@ class UsersBloc extends Bloc { // Build tree nodes from your data model. List _buildTreeNodes(List spaces) { return spaces.map((space) { - List childNodes = + final childNodes = space.children.isNotEmpty ? _buildTreeNodes(space.children) : []; return TreeNode( uuid: space.uuid!, @@ -170,7 +167,7 @@ class UsersBloc extends Bloc { _clearHighlights(updatedCommunities); } else { // Start with a fresh clone of the original tree. - List freshClone = _cloneNodes(originalCommunities); + final freshClone = _cloneNodes(originalCommunities); _searchAndHighlightNodes(freshClone, event.searchTerm!); @@ -180,7 +177,7 @@ class UsersBloc extends Bloc { } void _clearHighlights(List nodes) { - for (var node in nodes) { + for (final node in nodes) { node.isHighlighted = false; if (node.children.isNotEmpty) { _clearHighlights(node.children); @@ -189,11 +186,11 @@ class UsersBloc extends Bloc { } bool _searchAndHighlightNodes(List nodes, String searchTerm) { - bool anyMatch = false; - for (var node in nodes) { - bool isMatch = + var anyMatch = false; + for (final node in nodes) { + final isMatch = node.title.toLowerCase().contains(searchTerm.toLowerCase()); - bool childMatch = _searchAndHighlightNodes(node.children, searchTerm); + final childMatch = _searchAndHighlightNodes(node.children, searchTerm); node.isHighlighted = isMatch || childMatch; anyMatch = anyMatch || node.isHighlighted; @@ -202,11 +199,11 @@ class UsersBloc extends Bloc { } List _filterNodes(List nodes, String searchTerm) { - List filteredNodes = []; - for (var node in nodes) { - bool isMatch = + final filteredNodes = []; + for (final node in nodes) { + final isMatch = node.title.toLowerCase().contains(searchTerm.toLowerCase()); - List filteredChildren = _filterNodes(node.children, searchTerm); + final filteredChildren = _filterNodes(node.children, searchTerm); if (isMatch || filteredChildren.isNotEmpty) { node.isHighlighted = isMatch; node.children = filteredChildren; @@ -289,8 +286,8 @@ class UsersBloc extends Bloc { List selectedIds = []; List getSelectedIds(List nodes) { - List selectedIds = []; - for (var node in nodes) { + final selectedIds = []; + for (final node in nodes) { if (node.isChecked) { selectedIds.add(node.uuid); } @@ -304,7 +301,8 @@ class UsersBloc extends Bloc { List roles = []; List permissions = []; - _getRolePermission(RoleEvent event, Emitter emit) async { + Future _getRolePermission( + RoleEvent event, Emitter emit) async { try { emit(UsersLoadingState()); roles = await UserPermissionApi().fetchRoles(); @@ -314,11 +312,12 @@ class UsersBloc extends Bloc { } } - _getPermissions(PermissionEvent event, Emitter emit) async { + Future _getPermissions( + PermissionEvent event, Emitter emit) async { try { emit(UsersLoadingState()); permissions = await UserPermissionApi().fetchPermission( - event.roleUuid == "" ? roles.first.uuid : event.roleUuid); + event.roleUuid == '' ? roles.first.uuid : event.roleUuid); roleSelected = event.roleUuid!; emit(RolePermissionInitial()); } catch (e) { @@ -327,18 +326,19 @@ class UsersBloc extends Bloc { } bool _searchRolePermission(List nodes, String searchTerm) { - bool anyMatch = false; - for (var node in nodes) { - bool isMatch = + var anyMatch = false; + for (final node in nodes) { + final isMatch = node.title.toLowerCase().contains(searchTerm.toLowerCase()); - bool childMatch = _searchRolePermission(node.subOptions, searchTerm); + final childMatch = _searchRolePermission(node.subOptions, searchTerm); node.isHighlighted = isMatch || childMatch; anyMatch = anyMatch || node.isHighlighted; } return anyMatch; } - void _sendInvitUser(SendInviteUsers event, Emitter emit) async { + Future _sendInvitUser( + SendInviteUsers event, Emitter emit) async { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -346,10 +346,10 @@ class UsersBloc extends Bloc { // List selectedIds = // getSelectedIds(updatedCommunities).where((id) => !communityIds.contains(id)).toList(); - List selectedSpacesId = getSelectedSpacesIds(); + final selectedSpacesId = getSelectedSpacesIds(); // List selectedIds = getSelectedIds(updatedCommunities); - bool res = await UserPermissionApi().sendInviteUser( + final res = await UserPermissionApi().sendInviteUser( email: emailController.text, firstName: firstNameController.text, jobTitle: jobTitleController.text, @@ -363,9 +363,9 @@ class UsersBloc extends Bloc { showCustomDialog( barrierDismissible: false, context: event.context, - message: "The invite was sent successfully.", + message: 'The invite was sent successfully.', iconPath: Assets.deviceNoteIcon, - title: "Invite Success", + title: 'Invite Success', dialogHeight: MediaQuery.of(event.context).size.height * 0.3, actions: [ TextButton( @@ -382,27 +382,28 @@ class UsersBloc extends Bloc { } emit(SaveState()); } catch (e) { - emit(ErrorState('Failed to send invite: ${e.toString()}')); + emit(ErrorState('Failed to send invite: $e')); } } List getSelectedSpacesIds() { - List selectedSpacesId = []; - var spaceBloc = + final selectedSpacesId = []; + final spaceBloc = NavigationService.navigatorKey.currentContext!.read(); - for (var community in spaceBloc.state.selectedCommunities) { + for (final community in spaceBloc.state.selectedCommunities) { selectedSpacesId .addAll(spaceBloc.state.selectedCommunityAndSpaces[community] ?? []); } return selectedSpacesId; } - _editInviteUser(EditInviteUsers event, Emitter emit) async { + Future _editInviteUser( + EditInviteUsers event, Emitter emit) async { try { emit(UsersLoadingState()); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - bool res = await UserPermissionApi().editInviteUser( + final res = await UserPermissionApi().editInviteUser( userId: event.userId, firstName: firstNameController.text, jobTitle: jobTitleController.text, @@ -415,9 +416,9 @@ class UsersBloc extends Bloc { showCustomDialog( barrierDismissible: false, context: event.context, - message: "The invite was sent successfully.", + message: 'The invite was sent successfully.', iconPath: Assets.deviceNoteIcon, - title: "Invite Success", + title: 'Invite Success', dialogHeight: MediaQuery.of(event.context).size.height * 0.3, actions: [ TextButton( @@ -436,7 +437,7 @@ class UsersBloc extends Bloc { } emit(SaveState()); } catch (e) { - emit(ErrorState('Failed to send invite: ${e.toString()}')); + emit(ErrorState('Failed to send invite: $e')); } } @@ -455,7 +456,7 @@ class UsersBloc extends Bloc { Future checkEmail( CheckEmailEvent event, Emitter emit) async { emit(UsersLoadingState()); - String? res = await UserPermissionApi().checkEmail( + final res = await UserPermissionApi().checkEmail( emailController.text, ); checkEmailValid = res!; @@ -469,8 +470,8 @@ class UsersBloc extends Bloc { final emailRegex = RegExp( r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', ); - bool isEmailValid = emailRegex.hasMatch(emailController.text); - bool isEmailServerValid = checkEmailValid == 'Valid email'; + final isEmailValid = emailRegex.hasMatch(emailController.text); + final isEmailServerValid = checkEmailValid == 'Valid email'; isCompleteBasics = firstNameController.text.isNotEmpty && lastNameController.text.isNotEmpty && emailController.text.isNotEmpty && @@ -486,7 +487,7 @@ class UsersBloc extends Bloc { } void _clearHighlightsRolePermission(List nodes) { - for (var node in nodes) { + for (final node in nodes) { node.isHighlighted = false; if (node.subOptions.isNotEmpty) { _clearHighlightsRolePermission(node.subOptions); @@ -515,7 +516,7 @@ class UsersBloc extends Bloc { emit(UsersLoadingState()); try { - var spaceBloc = + final spaceBloc = NavigationService.navigatorKey.currentContext!.read(); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -533,9 +534,9 @@ class UsersBloc extends Bloc { res.roleType; res.spaces.map((space) { selectedIds.add(space.uuid); - CommunityModel community = spaceBloc.state.communityList + final community = spaceBloc.state.communityList .firstWhere((item) => item.uuid == space.communityUuid); - spaceBloc.add(OnSpaceSelected(community, space.uuid, [])); + spaceBloc.add(OnSpaceSelected(community, space.uuid, const [])); }).toList(); // if (updatedCommunities.isNotEmpty) { @@ -548,7 +549,7 @@ class UsersBloc extends Bloc { final roleId = roles .firstWhere((element) => element.type == - res.roleType.toString().toLowerCase().replaceAll("_", " ")) + res.roleType.toLowerCase().replaceAll('_', ' ')) .uuid; debugPrint('Role ID: $roleId'); roleSelected = roleId; @@ -604,14 +605,14 @@ class UsersBloc extends Bloc { } void _updateChildrenCheckStatus(TreeNode node, bool isChecked) { - for (var child in node.children) { + for (final child in node.children) { child.isChecked = isChecked; _updateChildrenCheckStatus(child, isChecked); } } void _updateParentCheckStatus(TreeNode node) { - TreeNode? parent = _findParent(updatedCommunities, node); + final parent = _findParent(updatedCommunities, node); if (parent != null) { parent.isChecked = _areAllChildrenChecked(parent); _updateParentCheckStatus(parent); @@ -626,7 +627,7 @@ class UsersBloc extends Bloc { } TreeNode? _findParent(List nodes, TreeNode target) { - for (var node in nodes) { + for (final node in nodes) { if (node.children.contains(target)) { return node; } diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart index 2e82168c..b7dbebd6 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart @@ -48,7 +48,7 @@ class RoleEvent extends UsersEvent { class PermissionEvent extends UsersEvent { final String? roleUuid; - const PermissionEvent({this.roleUuid = ""}); + const PermissionEvent({this.roleUuid = ''}); @override List get props => [roleUuid]; } diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart index 4141ccdd..2769fc09 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart @@ -17,7 +17,7 @@ class PermissionOption { return PermissionOption( id: json['id'] ?? '', title: json['title'] != null - ? json['title'].toString().toLowerCase().replaceAll("_", " ") + ? json['title'].toString().toLowerCase().replaceAll('_', ' ') : '', isChecked: json['isChecked'] ?? false, isHighlighted: json['isHighlighted'] ?? false, diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart index a5e622dc..6f715b5b 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart @@ -14,4 +14,4 @@ class TreeNode { this.isExpanded = false, this.children = const [], }); -} \ No newline at end of file +} diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart index 44ba81ff..7d39858c 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart @@ -29,12 +29,13 @@ class _AddNewUserDialogState extends State { child: BlocConsumer( listener: (context, state) {}, builder: (context, state) { - final _blocRole = BlocProvider.of(context); + final blocRole = BlocProvider.of(context); return Dialog( child: Container( decoration: const BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(20))), width: 900, child: Column( children: [ @@ -43,7 +44,7 @@ class _AddNewUserDialogState extends State { padding: EdgeInsets.all(8.0), child: SizedBox( child: Text( - "Add New User", + 'Add New User', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w700, @@ -61,9 +62,10 @@ class _AddNewUserDialogState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildStep1Indicator(1, "Basics", _blocRole), - _buildStep2Indicator(2, "Spaces", _blocRole), - _buildStep3Indicator(3, "Role & Permissions", _blocRole), + _buildStep1Indicator(1, 'Basics', blocRole), + _buildStep2Indicator(2, 'Spaces', blocRole), + _buildStep3Indicator( + 3, 'Role & Permissions', blocRole), ], ), ), @@ -101,31 +103,35 @@ class _AddNewUserDialogState extends State { onTap: () { Navigator.of(context).pop(); }, - child: const Text("Cancel"), + child: const Text('Cancel'), ), InkWell( onTap: () { - _blocRole.add(const CheckEmailEvent()); + blocRole.add(const CheckEmailEvent()); setState(() { if (currentStep < 3) { currentStep++; if (currentStep == 2) { - _blocRole.add(const CheckStepStatus(isEditUser: false)); + blocRole.add(const CheckStepStatus( + isEditUser: false)); } else if (currentStep == 3) { - _blocRole.add(const CheckSpacesStepStatus()); + blocRole.add(const CheckSpacesStepStatus()); } } else { - _blocRole.add(SendInviteUsers(context: context)); + blocRole + .add(SendInviteUsers(context: context)); } }); }, child: Text( - currentStep < 3 ? "Next" : "Save", + currentStep < 3 ? 'Next' : 'Save', style: TextStyle( - color: (_blocRole.isCompleteSpaces == false || - _blocRole.isCompleteBasics == false || - _blocRole.isCompleteRolePermissions == false) && + color: (blocRole.isCompleteSpaces == false || + blocRole.isCompleteBasics == + false || + blocRole.isCompleteRolePermissions == + false) && currentStep == 3 ? ColorsManager.grayColor : ColorsManager.secondaryColor), @@ -196,8 +202,12 @@ class _AddNewUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, - fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, + color: currentStep == step + ? ColorsManager.blackColor + : ColorsManager.greyColor, + fontWeight: currentStep == step + ? FontWeight.bold + : FontWeight.normal, ), ), ], @@ -260,8 +270,12 @@ class _AddNewUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, - fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, + color: currentStep == step + ? ColorsManager.blackColor + : ColorsManager.greyColor, + fontWeight: currentStep == step + ? FontWeight.bold + : FontWeight.normal, ), ), ], @@ -291,7 +305,7 @@ class _AddNewUserDialogState extends State { currentStep = step; step3 = step; bloc.add(const CheckSpacesStepStatus()); - bloc.add(CheckStepStatus(isEditUser: false)); + bloc.add(const CheckStepStatus(isEditUser: false)); }); }, child: Column( @@ -318,8 +332,12 @@ class _AddNewUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, - fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, + color: currentStep == step + ? ColorsManager.blackColor + : ColorsManager.greyColor, + fontWeight: currentStep == step + ? FontWeight.bold + : FontWeight.normal, ), ), ], diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart index fa04c051..e5933995 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart @@ -15,12 +15,12 @@ class BasicsView extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { - final _blocRole = BlocProvider.of(context); + final blocRole = BlocProvider.of(context); if (state is BasicsStepInvalidState) { - _blocRole.formKey.currentState?.validate(); + blocRole.formKey.currentState?.validate(); } return Form( - key: _blocRole.formKey, + key: blocRole.formKey, child: ListView( shrinkWrap: true, children: [ @@ -57,7 +57,7 @@ class BasicsView extends StatelessWidget { child: Row( children: [ const Text( - " * ", + ' * ', style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -84,9 +84,9 @@ class BasicsView extends StatelessWidget { // _blocRole.add(const ValidateBasicsStep()); // }); // }, - controller: _blocRole.firstNameController, + controller: blocRole.firstNameController, decoration: inputTextFormDeco( - hintText: "Enter first name", + hintText: 'Enter first name', ).copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, @@ -117,7 +117,7 @@ class BasicsView extends StatelessWidget { child: Row( children: [ const Text( - " * ", + ' * ', style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -140,10 +140,10 @@ class BasicsView extends StatelessWidget { // _blocRole.add(ValidateBasicsStep()); // }); // }, - controller: _blocRole.lastNameController, + controller: blocRole.lastNameController, style: const TextStyle(color: Colors.black), decoration: - inputTextFormDeco(hintText: "Enter last name") + inputTextFormDeco(hintText: 'Enter last name') .copyWith( hintStyle: context.textTheme.bodyMedium ?.copyWith( @@ -172,7 +172,7 @@ class BasicsView extends StatelessWidget { child: Row( children: [ const Text( - " * ", + ' * ', style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -199,9 +199,9 @@ class BasicsView extends StatelessWidget { // _blocRole.add(ValidateBasicsStep()); // }); // }, - controller: _blocRole.emailController, + controller: blocRole.emailController, style: const TextStyle(color: ColorsManager.blackColor), - decoration: inputTextFormDeco(hintText: "name@example.com") + decoration: inputTextFormDeco(hintText: 'name@example.com') .copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, @@ -218,9 +218,10 @@ class BasicsView extends StatelessWidget { if (!emailRegex.hasMatch(value)) { return 'Enter a valid Email Address'; } - if (_blocRole.checkEmailValid != "Valid email") { - return _blocRole.checkEmailValid; + if (blocRole.checkEmailValid != 'Valid email') { + return blocRole.checkEmailValid; } + return null; // return null; }, ), @@ -254,7 +255,7 @@ class BasicsView extends StatelessWidget { const TextStyle(color: ColorsManager.blackColor), textInputAction: TextInputAction.done, decoration: inputTextFormDeco( - hintText: "05x xxx xxxx", + hintText: '05x xxx xxxx', ).copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, @@ -264,32 +265,32 @@ class BasicsView extends StatelessWidget { initialCountryCode: 'AE', countries: const [ Country( - name: "United Arab Emirates", + name: 'United Arab Emirates', nameTranslations: { - "en": "United Arab Emirates", - "ar": "الإمارات العربية المتحدة", + 'en': 'United Arab Emirates', + 'ar': 'الإمارات العربية المتحدة', }, - flag: "🇦🇪", - code: "AE", - dialCode: "971", + flag: '🇦🇪', + code: 'AE', + dialCode: '971', minLength: 9, maxLength: 9, ), Country( - name: "Saudi Arabia", + name: 'Saudi Arabia', nameTranslations: { - "en": "Saudi Arabia", - "ar": "السعودية", + 'en': 'Saudi Arabia', + 'ar': 'السعودية', }, - flag: "🇸🇦", - code: "SA", - dialCode: "966", + flag: '🇸🇦', + code: 'SA', + dialCode: '966', minLength: 9, maxLength: 9, ), ], style: const TextStyle(color: Colors.black), - controller: _blocRole.phoneController, + controller: blocRole.phoneController, ) ], ), @@ -314,11 +315,11 @@ class BasicsView extends StatelessWidget { Padding( padding: const EdgeInsets.all(8.0), child: TextFormField( - controller: _blocRole.jobTitleController, + controller: blocRole.jobTitleController, style: const TextStyle(color: ColorsManager.blackColor), decoration: inputTextFormDeco( - hintText: "Job Title (Optional)") + hintText: 'Job Title (Optional)') .copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart index cbe15ecd..789e88e2 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart'; @@ -19,7 +18,7 @@ class TreeView extends StatelessWidget { @override Widget build(BuildContext context) { - final _blocRole = BlocProvider.of(context); + final blocRole = BlocProvider.of(context); return BlocProvider( create: (_) => UsersBloc(), // ..add(const LoadCommunityAndSpacesEvent()), @@ -34,7 +33,7 @@ class TreeView extends StatelessWidget { return const Center(child: CircularProgressIndicator()); } return SingleChildScrollView( - child: _buildTree(_blocRole.updatedCommunities, _blocRole), + child: _buildTree(blocRole.updatedCommunities, blocRole), ); }, ), @@ -48,7 +47,7 @@ class TreeView extends StatelessWidget { }) { return Column( children: nodes.map((node) { - return Container( + return ColoredBox( color: node.isHighlighted ? Colors.blue.shade50 : Colors.transparent, child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart index 10e8c273..fd6666c5 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class DeleteUserDialog extends StatefulWidget { final Function()? onTapDelete; - DeleteUserDialog({super.key, this.onTapDelete}); + const DeleteUserDialog({super.key, this.onTapDelete}); @override _DeleteUserDialogState createState() => _DeleteUserDialogState(); @@ -35,7 +34,7 @@ class _DeleteUserDialogState extends State { padding: EdgeInsets.all(8.0), child: SizedBox( child: Text( - "Delete User", + 'Delete User', style: TextStyle( color: ColorsManager.red, fontSize: 18, @@ -54,7 +53,7 @@ class _DeleteUserDialogState extends State { child: Padding( padding: EdgeInsets.only(left: 25, right: 25, top: 10, bottom: 10), child: Text( - "Are you sure you want to delete this user?", + 'Are you sure you want to delete this user?', textAlign: TextAlign.center, ), )), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart index 071de067..50ae1d7c 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart'; @@ -31,15 +30,17 @@ class _EditUserDialogState extends State { ..add(GetUserByIdEvent(uuid: widget.userId)), child: BlocConsumer(listener: (context, state) { if (state is SpacesLoadedState) { - BlocProvider.of(context).add(GetUserByIdEvent(uuid: widget.userId)); + BlocProvider.of(context) + .add(GetUserByIdEvent(uuid: widget.userId)); } }, builder: (context, state) { - final _blocRole = BlocProvider.of(context); + final blocRole = BlocProvider.of(context); return Dialog( child: Container( decoration: const BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(20))), width: 900, child: Column( children: [ @@ -48,7 +49,7 @@ class _EditUserDialogState extends State { padding: EdgeInsets.all(8.0), child: SizedBox( child: Text( - "Edit User", + 'Edit User', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w700, @@ -66,9 +67,10 @@ class _EditUserDialogState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildStep1Indicator(1, "Basics", _blocRole), - _buildStep2Indicator(2, "Spaces", _blocRole), - _buildStep3Indicator(3, "Role & Permissions", _blocRole), + _buildStep1Indicator(1, 'Basics', blocRole), + _buildStep2Indicator(2, 'Spaces', blocRole), + _buildStep3Indicator( + 3, 'Role & Permissions', blocRole), ], ), ), @@ -106,7 +108,7 @@ class _EditUserDialogState extends State { onTap: () { Navigator.of(context).pop(); }, - child: const Text("Cancel"), + child: const Text('Cancel'), ), InkWell( onTap: () { @@ -116,22 +118,24 @@ class _EditUserDialogState extends State { if (currentStep < 3) { currentStep++; if (currentStep == 2) { - _blocRole.add(CheckStepStatus(isEditUser: true)); + blocRole.add( + const CheckStepStatus(isEditUser: true)); } else if (currentStep == 3) { - _blocRole.add(const CheckSpacesStepStatus()); + blocRole.add(const CheckSpacesStepStatus()); } } else { - _blocRole - .add(EditInviteUsers(context: context, userId: widget.userId!)); + blocRole.add(EditInviteUsers( + context: context, userId: widget.userId!)); } }); }, child: Text( - currentStep < 3 ? "Next" : "Save", + currentStep < 3 ? 'Next' : 'Save', style: TextStyle( - color: (_blocRole.isCompleteSpaces == false || - _blocRole.isCompleteBasics == false || - _blocRole.isCompleteRolePermissions == false) && + color: (blocRole.isCompleteSpaces == false || + blocRole.isCompleteBasics == false || + blocRole.isCompleteRolePermissions == + false) && currentStep == 3 ? ColorsManager.grayColor : ColorsManager.secondaryColor), @@ -172,7 +176,7 @@ class _EditUserDialogState extends State { bloc.add(const CheckSpacesStepStatus()); currentStep = step; Future.delayed(const Duration(milliseconds: 500), () { - bloc.add(ValidateBasicsStep()); + bloc.add(const ValidateBasicsStep()); }); }); @@ -204,8 +208,12 @@ class _EditUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, - fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, + color: currentStep == step + ? ColorsManager.blackColor + : ColorsManager.greyColor, + fontWeight: currentStep == step + ? FontWeight.bold + : FontWeight.normal, ), ), ], @@ -233,7 +241,7 @@ class _EditUserDialogState extends State { onTap: () { setState(() { currentStep = step; - bloc.add(CheckStepStatus(isEditUser: true)); + bloc.add(const CheckStepStatus(isEditUser: true)); if (step3 == 3) { bloc.add(const CheckRoleStepStatus()); } @@ -263,8 +271,12 @@ class _EditUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, - fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, + color: currentStep == step + ? ColorsManager.blackColor + : ColorsManager.greyColor, + fontWeight: currentStep == step + ? FontWeight.bold + : FontWeight.normal, ), ), ], @@ -294,7 +306,7 @@ class _EditUserDialogState extends State { currentStep = step; step3 = step; bloc.add(const CheckSpacesStepStatus()); - bloc.add(CheckStepStatus(isEditUser: true)); + bloc.add(const CheckStepStatus(isEditUser: true)); }); }, child: Column( @@ -321,8 +333,12 @@ class _EditUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, - fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, + color: currentStep == step + ? ColorsManager.blackColor + : ColorsManager.greyColor, + fontWeight: currentStep == step + ? FontWeight.bold + : FontWeight.normal, ), ), ], diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart index aee84ed4..76bacad9 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart @@ -7,7 +7,7 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; class PermissionManagement extends StatefulWidget { final UsersBloc? bloc; - const PermissionManagement({Key? key, this.bloc}) : super(key: key); + const PermissionManagement({super.key, this.bloc}); @override _PermissionManagementState createState() => _PermissionManagementState(); @@ -16,25 +16,25 @@ class PermissionManagement extends StatefulWidget { class _PermissionManagementState extends State { void toggleOptionById(String id) { setState(() { - for (var mainOption in widget.bloc!.permissions) { + for (final mainOption in widget.bloc!.permissions) { if (mainOption.id == id) { final isChecked = checkifOneOfthemChecked(mainOption) == CheckState.all; mainOption.isChecked = !isChecked; - for (var subOption in mainOption.subOptions) { + for (final subOption in mainOption.subOptions) { subOption.isChecked = !isChecked; - for (var child in subOption.subOptions) { + for (final child in subOption.subOptions) { child.isChecked = !isChecked; } } return; } - for (var subOption in mainOption.subOptions) { + for (final subOption in mainOption.subOptions) { if (subOption.id == id) { subOption.isChecked = !subOption.isChecked; - for (var child in subOption.subOptions) { + for (final child in subOption.subOptions) { child.isChecked = subOption.isChecked; } mainOption.isChecked = @@ -42,7 +42,7 @@ class _PermissionManagementState extends State { return; } - for (var child in subOption.subOptions) { + for (final child in subOption.subOptions) { if (child.id == id) { child.isChecked = !child.isChecked; subOption.isChecked = @@ -58,17 +58,17 @@ class _PermissionManagementState extends State { } CheckState checkifOneOfthemChecked(PermissionOption mainOption) { - bool allSelected = true; - bool someSelected = false; + var allSelected = true; + var someSelected = false; - for (var subOption in mainOption.subOptions) { + for (final subOption in mainOption.subOptions) { if (subOption.isChecked) { someSelected = true; } else { allSelected = false; } - for (var child in subOption.subOptions) { + for (final child in subOption.subOptions) { if (child.isChecked) { someSelected = true; } else { @@ -143,7 +143,7 @@ class _PermissionManagementState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( + ColoredBox( color: option.isHighlighted ? Colors.blue.shade50 : Colors.white, @@ -208,7 +208,7 @@ class _PermissionManagementState extends State { itemCount: subOption.subOptions.length, itemBuilder: (context, index) { final child = subOption.subOptions[index]; - return Container( + return ColoredBox( color: option.isHighlighted ? Colors.blue.shade50 : Colors.white, @@ -260,7 +260,7 @@ class _PermissionManagementState extends State { ) ], ); - }).toList(), + }), ], ); }, @@ -268,28 +268,27 @@ class _PermissionManagementState extends State { } } - - // Container( - // height: 50, - // width: 120, - // child: CheckboxListTile( - // activeColor: ColorsManager.dialogBlueTitle, - // selectedTileColor: child.isHighlighted - // ? Colors.blue.shade50 - // : Colors.white, - // dense: true, - // controlAffinity: - // ListTileControlAffinity.leading, - // title: Text( - // child.title, - // style: context.textTheme.bodyMedium?.copyWith( - // fontWeight: FontWeight.w400, - // fontSize: 12, - // color: ColorsManager.lightGreyColor), - // ), - // value: child.isChecked, - // onChanged: (value) => - // toggleOptionById(child.id), - // enabled: false, - // ), - // ), \ No newline at end of file +// Container( +// height: 50, +// width: 120, +// child: CheckboxListTile( +// activeColor: ColorsManager.dialogBlueTitle, +// selectedTileColor: child.isHighlighted +// ? Colors.blue.shade50 +// : Colors.white, +// dense: true, +// controlAffinity: +// ListTileControlAffinity.leading, +// title: Text( +// child.title, +// style: context.textTheme.bodyMedium?.copyWith( +// fontWeight: FontWeight.w400, +// fontSize: 12, +// color: ColorsManager.lightGreyColor), +// ), +// value: child.isChecked, +// onChanged: (value) => +// toggleOptionById(child.id), +// enabled: false, +// ), +// ), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart index a7f6c2b5..e79249d7 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart @@ -47,9 +47,9 @@ Future showPopUpFilterMenu({ width: 25, ), title: Text( - "Sort A to Z", + 'Sort A to Z', style: TextStyle( - color: isSelected == "Asc" + color: isSelected == 'Asc' ? ColorsManager.blackColor : ColorsManager.grayColor), ), @@ -72,16 +72,16 @@ Future showPopUpFilterMenu({ width: 25, ), title: Text( - "Sort Z to A", + 'Sort Z to A', style: TextStyle( - color: isSelected == "Desc" + color: isSelected == 'Desc' ? ColorsManager.blackColor : ColorsManager.grayColor), ), ), const Divider(), const Text( - "Filter by ", + 'Filter by ', style: TextStyle(fontWeight: FontWeight.bold), ), Container( @@ -113,7 +113,8 @@ Future showPopUpFilterMenu({ ), Text( item, - style: TextStyle(color: ColorsManager.grayColor), + style: const TextStyle( + color: ColorsManager.grayColor), ), ], ); @@ -136,12 +137,12 @@ Future showPopUpFilterMenu({ onTap: () { Navigator.of(context).pop(); // Close the menu }, - child: const Text("Cancel"), + child: const Text('Cancel'), ), GestureDetector( onTap: onOkPressed, child: const Text( - "OK", + 'OK', style: TextStyle( color: ColorsManager.spaceColor, ), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart index 3a5ac65c..80ea8677 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart @@ -31,7 +31,7 @@ class _RoleDropdownState extends State { const Row( children: [ Text( - " * ", + ' * ', style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -39,7 +39,7 @@ class _RoleDropdownState extends State { ), ), Text( - "Role", + 'Role', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 16, @@ -77,7 +77,7 @@ class _RoleDropdownState extends State { hint: const Padding( padding: EdgeInsets.only(left: 10), child: Text( - "Please Select", + 'Please Select', style: TextStyle( color: ColorsManager.textGray, ), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart index f4b91747..a5e140b4 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart @@ -16,11 +16,11 @@ class RolesAndPermission extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { - final _blocRole = BlocProvider.of(context); - return Container( + final blocRole = BlocProvider.of(context); + return ColoredBox( color: Colors.white, child: Form( - key: _blocRole.formKey, + key: blocRole.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -39,7 +39,7 @@ class RolesAndPermission extends StatelessWidget { width: 350, height: 100, child: RoleDropdown( - bloc: _blocRole, + bloc: blocRole, )), const SizedBox(height: 10), Expanded( @@ -69,11 +69,10 @@ class RolesAndPermission extends StatelessWidget { child: TextFormField( style: const TextStyle(color: Colors.black), - controller: - _blocRole.roleSearchController, + controller: blocRole.roleSearchController, onChanged: (value) { - _blocRole.add(SearchPermission( - nodes: _blocRole.permissions, + blocRole.add(SearchPermission( + nodes: blocRole.permissions, searchTerm: value)); }, decoration: textBoxDecoration(radios: 20)! @@ -107,10 +106,10 @@ class RolesAndPermission extends StatelessWidget { child: Container( color: ColorsManager.circleRolesBackground, padding: const EdgeInsets.all(8.0), - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, child: PermissionManagement( - bloc: _blocRole, + bloc: blocRole, )))) ], ), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart index 63f870e6..dfd59ae8 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart @@ -11,19 +11,21 @@ class SpacesAccessView extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { - final _blocRole = BlocProvider.of(context); - return Container( + final blocRole = BlocProvider.of(context); + return ColoredBox( color: Colors.white, child: Form( - key: _blocRole.formKey, + key: blocRole.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( 'Spaces access', - style: context.textTheme.bodyLarge - ?.copyWith(fontWeight: FontWeight.w700, fontSize: 20, color: Colors.black), + style: context.textTheme.bodyLarge?.copyWith( + fontWeight: FontWeight.w700, + fontSize: 20, + color: Colors.black), ), const SizedBox( height: 35, diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart index e7eda606..e032f6e4 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart @@ -6,8 +6,6 @@ import 'package:syncrow_web/pages/roles_and_permission/model/roles_user_model.da 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/services/user_permission.dart'; -import 'package:syncrow_web/utils/constants/strings_manager.dart'; -import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart'; class UserTableBloc extends Bloc { UserTableBloc() : super(TableInitial()) { @@ -60,20 +58,20 @@ class UserTableBloc extends Bloc { final dateB = _parseDateTime(b.createdDate); return dateB.compareTo(dateA); }); - for (var user in users) { + for (final user in users) { roleTypes.add(user.roleType.toString()); } - for (var user in users) { + for (final user in users) { jobTitle.add(user.jobTitle.toString()); } - for (var user in users) { - createdBy.add(user.invitedBy.toString()); + for (final user in users) { + createdBy.add(user.invitedBy); } initialUsers = List.from(users); roleTypes = roleTypes.toSet().toList(); jobTitle = jobTitle.toSet().toList(); createdBy = createdBy.toSet().toList(); - _handlePageChange(ChangePage(1), emit); + _handlePageChange(const ChangePage(1), emit); totalUsersCount = initialUsers; add(ChangePage(currentPage)); emit(UsersLoadedState(users: users)); @@ -86,7 +84,7 @@ class UserTableBloc extends Bloc { DeleteUserEvent event, Emitter emit) async { emit(UsersLoadingState()); try { - bool res = await UserPermissionApi().deleteUserById(event.userId); + final res = await UserPermissionApi().deleteUserById(event.userId); if (res == true) { Navigator.of(event.context).pop(true); } else { @@ -104,8 +102,8 @@ class UserTableBloc extends Bloc { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; emit(UsersLoadingState()); - bool res = await UserPermissionApi().changeUserStatusById(event.userId, - event.newStatus == "disabled" ? false : true, projectUuid); + final res = await UserPermissionApi().changeUserStatusById(event.userId, + event.newStatus == 'disabled' ? false : true, projectUuid); if (res == true) { add(const GetUsers()); } @@ -121,13 +119,13 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrder == "Asc") { + if (currentSortOrder == 'Asc') { emit(UsersLoadingState()); - currentSortOrder = ""; + currentSortOrder = ''; users = List.from(users); } else { emit(UsersLoadingState()); - currentSortOrder = "Asc"; + currentSortOrder = 'Asc'; users.sort((a, b) => a.firstName .toString() .toLowerCase() @@ -146,13 +144,13 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrder == "Desc") { + if (currentSortOrder == 'Desc') { emit(UsersLoadingState()); - currentSortOrder = ""; + currentSortOrder = ''; users = List.from(initialUsers); } else { emit(UsersLoadingState()); - currentSortOrder = "Desc"; + currentSortOrder = 'Desc'; users.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } currentSortJopTitle = ''; @@ -168,15 +166,15 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrderDate == "NewestToOldest") { + if (currentSortOrderDate == 'NewestToOldest') { emit(UsersLoadingState()); - currentSortOrder = ""; - currentSortOrderDate = ""; + currentSortOrder = ''; + currentSortOrderDate = ''; users = List.from(initialUsers); emit(UsersLoadedState(users: users)); } else { emit(UsersLoadingState()); - currentSortOrder = "NewestToOldest"; + currentSortOrder = 'NewestToOldest'; users.sort((a, b) { final dateA = _parseDateTime(a.createdDate); final dateB = _parseDateTime(b.createdDate); @@ -192,10 +190,10 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrderDate == "OldestToNewest") { + if (currentSortOrderDate == 'OldestToNewest') { emit(UsersLoadingState()); - currentSortOrder = ""; - currentSortOrderDate = ""; + currentSortOrder = ''; + currentSortOrderDate = ''; users = List.from(initialUsers); emit(UsersLoadedState(users: users)); } else { @@ -205,7 +203,7 @@ class UserTableBloc extends Bloc { final dateB = _parseDateTime(b.createdDate); return dateA.compareTo(dateB); }); - currentSortOrder = "OldestToNewest"; + currentSortOrder = 'OldestToNewest'; emit(UsersLoadedState(users: users)); } } @@ -228,7 +226,7 @@ class UserTableBloc extends Bloc { emit(TableSearch()); final query = event.query.toLowerCase(); final filteredUsers = initialUsers.where((user) { - final fullName = "${user.firstName} ${user.lastName}".toLowerCase(); + final fullName = '${user.firstName} ${user.lastName}'.toLowerCase(); final email = user.email.toLowerCase(); return fullName.contains(query) || email.contains(query); }).toList(); @@ -283,22 +281,22 @@ class UserTableBloc extends Bloc { return selectedRoles.contains(user.roleType); }).toList(); - if (event.sortOrder == "Asc") { - currentSortOrder = "Asc"; + if (event.sortOrder == 'Asc') { + currentSortOrder = 'Asc'; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == "Desc") { - currentSortOrder = "Desc"; + } else if (event.sortOrder == 'Desc') { + currentSortOrder = 'Desc'; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } else {} - currentSortOrder = ""; + currentSortOrder = ''; currentSortCreatedDate = ''; currentSortStatus = ''; currentSortCreatedBy = ''; currentSortJopTitle = ''; - currentSortOrderDate = ""; + currentSortOrderDate = ''; totalUsersCount = filteredUsers; @@ -313,22 +311,22 @@ class UserTableBloc extends Bloc { if (selectedJobTitles.isEmpty) return true; return selectedJobTitles.contains(user.jobTitle); }).toList(); - if (event.sortOrder == "Asc") { - currentSortOrder = "Asc"; + if (event.sortOrder == 'Asc') { + currentSortOrder = 'Asc'; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == "Desc") { - currentSortOrder = "Desc"; + } else if (event.sortOrder == 'Desc') { + currentSortOrder = 'Desc'; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } else {} - currentSortOrder = ""; + currentSortOrder = ''; currentSortCreatedDate = ''; currentSortStatus = ''; currentSortCreatedBy = ''; currentSortRole = ''; - currentSortOrderDate = ""; + currentSortOrderDate = ''; totalUsersCount = filteredUsers; @@ -344,21 +342,21 @@ class UserTableBloc extends Bloc { return selectedCreatedBy.contains(user.invitedBy); }).toList(); - if (event.sortOrder == "Asc") { - currentSortOrder = "Asc"; + if (event.sortOrder == 'Asc') { + currentSortOrder = 'Asc'; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == "Desc") { - currentSortOrder = "Desc"; + } else if (event.sortOrder == 'Desc') { + currentSortOrder = 'Desc'; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } else {} currentSortOrder = ''; currentSortRole = ''; currentSortCreatedDate = ''; currentSortStatus = ''; - currentSortOrderDate = ""; + currentSortOrderDate = ''; totalUsersCount = filteredUsers; @@ -386,14 +384,14 @@ class UserTableBloc extends Bloc { } }); }).toList(); - if (event.sortOrder == "Asc") { - currentSortOrder = "Asc"; + if (event.sortOrder == 'Asc') { + currentSortOrder = 'Asc'; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == "Desc") { - currentSortOrder = "Desc"; + } else if (event.sortOrder == 'Desc') { + currentSortOrder = 'Desc'; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); totalUsersCount = filteredUsers; } else {} @@ -401,7 +399,7 @@ class UserTableBloc extends Bloc { currentSortRole = ''; currentSortCreatedDate = ''; currentSortCreatedBy = ''; - currentSortOrderDate = ""; + currentSortOrderDate = ''; emit(UsersLoadedState(users: filteredUsers)); } diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart index 1d9567cf..aea65950 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart @@ -64,7 +64,7 @@ class DateOldestToNewestEvent extends UserTableEvent { class SearchUsers extends UserTableEvent { final String query; - SearchUsers(this.query); + const SearchUsers(this.query); @override List get props => []; } @@ -72,7 +72,7 @@ class SearchUsers extends UserTableEvent { class ChangePage extends UserTableEvent { final int pageNumber; - ChangePage(this.pageNumber); + const ChangePage(this.pageNumber); @override List get props => [pageNumber]; @@ -93,6 +93,7 @@ class FilterUsersByRoleEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByRoleEvent({this.selectedRoles, this.sortOrder}); + @override List get props => [selectedRoles, sortOrder]; } @@ -101,6 +102,7 @@ class FilterUsersByJobEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByJobEvent({this.selectedJob, this.sortOrder}); + @override List get props => [selectedJob, sortOrder]; } @@ -110,6 +112,7 @@ class FilterUsersByCreatedEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByCreatedEvent({this.selectedCreatedBy, this.sortOrder}); + @override List get props => [selectedCreatedBy, sortOrder]; } @@ -118,6 +121,7 @@ class FilterUsersByDeActevateEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByDeActevateEvent({this.selectedActivate, this.sortOrder}); + @override List get props => [selectedActivate, sortOrder]; } @@ -125,14 +129,14 @@ class FilterOptionsEvent extends UserTableEvent { final String query; final List fullOptions; - FilterOptionsEvent({required this.query, required this.fullOptions}); + const FilterOptionsEvent({required this.query, required this.fullOptions}); @override List get props => [query, fullOptions]; } class FilterClearEvent extends UserTableEvent { - FilterClearEvent(); + const FilterClearEvent(); @override List get props => []; } diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart index ae99af3a..9d71602b 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart @@ -9,10 +9,12 @@ final class TableInitial extends UserTableState { @override List get props => []; } + final class TableSearch extends UserTableState { @override List get props => []; } + final class RolesLoadingState extends UserTableState { @override List get props => []; diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart b/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart index 7b7da0bd..198049f0 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart @@ -8,9 +8,8 @@ Future showDateFilterMenu({ Function()? zToaTap, String? isSelected, }) async { - final RenderBox overlay = - Overlay.of(context).context.findRenderObject() as RenderBox; - final RelativeRect position = RelativeRect.fromRect( + final overlay = Overlay.of(context).context.findRenderObject()! as RenderBox; + final position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width / 3, 240, @@ -39,9 +38,9 @@ Future showDateFilterMenu({ width: 25, ), title: Text( - "Sort from newest to oldest", + 'Sort from newest to oldest', style: TextStyle( - color: isSelected == "NewestToOldest" + color: isSelected == 'NewestToOldest' ? Colors.black : Colors.blueGrey), ), @@ -55,9 +54,9 @@ Future showDateFilterMenu({ width: 25, ), title: Text( - "Sort from oldest to newest", + 'Sort from oldest to newest', style: TextStyle( - color: isSelected == "OldestToNewest" + color: isSelected == 'OldestToNewest' ? Colors.black : Colors.blueGrey), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart b/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart index c8742ea5..166e1ca9 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart @@ -8,9 +8,8 @@ Future showDeActivateFilterMenu({ Function()? zToaTap, String? isSelected, }) async { - final RenderBox overlay = - Overlay.of(context).context.findRenderObject() as RenderBox; - final RelativeRect position = RelativeRect.fromRect( + final overlay = Overlay.of(context).context.findRenderObject()! as RenderBox; + final position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width / 2, 240, @@ -39,9 +38,9 @@ Future showDeActivateFilterMenu({ width: 25, ), title: Text( - "Sort A to Z", + 'Sort A to Z', style: TextStyle( - color: isSelected == "NewestToOldest" + color: isSelected == 'NewestToOldest' ? Colors.black : Colors.blueGrey), ), @@ -55,9 +54,9 @@ Future showDeActivateFilterMenu({ width: 25, ), title: Text( - "Sort Z to A", + 'Sort Z to A', style: TextStyle( - color: isSelected == "OldestToNewest" + color: isSelected == 'OldestToNewest' ? Colors.black : Colors.blueGrey), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart b/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart index f551cf3c..a047fe97 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart @@ -8,9 +8,8 @@ Future showNameMenu({ Function()? zToATap, String? isSelected, }) async { - final RenderBox overlay = - Overlay.of(context).context.findRenderObject() as RenderBox; - final RelativeRect position = RelativeRect.fromRect( + final overlay = Overlay.of(context).context.findRenderObject()! as RenderBox; + final position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width / 35, 240, @@ -39,9 +38,9 @@ Future showNameMenu({ width: 25, ), title: Text( - "Sort A to Z", + 'Sort A to Z', style: TextStyle( - color: isSelected == "Asc" ? Colors.black : Colors.blueGrey), + color: isSelected == 'Asc' ? Colors.black : Colors.blueGrey), ), ), ), @@ -53,9 +52,9 @@ Future showNameMenu({ width: 25, ), title: Text( - "Sort Z to A", + 'Sort Z to A', style: TextStyle( - color: isSelected == "Desc" ? Colors.black : Colors.blueGrey), + color: isSelected == 'Desc' ? Colors.black : Colors.blueGrey), ), ), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart b/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart index 9b10b5d4..624a57f7 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart @@ -17,8 +17,7 @@ class _HeaderColumn extends StatelessWidget { required this.showFilter, required this.onResize, this.onFilter, - Key? key, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -71,8 +70,7 @@ class _TableRow extends StatelessWidget { required this.cells, required this.columnWidths, required this.isLast, - Key? key, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -116,9 +114,9 @@ class DynamicTableScreen extends StatefulWidget { required this.titles, required this.rows, required this.onFilter, - Key? key, + super.key, required this.tableSize, - }) : super(key: key); + }); @override _DynamicTableScreenState createState() => _DynamicTableScreenState(); @@ -139,12 +137,12 @@ class _DynamicTableScreenState extends State { void _handleColumnResize(int index, double delta) { setState(() { - double newWidth = columnWidths[index] + delta; + var newWidth = columnWidths[index] + delta; newWidth = newWidth.clamp(_minColumnWidth, _maxColumnWidth); - double actualDelta = newWidth - columnWidths[index]; + final actualDelta = newWidth - columnWidths[index]; if (actualDelta == 0) return; - int nextIndex = (index + 1) % columnWidths.length; + final nextIndex = (index + 1) % columnWidths.length; columnWidths[index] = newWidth; columnWidths[nextIndex] = (columnWidths[nextIndex] - actualDelta) .clamp(_minColumnWidth, _maxColumnWidth); @@ -256,7 +254,7 @@ class _DynamicTableScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildHeader(), - Container(height: widget.tableSize - 37, child: _buildBody()), + SizedBox(height: widget.tableSize - 37, child: _buildBody()), ], ), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart b/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart index 735ce839..d007baf2 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart @@ -21,11 +21,11 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/style.dart'; class UsersPage extends StatelessWidget { - UsersPage({super.key}); + const UsersPage({super.key}); @override Widget build(BuildContext context) { - final TextEditingController searchController = TextEditingController(); + final searchController = TextEditingController(); Widget actionButton( {bool isActive = false, required String title, Function()? onTap}) { @@ -36,9 +36,9 @@ class UsersPage extends StatelessWidget { child: Text( title, style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: isActive == false && title != "Delete" + color: isActive == false && title != 'Delete' ? Colors.grey - : title == "Delete" + : title == 'Delete' ? ColorsManager.red : ColorsManager.spaceColor, fontWeight: FontWeight.w400, @@ -54,11 +54,11 @@ class UsersPage extends StatelessWidget { padding: const EdgeInsets.only(left: 5, right: 5, bottom: 5, top: 5), decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(20)), - color: status == "invited" - ? ColorsManager.invitedOrange.withOpacity(0.5) - : status == "active" - ? ColorsManager.activeGreen.withOpacity(0.5) - : ColorsManager.disabledPink.withOpacity(0.5), + color: status == 'invited' + ? ColorsManager.invitedOrange.withValues(alpha: 0.5) + : status == 'active' + ? ColorsManager.activeGreen.withValues(alpha: 0.5) + : ColorsManager.disabledPink.withValues(alpha: 0.5), ), child: Padding( padding: @@ -70,9 +70,9 @@ class UsersPage extends StatelessWidget { Text( status, style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: status == "invited" + color: status == 'invited' ? ColorsManager.invitedOrangeText - : status == "active" + : status == 'active' ? ColorsManager.activeGreenText : ColorsManager.disabledRedText, fontWeight: FontWeight.w400, @@ -96,9 +96,9 @@ class UsersPage extends StatelessWidget { padding: const EdgeInsets.only(left: 5, right: 5, bottom: 5, top: 5), child: SvgPicture.asset( - status == "invited" + status == 'invited' ? Assets.invitedIcon - : status == "active" + : status == 'active' ? Assets.activeUser : Assets.deActiveUser, height: 35, @@ -111,7 +111,7 @@ class UsersPage extends StatelessWidget { return BlocBuilder( builder: (context, state) { final screenSize = MediaQuery.of(context).size; - final _blocRole = BlocProvider.of(context); + final blocRole = BlocProvider.of(context); if (state is UsersLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is UsersLoadedState) { @@ -134,10 +134,10 @@ class UsersPage extends StatelessWidget { controller: searchController, onChanged: (value) { final bloc = context.read(); - bloc.add(FilterClearEvent()); + bloc.add(const FilterClearEvent()); bloc.add(SearchUsers(value)); if (value == '') { - bloc.add(ChangePage(1)); + bloc.add(const ChangePage(1)); } }, style: const TextStyle(color: Colors.black), @@ -170,7 +170,7 @@ class UsersPage extends StatelessWidget { }, ).then((v) { if (v != null) { - _blocRole.add(const GetUsers()); + blocRole.add(const GetUsers()); } }); }, @@ -193,7 +193,7 @@ class UsersPage extends StatelessWidget { ], ), const SizedBox(height: 20), - Container( + SizedBox( height: screenSize.height * 0.65, child: DynamicTableScreen( tableSize: screenSize.height * 0.65, @@ -201,7 +201,7 @@ class UsersPage extends StatelessWidget { if (columnIndex == 0) { showNameMenu( context: context, - isSelected: _blocRole.currentSortOrder, + isSelected: blocRole.currentSortOrder, aToZTap: () { context .read() @@ -215,13 +215,13 @@ class UsersPage extends StatelessWidget { ); } if (columnIndex == 2) { - final Map checkboxStates = { - for (var item in _blocRole.jobTitle) - item: _blocRole.selectedJobTitles.contains(item), + final checkboxStates = { + for (final item in blocRole.jobTitle) + item: blocRole.selectedJobTitles.contains(item), }; - final RenderBox overlay = Overlay.of(context) + final overlay = Overlay.of(context) .context - .findRenderObject() as RenderBox; + .findRenderObject()! as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( @@ -230,40 +230,40 @@ class UsersPage extends StatelessWidget { overlay.size.width / 4, 0, ), - list: _blocRole.jobTitle, + list: blocRole.jobTitle, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortJopTitle, + isSelected: blocRole.currentSortJopTitle, onOkPressed: () { searchController.clear(); - _blocRole.add(FilterClearEvent()); + blocRole.add(const FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) .toList(); Navigator.of(context).pop(); - _blocRole.add(FilterUsersByJobEvent( + blocRole.add(FilterUsersByJobEvent( selectedJob: selectedItems, - sortOrder: _blocRole.currentSortJopTitle, + sortOrder: blocRole.currentSortJopTitle, )); }, onSortAtoZ: (v) { - _blocRole.currentSortJopTitle = v; + blocRole.currentSortJopTitle = v; }, onSortZtoA: (v) { - _blocRole.currentSortJopTitle = v; + blocRole.currentSortJopTitle = v; }, ); } if (columnIndex == 3) { - final Map checkboxStates = { - for (var item in _blocRole.roleTypes) - item: _blocRole.selectedRoles.contains(item), + final checkboxStates = { + for (final item in blocRole.roleTypes) + item: blocRole.selectedRoles.contains(item), }; - final RenderBox overlay = Overlay.of(context) + final overlay = Overlay.of(context) .context - .findRenderObject() as RenderBox; + .findRenderObject()! as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( overlay.size.width / 4, @@ -271,13 +271,13 @@ class UsersPage extends StatelessWidget { overlay.size.width / 4, 0, ), - list: _blocRole.roleTypes, + list: blocRole.roleTypes, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortRole, + isSelected: blocRole.currentSortRole, onOkPressed: () { searchController.clear(); - _blocRole.add(FilterClearEvent()); + blocRole.add(const FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) @@ -286,20 +286,20 @@ class UsersPage extends StatelessWidget { context.read().add( FilterUsersByRoleEvent( selectedRoles: selectedItems, - sortOrder: _blocRole.currentSortRole)); + sortOrder: blocRole.currentSortRole)); }, onSortAtoZ: (v) { - _blocRole.currentSortRole = v; + blocRole.currentSortRole = v; }, onSortZtoA: (v) { - _blocRole.currentSortRole = v; + blocRole.currentSortRole = v; }, ); } if (columnIndex == 4) { showDateFilterMenu( context: context, - isSelected: _blocRole.currentSortOrder, + isSelected: blocRole.currentSortOrder, aToZTap: () { context .read() @@ -313,13 +313,13 @@ class UsersPage extends StatelessWidget { ); } if (columnIndex == 6) { - final Map checkboxStates = { - for (var item in _blocRole.createdBy) - item: _blocRole.selectedCreatedBy.contains(item), + final checkboxStates = { + for (final item in blocRole.createdBy) + item: blocRole.selectedCreatedBy.contains(item), }; - final RenderBox overlay = Overlay.of(context) + final overlay = Overlay.of(context) .context - .findRenderObject() as RenderBox; + .findRenderObject()! as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( overlay.size.width / 1, @@ -327,39 +327,39 @@ class UsersPage extends StatelessWidget { overlay.size.width / 4, 0, ), - list: _blocRole.createdBy, + list: blocRole.createdBy, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortCreatedBy, + isSelected: blocRole.currentSortCreatedBy, onOkPressed: () { searchController.clear(); - _blocRole.add(FilterClearEvent()); + blocRole.add(const FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) .toList(); Navigator.of(context).pop(); - _blocRole.add(FilterUsersByCreatedEvent( + blocRole.add(FilterUsersByCreatedEvent( selectedCreatedBy: selectedItems, - sortOrder: _blocRole.currentSortCreatedBy)); + sortOrder: blocRole.currentSortCreatedBy)); }, onSortAtoZ: (v) { - _blocRole.currentSortCreatedBy = v; + blocRole.currentSortCreatedBy = v; }, onSortZtoA: (v) { - _blocRole.currentSortCreatedBy = v; + blocRole.currentSortCreatedBy = v; }, ); } if (columnIndex == 7) { - final Map checkboxStates = { - for (var item in _blocRole.status) - item: _blocRole.selectedStatuses.contains(item), + final checkboxStates = { + for (final item in blocRole.status) + item: blocRole.selectedStatuses.contains(item), }; - final RenderBox overlay = Overlay.of(context) + final overlay = Overlay.of(context) .context - .findRenderObject() as RenderBox; + .findRenderObject()! as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( overlay.size.width / 0, @@ -367,34 +367,34 @@ class UsersPage extends StatelessWidget { overlay.size.width / 5, 0, ), - list: _blocRole.status, + list: blocRole.status, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortStatus, + isSelected: blocRole.currentSortStatus, onOkPressed: () { searchController.clear(); - _blocRole.add(FilterClearEvent()); + blocRole.add(const FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) .toList(); Navigator.of(context).pop(); - _blocRole.add(FilterUsersByDeActevateEvent( + blocRole.add(FilterUsersByDeActevateEvent( selectedActivate: selectedItems, - sortOrder: _blocRole.currentSortStatus)); + sortOrder: blocRole.currentSortStatus)); }, onSortAtoZ: (v) { - _blocRole.currentSortStatus = v; + blocRole.currentSortStatus = v; }, onSortZtoA: (v) { - _blocRole.currentSortStatus = v; + blocRole.currentSortStatus = v; }, ); } if (columnIndex == 8) { showDeActivateFilterMenu( context: context, - isSelected: _blocRole.currentSortOrderDate, + isSelected: blocRole.currentSortOrderDate, aToZTap: () { context .read() @@ -409,16 +409,16 @@ class UsersPage extends StatelessWidget { } }, titles: const [ - "Full Name", - "Email Address", - "Job Title", - "Role", - "Creation Date", - "Creation Time", - "Created By", - "Status", - "De/Activate", - "Action" + 'Full Name', + 'Email Address', + 'Job Title', + 'Role', + 'Creation Date', + 'Creation Time', + 'Created By', + 'Status', + 'De/Activate', + 'Action' ], rows: state.users.map((user) { return [ @@ -439,7 +439,7 @@ class UsersPage extends StatelessWidget { ? 'disabled' : user.status, userId: user.uuid, - onTap: user.status != "invited" + onTap: user.status != 'invited' ? () { context.read().add( ChangeUserStatus( @@ -452,35 +452,36 @@ class UsersPage extends StatelessWidget { ), Row( children: [ - user.isEnabled != false - ? actionButton( - isActive: true, - title: "Edit", - onTap: () { - context - .read() - .add(ClearCachedData()); - showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return EditUserDialog( - userId: user.uuid); - }, - ).then((v) { - if (v != null) { - if (v != null) { - _blocRole.add(const GetUsers()); - } - } - }); + if (user.isEnabled != false) + actionButton( + isActive: true, + title: 'Edit', + onTap: () { + context + .read() + .add(ClearCachedData()); + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return EditUserDialog( + userId: user.uuid); }, - ) - : actionButton( - title: "Edit", - ), + ).then((v) { + if (v != null) { + if (v != null) { + blocRole.add(const GetUsers()); + } + } + }); + }, + ) + else + actionButton( + title: 'Edit', + ), actionButton( - title: "Delete", + title: 'Delete', onTap: () { showDialog( context: context, @@ -489,7 +490,7 @@ class UsersPage extends StatelessWidget { return DeleteUserDialog( onTapDelete: () async { try { - _blocRole.add(DeleteUserEvent( + blocRole.add(DeleteUserEvent( user.uuid, context)); await Future.delayed( const Duration(seconds: 2)); @@ -501,7 +502,7 @@ class UsersPage extends StatelessWidget { }, ).then((v) { if (v != null) { - _blocRole.add(const GetUsers()); + blocRole.add(const GetUsers()); } }); }, @@ -529,10 +530,10 @@ class UsersPage extends StatelessWidget { const Icon(Icons.keyboard_double_arrow_right), firstPageIcon: const Icon(Icons.keyboard_double_arrow_left), - totalPages: (_blocRole.totalUsersCount.length / - _blocRole.itemsPerPage) + totalPages: (blocRole.totalUsersCount.length / + blocRole.itemsPerPage) .ceil(), - currentPage: _blocRole.currentPage, + currentPage: blocRole.currentPage, onPageChanged: (int pageNumber) { context .read() diff --git a/lib/pages/roles_and_permission/view/create_role_card.dart b/lib/pages/roles_and_permission/view/create_role_card.dart index e69de29b..8b137891 100644 --- a/lib/pages/roles_and_permission/view/create_role_card.dart +++ b/lib/pages/roles_and_permission/view/create_role_card.dart @@ -0,0 +1 @@ + diff --git a/lib/pages/roles_and_permission/view/role_card.dart b/lib/pages/roles_and_permission/view/role_card.dart index b08b14ea..866b0345 100644 --- a/lib/pages/roles_and_permission/view/role_card.dart +++ b/lib/pages/roles_and_permission/view/role_card.dart @@ -13,7 +13,8 @@ class RoleCard extends StatelessWidget { borderRadius: BorderRadius.circular(20), // Rounded corners boxShadow: [ BoxShadow( - color: ColorsManager.blackColor.withOpacity(0.2), // Shadow color + color: + ColorsManager.blackColor.withValues(alpha: 0.2), // Shadow color blurRadius: 20, // Spread of the shadow offset: const Offset(2, 2), // No directional bias spreadRadius: 1, // Ensures the shadow is more noticeable @@ -23,7 +24,7 @@ class RoleCard extends StatelessWidget { child: Container( decoration: BoxDecoration( color: ColorsManager.whiteColors, - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.circular(20), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, diff --git a/lib/pages/roles_and_permission/view/roles_and_permission_page.dart b/lib/pages/roles_and_permission/view/roles_and_permission_page.dart index 4ba83cc1..b7a510d0 100644 --- a/lib/pages/roles_and_permission/view/roles_and_permission_page.dart +++ b/lib/pages/roles_and_permission/view/roles_and_permission_page.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/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_state.dart'; @@ -22,7 +21,7 @@ class RolesAndPermissionPage extends StatelessWidget { child: BlocConsumer( listener: (context, state) {}, builder: (context, state) { - final _blocRole = BlocProvider.of(context); + final blocRole = BlocProvider.of(context); return state is RolesLoadingState ? const Center(child: CircularProgressIndicator()) @@ -65,10 +64,10 @@ class RolesAndPermissionPage extends StatelessWidget { child: Text( 'Users', style: context.textTheme.titleMedium?.copyWith( - color: (_blocRole.tapSelect == true) + color: (blocRole.tapSelect == true) ? ColorsManager.whiteColors : ColorsManager.grayColor, - fontWeight: (_blocRole.tapSelect == true) + fontWeight: (blocRole.tapSelect == true) ? FontWeight.w700 : FontWeight.w400, ), @@ -78,7 +77,7 @@ class RolesAndPermissionPage extends StatelessWidget { ), scaffoldBody: BlocProvider( create: (context) => UserTableBloc()..add(const GetUsers()), - child: UsersPage(), + child: const UsersPage(), ) // _blocRole.tapSelect == false // ? UsersPage( diff --git a/lib/pages/roles_and_permission/view/roles_page.dart b/lib/pages/roles_and_permission/view/roles_page.dart index 9c8ef0cd..b8c977e3 100644 --- a/lib/pages/roles_and_permission/view/roles_page.dart +++ b/lib/pages/roles_and_permission/view/roles_page.dart @@ -13,10 +13,10 @@ class RolesPage extends StatelessWidget { @override Widget build(BuildContext context) { - final TextEditingController searchController = TextEditingController(); - double screenWidth = MediaQuery.of(context).size.width; + final searchController = TextEditingController(); + final screenWidth = MediaQuery.of(context).size.width; - int crossAxisCount = (screenWidth ~/ 200).clamp(1, 6); + final crossAxisCount = (screenWidth ~/ 200).clamp(1, 6); return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -54,9 +54,6 @@ class RolesPage extends StatelessWidget { itemCount: blocRole.roleModel.length ?? 0, itemBuilder: (context, index) { final role = blocRole.roleModel[index]; - if (role == null) { - return const SizedBox.shrink(); - } return RoleCard( name: role.roleName ?? 'Unknown', ); diff --git a/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart b/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart index c664c2c4..b5326a40 100644 --- a/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart +++ b/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart @@ -1,4 +1,3 @@ - import 'dart:convert'; class AutomationStatusUpdate { @@ -17,23 +16,23 @@ class AutomationStatusUpdate { factory AutomationStatusUpdate.fromJson(Map json) => AutomationStatusUpdate( - spaceUuid: json["spaceUuid"], - isEnable: json["isEnable"], + spaceUuid: json['spaceUuid'], + isEnable: json['isEnable'], ); Map toJson() => { - "spaceUuid": spaceUuid, - "isEnable": isEnable, + 'spaceUuid': spaceUuid, + 'isEnable': isEnable, }; factory AutomationStatusUpdate.fromMap(Map map) => AutomationStatusUpdate( - spaceUuid: map["spaceUuid"], - isEnable: map["isEnable"], + spaceUuid: map['spaceUuid'], + isEnable: map['isEnable'], ); Map toMap() => { - "spaceUuid": spaceUuid, - "isEnable": isEnable, + 'spaceUuid': spaceUuid, + 'isEnable': isEnable, }; } diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart index b472d034..ab154342 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart @@ -36,7 +36,7 @@ class CreateRoutineBloc extends Bloc { } } - saveSpaceIdCommunityId( + void saveSpaceIdCommunityId( SaveCommunityIdAndSpaceIdEvent event, Emitter emit) { emit(const SpaceWithDeviceLoadingState()); selectedSpaceId = event.spaceID!; @@ -44,7 +44,8 @@ class CreateRoutineBloc extends Bloc { emit(const SelectedState()); } - resetSelected(ResetSelectedEvent event, Emitter emit) { + void resetSelected( + ResetSelectedEvent event, Emitter emit) { emit(const SpaceWithDeviceLoadingState()); selectedSpaceId = ''; selectedCommunityId = ''; diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart index ba901497..4b39fe62 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart @@ -42,10 +42,9 @@ class ResetSelectedEvent extends CreateRoutineEvent { List get props => []; } - class FetchCommunityEvent extends CreateRoutineEvent { const FetchCommunityEvent(); @override List get props => []; -} \ No newline at end of file +} diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart index 5ebc20f7..208b5e02 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart @@ -1,4 +1,3 @@ - import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; @@ -39,7 +38,6 @@ class SelectedState extends CreateRoutineState { const SelectedState(); } - class ResetSelectedState extends CreateRoutineState { const ResetSelectedState(); } @@ -50,4 +48,4 @@ class CommunityLoadedState extends CreateRoutineState { class CommunitiesLoadingState extends CreateRoutineState { const CommunitiesLoadingState(); -} \ No newline at end of file +} diff --git a/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart b/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart index fd56d232..af429f7d 100644 --- a/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart +++ b/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart @@ -25,7 +25,8 @@ class EffectPeriodBloc extends Bloc { on(_setAllDays); } - void _initialEvent(InitialEffectPeriodEvent event, Emitter emit) { + void _initialEvent( + InitialEffectPeriodEvent event, Emitter emit) { add(SetCustomTime(event.effectiveTime.start, event.effectiveTime.end)); emit(state.copyWith( selectedDaysBinary: event.effectiveTime.loops, @@ -35,8 +36,8 @@ class EffectPeriodBloc extends Bloc { } void _onSetPeriod(SetPeriod event, Emitter emit) { - String startTime = ''; - String endTime = ''; + var startTime = ''; + var endTime = ''; switch (event.period) { case EnumEffectivePeriodOptions.allDay: @@ -60,7 +61,9 @@ class EffectPeriodBloc extends Bloc { } emit(state.copyWith( - selectedPeriod: event.period, customStartTime: startTime, customEndTime: endTime)); + selectedPeriod: event.period, + customStartTime: startTime, + customEndTime: endTime)); } void _onToggleDay(ToggleDay event, Emitter emit) { @@ -76,8 +79,8 @@ class EffectPeriodBloc extends Bloc { } void _onSetCustomTime(SetCustomTime event, Emitter emit) { - String startTime = event.startTime; - String endTime = event.endTime; + final startTime = event.startTime; + final endTime = event.endTime; EnumEffectivePeriodOptions period; // Determine the period based on start and end times @@ -91,11 +94,14 @@ class EffectPeriodBloc extends Bloc { period = EnumEffectivePeriodOptions.custom; } - emit( - state.copyWith(customStartTime: startTime, customEndTime: endTime, selectedPeriod: period)); + emit(state.copyWith( + customStartTime: startTime, + customEndTime: endTime, + selectedPeriod: period)); } - void _onResetEffectivePeriod(ResetEffectivePeriod event, Emitter emit) { + void _onResetEffectivePeriod( + ResetEffectivePeriod event, Emitter emit) { emit(state.copyWith( selectedPeriod: EnumEffectivePeriodOptions.allDay, customStartTime: '00:00', diff --git a/lib/pages/routines/bloc/effective_period/effect_period_state.dart b/lib/pages/routines/bloc/effective_period/effect_period_state.dart index 2f8b66c8..4ecb83b9 100644 --- a/lib/pages/routines/bloc/effective_period/effect_period_state.dart +++ b/lib/pages/routines/bloc/effective_period/effect_period_state.dart @@ -17,9 +17,9 @@ class EffectPeriodState extends Equatable { factory EffectPeriodState.initial() { return const EffectPeriodState( selectedPeriod: EnumEffectivePeriodOptions.allDay, - selectedDaysBinary: "1111111", // All days selected - customStartTime: "00:00", - customEndTime: "23:59", + selectedDaysBinary: '1111111', // All days selected + customStartTime: '00:00', + customEndTime: '23:59', ); } @@ -50,5 +50,6 @@ class EffectPeriodState extends Equatable { } @override - List get props => [selectedPeriod, selectedDaysBinary, customStartTime, customEndTime]; + List get props => + [selectedPeriod, selectedDaysBinary, customStartTime, customEndTime]; } diff --git a/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart b/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart index ca8aac06..b58b953d 100644 --- a/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart +++ b/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart @@ -1,11 +1,9 @@ import 'dart:async'; -import 'package:bloc/bloc.dart'; -import 'package:dio/dio.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; @@ -75,7 +73,7 @@ class RoutineBloc extends Bloc { } } - _resetErrorMessage( + void _resetErrorMessage( ResetErrorMessage event, Emitter emit, ) { @@ -93,7 +91,7 @@ class RoutineBloc extends Bloc { final updatedIfItems = List>.from(state.ifItems); // Find the index of the item in teh current itemsList - int index = updatedIfItems.indexWhere( + final index = updatedIfItems.indexWhere( (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); // Replace the map if the index is valid if (index != -1) { @@ -116,7 +114,7 @@ class RoutineBloc extends Bloc { final currentItems = List>.from(state.thenItems); // Find the index of the item in teh current itemsList - int index = currentItems.indexWhere( + final index = currentItems.indexWhere( (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); // Replace the map if the index is valid if (index != -1) { @@ -135,7 +133,7 @@ class RoutineBloc extends Bloc { // List selectedFunction = List.from(event.functions); - Map> currentSelectedFunctions = + final currentSelectedFunctions = Map>.from(state.selectedFunctions); // if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) { @@ -176,18 +174,18 @@ class RoutineBloc extends Bloc { Future _onLoadScenes( LoadScenes event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); - List scenes = []; + final scenes = []; try { - BuildContext context = NavigationService.navigatorKey.currentContext!; - var createRoutineBloc = context.read(); + final context = NavigationService.navigatorKey.currentContext!; + final createRoutineBloc = context.read(); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { - var spaceBloc = context.read(); - for (var communityId in spaceBloc.state.selectedCommunities) { - List spacesList = + final spaceBloc = context.read(); + for (final communityId in spaceBloc.state.selectedCommunities) { + final spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - for (var spaceId in spacesList) { + for (final spaceId in spacesList) { scenes.addAll( await SceneApi.getScenes(spaceId, communityId, projectUuid)); } @@ -216,19 +214,19 @@ class RoutineBloc extends Bloc { Future _onLoadAutomation( LoadAutomation event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); - List automations = []; + final automations = []; final projectId = await ProjectManager.getProjectUUID() ?? ''; - BuildContext context = NavigationService.navigatorKey.currentContext!; - var createRoutineBloc = context.read(); + final context = NavigationService.navigatorKey.currentContext!; + final createRoutineBloc = context.read(); try { if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { - var spaceBloc = context.read(); - for (var communityId in spaceBloc.state.selectedCommunities) { - List spacesList = + final spaceBloc = context.read(); + for (final communityId in spaceBloc.state.selectedCommunities) { + final spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - for (var spaceId in spacesList) { + for (final spaceId in spacesList) { automations.addAll( await SceneApi.getAutomation(spaceId, communityId, projectId)); } @@ -336,8 +334,8 @@ class RoutineBloc extends Bloc { }); }).toList(); - BuildContext context = NavigationService.navigatorKey.currentContext!; - var createRoutineBloc = context.read(); + final context = NavigationService.navigatorKey.currentContext!; + final createRoutineBloc = context.read(); final createSceneModel = CreateSceneModel( spaceUuid: createRoutineBloc.selectedSpaceId, @@ -361,7 +359,7 @@ class RoutineBloc extends Bloc { } } on APIException catch (e) { final errorData = e.message; - String errorMessage = errorData; + final errorMessage = errorData; emit(state.copyWith( isLoading: false, errorMessage: errorMessage, @@ -400,7 +398,7 @@ class RoutineBloc extends Bloc { return; } emit(state.copyWith(isLoading: true, errorMessage: null)); - int i = 0; + var i = 0; final conditions = state.ifItems.expand((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; return functions.map((function) { @@ -468,8 +466,8 @@ class RoutineBloc extends Bloc { ); }); }).toList(); - BuildContext context = NavigationService.navigatorKey.currentContext!; - var createRoutineBloc = context.read(); + final context = NavigationService.navigatorKey.currentContext!; + final createRoutineBloc = context.read(); final createAutomationModel = CreateAutomationModel( spaceUuid: createRoutineBloc.selectedSpaceId, @@ -499,7 +497,7 @@ class RoutineBloc extends Bloc { } } on APIException catch (e) { final errorData = e.message; - String errorMessage = errorData; + final errorMessage = errorData; emit(state.copyWith( isLoading: false, errorMessage: errorMessage, @@ -705,14 +703,14 @@ class RoutineBloc extends Bloc { final List> thenItems; final List> ifItems; - final Map> updatedFunctions = + final updatedFunctions = Map>.from(state.selectedFunctions); - final Map> deviceCards = {}; + final deviceCards = >{}; - for (var action in sceneDetails.actions) { + for (final action in sceneDetails.actions) { AllDevicesModel? matchingDevice; - for (var device in state.devices) { + for (final device in state.devices) { if (device.uuid == action.entityId) { matchingDevice = device; break; @@ -777,7 +775,7 @@ class RoutineBloc extends Bloc { action.actionExecutor != 'delay') { final functions = matchingDevice?.functions ?? []; final functionCode = action.executorProperty?.functionCode; - for (DeviceFunction function in functions) { + for (final function in functions) { if (function.code == functionCode) { updatedFunctions[uniqueCustomId]!.add( DeviceFunctionData( @@ -871,8 +869,8 @@ class RoutineBloc extends Bloc { final projectId = await ProjectManager.getProjectUUID() ?? ''; emit(state.copyWith(isLoading: true)); - BuildContext context = NavigationService.navigatorKey.currentContext!; - var spaceBloc = context.read(); + final context = NavigationService.navigatorKey.currentContext!; + final spaceBloc = context.read(); if (state.isTabToRun) { await SceneApi.deleteScene( unitUuid: spaceBloc.state.selectedSpaces[0], @@ -901,7 +899,7 @@ class RoutineBloc extends Bloc { emit(state.copyWith(isLoading: false, createRoutineView: false)); } on APIException catch (e) { final errorData = e.message; - String errorMessage = errorData; + final errorMessage = errorData; emit(state.copyWith( isLoading: false, errorMessage: errorMessage, @@ -929,17 +927,17 @@ class RoutineBloc extends Bloc { emit(state.copyWith(isLoading: true)); try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - List devices = []; - BuildContext context = NavigationService.navigatorKey.currentContext!; - var createRoutineBloc = context.read(); - var spaceBloc = context.read(); + final devices = []; + final context = NavigationService.navigatorKey.currentContext!; + final createRoutineBloc = context.read(); + final spaceBloc = context.read(); if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { - for (var communityId in spaceBloc.state.selectedCommunities) { - List spacesList = + for (final communityId in spaceBloc.state.selectedCommunities) { + final spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - for (var spaceId in spacesList) { + for (final spaceId in spacesList) { devices.addAll(await DevicesManagementApi() .fetchDevices(communityId, spaceId, projectUuid)); } @@ -1071,7 +1069,7 @@ class RoutineBloc extends Bloc { return; } emit(state.copyWith(isLoading: true, errorMessage: null)); - int i = 0; + var i = 0; final conditions = state.ifItems.expand((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; return functions.map((function) { @@ -1142,8 +1140,8 @@ class RoutineBloc extends Bloc { }); }).toList(); - BuildContext context = NavigationService.navigatorKey.currentContext!; - var spaceBloc = context.read(); + final context = NavigationService.navigatorKey.currentContext!; + final spaceBloc = context.read(); final createAutomationModel = CreateAutomationModel( spaceUuid: spaceBloc.selectedSpaceId, @@ -1163,8 +1161,8 @@ class RoutineBloc extends Bloc { if (result['success']) { add(ResetRoutineState()); - add(LoadAutomation()); - add(LoadScenes()); + add(const LoadAutomation()); + add(const LoadScenes()); } else { emit(state.copyWith( isLoading: false, @@ -1197,14 +1195,14 @@ class RoutineBloc extends Bloc { final automationDetails = await SceneApi.getAutomationDetails(event.automationId, projectUuid); - final Map> deviceIfCards = {}; - final Map> deviceThenCards = {}; + final deviceIfCards = >{}; + final deviceThenCards = >{}; - final Map> updatedFunctions = + final updatedFunctions = Map>.from(state.selectedFunctions); - for (RoutineCondition condition in automationDetails.conditions ?? []) { - AllDevicesModel? matchingDevice = state.devices.firstWhere( + for (final condition in automationDetails.conditions ?? []) { + final matchingDevice = state.devices.firstWhere( (device) => device.uuid == condition.entityId, orElse: () => AllDevicesModel( uuid: condition.entityId, @@ -1241,7 +1239,7 @@ class RoutineBloc extends Bloc { } final functions = matchingDevice.functions; - for (var function in functions) { + for (final function in functions) { if (function.code == condition.expr.statusCode) { updatedFunctions[uniqueCustomId]!.add( DeviceFunctionData( @@ -1257,8 +1255,8 @@ class RoutineBloc extends Bloc { } // Process actions (thenItems) - for (var action in automationDetails.actions) { - AllDevicesModel? matchingDevice = state.devices.firstWhere( + for (final action in automationDetails.actions) { + final matchingDevice = state.devices.firstWhere( (device) => device.uuid == action.entityId, orElse: () => AllDevicesModel( uuid: action.entityId, @@ -1312,7 +1310,7 @@ class RoutineBloc extends Bloc { action.actionExecutor != 'delay') { final functions = matchingDevice.functions; final functionCode = action.executorProperty!.functionCode; - for (var function in functions) { + for (final function in functions) { if (function.code == functionCode) { updatedFunctions[uniqueCustomId]!.add( DeviceFunctionData( @@ -1403,7 +1401,7 @@ class RoutineBloc extends Bloc { } catch (e) { emit(state.copyWith( loadingSceneId: null, - errorMessage: 'Trigger error: ${e.toString()}', + errorMessage: 'Trigger error: $e', )); } } @@ -1448,7 +1446,7 @@ class RoutineBloc extends Bloc { ..remove(event.automationId); emit(state.copyWith( loadingAutomationIds: updatedLoadingIds, - errorMessage: 'Update error: ${e.toString()}', + errorMessage: 'Update error: $e', )); } } diff --git a/lib/pages/routines/bloc/routine_bloc/routine_event.dart b/lib/pages/routines/bloc/routine_bloc/routine_event.dart index b532235d..dd7adf71 100644 --- a/lib/pages/routines/bloc/routine_bloc/routine_event.dart +++ b/lib/pages/routines/bloc/routine_bloc/routine_event.dart @@ -86,7 +86,8 @@ class RemoveDragCard extends RoutineEvent { final int index; final bool isFromThen; final String key; - const RemoveDragCard({required this.index, required this.isFromThen, required this.key}); + const RemoveDragCard( + {required this.index, required this.isFromThen, required this.key}); @override List get props => [index, isFromThen, key]; } @@ -211,9 +212,6 @@ class ClearFunctions extends RoutineEvent {} class ResetErrorMessage extends RoutineEvent {} - - - class SceneTrigger extends RoutineEvent { final String? sceneId; final String? name; @@ -221,7 +219,7 @@ class SceneTrigger extends RoutineEvent { const SceneTrigger({this.sceneId, this.name}); @override - List get props => [sceneId!,name!]; + List get props => [sceneId!, name!]; } //updateAutomationStatus @@ -230,7 +228,10 @@ class UpdateAutomationStatus extends RoutineEvent { final AutomationStatusUpdate automationStatusUpdate; final String communityId; - const UpdateAutomationStatus({required this.automationStatusUpdate, required this.automationId, required this.communityId}); + const UpdateAutomationStatus( + {required this.automationStatusUpdate, + required this.automationId, + required this.communityId}); @override List get props => [automationStatusUpdate]; diff --git a/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart b/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart index 843b35df..b35e3b21 100644 --- a/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart +++ b/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart @@ -15,37 +15,44 @@ class SettingBloc extends Bloc { on(_selectIcon); } - void _initialSetting(InitialEvent event, Emitter emit) async { + Future _initialSetting( + InitialEvent event, Emitter emit) async { try { emit(const LoadingState()); selectedIcon = event.selectedIcon; emit(TabToRunSettingLoaded( - showInDevice: true, selectedIcon: event.selectedIcon, iconList: iconModelList)); + showInDevice: true, + selectedIcon: event.selectedIcon, + iconList: iconModelList)); } catch (e) { emit(const FailedState(error: 'Something went wrong')); } } - void _fetchIcons(FetchIcons event, Emitter emit) async { + Future _fetchIcons(FetchIcons event, Emitter emit) async { try { isExpanded = event.expanded; emit(const LoadingState()); if (isExpanded) { iconModelList = await SceneApi.getIcon(); emit(TabToRunSettingLoaded( - showInDevice: true, selectedIcon: selectedIcon, iconList: iconModelList)); + showInDevice: true, + selectedIcon: selectedIcon, + iconList: iconModelList)); } } catch (e) { emit(const FailedState(error: 'Something went wrong')); } } - void _selectIcon(SelectIcon event, Emitter emit) async { + Future _selectIcon(SelectIcon event, Emitter emit) async { try { emit(const LoadingState()); selectedIcon = event.iconId; emit(TabToRunSettingLoaded( - showInDevice: true, selectedIcon: event.iconId, iconList: iconModelList)); + showInDevice: true, + selectedIcon: event.iconId, + iconList: iconModelList)); } catch (e) { emit(const FailedState(error: 'Something went wrong')); } diff --git a/lib/pages/routines/create_new_routines/commu_dropdown.dart b/lib/pages/routines/create_new_routines/commu_dropdown.dart index 6fd562b0..a3424013 100644 --- a/lib/pages/routines/create_new_routines/commu_dropdown.dart +++ b/lib/pages/routines/create_new_routines/commu_dropdown.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/dropdown_menu_content.dart'; +import 'package:syncrow_web/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.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/utils/color_manager.dart'; -import 'space_tree_dropdown_bloc.dart'; class SpaceTreeDropdown extends StatefulWidget { final String? selectedSpaceId; @@ -68,7 +68,7 @@ class _SpaceTreeDropdownState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text( - "Community", + 'Community', style: Theme.of(context).textTheme.bodyMedium!.copyWith( fontWeight: FontWeight.w400, fontSize: 13, diff --git a/lib/pages/routines/create_new_routines/create_new_routines.dart b/lib/pages/routines/create_new_routines/create_new_routines.dart index fe207910..adaff718 100644 --- a/lib/pages/routines/create_new_routines/create_new_routines.dart +++ b/lib/pages/routines/create_new_routines/create_new_routines.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_event.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_state.dart'; -import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/commu_dropdown.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/space_dropdown.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -27,11 +27,11 @@ class _CreateNewRoutinesDialogState extends State { CreateRoutineBloc()..add(const FetchCommunityEvent()), child: BlocBuilder( builder: (context, state) { - final _bloc = BlocProvider.of(context); - final spaces = _bloc.spacesOnlyWithDevices; + final bloc = BlocProvider.of(context); + final spaces = bloc.spacesOnlyWithDevices; final isLoadingCommunities = state is CommunitiesLoadingState; final isLoadingSpaces = state is SpaceWithDeviceLoadingState; - String spaceHint = 'Please Select'; + var spaceHint = 'Please Select'; if (_selectedCommunity != null) { if (isLoadingSpaces) { spaceHint = 'Loading spaces...'; @@ -77,9 +77,9 @@ class _CreateNewRoutinesDialogState extends State { SpaceTreeDropdown( selectedSpaceId: _selectedId, onChanged: (String? newValue) { - setState(() => _selectedId = newValue!); + setState(() => _selectedId = newValue); if (_selectedId != null) { - _bloc.add(SpaceOnlyWithDevicesEvent( + bloc.add(SpaceOnlyWithDevicesEvent( _selectedId!)); } }, diff --git a/lib/pages/routines/create_new_routines/dropdown_menu_content.dart b/lib/pages/routines/create_new_routines/dropdown_menu_content.dart index 70c88087..1ae5be86 100644 --- a/lib/pages/routines/create_new_routines/dropdown_menu_content.dart +++ b/lib/pages/routines/create_new_routines/dropdown_menu_content.dart @@ -1,7 +1,3 @@ - - - - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; @@ -14,6 +10,7 @@ class DropdownMenuContent extends StatefulWidget { final VoidCallback onClose; const DropdownMenuContent({ + super.key, required this.selectedSpaceId, required this.onChanged, required this.onClose, @@ -45,7 +42,7 @@ class _DropdownMenuContentState extends State { final state = bloc.state; if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 30) { - if (state is SpaceTreeState && !state.paginationIsLoading) { + if (!state.paginationIsLoading) { bloc.add(PaginationEvent(state.paginationModel, state.communityList)); } } @@ -126,7 +123,7 @@ class _DropdownMenuContentState extends State { _searchController.text.isEmpty ? context .read() - .add(SearchQueryEvent('')) + .add(const SearchQueryEvent('')) : context.read().add( SearchQueryEvent(_searchController.text)); }); diff --git a/lib/pages/routines/create_new_routines/space_dropdown.dart b/lib/pages/routines/create_new_routines/space_dropdown.dart index 1d11b02d..5af30f28 100644 --- a/lib/pages/routines/create_new_routines/space_dropdown.dart +++ b/lib/pages/routines/create_new_routines/space_dropdown.dart @@ -10,12 +10,12 @@ class SpaceDropdown extends StatelessWidget { final String hintMessage; const SpaceDropdown({ - Key? key, + super.key, required this.spaces, required this.selectedValue, required this.onChanged, required this.hintMessage, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -25,7 +25,7 @@ class SpaceDropdown extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Space", + 'Space', style: Theme.of(context).textTheme.bodyMedium!.copyWith( fontWeight: FontWeight.w400, fontSize: 13, @@ -67,7 +67,7 @@ class SpaceDropdown extends StatelessWidget { ); }).toList(), onChanged: onChanged, - style: TextStyle(color: Colors.black), + style: const TextStyle(color: Colors.black), hint: Padding( padding: const EdgeInsets.only(left: 10), child: Text( diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart index be2a7e9b..da835e4b 100644 --- a/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart @@ -24,4 +24,4 @@ class SpaceTreeDropdownBloc ) { emit(SpaceTreeDropdownState(selectedSpaceId: event.initialId)); } -} \ No newline at end of file +} diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart index dec701dc..69cf3d3f 100644 --- a/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart @@ -12,4 +12,4 @@ class SpaceTreeDropdownResetEvent extends SpaceTreeDropdownEvent { final String? initialId; SpaceTreeDropdownResetEvent(this.initialId); -} \ No newline at end of file +} diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart index dd22d095..c815da17 100644 --- a/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart @@ -4,4 +4,4 @@ class SpaceTreeDropdownState { final String? selectedSpaceId; SpaceTreeDropdownState({this.selectedSpaceId}); -} \ No newline at end of file +} diff --git a/lib/pages/routines/helper/save_routine_helper.dart b/lib/pages/routines/helper/save_routine_helper.dart index f8b52dab..2b506620 100644 --- a/lib/pages/routines/helper/save_routine_helper.dart +++ b/lib/pages/routines/helper/save_routine_helper.dart @@ -17,9 +17,10 @@ class SaveRoutineHelper { builder: (context) { return BlocBuilder( builder: (context, state) { - final selectedConditionLabel = state.selectedAutomationOperator == 'and' - ? 'All Conditions are met' - : 'Any Condition is met'; + final selectedConditionLabel = + state.selectedAutomationOperator == 'and' + ? 'All Conditions are met' + : 'Any Condition is met'; return AlertDialog( contentPadding: EdgeInsets.zero, @@ -37,10 +38,11 @@ class SaveRoutineHelper { Text( 'Create a scene: ${state.routineName ?? ""}', textAlign: TextAlign.center, - style: Theme.of(context).textTheme.headlineMedium!.copyWith( - color: ColorsManager.primaryColorWithOpacity, - fontWeight: FontWeight.bold, - ), + style: + Theme.of(context).textTheme.headlineMedium!.copyWith( + color: ColorsManager.primaryColorWithOpacity, + fontWeight: FontWeight.bold, + ), ), const SizedBox(height: 18), _buildDivider(), @@ -58,7 +60,8 @@ class SaveRoutineHelper { _buildIfConditions(state, context), Container( width: 1, - color: ColorsManager.greyColor.withValues(alpha: 0.8), + color: ColorsManager.greyColor + .withValues(alpha: 0.8), ), _buildThenActions(state, context), ], @@ -97,7 +100,8 @@ class SaveRoutineHelper { child: Row( spacing: 16, children: [ - Expanded(child: Text('IF: $selectedConditionLabel', style: textStyle)), + Expanded( + child: Text('IF: $selectedConditionLabel', style: textStyle)), const Expanded(child: Text('THEN:', style: textStyle)), ], ), @@ -109,7 +113,7 @@ class SaveRoutineHelper { spacing: 16, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - DialogFooterButton( + DialogFooterButton( text: 'Back', onTap: () => Navigator.pop(context), ), @@ -143,7 +147,8 @@ class SaveRoutineHelper { child: ListView( // shrinkWrap: true, children: state.thenItems.map((item) { - final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; + final functions = + state.selectedFunctions[item['uniqueCustomId']] ?? []; return functionRow(item, context, functions); }).toList(), ), @@ -203,19 +208,20 @@ class SaveRoutineHelper { ), ), child: Center( - child: item['type'] == 'tap_to_run' || item['type'] == 'scene' - ? Image.memory( - base64Decode(item['icon']), - width: 12, - height: 22, - fit: BoxFit.scaleDown, - ) - : SvgPicture.asset( - item['imagePath'], - width: 12, - height: 12, - fit: BoxFit.scaleDown, - ), + child: + item['type'] == 'tap_to_run' || item['type'] == 'scene' + ? Image.memory( + base64Decode(item['icon']), + width: 12, + height: 22, + fit: BoxFit.scaleDown, + ) + : SvgPicture.asset( + item['imagePath'], + width: 12, + height: 12, + fit: BoxFit.scaleDown, + ), ), ), Flexible( diff --git a/lib/pages/routines/models/ac/ac_function.dart b/lib/pages/routines/models/ac/ac_function.dart index edc377dd..e92b6dee 100644 --- a/lib/pages/routines/models/ac/ac_function.dart +++ b/lib/pages/routines/models/ac/ac_function.dart @@ -37,12 +37,12 @@ class SwitchFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), ACOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; @@ -62,17 +62,17 @@ class ModeFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsAcCooling, - description: "Cooling", + description: 'Cooling', value: TempModes.cold.name, ), ACOperationalValue( icon: Assets.assetsAcHeating, - description: "Heating", + description: 'Heating', value: TempModes.hot.name, ), ACOperationalValue( icon: Assets.assetsFanSpeed, - description: "Ventilation", + description: 'Ventilation', value: TempModes.wind.name, ), ]; @@ -90,22 +90,23 @@ class TempSetFunction extends ACFunction { min: 200, max: 300, step: 1, - unit: "°C", + unit: '°C', ); @override List getOperationalValues() { - List values = []; - for (int temp = min!.toInt(); temp <= max!; temp += step!.toInt()) { + final values = []; + for (var temp = min!.toInt(); temp <= max!; temp += step!.toInt()) { values.add(ACOperationalValue( icon: Assets.assetsTempreture, - description: "${temp / 10}°C", + description: '${temp / 10}°C', value: temp, )); } return values; } } + class LevelFunction extends ACFunction { LevelFunction( {required super.deviceId, required super.deviceName, required type}) @@ -120,22 +121,22 @@ class LevelFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsAcFanLow, - description: "LOW", + description: 'LOW', value: FanSpeeds.low.name, ), ACOperationalValue( icon: Assets.assetsAcFanMiddle, - description: "MIDDLE", + description: 'MIDDLE', value: FanSpeeds.middle.name, ), ACOperationalValue( icon: Assets.assetsAcFanHigh, - description: "HIGH", + description: 'HIGH', value: FanSpeeds.high.name, ), ACOperationalValue( icon: Assets.assetsAcFanAuto, - description: "AUTO", + description: 'AUTO', value: FanSpeeds.auto.name, ), ]; @@ -155,22 +156,26 @@ class ChildLockFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsSceneChildLock, - description: "Lock", + description: 'Lock', value: true, ), ACOperationalValue( icon: Assets.assetsSceneChildUnlock, - description: "Unlock", + description: 'Unlock', value: false, ), ]; } class CurrentTempFunction extends ACFunction { + @override final double min; + @override final double max; + @override final double step; - final String unit = "°C"; + @override + final String unit = '°C'; CurrentTempFunction( {required super.deviceId, required super.deviceName, required type}) @@ -186,11 +191,11 @@ class CurrentTempFunction extends ACFunction { @override List getOperationalValues() { - List values = []; - for (int temp = min.toInt(); temp <= max; temp += step.toInt()) { + final values = []; + for (var temp = min.toInt(); temp <= max; temp += step.toInt()) { values.add(ACOperationalValue( icon: Assets.currentTemp, - description: "${temp / 10}°C", + description: '${temp / 10}°C', value: temp, )); } diff --git a/lib/pages/routines/models/ceiling_presence_sensor_functions.dart b/lib/pages/routines/models/ceiling_presence_sensor_functions.dart index 122d8ea1..f364abdb 100644 --- a/lib/pages/routines/models/ceiling_presence_sensor_functions.dart +++ b/lib/pages/routines/models/ceiling_presence_sensor_functions.dart @@ -6,12 +6,10 @@ class CpsOperationalValue { final String description; final dynamic value; - CpsOperationalValue({ required this.icon, required this.description, required this.value, - }); } @@ -45,12 +43,12 @@ final class CpsRadarSwitchFunction extends CpsFunctions { List getOperationalValues() => [ CpsOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), CpsOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; @@ -71,12 +69,12 @@ final class CpsSpatialParameterSwitchFunction extends CpsFunctions { List getOperationalValues() => [ CpsOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), CpsOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; @@ -96,8 +94,11 @@ final class CpsSensitivityFunction extends CpsFunctions { icon: Assets.sensitivity, ); + @override final double min; + @override final double max; + @override final double step; static const _images = [ @@ -144,8 +145,11 @@ final class CpsMovingSpeedFunction extends CpsFunctions { icon: Assets.speedoMeter, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -175,8 +179,11 @@ final class CpsSpatialStaticValueFunction extends CpsFunctions { icon: Assets.spatialStaticValue, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -206,8 +213,11 @@ final class CpsSpatialMotionValueFunction extends CpsFunctions { icon: Assets.spatialMotionValue, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -237,8 +247,11 @@ final class CpsMaxDistanceOfDetectionFunction extends CpsFunctions { icon: Assets.currentDistanceIcon, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -247,7 +260,7 @@ final class CpsMaxDistanceOfDetectionFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.currentDistanceIcon, description: '${value.toStringAsFixed(1)} M', @@ -272,8 +285,11 @@ final class CpsMaxDistanceOfStaticDetectionFunction extends CpsFunctions { icon: Assets.currentDistanceIcon, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -282,7 +298,7 @@ final class CpsMaxDistanceOfStaticDetectionFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.currentDistanceIcon, description: '${value.toStringAsFixed(1)} M', @@ -307,8 +323,11 @@ final class CpsDetectionRangeFunction extends CpsFunctions { icon: Assets.farDetection, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -317,7 +336,7 @@ final class CpsDetectionRangeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.farDetection, description: '${value.toStringAsFixed(1)} M', @@ -342,8 +361,11 @@ final class CpsDistanceOfMovingObjectsFunction extends CpsFunctions { icon: Assets.currentDistanceIcon, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -352,7 +374,7 @@ final class CpsDistanceOfMovingObjectsFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.currentDistanceIcon, description: '${value.toStringAsFixed(1)} M', @@ -377,8 +399,11 @@ final class CpsPresenceJudgementThrsholdFunction extends CpsFunctions { icon: Assets.presenceJudgementThrshold, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -408,8 +433,11 @@ final class CpsMotionAmplitudeTriggerThresholdFunction extends CpsFunctions { icon: Assets.presenceJudgementThrshold, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -439,8 +467,11 @@ final class CpsPerpetualBoundaryFunction extends CpsFunctions { icon: Assets.boundary, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -449,7 +480,7 @@ final class CpsPerpetualBoundaryFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.boundary, description: '${value.toStringAsFixed(1)}M', @@ -474,8 +505,11 @@ final class CpsMotionTriggerBoundaryFunction extends CpsFunctions { icon: Assets.motionMeter, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -484,7 +518,7 @@ final class CpsMotionTriggerBoundaryFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(1)} M', @@ -509,8 +543,11 @@ final class CpsMotionTriggerTimeFunction extends CpsFunctions { icon: Assets.motionMeter, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -519,7 +556,7 @@ final class CpsMotionTriggerTimeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(3)} sec', @@ -544,8 +581,11 @@ final class CpsMotionToStaticTimeFunction extends CpsFunctions { icon: Assets.motionMeter, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -554,7 +594,7 @@ final class CpsMotionToStaticTimeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(0)} sec', @@ -579,8 +619,11 @@ final class CpsEnteringNoBodyStateTimeFunction extends CpsFunctions { icon: Assets.motionMeter, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -589,7 +632,7 @@ final class CpsEnteringNoBodyStateTimeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(0)} sec', @@ -869,8 +912,11 @@ final class CpsSportsParaFunction extends CpsFunctions { icon: Assets.sportsPara, ); + @override final double min; + @override final double max; + @override final double step; @override @@ -879,7 +925,7 @@ final class CpsSportsParaFunction extends CpsFunctions { return List.generate( count, (index) { - final value = (min + (index * step)); + final value = min + (index * step); return CpsOperationalValue( icon: Assets.motionMeter, description: value.toStringAsFixed(0), diff --git a/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart b/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart index 81ee1096..835d8886 100644 --- a/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart +++ b/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart @@ -112,7 +112,7 @@ class CreateSceneAction { CreateSceneExecutorProperty? executorProperty, }) { return CreateSceneAction( - actionType: actionType ?? this.actionType, + actionType: actionType ?? actionType, entityId: entityId ?? this.entityId, actionExecutor: actionExecutor ?? this.actionExecutor, executorProperty: executorProperty ?? this.executorProperty, @@ -128,7 +128,7 @@ class CreateSceneAction { }; } else { return { - "actionType": actionType, + 'actionType': actionType, 'entityId': entityId, 'actionExecutor': actionExecutor, }; diff --git a/lib/pages/routines/models/delay/delay_fucntions.dart b/lib/pages/routines/models/delay/delay_fucntions.dart index 428825f4..28c87a25 100644 --- a/lib/pages/routines/models/delay/delay_fucntions.dart +++ b/lib/pages/routines/models/delay/delay_fucntions.dart @@ -14,7 +14,7 @@ class DelayFunction extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: "Duration in seconds", + description: 'Duration in seconds', value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/flush/flush_functions.dart b/lib/pages/routines/models/flush/flush_functions.dart index a8f6ccd4..6f4b01a6 100644 --- a/lib/pages/routines/models/flush/flush_functions.dart +++ b/lib/pages/routines/models/flush/flush_functions.dart @@ -24,8 +24,7 @@ class FlushPresenceDelayFunction extends FlushFunctions { required super.deviceId, required super.deviceName, required super.type, - }) : - super( + }) : super( code: FlushMountedPresenceSensorModel.codePresenceState, operationName: 'Presence State', icon: Assets.presenceStateIcon, @@ -37,7 +36,7 @@ class FlushPresenceDelayFunction extends FlushFunctions { FlushOperationalValue( icon: Assets.nobodyTime, description: 'None', - value: "none", + value: 'none', ), FlushOperationalValue( icon: Assets.presenceStateIcon, @@ -49,8 +48,11 @@ class FlushPresenceDelayFunction extends FlushFunctions { } class FlushSensiReduceFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; FlushSensiReduceFunction({ @@ -79,8 +81,11 @@ class FlushSensiReduceFunction extends FlushFunctions { } class FlushNoneDelayFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final String unit; FlushNoneDelayFunction({ @@ -109,8 +114,11 @@ class FlushNoneDelayFunction extends FlushFunctions { } class FlushIlluminanceFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; FlushIlluminanceFunction({ @@ -128,11 +136,11 @@ class FlushIlluminanceFunction extends FlushFunctions { @override List getOperationalValues() { - List values = []; - for (int lux = min.toInt(); lux <= max; lux += step.toInt()) { + final values = []; + for (var lux = min.toInt(); lux <= max; lux += step.toInt()) { values.add(FlushOperationalValue( icon: Assets.IlluminanceIcon, - description: "$lux Lux", + description: '$lux Lux', value: lux, )); } @@ -141,8 +149,11 @@ class FlushIlluminanceFunction extends FlushFunctions { } class FlushOccurDistReduceFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; FlushOccurDistReduceFunction({ @@ -172,8 +183,11 @@ class FlushOccurDistReduceFunction extends FlushFunctions { // ==== then functions ==== class FlushSensitivityFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; FlushSensitivityFunction({ @@ -202,9 +216,13 @@ class FlushSensitivityFunction extends FlushFunctions { } class FlushNearDetectionFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; + @override final String unit; FlushNearDetectionFunction({ @@ -224,7 +242,7 @@ class FlushNearDetectionFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min.toDouble(); value <= max; value += step) { + for (var value = min; value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -236,9 +254,13 @@ class FlushNearDetectionFunction extends FlushFunctions { } class FlushMaxDetectDistFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; + @override final String unit; FlushMaxDetectDistFunction({ @@ -270,9 +292,13 @@ class FlushMaxDetectDistFunction extends FlushFunctions { } class FlushTargetConfirmTimeFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; + @override final String unit; FlushTargetConfirmTimeFunction({ @@ -292,7 +318,7 @@ class FlushTargetConfirmTimeFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min.toDouble(); value <= max; value += step) { + for (var value = min; value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -304,9 +330,13 @@ class FlushTargetConfirmTimeFunction extends FlushFunctions { } class FlushDisappeDelayFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; + @override final String unit; FlushDisappeDelayFunction({ @@ -326,7 +356,7 @@ class FlushDisappeDelayFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min.toDouble(); value <= max; value += step) { + for (var value = min; value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -338,9 +368,13 @@ class FlushDisappeDelayFunction extends FlushFunctions { } class FlushIndentLevelFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; + @override final String unit; FlushIndentLevelFunction({ @@ -360,7 +394,7 @@ class FlushIndentLevelFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min.toDouble(); value <= max; value += step) { + for (var value = min; value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -372,9 +406,13 @@ class FlushIndentLevelFunction extends FlushFunctions { } class FlushTriggerLevelFunction extends FlushFunctions { + @override final double min; + @override final double max; + @override final double step; + @override final String unit; FlushTriggerLevelFunction({ @@ -394,7 +432,7 @@ class FlushTriggerLevelFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min.toDouble(); value <= max; value += step) { + for (var value = min; value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', diff --git a/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart b/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart index 9451f89f..78d32069 100644 --- a/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart +++ b/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart @@ -14,12 +14,12 @@ class OneGangSwitchFunction extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; @@ -37,7 +37,7 @@ class OneGangCountdownFunction extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: "sec", + description: 'sec', value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart b/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart index 9bdd30b4..eee0019d 100644 --- a/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart +++ b/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart @@ -3,8 +3,11 @@ import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operation import 'package:syncrow_web/utils/constants/assets.dart'; class ThreeGangSwitch1Function extends BaseSwitchFunction { - ThreeGangSwitch1Function({required super.deviceId, required super.deviceName ,required type}) - : super( + ThreeGangSwitch1Function({ + required super.deviceId, + required super.deviceName, + required String type, + }) : super( code: 'switch_1', operationName: 'Light 1 Switch', icon: Assets.assetsAcPower, @@ -14,20 +17,23 @@ class ThreeGangSwitch1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; } class ThreeGangCountdown1Function extends BaseSwitchFunction { - ThreeGangCountdown1Function({required super.deviceId, required super.deviceName ,required type}) - : super( + ThreeGangCountdown1Function({ + required super.deviceId, + required super.deviceName, + required String type, + }) : super( code: 'countdown_1', operationName: 'Light 1 Countdown', icon: Assets.assetsLightCountdown, @@ -37,7 +43,7 @@ class ThreeGangCountdown1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: "sec", + description: 'sec', value: 0.0, minValue: 0, maxValue: 43200, @@ -47,8 +53,11 @@ class ThreeGangCountdown1Function extends BaseSwitchFunction { } class ThreeGangSwitch2Function extends BaseSwitchFunction { - ThreeGangSwitch2Function({required super.deviceId, required super.deviceName, required type}) - : super( + ThreeGangSwitch2Function({ + required super.deviceId, + required super.deviceName, + required String type, + }) : super( code: 'switch_2', operationName: 'Light 2 Switch', icon: Assets.assetsAcPower, @@ -58,20 +67,23 @@ class ThreeGangSwitch2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; } class ThreeGangCountdown2Function extends BaseSwitchFunction { - ThreeGangCountdown2Function({required super.deviceId, required super.deviceName ,required type}) - : super( + ThreeGangCountdown2Function({ + required super.deviceId, + required super.deviceName, + required String type, + }) : super( code: 'countdown_2', operationName: 'Light 2 Countdown', icon: Assets.assetsLightCountdown, @@ -81,7 +93,7 @@ class ThreeGangCountdown2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: "sec", + description: 'sec', value: 0.0, minValue: 0, maxValue: 43200, @@ -91,8 +103,11 @@ class ThreeGangCountdown2Function extends BaseSwitchFunction { } class ThreeGangSwitch3Function extends BaseSwitchFunction { - ThreeGangSwitch3Function({required super.deviceId, required super.deviceName ,required type}) - : super( + ThreeGangSwitch3Function({ + required super.deviceId, + required super.deviceName, + required String type, + }) : super( code: 'switch_3', operationName: 'Light 3 Switch', icon: Assets.assetsAcPower, @@ -102,20 +117,23 @@ class ThreeGangSwitch3Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; } class ThreeGangCountdown3Function extends BaseSwitchFunction { - ThreeGangCountdown3Function({required super.deviceId, required super.deviceName ,required type}) - : super( + ThreeGangCountdown3Function({ + required super.deviceId, + required super.deviceName, + required String type, + }) : super( code: 'countdown_3', operationName: 'Light 3 Countdown', icon: Assets.assetsLightCountdown, @@ -125,7 +143,7 @@ class ThreeGangCountdown3Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: "sec", + description: 'sec', value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart b/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart index 95de1122..a5f78436 100644 --- a/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart +++ b/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart @@ -14,12 +14,12 @@ class TwoGangSwitch1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; @@ -37,19 +37,20 @@ class TwoGangSwitch2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; } class TwoGangCountdown1Function extends BaseSwitchFunction { - TwoGangCountdown1Function({required super.deviceId, required super.deviceName}) + TwoGangCountdown1Function( + {required super.deviceId, required super.deviceName}) : super( code: 'countdown_1', operationName: 'Light 1 Countdown', @@ -60,7 +61,7 @@ class TwoGangCountdown1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: "sec", + description: 'sec', value: 0.0, minValue: 0, maxValue: 43200, @@ -70,7 +71,8 @@ class TwoGangCountdown1Function extends BaseSwitchFunction { } class TwoGangCountdown2Function extends BaseSwitchFunction { - TwoGangCountdown2Function({required super.deviceId, required super.deviceName}) + TwoGangCountdown2Function( + {required super.deviceId, required super.deviceName}) : super( code: 'countdown_2', operationName: 'Light 2 Countdown', @@ -81,7 +83,7 @@ class TwoGangCountdown2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: "sec", + description: 'sec', value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/gateway.dart b/lib/pages/routines/models/gateway.dart index b1a70d2e..06dc6f52 100644 --- a/lib/pages/routines/models/gateway.dart +++ b/lib/pages/routines/models/gateway.dart @@ -13,7 +13,8 @@ class GatewayOperationalValue { }); } -abstract class GatewayFunctions extends DeviceFunction { +abstract class GatewayFunctions + extends DeviceFunction { final String type; GatewayFunctions({ @@ -43,12 +44,12 @@ final class GatewaySwitchAlarmSound extends GatewayFunctions { List getOperationalValues() => [ GatewayOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), GatewayOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; @@ -70,12 +71,12 @@ final class GatewayMasterState extends GatewayFunctions { return [ GatewayOperationalValue( icon: Assets.assetsAcPower, - description: "Normal", + description: 'Normal', value: 'normal', ), GatewayOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "Alarm", + description: 'Alarm', value: 'alarm', ), ]; @@ -98,12 +99,12 @@ final class GatewayFactoryReset extends GatewayFunctions { return [ GatewayOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), GatewayOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; diff --git a/lib/pages/routines/models/pc/energy_clamp_functions.dart b/lib/pages/routines/models/pc/energy_clamp_functions.dart index 4bf3ddd8..5945faa4 100644 --- a/lib/pages/routines/models/pc/energy_clamp_functions.dart +++ b/lib/pages/routines/models/pc/energy_clamp_functions.dart @@ -35,7 +35,7 @@ class TotalEnergyConsumedStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: "kWh", + unit: 'kWh', ); @override @@ -54,7 +54,7 @@ class TotalActivePowerConsumedStatusFunction extends EnergyClampFunctions { min: -19800000, max: 19800000, step: 0.1, - unit: "kW", + unit: 'kW', ); @override @@ -101,7 +101,7 @@ class TotalCurrentStatusFunction extends EnergyClampFunctions { min: 0.000, max: 9000.000, step: 1, - unit: "A", + unit: 'A', ); @override @@ -120,7 +120,7 @@ class FrequencyStatusFunction extends EnergyClampFunctions { min: 0, max: 80, step: 1, - unit: "Hz", + unit: 'Hz', ); @override @@ -140,7 +140,7 @@ class EnergyConsumedAStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: "kWh", + unit: 'kWh', ); @override @@ -159,7 +159,7 @@ class ActivePowerAStatusFunction extends EnergyClampFunctions { min: 200, max: 300, step: 1, - unit: "kW", + unit: 'kW', ); @override @@ -178,7 +178,7 @@ class VoltageAStatusFunction extends EnergyClampFunctions { min: 0.0, max: 500, step: 1, - unit: "V", + unit: 'V', ); @override @@ -197,7 +197,7 @@ class PowerFactorAStatusFunction extends EnergyClampFunctions { min: 0.00, max: 1.00, step: 0.1, - unit: "", + unit: '', ); @override @@ -216,7 +216,7 @@ class CurrentAStatusFunction extends EnergyClampFunctions { min: 0.000, max: 3000.000, step: 1, - unit: "A", + unit: 'A', ); @override @@ -236,7 +236,7 @@ class EnergyConsumedBStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: "kWh", + unit: 'kWh', ); @override @@ -255,7 +255,7 @@ class ActivePowerBStatusFunction extends EnergyClampFunctions { min: -6600000, max: 6600000, step: 1, - unit: "kW", + unit: 'kW', ); @override @@ -274,7 +274,7 @@ class VoltageBStatusFunction extends EnergyClampFunctions { min: 0.0, max: 500, step: 1, - unit: "V", + unit: 'V', ); @override @@ -293,7 +293,7 @@ class CurrentBStatusFunction extends EnergyClampFunctions { min: 0.000, max: 3000.000, step: 1, - unit: "A", + unit: 'A', ); @override @@ -312,7 +312,7 @@ class PowerFactorBStatusFunction extends EnergyClampFunctions { min: 0.0, max: 1.0, step: 0.1, - unit: "", + unit: '', ); @override @@ -332,7 +332,7 @@ class EnergyConsumedCStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: "kWh", + unit: 'kWh', ); @override @@ -351,7 +351,7 @@ class ActivePowerCStatusFunction extends EnergyClampFunctions { min: -6600000, max: 6600000, step: 1, - unit: "kW", + unit: 'kW', ); @override @@ -370,7 +370,7 @@ class VoltageCStatusFunction extends EnergyClampFunctions { min: 0.00, max: 500, step: 0.1, - unit: "V", + unit: 'V', ); @override @@ -389,7 +389,7 @@ class CurrentCStatusFunction extends EnergyClampFunctions { min: 0.000, max: 3000.000, step: 0.1, - unit: "A", + unit: 'A', ); @override @@ -408,7 +408,7 @@ class PowerFactorCStatusFunction extends EnergyClampFunctions { min: 0.00, max: 1.00, step: 0.1, - unit: "", + unit: '', ); @override diff --git a/lib/pages/routines/models/routine_details_model.dart b/lib/pages/routines/models/routine_details_model.dart index c42b4d36..364a5bec 100644 --- a/lib/pages/routines/models/routine_details_model.dart +++ b/lib/pages/routines/models/routine_details_model.dart @@ -48,7 +48,8 @@ class RoutineDetailsModel { spaceUuid: spaceUuid, automationName: name, decisionExpr: decisionExpr, - effectiveTime: effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''), + effectiveTime: + effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''), conditions: conditions?.map((c) => c.toCondition()).toList() ?? [], actions: actions.map((a) => a.toAutomationAction()).toList(), ); @@ -63,7 +64,8 @@ class RoutineDetailsModel { if (iconId != null) 'iconUuid': iconId, if (showInDevice != null) 'showInDevice': showInDevice, if (effectiveTime != null) 'effectiveTime': effectiveTime!.toMap(), - if (conditions != null) 'conditions': conditions!.map((x) => x.toMap()).toList(), + if (conditions != null) + 'conditions': conditions!.map((x) => x.toMap()).toList(), if (type != null) 'type': type, if (sceneId != null) 'sceneId': sceneId, if (automationId != null) 'automationId': automationId, @@ -80,10 +82,12 @@ class RoutineDetailsModel { ), iconId: map['iconUuid'], showInDevice: map['showInDevice'], - effectiveTime: - map['effectiveTime'] != null ? EffectiveTime.fromMap(map['effectiveTime']) : null, + effectiveTime: map['effectiveTime'] != null + ? EffectiveTime.fromMap(map['effectiveTime']) + : null, conditions: map['conditions'] != null - ? List.from(map['conditions'].map((x) => RoutineCondition.fromMap(x))) + ? List.from( + map['conditions'].map((x) => RoutineCondition.fromMap(x))) : null, type: map['type'], sceneId: map['sceneId'], @@ -137,7 +141,8 @@ class RoutineAction { 'actionExecutor': actionExecutor, if (type != null) 'type': type, if (name != null) 'name': name, - if (executorProperty != null) 'executorProperty': executorProperty!.toMap(), + if (executorProperty != null) + 'executorProperty': executorProperty!.toMap(), }; } diff --git a/lib/pages/routines/models/routine_model.dart b/lib/pages/routines/models/routine_model.dart index 2f7c2a24..d1d3cdcd 100644 --- a/lib/pages/routines/models/routine_model.dart +++ b/lib/pages/routines/models/routine_model.dart @@ -42,27 +42,27 @@ class ScenesModel { factory ScenesModel.fromJson(Map json, {bool? isAutomation}) { return ScenesModel( - id: json["id"] ?? json["uuid"] ?? '', - sceneTuyaId: json["sceneTuyaId"] as String?, - name: json["name"] ?? '', - status: json["status"] ?? '', - type: json["type"] ?? '', - spaceName: json["spaceName"] ?? '', - spaceId: json["spaceId"] ?? '', - communityId: json["communityId"] ?? '', + id: json['id'] ?? json['uuid'] ?? '', + sceneTuyaId: json['sceneTuyaId'] as String?, + name: json['name'] ?? '', + status: json['status'] ?? '', + type: json['type'] ?? '', + spaceName: json['spaceName'] ?? '', + spaceId: json['spaceId'] ?? '', + communityId: json['communityId'] ?? '', icon: - isAutomation == true ? Assets.automation : (json["icon"] as String?), + isAutomation == true ? Assets.automation : (json['icon'] as String?), ); } Map toJson() => { - "id": id, - "sceneTuyaId": sceneTuyaId ?? '', - "name": name, - "status": status, - "type": type, - "spaceName": spaceName, - "spaceId": spaceId, - "communityId": communityId, + 'id': id, + 'sceneTuyaId': sceneTuyaId ?? '', + 'name': name, + 'status': status, + 'type': type, + 'spaceName': spaceName, + 'spaceId': spaceId, + 'communityId': communityId, }; } diff --git a/lib/pages/routines/models/water_heater/water_heater_functions.dart b/lib/pages/routines/models/water_heater/water_heater_functions.dart index 7ebea019..6c76a41d 100644 --- a/lib/pages/routines/models/water_heater/water_heater_functions.dart +++ b/lib/pages/routines/models/water_heater/water_heater_functions.dart @@ -29,7 +29,6 @@ class WHRestartStatusFunction extends WaterHeaterFunctions { operationName: 'Restart Status', icon: Assets.refreshStatusIcon, ); - @override List getOperationalValues() { @@ -37,7 +36,7 @@ class WHRestartStatusFunction extends WaterHeaterFunctions { WaterHeaterOperationalValue( icon: Assets.assetsAcPowerOFF, description: 'Power OFF', - value: "off", + value: 'off', ), WaterHeaterOperationalValue( icon: Assets.assetsAcPower, @@ -46,7 +45,7 @@ class WHRestartStatusFunction extends WaterHeaterFunctions { ), WaterHeaterOperationalValue( icon: Assets.refreshStatusIcon, - description: "Restart Memory", + description: 'Restart Memory', value: 'memory', ), ]; @@ -105,8 +104,7 @@ class BacklightFunction extends WaterHeaterFunctions { required super.deviceId, required super.deviceName, required super.type, - }) : - super( + }) : super( code: 'switch_backlight', operationName: 'Backlight', icon: Assets.indicator, diff --git a/lib/pages/routines/models/wps/wps_functions.dart b/lib/pages/routines/models/wps/wps_functions.dart index 101c5cf0..3eae35a8 100644 --- a/lib/pages/routines/models/wps/wps_functions.dart +++ b/lib/pages/routines/models/wps/wps_functions.dart @@ -24,11 +24,11 @@ abstract class WpsFunctions extends DeviceFunction { // For far_detection (75-600cm in 75cm steps) class FarDetectionFunction extends WpsFunctions { - + @override final double min; - @override + @override final double max; - @override + @override final double step; @override final String unit; @@ -62,9 +62,13 @@ class FarDetectionFunction extends WpsFunctions { // For presence_time (0-65535 minutes) class PresenceTimeFunction extends WpsFunctions { + @override final double min; + @override final double max; + @override final double step; + @override final String unit; PresenceTimeFunction( @@ -94,8 +98,11 @@ class PresenceTimeFunction extends WpsFunctions { // For motion_sensitivity_value (1-5 levels) class MotionSensitivityFunction extends WpsFunctions { + @override final double min; + @override final double max; + @override final double step; MotionSensitivityFunction( @@ -124,8 +131,11 @@ class MotionSensitivityFunction extends WpsFunctions { } class MotionLessSensitivityFunction extends WpsFunctions { + @override final double min; + @override final double max; + @override final double step; MotionLessSensitivityFunction( @@ -167,20 +177,23 @@ class IndicatorFunction extends WpsFunctions { List getOperationalValues() => [ WpsOperationalValue( icon: Assets.assetsAcPower, - description: "ON", + description: 'ON', value: true, ), WpsOperationalValue( icon: Assets.assetsAcPowerOFF, - description: "OFF", + description: 'OFF', value: false, ), ]; } class NoOneTimeFunction extends WpsFunctions { + @override final double min; + @override final double max; + @override final String unit; NoOneTimeFunction( @@ -221,20 +234,23 @@ class PresenceStateFunction extends WpsFunctions { List getOperationalValues() => [ WpsOperationalValue( icon: Assets.assetsAcPower, - description: "None", + description: 'None', value: 'none', ), WpsOperationalValue( icon: Assets.presenceStateIcon, - description: "Presence", + description: 'Presence', value: 'presence', ), ]; } class CurrentDistanceFunction extends WpsFunctions { + @override final double min; + @override final double max; + @override final double step; CurrentDistanceFunction( @@ -251,11 +267,11 @@ class CurrentDistanceFunction extends WpsFunctions { @override List getOperationalValues() { - List values = []; - for (int cm = min.toInt(); cm <= max; cm += step.toInt()) { + final values = []; + for (var cm = min.toInt(); cm <= max; cm += step.toInt()) { values.add(WpsOperationalValue( icon: Assets.assetsTempreture, - description: "${cm}CM", + description: '${cm}CM', value: cm, )); } @@ -264,8 +280,11 @@ class CurrentDistanceFunction extends WpsFunctions { } class IlluminanceValueFunction extends WpsFunctions { + @override final double min; + @override final double max; + @override final double step; IlluminanceValueFunction({ @@ -283,11 +302,11 @@ class IlluminanceValueFunction extends WpsFunctions { @override List getOperationalValues() { - List values = []; - for (int lux = min.toInt(); lux <= max; lux += step.toInt()) { + final values = []; + for (var lux = min.toInt(); lux <= max; lux += step.toInt()) { values.add(WpsOperationalValue( icon: Assets.IlluminanceIcon, - description: "$lux Lux", + description: '$lux Lux', value: lux, )); } diff --git a/lib/pages/routines/view/effective_period_view.dart b/lib/pages/routines/view/effective_period_view.dart index b54e4075..8369d790 100644 --- a/lib/pages/routines/view/effective_period_view.dart +++ b/lib/pages/routines/view/effective_period_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart'; import 'package:syncrow_web/pages/routines/widgets/period_option.dart'; import 'package:syncrow_web/pages/routines/widgets/repeat_days.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class EffectivePeriodView extends StatelessWidget { diff --git a/lib/pages/routines/view/routines_view.dart b/lib/pages/routines/view/routines_view.dart index f46ef15f..51176419 100644 --- a/lib/pages/routines/view/routines_view.dart +++ b/lib/pages/routines/view/routines_view.dart @@ -19,7 +19,7 @@ class RoutinesView extends StatefulWidget { } class _RoutinesViewState extends State { - void _handleRoutineCreation(BuildContext context) async { + Future _handleRoutineCreation(BuildContext context) async { final result = await showDialog>( context: context, builder: (context) => const CreateNewRoutinesDialog(), @@ -69,7 +69,7 @@ class _RoutinesViewState extends State { spacing: 16, children: [ Text( - "Create New Routines", + 'Create New Routines', style: Theme.of(context).textTheme.titleLarge?.copyWith( color: ColorsManager.grayColor, diff --git a/lib/pages/routines/widgets/condition_toggle.dart b/lib/pages/routines/widgets/condition_toggle.dart index 541ad431..8a26db83 100644 --- a/lib/pages/routines/widgets/condition_toggle.dart +++ b/lib/pages/routines/widgets/condition_toggle.dart @@ -11,8 +11,8 @@ class ConditionToggle extends StatelessWidget { super.key, }); - static const _conditions = ["<", "==", ">"]; - static const _icons = [ + static const _conditions = ['<', '==', '>']; + static const List _icons = [ Icons.chevron_left, Icons.drag_handle, Icons.chevron_right @@ -20,13 +20,13 @@ class ConditionToggle extends StatelessWidget { @override Widget build(BuildContext context) { - final selectedIndex = _conditions.indexOf(currentCondition ?? "=="); + final selectedIndex = _conditions.indexOf(currentCondition ?? '=='); return Container( height: 30, width: MediaQuery.of(context).size.width * 0.1, decoration: BoxDecoration( - color: ColorsManager.softGray.withOpacity(0.5), + color: ColorsManager.softGray.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(50), ), clipBehavior: Clip.antiAlias, diff --git a/lib/pages/routines/widgets/custom_routines_textbox.dart b/lib/pages/routines/widgets/custom_routines_textbox.dart index f0767df4..f7ceda8f 100644 --- a/lib/pages/routines/widgets/custom_routines_textbox.dart +++ b/lib/pages/routines/widgets/custom_routines_textbox.dart @@ -1,4 +1,5 @@ import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:syncrow_web/pages/routines/widgets/condition_toggle.dart'; @@ -45,10 +46,10 @@ class _CustomRoutinesTextboxState extends State { String? errorMessage; int getDecimalPlaces(double step) { - String stepStr = step.toString(); + final stepStr = step.toString(); if (stepStr.contains('.')) { - List parts = stepStr.split('.'); - String decimalPart = parts[1]; + final parts = stepStr.split('.'); + var decimalPart = parts[1]; decimalPart = decimalPart.replaceAll(RegExp(r'0+$'), ''); return decimalPart.isEmpty ? 0 : decimalPart.length; } else { @@ -111,13 +112,11 @@ class _CustomRoutinesTextboxState extends State { } } - - void _validateInput(String value) { final doubleValue = double.tryParse(value); if (doubleValue == null) { setState(() { - errorMessage = "Invalid number"; + errorMessage = 'Invalid number'; hasError = true; }); return; @@ -128,23 +127,23 @@ class _CustomRoutinesTextboxState extends State { if (doubleValue < min) { setState(() { - errorMessage = "Value must be at least $min"; + errorMessage = 'Value must be at least $min'; hasError = true; }); } else if (doubleValue > max) { setState(() { - errorMessage = "Value must be at most $max"; + errorMessage = 'Value must be at most $max'; hasError = true; }); } else { - int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); - int factor = pow(10, decimalPlaces).toInt(); - int scaledStep = (widget.stepIncreaseAmount * factor).round(); - int scaledValue = (doubleValue * factor).round(); + final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); + final factor = pow(10, decimalPlaces).toInt(); + final scaledStep = (widget.stepIncreaseAmount * factor).round(); + final scaledValue = (doubleValue * factor).round(); if (scaledValue % scaledStep != 0) { setState(() { - errorMessage = "must be a multiple of ${widget.stepIncreaseAmount}"; + errorMessage = 'must be a multiple of ${widget.stepIncreaseAmount}'; hasError = true; }); } else { @@ -156,11 +155,10 @@ class _CustomRoutinesTextboxState extends State { } } - void _correctAndUpdateValue(String value) { final doubleValue = double.tryParse(value) ?? 0.0; - int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); - double rounded = (doubleValue / widget.stepIncreaseAmount).round() * + final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); + var rounded = (doubleValue / widget.stepIncreaseAmount).round() * widget.stepIncreaseAmount; rounded = rounded.clamp(widget.sliderRange.$1, widget.sliderRange.$2); rounded = double.parse(rounded.toStringAsFixed(decimalPlaces)); @@ -179,9 +177,9 @@ class _CustomRoutinesTextboxState extends State { @override Widget build(BuildContext context) { - int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); + final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); - List formatters = []; + final formatters = []; if (decimalPlaces == 0) { formatters.add(FilteringTextInputFormatter.digitsOnly); } else { @@ -233,7 +231,7 @@ class _CustomRoutinesTextboxState extends State { color: ColorsManager.lightGrayBorderColor, width: 1), boxShadow: [ BoxShadow( - color: ColorsManager.blackColor.withOpacity(0.05), + color: ColorsManager.blackColor.withValues(alpha: 0.05), blurRadius: 8, offset: const Offset(0, 4), ), diff --git a/lib/pages/routines/widgets/delete_scene.dart b/lib/pages/routines/widgets/delete_scene.dart index 10eeb493..13121493 100644 --- a/lib/pages/routines/widgets/delete_scene.dart +++ b/lib/pages/routines/widgets/delete_scene.dart @@ -33,13 +33,17 @@ class DeleteSceneWidget extends StatelessWidget { alignment: AlignmentDirectional.center, child: Text( 'Cancel', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( color: ColorsManager.textGray, ), ), ), ), - Container(width: 1, height: 50, color: ColorsManager.greyColor), + Container( + width: 1, height: 50, color: ColorsManager.greyColor), InkWell( onTap: () { context.read().add(const DeleteScene()); @@ -50,7 +54,10 @@ class DeleteSceneWidget extends StatelessWidget { alignment: AlignmentDirectional.center, child: Text( 'Confirm', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( color: ColorsManager.primaryColorWithOpacity, ), ), diff --git a/lib/pages/routines/widgets/dragable_card.dart b/lib/pages/routines/widgets/dragable_card.dart index 9853df7c..69daa31c 100644 --- a/lib/pages/routines/widgets/dragable_card.dart +++ b/lib/pages/routines/widgets/dragable_card.dart @@ -33,17 +33,18 @@ class DraggableCard extends StatelessWidget { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - final deviceFunctions = state.selectedFunctions[deviceData['uniqueCustomId']] ?? []; + final deviceFunctions = + state.selectedFunctions[deviceData['uniqueCustomId']] ?? []; - int index = state.thenItems - .indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); + final index = state.thenItems.indexWhere( + (item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); if (index != -1) { return _buildCardContent(context, deviceFunctions, padding: padding); } - int ifIndex = state.ifItems - .indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); + final ifIndex = state.ifItems.indexWhere( + (item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); if (ifIndex != -1) { return _buildCardContent(context, deviceFunctions, padding: padding); @@ -53,7 +54,8 @@ class DraggableCard extends StatelessWidget { data: deviceData, feedback: Transform.rotate( angle: -0.1, - child: _buildCardContent(context, deviceFunctions, padding: padding), + child: + _buildCardContent(context, deviceFunctions, padding: padding), ), childWhenDragging: _buildGreyContainer(), child: _buildCardContent(context, deviceFunctions, padding: padding), @@ -62,7 +64,8 @@ class DraggableCard extends StatelessWidget { ); } - Widget _buildCardContent(BuildContext context, List deviceFunctions, + Widget _buildCardContent( + BuildContext context, List deviceFunctions, {EdgeInsetsGeometry? padding}) { return Stack( children: [ @@ -92,7 +95,8 @@ class DraggableCard extends StatelessWidget { ), ), padding: const EdgeInsets.all(8), - child: deviceData['type'] == 'tap_to_run' || deviceData['type'] == 'scene' + child: deviceData['type'] == 'tap_to_run' || + deviceData['type'] == 'scene' ? Image.memory( base64Decode(deviceData['icon']), ) @@ -118,12 +122,15 @@ class DraggableCard extends StatelessWidget { height: 4, ), Visibility( - visible: deviceData['tag'] != null && deviceData['tag'] != '', + visible: + deviceData['tag'] != null && deviceData['tag'] != '', child: Row( spacing: 2, children: [ SizedBox( - width: 8, height: 8, child: SvgPicture.asset(Assets.deviceTagIcon)), + width: 8, + height: 8, + child: SvgPicture.asset(Assets.deviceTagIcon)), Flexible( child: Text( deviceData['tag'] ?? '', @@ -141,20 +148,23 @@ class DraggableCard extends StatelessWidget { ), ), Visibility( - visible: deviceData['subSpace'] != null && deviceData['subSpace'] != '', + visible: deviceData['subSpace'] != null && + deviceData['subSpace'] != '', child: const SizedBox( height: 4, ), ), Visibility( - visible: deviceData['subSpace'] != null && deviceData['subSpace'] != '', + visible: deviceData['subSpace'] != null && + deviceData['subSpace'] != '', child: Row( spacing: 2, children: [ SizedBox( width: 8, height: 8, - child: SvgPicture.asset(Assets.spaceLocationIcon)), + child: + SvgPicture.asset(Assets.spaceLocationIcon)), Flexible( child: Text( deviceData['subSpace'] ?? '', @@ -222,7 +232,8 @@ class DraggableCard extends StatelessWidget { } String _formatFunctionValue(DeviceFunctionData function) { - if (function.functionCode == 'temp_set' || function.functionCode == 'temp_current') { + if (function.functionCode == 'temp_set' || + function.functionCode == 'temp_current') { return '${(function.value / 10).toStringAsFixed(0)}°C'; } else if (function.functionCode.contains('countdown')) { final seconds = function.value?.toInt() ?? 0; diff --git a/lib/pages/routines/widgets/function_slider.dart b/lib/pages/routines/widgets/function_slider.dart index 50167a7b..559d8b20 100644 --- a/lib/pages/routines/widgets/function_slider.dart +++ b/lib/pages/routines/widgets/function_slider.dart @@ -17,12 +17,13 @@ class FunctionSlider extends StatelessWidget { @override Widget build(BuildContext context) { final (min, max) = range; - final bool isValidRange = max > min; - final double value = initialValue is int + final isValidRange = max > min; + final value = initialValue is int ? (initialValue as int).toDouble() : (initialValue as double); - final int? divisions = isValidRange ? ((max - min) / dividendOfRange).round() : null; + final divisions = + isValidRange ? ((max - min) / dividendOfRange).round() : null; return Slider( value: value.clamp(min, max), diff --git a/lib/pages/routines/widgets/if_container.dart b/lib/pages/routines/widgets/if_container.dart index da77c7c2..9832f627 100644 --- a/lib/pages/routines/widgets/if_container.dart +++ b/lib/pages/routines/widgets/if_container.dart @@ -62,7 +62,7 @@ class IfContainer extends StatelessWidget { context: context, data: state.ifItems[index], removeComparetors: false, - dialogType: "IF"); + dialogType: 'IF'); if (result != null) { context.read().add( diff --git a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart index f9c20c54..d28f88f0 100644 --- a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart +++ b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart @@ -16,8 +16,9 @@ class FetchRoutineScenesAutomation extends StatelessWidget Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - if (state.isLoading) + if (state.isLoading) { return const Center(child: CircularProgressIndicator()); + } return SingleChildScrollView( child: Padding( @@ -26,23 +27,23 @@ class FetchRoutineScenesAutomation extends StatelessWidget crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - _buildListTitle(context, "Scenes (Tap to Run)"), + _buildListTitle(context, 'Scenes (Tap to Run)'), const SizedBox(height: 10), Visibility( visible: state.scenes.isNotEmpty, - replacement: _buildEmptyState(context, "No scenes found"), + replacement: _buildEmptyState(context, 'No scenes found'), child: SizedBox( height: 200, child: _buildScenes(state), ), ), const SizedBox(height: 10), - _buildListTitle(context, "Automations"), + _buildListTitle(context, 'Automations'), const SizedBox(height: 3), Visibility( visible: state.automations.isNotEmpty, replacement: - _buildEmptyState(context, "No automations found"), + _buildEmptyState(context, 'No automations found'), child: SizedBox( height: 200, child: _buildAutomations(state), diff --git a/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart b/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart index 4fc4bd0f..8c587aba 100644 --- a/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart +++ b/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart @@ -67,15 +67,15 @@ class _RoutineViewCardState extends State { @override Widget build(BuildContext context) { - final double cardWidth = widget.isSmallScreenSize(context) + final cardWidth = widget.isSmallScreenSize(context) ? 120 : widget.isMediumScreenSize(context) ? 135 : 150; - final double cardHeight = widget.isSmallScreenSize(context) ? 190 : 200; + final cardHeight = widget.isSmallScreenSize(context) ? 190 : 200; - final double iconSize = widget.isSmallScreenSize(context) + final iconSize = widget.isSmallScreenSize(context) ? 70 : widget.isMediumScreenSize(context) ? 80 @@ -99,41 +99,42 @@ class _RoutineViewCardState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - widget.cardType != '' - ? Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - if (widget.isFromScenes ?? false) - InkWell( - onTap: _handleSceneTap, - child: Image.asset( - _showTemporaryCheck - ? Assets.scenesPlayIcon - : Assets.scenesPlayIconCheck, - fit: BoxFit.contain, - ), - ) - else if (widget.isLoading) - const SizedBox( - width: 49, - height: 20, - child: Center( - child: SizedBox( - width: 16, - height: 16, - child: CircularProgressIndicator(strokeWidth: 2), - ), - ), - ) - else - CupertinoSwitch( - activeTrackColor: ColorsManager.primaryColor, - value: widget.status == 'enable', - onChanged: widget.onChanged, - ) - ], - ) - : const SizedBox(), + if (widget.cardType != '') + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (widget.isFromScenes ?? false) + InkWell( + onTap: _handleSceneTap, + child: Image.asset( + _showTemporaryCheck + ? Assets.scenesPlayIcon + : Assets.scenesPlayIconCheck, + fit: BoxFit.contain, + ), + ) + else if (widget.isLoading) + const SizedBox( + width: 49, + height: 20, + child: Center( + child: SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(strokeWidth: 2), + ), + ), + ) + else + CupertinoSwitch( + activeTrackColor: ColorsManager.primaryColor, + value: widget.status == 'enable', + onChanged: widget.onChanged, + ) + ], + ) + else + const SizedBox(), Column( children: [ Center( @@ -159,8 +160,9 @@ class _RoutineViewCardState extends State { height: iconSize, width: iconSize, fit: BoxFit.contain, - errorBuilder: (context, error, stackTrace) => - Image.asset( + errorBuilder: + (context, error, stackTrace) => + Image.asset( Assets.logo, height: iconSize, width: iconSize, @@ -203,7 +205,8 @@ class _RoutineViewCardState extends State { maxLines: 1, style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, - fontSize: widget.isSmallScreenSize(context) ? 10 : 12, + fontSize: + widget.isSmallScreenSize(context) ? 10 : 12, ), ), if (widget.spaceName != '') @@ -222,8 +225,9 @@ class _RoutineViewCardState extends State { maxLines: 1, style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, - fontSize: - widget.isSmallScreenSize(context) ? 10 : 12, + fontSize: widget.isSmallScreenSize(context) + ? 10 + : 12, ), ), ], diff --git a/lib/pages/routines/widgets/period_option.dart b/lib/pages/routines/widgets/period_option.dart index 09ec590e..2e455008 100644 --- a/lib/pages/routines/widgets/period_option.dart +++ b/lib/pages/routines/widgets/period_option.dart @@ -21,9 +21,12 @@ class PeriodOptions extends StatelessWidget { builder: (context, state) { return Column( children: [ - _buildRadioOption(context, EnumEffectivePeriodOptions.allDay, '24 Hours'), - _buildRadioOption(context, EnumEffectivePeriodOptions.daytime, 'Sunrise to Sunset'), - _buildRadioOption(context, EnumEffectivePeriodOptions.night, 'Sunset to Sunrise'), + _buildRadioOption( + context, EnumEffectivePeriodOptions.allDay, '24 Hours'), + _buildRadioOption(context, EnumEffectivePeriodOptions.daytime, + 'Sunrise to Sunset'), + _buildRadioOption( + context, EnumEffectivePeriodOptions.night, 'Sunset to Sunrise'), ListTile( contentPadding: EdgeInsets.zero, onTap: () => showCustomTimePicker(context), @@ -34,7 +37,8 @@ class PeriodOptions extends StatelessWidget { fontWeight: FontWeight.w400, fontSize: 14), ), - subtitle: state.customStartTime != null && state.customEndTime != null + subtitle: state.customStartTime != null && + state.customEndTime != null ? Text( '${"${state.customStartTime}"} - ${"${state.customEndTime}"}', style: Theme.of(context).textTheme.bodyMedium!.copyWith( @@ -78,12 +82,16 @@ class PeriodOptions extends StatelessWidget { title: Text( EffectPeriodHelper.formatEnumValue(value), style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 12), + color: ColorsManager.blackColor, + fontWeight: FontWeight.w400, + fontSize: 12), ), subtitle: Text( subtitle, style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, fontSize: 10), + color: ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, + fontSize: 10), ), trailing: Radio( value: value, diff --git a/lib/pages/routines/widgets/repeat_days.dart b/lib/pages/routines/widgets/repeat_days.dart index 4920408a..ee2389be 100644 --- a/lib/pages/routines/widgets/repeat_days.dart +++ b/lib/pages/routines/widgets/repeat_days.dart @@ -16,7 +16,9 @@ class RepeatDays extends StatelessWidget { children: [ Text('Repeat', style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, fontSize: 14)), + color: ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, + fontSize: 14)), const SizedBox(width: 8), BlocBuilder( builder: (context, state) { @@ -31,7 +33,8 @@ class RepeatDays extends StatelessWidget { final day = entry.key; final abbreviation = entry.value; final dayIndex = effectiveBloc.getDayIndex(day); - final isSelected = state.selectedDaysBinary[dayIndex] == '1'; + final isSelected = + state.selectedDaysBinary[dayIndex] == '1'; return Padding( padding: const EdgeInsets.symmetric(horizontal: 3.0), child: GestureDetector( @@ -42,7 +45,9 @@ class RepeatDays extends StatelessWidget { decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( - color: isSelected ? Colors.grey : Colors.grey.shade300, + color: isSelected + ? Colors.grey + : Colors.grey.shade300, width: 1, ), ), @@ -53,7 +58,9 @@ class RepeatDays extends StatelessWidget { abbreviation, style: TextStyle( fontSize: 16, - color: isSelected ? Colors.grey : Colors.grey.shade300, + color: isSelected + ? Colors.grey + : Colors.grey.shade300, ), ), ), diff --git a/lib/pages/routines/widgets/routine_devices.dart b/lib/pages/routines/widgets/routine_devices.dart index f0b77467..5b054908 100644 --- a/lib/pages/routines/widgets/routine_devices.dart +++ b/lib/pages/routines/widgets/routine_devices.dart @@ -74,15 +74,15 @@ class _RoutineDevicesState extends State { .toLowerCase() .contains(state.searchText!.toLowerCase()) ? DraggableCard( - imagePath: deviceData['imagePath'] as String, - title: deviceData['title'] as String, + imagePath: deviceData['imagePath']! as String, + title: deviceData['title']! as String, deviceData: deviceData, ) : const SizedBox.shrink(); } else { return DraggableCard( - imagePath: deviceData['imagePath'] as String, - title: deviceData['title'] as String, + imagePath: deviceData['imagePath']! as String, + title: deviceData['title']! as String, deviceData: deviceData, ); } diff --git a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart index cbf13178..220bcde0 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart @@ -24,8 +24,7 @@ class ACHelper { required bool? removeComparetors, required String dialogType, }) async { - List acFunctions = - functions.whereType().where((function) { + final acFunctions = functions.whereType().where((function) { if (dialogType == 'THEN') { return function.type == 'THEN' || function.type == 'BOTH'; } @@ -371,7 +370,7 @@ class ACHelper { // return Container( // padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), // decoration: BoxDecoration( - // color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), + // color: ColorsManager.primaryColorWithOpacity.withValues(alpha:0.1), // borderRadius: BorderRadius.circular(10), // ), // child: Text( diff --git a/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart index 3c1eb1c2..0ef19067 100644 --- a/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart @@ -3,8 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routines/models/device_functions.dart'; -import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; +import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class AutomationDialog extends StatefulWidget { @@ -31,9 +31,11 @@ class _AutomationDialogState extends State { @override void initState() { super.initState(); - List? functions = - context.read().state.selectedFunctions[widget.uniqueCustomId]; - for (DeviceFunctionData data in functions ?? []) { + final functions = context + .read() + .state + .selectedFunctions[widget.uniqueCustomId]; + for (final data in functions ?? []) { if (data.entityId == widget.automationId) { selectedAutomationActionExecutor = data.value; } @@ -65,7 +67,8 @@ class _AutomationDialogState extends State { }), ), ListTile( - leading: SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24), + leading: + SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24), title: const Text('Disable'), trailing: Radio( value: 'rule_disable', diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart index 504017a2..5bcc558d 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart @@ -45,7 +45,8 @@ class CpsDialogValueSelector extends StatelessWidget { operationName: operationName, value: operation.value, condition: selectedFunctionData?.condition, - valueDescription: selectedFunctionData?.valueDescription, + valueDescription: + selectedFunctionData?.valueDescription, ), ), ); diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart index d11871a7..0ce2fd04 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart @@ -57,7 +57,7 @@ class CpsFunctionsList extends StatelessWidget { 'moving_max_dis', 'moving_range', 'presence_range', - if (dialogType == "IF") 'sensitivity', + if (dialogType == 'IF') 'sensitivity', ], ); }); diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart index fd637c28..4fa2e66c 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart @@ -1,5 +1,6 @@ abstract final class CpsSliderHelpers { - static (double min, double max, double step) mappedRange(String functionCode) { + static (double min, double max, double step) mappedRange( + String functionCode) { final (defaultMin, defaultMax) = sliderRange(functionCode); final defaultDivdidend = dividendOfRange(functionCode); return switch (functionCode) { @@ -62,7 +63,10 @@ abstract final class CpsSliderHelpers { 'perceptual_boundary' || 'moving_boundary' => 'M', - 'moving_rigger_time' || 'moving_static_time' || 'none_body_time' => 'sec', + 'moving_rigger_time' || + 'moving_static_time' || + 'none_body_time' => + 'sec', _ => '', }; diff --git a/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart index 4580f6e1..b81c6a80 100644 --- a/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart @@ -9,14 +9,14 @@ import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; class DelayHelper { static Future?> showDelayPickerDialog( BuildContext context, Map data) async { - int hours = 0; - int minutes = 0; + var hours = 0; + var minutes = 0; return showDialog?>( context: context, builder: (BuildContext context) { final routineBloc = context.read(); - int totalSec = 0; + var totalSec = 0; final selectedFunctionData = routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? []; @@ -43,7 +43,8 @@ class DelayHelper { Expanded( child: CupertinoTimerPicker( mode: CupertinoTimerPickerMode.hm, - initialTimerDuration: Duration(hours: hours, minutes: minutes), + initialTimerDuration: + Duration(hours: hours, minutes: minutes), onTimerDurationChanged: (Duration newDuration) { hours = newDuration.inHours; minutes = newDuration.inMinutes % 60; @@ -55,7 +56,7 @@ class DelayHelper { Navigator.of(context).pop(); }, onConfirm: () { - int totalSeconds = (hours * 3600) + (minutes * 60); + final totalSeconds = (hours * 3600) + (minutes * 60); context.read().add(AddFunctionToRoutine( [ DeviceFunctionData( diff --git a/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart index 40036d32..3a493abd 100644 --- a/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart @@ -38,10 +38,10 @@ class DiscardDialog { color: ColorsManager.red, fontWeight: FontWeight.bold, ), - onDismissText: "Don’t Close", - onConfirmText: "Close", + onDismissText: 'Don’t Close', + onConfirmText: 'Close', onDismissColor: ColorsManager.grayColor, - onConfirmColor: ColorsManager.red.withOpacity(0.8), + onConfirmColor: ColorsManager.red.withValues(alpha: 0.8), onDismiss: () { Navigator.pop(context); }, diff --git a/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart index 5fc31a96..5543ec96 100644 --- a/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart @@ -8,13 +8,14 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:time_picker_spinner/time_picker_spinner.dart'; class EffectPeriodHelper { - static Future?> showCustomTimePicker(BuildContext context) async { - String selectedStartTime = "00:00"; - String selectedEndTime = "23:59"; - PageController pageController = PageController(initialPage: 0); + static Future?> showCustomTimePicker( + BuildContext context) async { + var selectedStartTime = '00:00'; + var selectedEndTime = '23:59'; + final pageController = PageController(initialPage: 0); - DateTime startDateTime = DateTime(2022, 1, 1, 0, 0); - DateTime endDateTime = DateTime(2022, 1, 1, 23, 59); + final startDateTime = DateTime(2022, 1, 1, 0, 0); + final endDateTime = DateTime(2022, 1, 1, 23, 59); context.customAlertDialog( alertBody: SizedBox( @@ -46,7 +47,7 @@ class EffectPeriodHelper { ], ), ), - title: "Custom", + title: 'Custom', onConfirm: () { context.read().add( SetCustomTime(selectedStartTime, selectedEndTime), @@ -88,7 +89,7 @@ class EffectPeriodHelper { ), TextButton( onPressed: () {}, - child: Text(isStartTime ? "Start" : "End", + child: Text(isStartTime ? 'Start' : 'End', style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, @@ -135,17 +136,17 @@ class EffectPeriodHelper { static String formatEnumValue(EnumEffectivePeriodOptions value) { switch (value) { case EnumEffectivePeriodOptions.allDay: - return "All Day"; + return 'All Day'; case EnumEffectivePeriodOptions.daytime: - return "Daytime"; + return 'Daytime'; case EnumEffectivePeriodOptions.night: - return "Night"; + return 'Night'; case EnumEffectivePeriodOptions.custom: - return "Custom"; + return 'Custom'; case EnumEffectivePeriodOptions.none: - return "None"; + return 'None'; default: - return ""; + return ''; } } } diff --git a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart index 7ca89edb..b4fa1080 100644 --- a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart +++ b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart @@ -7,7 +7,6 @@ import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/models/flush/flush_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/custom_routines_textbox.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart'; -import 'package:syncrow_web/pages/routines/widgets/slider_value_selector.dart'; class FlushValueSelectorWidget extends StatelessWidget { final String selectedFunction; @@ -62,7 +61,7 @@ class FlushValueSelectorWidget extends StatelessWidget { selectedFunction == FlushMountedPresenceSensorModel.codeFarDetection; final isDistanceDetection = isNearDetection || isFarDetection; - double initialValue = (functionData.value as num?)?.toDouble() ?? 0.0; + var initialValue = (functionData.value as num?)?.toDouble() ?? 0.0; if (isDistanceDetection) { initialValue = initialValue / 100; @@ -157,7 +156,7 @@ class FlushValueSelectorWidget extends StatelessWidget { String get getDisplayText { final num? value = functionData.value; - double displayValue = value?.toDouble() ?? 0.0; + var displayValue = value?.toDouble() ?? 0.0; if (functionData.functionCode == FlushMountedPresenceSensorModel.codeNearDetection || diff --git a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart index 56f74054..4e296e65 100644 --- a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart +++ b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart @@ -49,8 +49,6 @@ class _TimeWheelPickerState extends State { } } - - @override void dispose() { _hoursController.dispose(); @@ -103,7 +101,7 @@ class _TimeWheelPickerState extends State { } void _handleTimeChange(int hours, int minutes, int seconds) { - int total = hours * 3600 + minutes * 60 + seconds; + var total = hours * 3600 + minutes * 60 + seconds; if (total > 10000) { hours = 2; minutes = 46; diff --git a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart index 392c3012..1d22f1a1 100644 --- a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart +++ b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart @@ -45,7 +45,8 @@ class GatewayDialogValueSelector extends StatelessWidget { operationName: operationName, value: operation.value, condition: selectedFunctionData?.condition, - valueDescription: selectedFunctionData?.valueDescription, + valueDescription: + selectedFunctionData?.valueDescription, ), ), ); diff --git a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart index 641fd234..e2b103c5 100644 --- a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart @@ -25,8 +25,7 @@ class OneGangSwitchHelper { required String uniqueCustomId, required bool removeComparetors, }) async { - List oneGangFunctions = - functions.whereType().toList(); + final oneGangFunctions = functions.whereType().toList(); return showDialog?>( context: context, @@ -246,9 +245,9 @@ class OneGangSwitchHelper { withSpecialChar: false, currentCondition: selectedFunctionData?.condition, dialogType: dialogType, - sliderRange: (0, 43200), + sliderRange: (0, 43200), displayedValue: (initialValue ?? 0).toString(), - initialValue: (initialValue ?? 0).toString(), + initialValue: (initialValue ?? 0).toString(), onConditionChanged: (condition) { context.read().add( AddFunction( diff --git a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart index 2b8ba68f..e6f832c8 100644 --- a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart @@ -81,6 +81,4 @@ class EnergyOperationalValuesList extends StatelessWidget { ), ); } - - } diff --git a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart index 696251a1..3695d075 100644 --- a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart +++ b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart @@ -27,13 +27,11 @@ class EnergyValueSelectorWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final selectedFn = - functions.firstWhere((f) => f.code == selectedFunction); + final selectedFn = functions.firstWhere((f) => f.code == selectedFunction); final values = selectedFn.getOperationalValues(); - final step = selectedFn.step ?? 1.0; - final _unit = selectedFn.unit ?? ''; - final (double, double) sliderRange = - (selectedFn.min ?? 0.0, selectedFn.max ?? 100.0); + final step = selectedFn.step ?? 1.0; + final unit = selectedFn.unit ?? ''; + final sliderRange = (selectedFn.min ?? 0.0, selectedFn.max ?? 100.0); if (_isSliderFunction(selectedFunction)) { return CustomRoutinesTextbox( @@ -65,7 +63,7 @@ class EnergyValueSelectorWidget extends StatelessWidget { ), ), ), - unit: _unit, + unit: unit, dividendOfRange: 1, stepIncreaseAmount: step, ); diff --git a/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart index b8449838..2d02304a 100644 --- a/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_bloc.dart'; @@ -13,7 +14,6 @@ import 'package:syncrow_web/pages/routines/view/effective_period_view.dart'; import 'package:syncrow_web/pages/routines/widgets/delete_scene.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:flutter/cupertino.dart'; class SettingHelper { static Future showSettingDialog({ @@ -30,14 +30,16 @@ class SettingHelper { providers: [ if (effectiveTime != null) BlocProvider( - create: (_) => EffectPeriodBloc()..add(InitialEffectPeriodEvent(effectiveTime)), + create: (_) => EffectPeriodBloc() + ..add(InitialEffectPeriodEvent(effectiveTime)), ), if (effectiveTime == null) BlocProvider( create: (_) => EffectPeriodBloc(), ), BlocProvider( - create: (_) => SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? ''))), + create: (_) => SettingBloc() + ..add(InitialEvent(selectedIcon: iconId ?? ''))), ], child: AlertDialog( contentPadding: EdgeInsets.zero, @@ -45,15 +47,18 @@ class SettingHelper { builder: (context, effectPeriodState) { return BlocBuilder( builder: (context, settingState) { - String selectedIcon = ''; - List list = []; + var selectedIcon = ''; + var list = []; if (settingState is TabToRunSettingLoaded) { selectedIcon = settingState.selectedIcon; list = settingState.iconList; } return Container( width: context.read().isExpanded ? 800 : 400, - height: context.read().isExpanded && isAutomation ? 500 : 350, + height: + context.read().isExpanded && isAutomation + ? 500 + : 350, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), @@ -76,14 +81,18 @@ class SettingHelper { children: [ Container( padding: const EdgeInsets.only( - top: 10, left: 10, right: 10, bottom: 10), + top: 10, + left: 10, + right: 10, + bottom: 10), child: Column( children: [ InkWell( onTap: () {}, child: Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment + .spaceBetween, children: [ Text( 'Validity', @@ -91,14 +100,18 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: - ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, + color: ColorsManager + .textPrimaryColor, + fontWeight: + FontWeight + .w400, fontSize: 14), ), const Icon( - Icons.arrow_forward_ios_outlined, - color: ColorsManager.textGray, + Icons + .arrow_forward_ios_outlined, + color: ColorsManager + .textGray, size: 15, ) ], @@ -108,22 +121,27 @@ class SettingHelper { height: 5, ), const Divider( - color: ColorsManager.graysColor, + color: + ColorsManager.graysColor, ), const SizedBox( height: 5, ), InkWell( onTap: () { - BlocProvider.of(context).add( - FetchIcons( + BlocProvider.of< + SettingBloc>( + context) + .add(FetchIcons( expanded: !context - .read() + .read< + SettingBloc>() .isExpanded)); }, child: Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment + .spaceBetween, children: [ Text( 'Effective Period', @@ -131,14 +149,18 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: - ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, + color: ColorsManager + .textPrimaryColor, + fontWeight: + FontWeight + .w400, fontSize: 14), ), const Icon( - Icons.arrow_forward_ios_outlined, - color: ColorsManager.textGray, + Icons + .arrow_forward_ios_outlined, + color: ColorsManager + .textGray, size: 15, ) ], @@ -148,13 +170,16 @@ class SettingHelper { height: 5, ), const Divider( - color: ColorsManager.graysColor, + color: + ColorsManager.graysColor, ), const SizedBox( height: 5, ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, children: [ Text( 'Executed by', @@ -162,8 +187,11 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, + color: ColorsManager + .textPrimaryColor, + fontWeight: + FontWeight + .w400, fontSize: 14), ), Text('Cloud', @@ -171,12 +199,19 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager.textGray, - fontWeight: FontWeight.w400, + color: + ColorsManager + .textGray, + fontWeight: + FontWeight + .w400, fontSize: 14)), ], ), - if (context.read().state.isUpdate ?? + if (context + .read() + .state + .isUpdate ?? false) const DeleteSceneWidget() ], @@ -188,20 +223,27 @@ class SettingHelper { children: [ Container( padding: const EdgeInsets.only( - top: 10, left: 10, right: 10, bottom: 10), + top: 10, + left: 10, + right: 10, + bottom: 10), child: Column( children: [ InkWell( onTap: () { - BlocProvider.of(context).add( - FetchIcons( + BlocProvider.of< + SettingBloc>( + context) + .add(FetchIcons( expanded: !context - .read() + .read< + SettingBloc>() .isExpanded)); }, child: Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment + .spaceBetween, children: [ Text( 'Icons', @@ -209,14 +251,18 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: - ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, + color: ColorsManager + .textPrimaryColor, + fontWeight: + FontWeight + .w400, fontSize: 14), ), const Icon( - Icons.arrow_forward_ios_outlined, - color: ColorsManager.textGray, + Icons + .arrow_forward_ios_outlined, + color: ColorsManager + .textGray, size: 15, ) ], @@ -226,13 +272,16 @@ class SettingHelper { height: 5, ), const Divider( - color: ColorsManager.graysColor, + color: + ColorsManager.graysColor, ), const SizedBox( height: 5, ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, children: [ Text( 'Show on devices page', @@ -240,23 +289,30 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, + color: ColorsManager + .textPrimaryColor, + fontWeight: + FontWeight + .w400, fontSize: 14), ), Row( - mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: + MainAxisAlignment.end, children: [ Container( height: 30, width: 1, - color: ColorsManager.graysColor, + color: ColorsManager + .graysColor, ), Transform.scale( scale: .8, - child: CupertinoSwitch( + child: + CupertinoSwitch( value: true, - onChanged: (value) {}, + onChanged: + (value) {}, applyTheme: true, ), ), @@ -268,13 +324,16 @@ class SettingHelper { height: 5, ), const Divider( - color: ColorsManager.graysColor, + color: + ColorsManager.graysColor, ), const SizedBox( height: 5, ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, children: [ Text( 'Executed by', @@ -282,8 +341,11 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, + color: ColorsManager + .textPrimaryColor, + fontWeight: + FontWeight + .w400, fontSize: 14), ), Text('Cloud', @@ -291,12 +353,19 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager.textGray, - fontWeight: FontWeight.w400, + color: + ColorsManager + .textGray, + fontWeight: + FontWeight + .w400, fontSize: 14)), ], ), - if (context.read().state.isUpdate ?? + if (context + .read() + .state + .isUpdate ?? false) const DeleteSceneWidget() ], @@ -304,12 +373,14 @@ class SettingHelper { ], ), ), - if (context.read().isExpanded && !isAutomation) + if (context.read().isExpanded && + !isAutomation) SizedBox( width: 400, height: 150, child: settingState is LoadingState - ? const Center(child: CircularProgressIndicator()) + ? const Center( + child: CircularProgressIndicator()) : GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( @@ -326,7 +397,8 @@ class SettingHelper { height: 35, child: InkWell( onTap: () { - BlocProvider.of(context) + BlocProvider.of( + context) .add(SelectIcon( iconId: iconModel.uuid, )); @@ -335,13 +407,17 @@ class SettingHelper { child: SizedBox( child: ClipOval( child: Container( - padding: const EdgeInsets.all(1), + padding: + const EdgeInsets.all( + 1), decoration: BoxDecoration( border: Border.all( - color: selectedIcon == iconModel.uuid + color: selectedIcon == + iconModel.uuid ? ColorsManager .primaryColorWithOpacity - : Colors.transparent, + : Colors + .transparent, width: 2, ), shape: BoxShape.circle, @@ -356,8 +432,12 @@ class SettingHelper { ); }, )), - if (context.read().isExpanded && isAutomation) - const SizedBox(height: 350, width: 400, child: EffectivePeriodView()) + if (context.read().isExpanded && + isAutomation) + const SizedBox( + height: 350, + width: 400, + child: EffectivePeriodView()) ], ), Container( @@ -381,23 +461,33 @@ class SettingHelper { alignment: AlignmentDirectional.center, child: Text( 'Cancel', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( color: ColorsManager.textGray, ), ), ), ), ), - Container(width: 1, height: 50, color: ColorsManager.greyColor), + Container( + width: 1, + height: 50, + color: ColorsManager.greyColor), Expanded( child: InkWell( onTap: () { if (isAutomation) { BlocProvider.of(context).add( - EffectiveTimePeriodEvent(EffectiveTime( - start: effectPeriodState.customStartTime!, - end: effectPeriodState.customEndTime!, - loops: effectPeriodState.selectedDaysBinary))); + EffectiveTimePeriodEvent( + EffectiveTime( + start: effectPeriodState + .customStartTime!, + end: effectPeriodState + .customEndTime!, + loops: effectPeriodState + .selectedDaysBinary))); Navigator.of(context).pop(); } else { Navigator.of(context).pop(selectedIcon); @@ -407,8 +497,12 @@ class SettingHelper { alignment: AlignmentDirectional.center, child: Text( 'Confirm', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.primaryColorWithOpacity, + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + color: ColorsManager + .primaryColorWithOpacity, ), ), ), diff --git a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart index 5e50c11d..8416837a 100644 --- a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart @@ -24,8 +24,7 @@ class ThreeGangSwitchHelper { required String dialogType, required bool removeComparetors, }) async { - List switchFunctions = - functions.whereType().toList(); + final switchFunctions = functions.whereType().toList(); return showDialog?>( context: context, diff --git a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart index 6b3dc813..1ed89cd4 100644 --- a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart @@ -25,8 +25,7 @@ class TwoGangSwitchHelper { required bool removeComparetors, required String dialogType, }) async { - List switchFunctions = - functions.whereType().toList(); + final switchFunctions = functions.whereType().toList(); return showDialog?>( context: context, @@ -237,7 +236,7 @@ class TwoGangSwitchHelper { DeviceFunctionData? selectedFunctionData, // Function(String) onConditionChanged, ) { - final conditions = ["<", "==", ">"]; + final conditions = ['<', '==', '>']; return ToggleButtons( onPressed: (int index) { @@ -264,8 +263,8 @@ class TwoGangSwitchHelper { minWidth: 40.0, ), isSelected: - conditions.map((c) => c == (currentCondition ?? "==")).toList(), - children: conditions.map((c) => Text(c)).toList(), + conditions.map((c) => c == (currentCondition ?? '==')).toList(), + children: conditions.map(Text.new).toList(), ); } @@ -280,7 +279,7 @@ class TwoGangSwitchHelper { return Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: BoxDecoration( - color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), + color: ColorsManager.primaryColorWithOpacity.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(10), ), child: Text( diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart index 56f74054..4e296e65 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart @@ -49,8 +49,6 @@ class _TimeWheelPickerState extends State { } } - - @override void dispose() { _hoursController.dispose(); @@ -103,7 +101,7 @@ class _TimeWheelPickerState extends State { } void _handleTimeChange(int hours, int minutes, int seconds) { - int total = hours * 3600 + minutes * 60 + seconds; + var total = hours * 3600 + minutes * 60 + seconds; if (total > 10000) { hours = 2; minutes = 46; diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart index 4d04102d..497ee3db 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart @@ -63,7 +63,8 @@ class _WallPresenceSensorState extends State { @override void initState() { super.initState(); - _wpsFunctions = widget.functions.whereType().where((function) { + _wpsFunctions = + widget.functions.whereType().where((function) { if (widget.dialogType == 'THEN') { return function.type == 'THEN' || function.type == 'BOTH'; } diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart index 6c149cd3..6dacb85e 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart @@ -30,7 +30,8 @@ class WpsOperationalValuesList extends StatelessWidget { : ListView.builder( padding: const EdgeInsets.all(20), itemCount: values.length, - itemBuilder: (context, index) => _buildValueItem(context, values[index]), + itemBuilder: (context, index) => + _buildValueItem(context, values[index]), ); } @@ -61,7 +62,8 @@ class WpsOperationalValuesList extends StatelessWidget { Widget _buildValueIcon(context, WpsOperationalValue value) { return Column( children: [ - if (_shouldShowTextDescription) Text(value.description.replaceAll("cm", '')), + if (_shouldShowTextDescription) + Text(value.description.replaceAll('cm', '')), SvgPicture.asset(value.icon, width: 25, height: 25), ], ); diff --git a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart index 4042df36..25839c68 100644 --- a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart @@ -61,5 +61,4 @@ class WaterHeaterOperationalValuesList extends StatelessWidget { groupValue: selectedValue, onChanged: (_) => onSelect(value)); } - } diff --git a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart index a09bbba7..9647408c 100644 --- a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart +++ b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart @@ -12,7 +12,7 @@ class WaterHeaterValueSelectorWidget extends StatelessWidget { final DeviceFunctionData functionData; final List whFunctions; final AllDevicesModel? device; - final String dialogType; + final String dialogType; const WaterHeaterValueSelectorWidget({ required this.selectedFunction, @@ -39,14 +39,13 @@ class WaterHeaterValueSelectorWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ _buildCountDownSlider( - context, - functionData.value, - device, - selectedFn.operationName, - functionData, - selectedFunction, - dialogType - ), + context, + functionData.value, + device, + selectedFn.operationName, + functionData, + selectedFunction, + dialogType), const SizedBox(height: 10), ], ); diff --git a/lib/pages/routines/widgets/routine_search_and_buttons.dart b/lib/pages/routines/widgets/routine_search_and_buttons.dart index efeedf9d..e261b3b1 100644 --- a/lib/pages/routines/widgets/routine_search_and_buttons.dart +++ b/lib/pages/routines/widgets/routine_search_and_buttons.dart @@ -15,7 +15,8 @@ class RoutineSearchAndButtons extends StatefulWidget { }); @override - State createState() => _RoutineSearchAndButtonsState(); + State createState() => + _RoutineSearchAndButtonsState(); } class _RoutineSearchAndButtonsState extends State { @@ -61,8 +62,9 @@ class _RoutineSearchAndButtonsState extends State { children: [ ConstrainedBox( constraints: BoxConstraints( - maxWidth: - constraints.maxWidth > 700 ? 450 : constraints.maxWidth - 32), + maxWidth: constraints.maxWidth > 700 + ? 450 + : constraints.maxWidth - 32), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -71,10 +73,13 @@ class _RoutineSearchAndButtonsState extends State { children: [ Text('* ', style: context.textTheme.bodyMedium! - .copyWith(color: ColorsManager.red, fontSize: 13)), + .copyWith( + color: ColorsManager.red, + fontSize: 13)), Text( 'Routine Name', - style: context.textTheme.bodyMedium!.copyWith( + style: context.textTheme.bodyMedium! + .copyWith( fontSize: 13, fontWeight: FontWeight.w600, color: ColorsManager.blackColor, @@ -88,20 +93,23 @@ class _RoutineSearchAndButtonsState extends State { decoration: containerWhiteDecoration, child: TextFormField( style: context.textTheme.bodyMedium! - .copyWith(color: ColorsManager.blackColor), + .copyWith( + color: ColorsManager.blackColor), controller: _nameController, decoration: InputDecoration( hintText: 'Please enter the name', hintStyle: context.textTheme.bodyMedium! - .copyWith(fontSize: 12, color: ColorsManager.grayColor), + .copyWith( + fontSize: 12, + color: ColorsManager.grayColor), contentPadding: - const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + const EdgeInsets.symmetric( + horizontal: 12, vertical: 10), border: InputBorder.none, ), onTapOutside: (_) { - context - .read() - .add(SetRoutineName(_nameController.text)); + context.read().add( + SetRoutineName(_nameController.text)); }, validator: (value) { if (value == null || value.isEmpty) { @@ -114,41 +122,44 @@ class _RoutineSearchAndButtonsState extends State { ], ), ), - (constraints.maxWidth <= 1000) - ? const SizedBox() - : SizedBox( - height: 40, - width: 200, - child: Center( - child: DefaultButton( - onPressed: state.isAutomation || state.isTabToRun - ? () async { - final result = await SettingHelper.showSettingDialog( - context: context, - iconId: state.selectedIcon ?? '', - ); - if (result != null) { - context - .read() - .add(AddSelectedIcon(result)); - } - } - : null, - borderRadius: 15, - elevation: 0, - borderColor: ColorsManager.greyColor, - backgroundColor: ColorsManager.boxColor, - child: const Text( - 'Settings', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, - color: ColorsManager.primaryColor, - ), - ), + if (constraints.maxWidth <= 1000) + const SizedBox() + else + SizedBox( + height: 40, + width: 200, + child: Center( + child: DefaultButton( + onPressed: state.isAutomation || + state.isTabToRun + ? () async { + final result = await SettingHelper + .showSettingDialog( + context: context, + iconId: state.selectedIcon ?? '', + ); + if (result != null) { + context + .read() + .add(AddSelectedIcon(result)); + } + } + : null, + borderRadius: 15, + elevation: 0, + borderColor: ColorsManager.greyColor, + backgroundColor: ColorsManager.boxColor, + child: const Text( + 'Settings', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + color: ColorsManager.primaryColor, ), ), ), + ), + ), ], ), ), @@ -186,10 +197,12 @@ class _RoutineSearchAndButtonsState extends State { child: Center( child: DefaultButton( onPressed: () async { - if (state.routineName == null || state.routineName!.isEmpty) { + if (state.routineName == null || + state.routineName!.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text('Please enter the routine name'), + content: const Text( + 'Please enter the routine name'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -203,10 +216,12 @@ class _RoutineSearchAndButtonsState extends State { return; } - if (state.ifItems.isEmpty || state.thenItems.isEmpty) { + if (state.ifItems.isEmpty || + state.thenItems.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text('Please add if and then condition'), + content: const Text( + 'Please add if and then condition'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -221,8 +236,10 @@ class _RoutineSearchAndButtonsState extends State { } // final result = // await - BlocProvider.of(context).add(ResetErrorMessage()); - SaveRoutineHelper.showSaveRoutineDialog(context); + BlocProvider.of(context) + .add(ResetErrorMessage()); + SaveRoutineHelper.showSaveRoutineDialog( + context); // if (result != null && result) { // BlocProvider.of(context).add( // const CreateNewRoutineViewEvent(createRoutineView: false), @@ -261,10 +278,14 @@ class _RoutineSearchAndButtonsState extends State { child: DefaultButton( onPressed: state.isAutomation || state.isTabToRun ? () async { - final result = await SettingHelper.showSettingDialog( - context: context, iconId: state.selectedIcon ?? ''); + final result = + await SettingHelper.showSettingDialog( + context: context, + iconId: state.selectedIcon ?? ''); if (result != null) { - context.read().add(AddSelectedIcon(result)); + context + .read() + .add(AddSelectedIcon(result)); } } : null, @@ -314,10 +335,12 @@ class _RoutineSearchAndButtonsState extends State { child: Center( child: DefaultButton( onPressed: () async { - if (state.routineName == null || state.routineName!.isEmpty) { + if (state.routineName == null || + state.routineName!.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text('Please enter the routine name'), + content: const Text( + 'Please enter the routine name'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -331,10 +354,12 @@ class _RoutineSearchAndButtonsState extends State { return; } - if (state.ifItems.isEmpty || state.thenItems.isEmpty) { + if (state.ifItems.isEmpty || + state.thenItems.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text('Please add if and then condition'), + content: const Text( + 'Please add if and then condition'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -349,7 +374,8 @@ class _RoutineSearchAndButtonsState extends State { } // final result = // await - BlocProvider.of(context).add(ResetErrorMessage()); + BlocProvider.of(context) + .add(ResetErrorMessage()); SaveRoutineHelper.showSaveRoutineDialog(context); // if (result != null && result) { // BlocProvider.of(context).add( diff --git a/lib/pages/routines/widgets/scenes_and_automations.dart b/lib/pages/routines/widgets/scenes_and_automations.dart index 14cb8d61..785686b6 100644 --- a/lib/pages/routines/widgets/scenes_and_automations.dart +++ b/lib/pages/routines/widgets/scenes_and_automations.dart @@ -27,14 +27,16 @@ class _ScenesAndAutomationsState extends State { return BlocBuilder( builder: (context, state) { if (!state.isLoading) { - var scenes = [...state.scenes, ...state.automations]; + final scenes = [...state.scenes, ...state.automations]; return Wrap( spacing: 10, runSpacing: 10, children: scenes.asMap().entries.map((entry) { final scene = entry.value; if (state.searchText != null && state.searchText!.isNotEmpty) { - return scene.name.toLowerCase().contains(state.searchText!.toLowerCase()) + return scene.name + .toLowerCase() + .contains(state.searchText!.toLowerCase()) ? DraggableCard( imagePath: scene.icon ?? Assets.loginLogo, title: scene.name, diff --git a/lib/pages/routines/widgets/search_bar_condition_title.dart b/lib/pages/routines/widgets/search_bar_condition_title.dart index 9ffcbf63..9d2320bd 100644 --- a/lib/pages/routines/widgets/search_bar_condition_title.dart +++ b/lib/pages/routines/widgets/search_bar_condition_title.dart @@ -6,7 +6,8 @@ import 'package:syncrow_web/pages/routines/widgets/routines_title_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class ConditionTitleAndSearchBar extends StatelessWidget with HelperResponsiveLayout { +class ConditionTitleAndSearchBar extends StatelessWidget + with HelperResponsiveLayout { const ConditionTitleAndSearchBar({ super.key, }); diff --git a/lib/pages/routines/widgets/then_container.dart b/lib/pages/routines/widgets/then_container.dart index d9eee4c4..e32a2e67 100644 --- a/lib/pages/routines/widgets/then_container.dart +++ b/lib/pages/routines/widgets/then_container.dart @@ -30,123 +30,118 @@ class ThenContainer extends StatelessWidget { style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 16), - state.isLoading && state.isUpdate == true - ? const Center( - child: CircularProgressIndicator(), - ) - : Wrap( - spacing: 8, - runSpacing: 8, - children: List.generate( - state.thenItems.length, - (index) => GestureDetector( - onTap: () async { - if (state.thenItems[index] - ['deviceId'] == - 'delay') { - final result = await DelayHelper - .showDelayPickerDialog(context, - state.thenItems[index]); - - if (result != null) { - context - .read() - .add(AddToThenContainer({ - ...state.thenItems[index], - 'imagePath': Assets.delay, - 'title': 'Delay', - })); - } - return; - } - - if (state.thenItems[index]['type'] == - 'automation') { - final result = await showDialog( - context: context, - builder: (BuildContext context) => - AutomationDialog( - automationName: - state.thenItems[index] - ['name'] ?? - 'Automation', - automationId: - state.thenItems[index] - ['deviceId'] ?? - '', - uniqueCustomId: - state.thenItems[index] - ['uniqueCustomId'], - ), - ); - - if (result != null) { - context - .read() - .add(AddToThenContainer({ - ...state.thenItems[index], - 'imagePath': - Assets.automation, - 'title': - state.thenItems[index] - ['name'] ?? - state.thenItems[index] - ['title'], - })); - } - return; - } - - final result = await DeviceDialogHelper - .showDeviceDialog( - context: context, - data: state.thenItems[index], - removeComparetors: true, - dialogType: "THEN"); + if (state.isLoading && state.isUpdate == true) + const Center( + child: CircularProgressIndicator(), + ) + else + Wrap( + spacing: 8, + runSpacing: 8, + children: List.generate( + state.thenItems.length, + (index) => GestureDetector( + onTap: () async { + if (state.thenItems[index]['deviceId'] == + 'delay') { + final result = await DelayHelper + .showDelayPickerDialog(context, + state.thenItems[index]); if (result != null) { - context.read().add( - AddToThenContainer( - state.thenItems[index])); - } else if (![ - 'AC', - '1G', - '2G', - '3G', - 'WPS', - 'CPS', - "GW", - "NCPS", - 'WH', - ].contains(state.thenItems[index] - ['productType'])) { - context.read().add( - AddToThenContainer( - state.thenItems[index])); + context + .read() + .add(AddToThenContainer({ + ...state.thenItems[index], + 'imagePath': Assets.delay, + 'title': 'Delay', + })); } + return; + } + + if (state.thenItems[index]['type'] == + 'automation') { + final result = await showDialog( + context: context, + builder: (BuildContext context) => + AutomationDialog( + automationName: state + .thenItems[index]['name'] ?? + 'Automation', + automationId: state.thenItems[index] + ['deviceId'] ?? + '', + uniqueCustomId: + state.thenItems[index] + ['uniqueCustomId'], + ), + ); + + if (result != null) { + context + .read() + .add(AddToThenContainer({ + ...state.thenItems[index], + 'imagePath': Assets.automation, + 'title': state.thenItems[index] + ['name'] ?? + state.thenItems[index] + ['title'], + })); + } + return; + } + + final result = await DeviceDialogHelper + .showDeviceDialog( + context: context, + data: state.thenItems[index], + removeComparetors: true, + dialogType: 'THEN'); + + if (result != null) { + context.read().add( + AddToThenContainer( + state.thenItems[index])); + } else if (![ + 'AC', + '1G', + '2G', + '3G', + 'WPS', + 'CPS', + 'GW', + 'NCPS', + 'WH', + ].contains(state.thenItems[index] + ['productType'])) { + context.read().add( + AddToThenContainer( + state.thenItems[index])); + } + }, + child: DraggableCard( + imagePath: state.thenItems[index] + ['imagePath'] ?? + '', + title: + state.thenItems[index]['title'] ?? '', + deviceData: state.thenItems[index], + padding: const EdgeInsets.symmetric( + horizontal: 4, vertical: 8), + isFromThen: true, + isFromIf: false, + onRemove: () { + context.read().add( + RemoveDragCard( + index: index, + isFromThen: true, + key: state.thenItems[index] + ['uniqueCustomId'])); }, - child: DraggableCard( - imagePath: state.thenItems[index] - ['imagePath'] ?? - '', - title: state.thenItems[index] - ['title'] ?? - '', - deviceData: state.thenItems[index], - padding: const EdgeInsets.symmetric( - horizontal: 4, vertical: 8), - isFromThen: true, - isFromIf: false, - onRemove: () { - context.read().add( - RemoveDragCard( - index: index, - isFromThen: true, - key: state.thenItems[index] - ['uniqueCustomId'])); - }, - ), - ))), + ), + ))), ], ), ), @@ -168,7 +163,7 @@ class ThenContainer extends StatelessWidget { } if (mutableData['type'] == 'automation') { - int index = state.thenItems.indexWhere( + final index = state.thenItems.indexWhere( (item) => item['deviceId'] == mutableData['deviceId']); if (index != -1) { return; @@ -194,7 +189,7 @@ class ThenContainer extends StatelessWidget { } if (mutableData['type'] == 'tap_to_run' && state.isAutomation) { - int index = state.thenItems.indexWhere( + final index = state.thenItems.indexWhere( (item) => item['deviceId'] == mutableData['deviceId']); if (index != -1) { return; @@ -230,7 +225,7 @@ class ThenContainer extends StatelessWidget { context: context, data: mutableData, removeComparetors: true, - dialogType: "THEN"); + dialogType: 'THEN'); if (result != null) { context.read().add(AddToThenContainer(mutableData)); } else if (![ @@ -241,8 +236,8 @@ class ThenContainer extends StatelessWidget { 'WPS', 'GW', 'CPS', - "NCPS", - "WH", + 'NCPS', + 'WH', 'PC', ].contains(mutableData['productType'])) { context.read().add(AddToThenContainer(mutableData)); diff --git a/lib/pages/routines/widgets/value_display.dart b/lib/pages/routines/widgets/value_display.dart index 6a8bd949..b03720cf 100644 --- a/lib/pages/routines/widgets/value_display.dart +++ b/lib/pages/routines/widgets/value_display.dart @@ -19,7 +19,7 @@ class ValueDisplay extends StatelessWidget { return Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: BoxDecoration( - color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), + color: ColorsManager.primaryColorWithOpacity.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(10), ), child: Text( diff --git a/lib/pages/space_tree/bloc/space_tree_bloc.dart b/lib/pages/space_tree/bloc/space_tree_bloc.dart index e8c2e015..cd374eb5 100644 --- a/lib/pages/space_tree/bloc/space_tree_bloc.dart +++ b/lib/pages/space_tree/bloc/space_tree_bloc.dart @@ -30,7 +30,7 @@ class SpaceTreeBloc extends Bloc { } Timer _timer = Timer(const Duration(microseconds: 0), () {}); - void _onCommunityUpdate( + Future _onCommunityUpdate( OnCommunityUpdated event, Emitter emit, ) async { @@ -54,12 +54,13 @@ class SpaceTreeBloc extends Bloc { } } - _fetchSpaces(InitialEvent event, Emitter emit) async { + Future _fetchSpaces( + InitialEvent event, Emitter emit) async { emit(SpaceTreeLoadingState()); try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - PaginationModel paginationModel = await CommunitySpaceManagementApi() + final paginationModel = await CommunitySpaceManagementApi() .fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1); // List updatedCommunities = await Future.wait( @@ -89,10 +90,11 @@ class SpaceTreeBloc extends Bloc { } } - _fetchPaginationSpaces(PaginationEvent event, Emitter emit) async { + Future _fetchPaginationSpaces( + PaginationEvent event, Emitter emit) async { emit(state.copyWith(paginationIsLoading: true)); - PaginationModel paginationModel = event.paginationModel; - List communities = List.from(event.communities); + var paginationModel = event.paginationModel; + final communities = List.from(event.communities); try { if (paginationModel.hasNext && state.searchQuery.isEmpty) { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -114,7 +116,7 @@ class SpaceTreeBloc extends Bloc { paginationIsLoading: false)); } - void _onCommunityAdded( + Future _onCommunityAdded( OnCommunityAdded event, Emitter emit) async { final updatedCommunities = List.from(state.communityList); updatedCommunities.add(event.newCommunity); @@ -122,11 +124,11 @@ class SpaceTreeBloc extends Bloc { emit(state.copyWith(communitiesList: updatedCommunities)); } - _onCommunityExpanded( + Future _onCommunityExpanded( OnCommunityExpanded event, Emitter emit) async { try { - List updatedExpandedCommunityList = - List.from(state.expandedCommunities); + final updatedExpandedCommunityList = + List.from(state.expandedCommunities); if (updatedExpandedCommunityList.contains(event.communityId)) { updatedExpandedCommunityList.remove(event.communityId); @@ -142,9 +144,10 @@ class SpaceTreeBloc extends Bloc { } } - _onSpaceExpanded(OnSpaceExpanded event, Emitter emit) async { + Future _onSpaceExpanded( + OnSpaceExpanded event, Emitter emit) async { try { - List updatedExpandedSpacesList = List.from(state.expandedSpaces); + final updatedExpandedSpacesList = List.from(state.expandedSpaces); if (updatedExpandedSpacesList.contains(event.spaceId)) { updatedExpandedSpacesList.remove(event.spaceId); @@ -158,20 +161,21 @@ class SpaceTreeBloc extends Bloc { } } - _onCommunitySelected( + Future _onCommunitySelected( OnCommunitySelected event, Emitter emit) async { try { - List updatedSelectedCommunities = - List.from(state.selectedCommunities.toSet().toList()); - List updatedSelectedSpaces = - List.from(state.selectedSpaces.toSet().toList()); - List updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); - Map> communityAndSpaces = - Map.from(state.selectedCommunityAndSpaces); - List selectedSpacesInCommunity = + final updatedSelectedCommunities = + List.from(state.selectedCommunities.toSet().toList()); + final updatedSelectedSpaces = + List.from(state.selectedSpaces.toSet().toList()); + final updatedSoldChecks = + List.from(state.soldCheck.toSet().toList()); + final communityAndSpaces = + Map>.from(state.selectedCommunityAndSpaces); + final selectedSpacesInCommunity = communityAndSpaces[event.communityId] ?? []; - List childrenIds = _getAllChildIds(event.children); + final childrenIds = _getAllChildIds(event.children); if (!updatedSelectedCommunities.contains(event.communityId)) { // Select the community and all its children @@ -198,23 +202,25 @@ class SpaceTreeBloc extends Bloc { } } - _onSpaceSelected(OnSpaceSelected event, Emitter emit) async { + Future _onSpaceSelected( + OnSpaceSelected event, Emitter emit) async { try { - List updatedSelectedCommunities = - List.from(state.selectedCommunities.toSet().toList()); - List updatedSelectedSpaces = - List.from(state.selectedSpaces.toSet().toList()); - List updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); - Map> communityAndSpaces = - Map.from(state.selectedCommunityAndSpaces); + final updatedSelectedCommunities = + List.from(state.selectedCommunities.toSet().toList()); + final updatedSelectedSpaces = + List.from(state.selectedSpaces.toSet().toList()); + final updatedSoldChecks = + List.from(state.soldCheck.toSet().toList()); + final communityAndSpaces = + Map>.from(state.selectedCommunityAndSpaces); - List selectedSpacesInCommunity = + final selectedSpacesInCommunity = communityAndSpaces[event.communityModel.uuid] ?? []; - List childrenIds = _getAllChildIds(event.children); - bool isChildSelected = false; + final childrenIds = _getAllChildIds(event.children); + var isChildSelected = false; - for (String id in childrenIds) { + for (final id in childrenIds) { if (updatedSelectedSpaces.contains(id)) { isChildSelected = true; } @@ -232,9 +238,9 @@ class SpaceTreeBloc extends Bloc { selectedSpacesInCommunity.addAll(childrenIds); } - List spaces = + final spaces = _getThePathToChild(event.communityModel.uuid, event.spaceId); - for (String space in spaces) { + for (final space in spaces) { if (!updatedSelectedSpaces.contains(space) && !updatedSoldChecks.contains(space)) { updatedSoldChecks.add(space); @@ -258,7 +264,7 @@ class SpaceTreeBloc extends Bloc { } updatedSoldChecks.remove(event.spaceId); - List parents = + final parents = _getThePathToChild(event.communityModel.uuid, event.spaceId) .toSet() .toList(); @@ -268,7 +274,7 @@ class SpaceTreeBloc extends Bloc { updatedSelectedCommunities.remove(event.communityModel.uuid); } else { // Check if any parent has selected children - for (String space in parents) { + for (final space in parents) { if (!_noChildrenSelected( event.communityModel, space, updatedSelectedSpaces, parents)) { updatedSoldChecks.remove(space); @@ -295,17 +301,17 @@ class SpaceTreeBloc extends Bloc { } } - _noChildrenSelected(CommunityModel community, String spaceId, + bool _noChildrenSelected(CommunityModel community, String spaceId, List selectedSpaces, List parents) { if (selectedSpaces.contains(spaceId)) { return true; } - List children = _getAllChildSpaces(community.spaces); - for (var child in children) { + final children = _getAllChildSpaces(community.spaces); + for (final child in children) { if (spaceId == child.uuid) { - List ids = _getAllChildIds(child.children); - for (var id in ids) { + final ids = _getAllChildIds(child.children); + for (final id in ids) { if (selectedSpaces.contains(id)) { return true; } @@ -316,14 +322,15 @@ class SpaceTreeBloc extends Bloc { return false; } - _onSearch(SearchQueryEvent event, Emitter emit) async { + Future _onSearch( + SearchQueryEvent event, Emitter emit) async { try { const duration = Duration(seconds: 1); if (_timer.isActive) { _timer.cancel(); // clear timer } - _timer = - Timer(duration, () async => add(DebouncedSearchEvent(event.searchQuery))); + _timer = Timer( + duration, () async => add(DebouncedSearchEvent(event.searchQuery))); // List communities = List.from(state.communityList); // List filteredCommunity = []; @@ -347,12 +354,12 @@ class SpaceTreeBloc extends Bloc { } } - _onDebouncedSearch( + Future _onDebouncedSearch( DebouncedSearchEvent event, Emitter emit) async { emit(state.copyWith( isSearching: true, )); - PaginationModel paginationModel = const PaginationModel.emptyConstructor(); + var paginationModel = const PaginationModel.emptyConstructor(); try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -367,7 +374,8 @@ class SpaceTreeBloc extends Bloc { searchQuery: event.searchQuery)); } - _clearAllData(ClearAllData event, Emitter emit) async { + Future _clearAllData( + ClearAllData event, Emitter emit) async { try { emit(state.copyWith( communitiesList: [], @@ -385,7 +393,8 @@ class SpaceTreeBloc extends Bloc { } } - _clearCachedData(ClearCachedData event, Emitter emit) async { + Future _clearCachedData( + ClearCachedData event, Emitter emit) async { try { emit(state.copyWith( communitiesList: state.communityList, @@ -413,8 +422,8 @@ class SpaceTreeBloc extends Bloc { // } List _getAllChildIds(List spaces) { - List ids = []; - for (var child in spaces) { + final ids = []; + for (final child in spaces) { ids.add(child.uuid!); ids.addAll(_getAllChildIds(child.children)); } @@ -422,8 +431,8 @@ class SpaceTreeBloc extends Bloc { } List _getAllChildSpaces(List spaces) { - List children = []; - for (var child in spaces) { + final children = []; + for (final child in spaces) { children.add(child); children.addAll(_getAllChildSpaces(child.children)); } @@ -432,9 +441,9 @@ class SpaceTreeBloc extends Bloc { bool _anySpacesSelectedInCommunity(CommunityModel community, List selectedSpaces, List partialCheckedList) { - bool result = false; - List ids = _getAllChildIds(community.spaces); - for (var id in ids) { + var result = false; + final ids = _getAllChildIds(community.spaces); + for (final id in ids) { result = selectedSpaces.contains(id) || partialCheckedList.contains(id); if (result) { return result; @@ -444,11 +453,11 @@ class SpaceTreeBloc extends Bloc { } List _getThePathToChild(String communityId, String selectedSpaceId) { - List ids = []; - for (var community in state.communityList) { + var ids = []; + for (final community in state.communityList) { if (community.uuid == communityId) { - for (var space in community.spaces) { - List list = []; + for (final space in community.spaces) { + final list = []; list.add(space.uuid!); ids = _getAllParentsIds(space, selectedSpaceId, List.from(list)); if (ids.isNotEmpty) { @@ -462,7 +471,7 @@ class SpaceTreeBloc extends Bloc { List _getAllParentsIds( SpaceModel child, String spaceId, List listIds) { - List ids = listIds; + final ids = listIds; ids.add(child.uuid ?? ''); @@ -471,8 +480,8 @@ class SpaceTreeBloc extends Bloc { } if (child.children.isNotEmpty) { - for (var space in child.children) { - var result = _getAllParentsIds(space, spaceId, List.from(ids)); + for (final space in child.children) { + final result = _getAllParentsIds(space, spaceId, List.from(ids)); if (result.isNotEmpty) { return result; } @@ -483,7 +492,7 @@ class SpaceTreeBloc extends Bloc { return []; } - void _onSpaceTreeClearSelectionEvent( + Future _onSpaceTreeClearSelectionEvent( SpaceTreeClearSelectionEvent event, Emitter emit, ) async { @@ -496,7 +505,7 @@ class SpaceTreeBloc extends Bloc { ); } - void _onAnalyticsClearAllSpaceTreeSelectionsEvent( + Future _onAnalyticsClearAllSpaceTreeSelectionsEvent( AnalyticsClearAllSpaceTreeSelectionsEvent event, Emitter emit, ) async { diff --git a/lib/pages/space_tree/bloc/space_tree_state.dart b/lib/pages/space_tree/bloc/space_tree_state.dart index 595380fd..175a9da6 100644 --- a/lib/pages/space_tree/bloc/space_tree_state.dart +++ b/lib/pages/space_tree/bloc/space_tree_state.dart @@ -44,15 +44,16 @@ class SpaceTreeState extends Equatable { PaginationModel? paginationModel, bool? paginationIsLoading}) { return SpaceTreeState( - communityList: communitiesList ?? this.communityList, + communityList: communitiesList ?? communityList, filteredCommunity: filteredCommunity ?? this.filteredCommunity, expandedSpaces: expandedSpaces ?? this.expandedSpaces, - expandedCommunities: expandedCommunity ?? this.expandedCommunities, + expandedCommunities: expandedCommunity ?? expandedCommunities, selectedCommunities: selectedCommunities ?? this.selectedCommunities, selectedSpaces: selectedSpaces ?? this.selectedSpaces, soldCheck: soldCheck ?? this.soldCheck, isSearching: isSearching ?? this.isSearching, - selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces, + selectedCommunityAndSpaces: + selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces, searchQuery: searchQuery ?? this.searchQuery, paginationModel: paginationModel ?? this.paginationModel, paginationIsLoading: paginationIsLoading ?? this.paginationIsLoading); diff --git a/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart b/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart index e84851c5..624045e9 100644 --- a/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart +++ b/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart @@ -1,7 +1,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_state.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; class AddDeviceTypeBloc extends Bloc { AddDeviceTypeBloc() : super(AddDeviceInitial()) { diff --git a/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart b/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart index 254b78fd..51b1ea34 100644 --- a/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart +++ b/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart @@ -16,7 +16,7 @@ class UpdateProductCountEvent extends AddDeviceTypeEvent { final String productName; final ProductModel product; - UpdateProductCountEvent( + const UpdateProductCountEvent( {required this.productId, required this.count, required this.productName, @@ -26,7 +26,6 @@ class UpdateProductCountEvent extends AddDeviceTypeEvent { List get props => [productId, count]; } - class InitializeDevice extends AddDeviceTypeEvent { final List initialTags; final List addedProducts; diff --git a/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart b/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart index ede6afb9..e95bc74d 100644 --- a/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart +++ b/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart @@ -6,10 +6,10 @@ import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_dev import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_state.dart'; import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/add_device_type/widgets/scrollable_grid_view_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -24,8 +24,7 @@ class AddDeviceTypeWidget extends StatelessWidget { final String spaceName; final bool isCreate; final Function(List, List?)? onSave; - final List projectTags; - + final List projectTags; const AddDeviceTypeWidget( {super.key, diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index a4d6628e..4bda7999 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -1,20 +1,19 @@ import 'dart:async'; + import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_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/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/space_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/tag_body_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; @@ -57,10 +56,10 @@ class SpaceManagementBloc UpdateSpaceModelCache event, Emitter emit) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - List allSpaceModels = []; + final allSpaceModels = []; - bool hasNext = true; - int page = 1; + var hasNext = true; + var page = 1; while (hasNext) { final spaceModels = await _spaceModelApi.listSpaceModels( @@ -85,7 +84,7 @@ class SpaceManagementBloc allTags: _cachedTags ?? [])); } - void _deleteSpaceModelFromCache(DeleteSpaceModelFromCache event, + Future _deleteSpaceModelFromCache(DeleteSpaceModelFromCache event, Emitter emit) async { if (_cachedSpaceModels != null) { _cachedSpaceModels = _cachedSpaceModels! @@ -121,10 +120,10 @@ class SpaceManagementBloc final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - List allSpaceModels = []; + final allSpaceModels = []; - bool hasNext = true; - int page = 1; + var hasNext = true; + var page = 1; while (hasNext) { final spaceModels = await _spaceModelApi.listSpaceModels( @@ -159,7 +158,7 @@ class SpaceManagementBloc } } - void _onUpdateCommunity( + Future _onUpdateCommunity( UpdateCommunityEvent event, Emitter emit, ) async { @@ -175,7 +174,7 @@ class SpaceManagementBloc if (previousState is SpaceManagementLoaded) { final updatedCommunities = List.from(previousState.communities); - for (var community in updatedCommunities) { + for (final community in updatedCommunities) { if (community.uuid == event.communityUuid) { community.name = event.name; _spaceTreeBloc.add(OnCommunityAdded(community)); @@ -184,7 +183,7 @@ class SpaceManagementBloc } } - var prevSpaceModels = await fetchSpaceModels(); + final prevSpaceModels = await fetchSpaceModels(); emit(SpaceManagementLoaded( communities: updatedCommunities, @@ -201,14 +200,14 @@ class SpaceManagementBloc } } - void _onloadProducts() async { + Future _onloadProducts() async { if (_cachedProducts == null) { final products = await _productApi.fetchProducts(); _cachedProducts = products; } } - void _onFetchProducts( + Future _onFetchProducts( FetchProductsEvent event, Emitter emit, ) async { @@ -223,7 +222,7 @@ class SpaceManagementBloc String communityUuid) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - return await _api.getSpaceHierarchy(communityUuid, projectUuid); + return _api.getSpaceHierarchy(communityUuid, projectUuid); } Future _onNewCommunity( @@ -238,7 +237,7 @@ class SpaceManagementBloc return; } - var prevSpaceModels = await fetchSpaceModels(); + final prevSpaceModels = await fetchSpaceModels(); emit(BlankState( communities: event.communities, @@ -255,15 +254,15 @@ class SpaceManagementBloc try { final previousState = state; final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - var spaceBloc = event.context.read(); - var spaceTreeState = event.context.read().state; + final spaceBloc = event.context.read(); + final spaceTreeState = event.context.read().state; - List communities = + final communities = await _waitForCommunityList(spaceBloc, spaceTreeState); await fetchSpaceModels(); // await fetchTags(); - var prevSpaceModels = await fetchSpaceModels(); + final prevSpaceModels = await fetchSpaceModels(); if (previousState is SpaceManagementLoaded || previousState is BlankState) { @@ -287,18 +286,17 @@ class SpaceManagementBloc } } - void _onLoadCommunityAndSpaces( + Future _onLoadCommunityAndSpaces( LoadCommunityAndSpacesEvent event, Emitter emit, ) async { - var spaceTreeState = event.context.read().state; - var spaceBloc = event.context.read(); + final spaceTreeState = event.context.read().state; + final spaceBloc = event.context.read(); _onloadProducts(); await fetchTags(); // Wait until `communityList` is loaded - List communities = - await _waitForCommunityList(spaceBloc, spaceTreeState); + final communities = await _waitForCommunityList(spaceBloc, spaceTreeState); // Fetch space models after communities are available final prevSpaceModels = await fetchSpaceModels(); @@ -344,7 +342,7 @@ class SpaceManagementBloc } } - void _onCommunityDelete( + Future _onCommunityDelete( DeleteCommunityEvent event, Emitter emit, ) async { @@ -365,7 +363,7 @@ class SpaceManagementBloc } } - void _onCreateCommunity( + Future _onCreateCommunity( CreateCommunityEvent event, Emitter emit, ) async { @@ -375,9 +373,9 @@ class SpaceManagementBloc try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; await fetchTags(); - CommunityModel? newCommunity = await _api.createCommunity( + final newCommunity = await _api.createCommunity( event.name, event.description, projectUuid); - var prevSpaceModels = await fetchSpaceModels(); + final prevSpaceModels = await fetchSpaceModels(); if (newCommunity != null) { if (previousState is SpaceManagementLoaded || @@ -405,7 +403,7 @@ class SpaceManagementBloc } } - void _onSelectCommunity( + Future _onSelectCommunity( SelectCommunityEvent event, Emitter emit, ) async { @@ -431,7 +429,7 @@ class SpaceManagementBloc ); } - void _handleCommunitySpaceStateUpdate({ + Future _handleCommunitySpaceStateUpdate({ required Emitter emit, CommunityModel? selectedCommunity, SpaceModel? selectedSpace, @@ -464,7 +462,7 @@ class SpaceManagementBloc } } - void _onSaveSpaces( + Future _onSaveSpaces( SaveSpacesEvent event, Emitter emit, ) async { @@ -494,9 +492,9 @@ class SpaceManagementBloc event.spaces.removeWhere( (space) => space.status == SpaceStatus.deleted, ); - event.spaces.forEach( - (space) => space.status = SpaceStatus.unchanged, - ); + for (final space in event.spaces) { + space.status = SpaceStatus.unchanged; + } } } catch (e) { // emit(SpaceManagementError('Error saving spaces: $e')); @@ -515,7 +513,7 @@ class SpaceManagementBloc Emitter emit, ) async { try { - var prevSpaceModels = await fetchSpaceModels(); + final prevSpaceModels = await fetchSpaceModels(); await fetchTags(); @@ -523,7 +521,7 @@ class SpaceManagementBloc ? spaceTreeState.filteredCommunity : spaceTreeState.communityList; - for (var community in communities) { + for (final community in communities) { if (community.uuid == communityUuid) { community.spaces = allSpaces; _spaceTreeBloc.add(InitialEvent()); @@ -540,7 +538,7 @@ class SpaceManagementBloc } } emit(previousState); - } catch (e, stackTrace) { + } catch (e) { emit(previousState); // rethrow; } @@ -577,36 +575,36 @@ class SpaceManagementBloc space.status == SpaceStatus.deleted && (space.parent == null || space.parent?.status != SpaceStatus.deleted)); - for (var parent in parentsToDelete) { + for (final parent in parentsToDelete) { try { if (parent.uuid != null) { await _api.deleteSpace(communityUuid, parent.uuid!, projectUuid); } } catch (e) {} } - orderedSpaces.removeWhere((space) => parentsToDelete.contains(space)); + orderedSpaces.removeWhere(parentsToDelete.contains); - for (var space in orderedSpaces) { + for (final space in orderedSpaces) { try { if (space.uuid != null && space.uuid!.isNotEmpty) { - List tagUpdates = []; + var tagUpdates = []; - List matchedSpaces = + final matchedSpaces = findMatchingSpaces(selectedCommunity.spaces, space.uuid!); if (matchedSpaces.isEmpty) continue; final prevSpace = matchedSpaces.elementAtOrNull(0); - final List subspaceUpdates = []; - final List? prevSubspaces = prevSpace?.subspaces; - final List? newSubspaces = space.subspaces; + final subspaceUpdates = []; + final prevSubspaces = prevSpace?.subspaces; + final newSubspaces = space.subspaces; tagUpdates = processTagUpdates(prevSpace?.tags, space.tags); if (prevSubspaces != null || newSubspaces != null) { if (prevSubspaces != null && newSubspaces != null) { - for (var prevSubspace in prevSubspaces) { + for (final prevSubspace in prevSubspaces) { final existsInNew = newSubspaces .any((subspace) => subspace.uuid == prevSubspace.uuid); if (!existsInNew) { @@ -616,7 +614,7 @@ class SpaceManagementBloc } } } else if (prevSubspaces != null && newSubspaces == null) { - for (var prevSubspace in prevSubspaces) { + for (final prevSubspace in prevSubspaces) { subspaceUpdates.add(UpdateSubspaceTemplateModel( action: custom_action.Action.delete, uuid: prevSubspace.uuid)); @@ -624,13 +622,13 @@ class SpaceManagementBloc } if (newSubspaces != null) { - for (var newSubspace in newSubspaces) { + for (final newSubspace in newSubspaces) { // Tag without UUID - if ((newSubspace.uuid == null || newSubspace.uuid!.isEmpty)) { - final List tagUpdates = []; + if (newSubspace.uuid == null || newSubspace.uuid!.isEmpty) { + final tagUpdates = []; if (newSubspace.tags != null) { - for (var tag in newSubspace.tags!) { + for (final tag in newSubspace.tags!) { tagUpdates.add(TagModelUpdate( action: custom_action.Action.add, newTagUuid: tag.uuid == '' ? null : tag.uuid, @@ -648,14 +646,14 @@ class SpaceManagementBloc if (prevSubspaces != null && newSubspaces != null) { final newSubspaceMap = { - for (var subspace in newSubspaces) subspace.uuid: subspace + for (final subspace in newSubspaces) subspace.uuid: subspace }; - for (var prevSubspace in prevSubspaces) { + for (final prevSubspace in prevSubspaces) { final newSubspace = newSubspaceMap[prevSubspace.uuid]; if (newSubspace != null) { - final List tagSubspaceUpdates = + final tagSubspaceUpdates = processTagUpdates(prevSubspace.tags, newSubspace.tags); subspaceUpdates.add(UpdateSubspaceTemplateModel( action: custom_action.Action.update, @@ -669,7 +667,7 @@ class SpaceManagementBloc final response = await _api.updateSpace( communityId: communityUuid, - spaceId: space.uuid!, + spaceId: space.uuid, name: space.name, parentId: space.parent?.uuid, isPrivate: space.isPrivate, @@ -683,7 +681,7 @@ class SpaceManagementBloc projectId: projectUuid); } else { // Call create if the space does not have a UUID - List tagBodyModels = space.tags != null + var tagBodyModels = space.tags != null ? space.tags!.map((tag) => tag.toCreateTagBodyModel()).toList() : []; @@ -731,17 +729,17 @@ class SpaceManagementBloc void visit(SpaceModel space) { if (!result.contains(space)) { result.add(space); - for (var child in spaces.where((s) => s.parent == space)) { + for (final child in spaces.where((s) => s.parent == space)) { visit(child); } } } - for (var space in topLevelSpaces) { + for (final space in topLevelSpaces) { visit(space); } - for (var space in spaces) { + for (final space in spaces) { if (!result.contains(space)) { result.add(space); } @@ -749,7 +747,7 @@ class SpaceManagementBloc return result.toList(); // Convert back to a list } - void _onLoadSpaceModel( + Future _onLoadSpaceModel( SpaceModelLoadEvent event, Emitter emit) async { emit(SpaceManagementLoading()); @@ -760,9 +758,9 @@ class SpaceManagementBloc ? spaceTreeState.filteredCommunity : spaceTreeState.communityList; - List communities = filteredCommunities; + final communities = filteredCommunities; - var prevSpaceModels = await fetchSpaceModels(); + final prevSpaceModels = await fetchSpaceModels(); emit(SpaceModelLoaded( communities: communities, @@ -778,11 +776,11 @@ class SpaceManagementBloc List? prevTags, List? newTags, ) { - final List tagUpdates = []; + final tagUpdates = []; final processedTags = {}; if (prevTags == null && newTags != null) { - for (var newTag in newTags) { + for (final newTag in newTags) { tagUpdates.add(TagModelUpdate( action: custom_action.Action.add, tag: newTag.tag, @@ -796,7 +794,7 @@ class SpaceManagementBloc if (newTags != null || prevTags != null) { // Case 1: Tags deleted if (prevTags != null && newTags != null) { - for (var prevTag in prevTags) { + for (final prevTag in prevTags) { final existsInNew = newTags.any((newTag) => newTag.uuid == prevTag.uuid); if (!existsInNew) { @@ -805,7 +803,7 @@ class SpaceManagementBloc } } } else if (prevTags != null && newTags == null) { - for (var prevTag in prevTags) { + for (final prevTag in prevTags) { tagUpdates.add(TagModelUpdate( action: custom_action.Action.delete, uuid: prevTag.uuid)); } @@ -815,7 +813,7 @@ class SpaceManagementBloc if (newTags != null) { final prevTagUuids = prevTags?.map((t) => t.uuid).toSet() ?? {}; - for (var newTag in newTags) { + for (final newTag in newTags) { // Tag without UUID if ((newTag.uuid == null || !prevTagUuids.contains(newTag.uuid)) && !processedTags.contains(newTag.tag)) { @@ -831,9 +829,9 @@ class SpaceManagementBloc // Case 3: Tags updated if (prevTags != null && newTags != null) { - final newTagMap = {for (var tag in newTags) tag.uuid: tag}; + final newTagMap = {for (final tag in newTags) tag.uuid: tag}; - for (var prevTag in prevTags) { + for (final prevTag in prevTags) { final newTag = newTagMap[prevTag.uuid]; if (newTag != null) { tagUpdates.add(TagModelUpdate( @@ -852,9 +850,9 @@ class SpaceManagementBloc List findMatchingSpaces( List spaces, String targetUuid) { - List matched = []; + final matched = []; - for (var space in spaces) { + for (final space in spaces) { if (space.uuid == targetUuid) { matched.add(space); } diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart index 8a9db432..b6c90304 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart @@ -166,10 +166,10 @@ class SpaceModelLoadEvent extends SpaceManagementEvent { class UpdateSpaceModelCache extends SpaceManagementEvent { final SpaceTemplateModel updatedModel; - UpdateSpaceModelCache(this.updatedModel); + const UpdateSpaceModelCache(this.updatedModel); } class DeleteSpaceModelFromCache extends SpaceManagementEvent { final String deletedUuid; - DeleteSpaceModelFromCache(this.deletedUuid); + const DeleteSpaceModelFromCache(this.deletedUuid); } diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart index 3efa7c00..361be6c9 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart @@ -40,7 +40,10 @@ class BlankState extends SpaceManagementState { final List allTags; BlankState( - {required this.communities, required this.products, this.spaceModels, required this.allTags}); + {required this.communities, + required this.products, + this.spaceModels, + required this.allTags}); } class SpaceCreationSuccess extends SpaceManagementState { diff --git a/lib/pages/spaces_management/all_spaces/model/base_tag.dart b/lib/pages/spaces_management/all_spaces/model/base_tag.dart index 57f223f4..44babc9e 100644 --- a/lib/pages/spaces_management/all_spaces/model/base_tag.dart +++ b/lib/pages/spaces_management/all_spaces/model/base_tag.dart @@ -16,7 +16,7 @@ abstract class BaseTag { this.location, }) : internalId = internalId ?? const Uuid().v4(); - Map toJson(); + Map toJson(); BaseTag copyWith({ String? tag, ProductModel? product, diff --git a/lib/pages/spaces_management/all_spaces/model/community_model.dart b/lib/pages/spaces_management/all_spaces/model/community_model.dart index d1e27095..23388375 100644 --- a/lib/pages/spaces_management/all_spaces/model/community_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/community_model.dart @@ -27,9 +27,12 @@ class CommunityModel { updatedAt: DateTime.parse(json['updatedAt'] ?? ''), name: json['name'] ?? '', description: json['description'] ?? '', - region: json['region'] != null ? RegionModel.fromJson(json['region']) : null, + region: + json['region'] != null ? RegionModel.fromJson(json['region']) : null, spaces: json['spaces'] != null - ? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList() + ? (json['spaces'] as List) + .map((space) => SpaceModel.fromJson(space)) + .toList() : [], ); } @@ -42,7 +45,9 @@ class CommunityModel { 'name': name, 'description': description, 'region': region?.toJson(), - 'spaces': spaces.map((space) => space.toMap()).toList(), // Convert spaces to Map + 'spaces': spaces + .map((space) => space.toMap()) + .toList(), // Convert spaces to Map }; } } diff --git a/lib/pages/spaces_management/all_spaces/model/product_model.dart b/lib/pages/spaces_management/all_spaces/model/product_model.dart index 8f905032..9ed528ed 100644 --- a/lib/pages/spaces_management/all_spaces/model/product_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/product_model.dart @@ -1,7 +1,6 @@ +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; -import 'selected_product_model.dart'; - class ProductModel { final String uuid; final String catName; diff --git a/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart b/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart index 91314e42..17fd429c 100644 --- a/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart @@ -6,7 +6,11 @@ class SelectedProduct { final String productName; final ProductModel? product; - SelectedProduct({required this.productId, required this.count, required this.productName, this.product}); + SelectedProduct( + {required this.productId, + required this.count, + required this.productName, + this.product}); Map toJson() { return { @@ -16,7 +20,7 @@ class SelectedProduct { }; } - @override + @override String toString() { return 'SelectedProduct(productId: $productId, count: $count)'; } diff --git a/lib/pages/spaces_management/all_spaces/model/space_model.dart b/lib/pages/spaces_management/all_spaces/model/space_model.dart index f9c59d24..50cdb36c 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_model.dart @@ -56,7 +56,7 @@ class SpaceModel { {String? parentInternalId}) { final String internalId = json['internalId'] ?? const Uuid().v4(); - final List children = json['children'] != null + final children = json['children'] != null ? (json['children'] as List).map((childJson) { return SpaceModel.fromJson( childJson, @@ -73,8 +73,8 @@ class SpaceModel { isPrivate: json['isPrivate'] ?? false, invitationCode: json['invitationCode'], subspaces: (json['subspaces'] as List?) - ?.where((e) => e is Map) // Validate type - .map((e) => SubspaceModel.fromJson(e as Map)) + ?.whereType>() // Validate type + .map(SubspaceModel.fromJson) .toList() ?? [], parent: parentInternalId != null @@ -102,8 +102,8 @@ class SpaceModel { ? SpaceTemplateModel.fromJson(json['spaceModel']) : null, tags: (json['productAllocations'] as List?) - ?.where((item) => item is Map) // Validate type - .map((item) => Tag.fromJson(item as Map)) + ?.whereType>() // Validate type + .map(Tag.fromJson) .toList() ?? [], ); @@ -150,7 +150,7 @@ class SpaceModel { extension SpaceExtensions on SpaceModel { List listAllTagValues() { - final List tagValues = []; + final tagValues = []; if (tags != null) { tagValues.addAll( @@ -174,10 +174,10 @@ extension SpaceExtensions on SpaceModel { bool isNoChangesSubmited(String name, icon, SpaceTemplateModel? spaceModel, List? subspaces, List? tags) { - return (name == this.name && + return name == this.name && icon == this.icon && spaceModel == this.spaceModel && subspaces == this.subspaces && - tags == this.tags); + tags == this.tags; } } diff --git a/lib/pages/spaces_management/all_spaces/model/space_response_model.dart b/lib/pages/spaces_management/all_spaces/model/space_response_model.dart index 34df3d30..d698b48b 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_response_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_response_model.dart @@ -1,5 +1,4 @@ - -import 'space_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; class SpacesResponse { final List data; diff --git a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart index fd3e780e..9c1defa8 100644 --- a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart @@ -1,9 +1,8 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart'; import 'package:uuid/uuid.dart'; -import 'tag.dart'; - class SubspaceModel { final String? uuid; String subspaceName; diff --git a/lib/pages/spaces_management/all_spaces/model/tag.dart b/lib/pages/spaces_management/all_spaces/model/tag.dart index a7ec1e15..f17c3d86 100644 --- a/lib/pages/spaces_management/all_spaces/model/tag.dart +++ b/lib/pages/spaces_management/all_spaces/model/tag.dart @@ -6,18 +6,12 @@ import 'package:uuid/uuid.dart'; class Tag extends BaseTag { Tag({ - String? uuid, - required String? tag, - ProductModel? product, - String? internalId, - String? location, - }) : super( - uuid: uuid, - tag: tag, - product: product, - internalId: internalId, - location: location, - ); + super.uuid, + required super.tag, + super.product, + super.internalId, + super.location, + }); factory Tag.fromJson(Map json) { final String internalId = json['internalId'] ?? const Uuid().v4(); @@ -50,6 +44,7 @@ class Tag extends BaseTag { ); } + @override Map toJson() { return { if (uuid != null) 'uuid': uuid, diff --git a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart index 291e6235..9094ebc0 100644 --- a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_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_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/structure_selector/view/center_body_widget.dart'; import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; @@ -47,7 +47,7 @@ class SpaceManagementPageState extends State { style: ResponsiveTextTheme.of(context).deviceManagementTitle, ), enableMenuSidebar: false, - centerBody: CenterBodyWidget(), + centerBody: const CenterBodyWidget(), rightBody: const NavigateHomeGridView(), scaffoldBody: BlocBuilder( builder: (context, state) { diff --git a/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart index 0e9f4bd1..71bda2ca 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart @@ -32,8 +32,9 @@ class _AddDeviceWidgetState extends State { void initState() { super.initState(); _scrollController = ScrollController(); - productCounts = - widget.initialSelectedProducts != null ? List.from(widget.initialSelectedProducts!) : []; + productCounts = widget.initialSelectedProducts != null + ? List.from(widget.initialSelectedProducts!) + : []; } @override @@ -96,10 +97,12 @@ class _AddDeviceWidgetState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - _buildActionButton('Cancel', ColorsManager.boxColor, ColorsManager.blackColor, () { + _buildActionButton( + 'Cancel', ColorsManager.boxColor, ColorsManager.blackColor, () { Navigator.of(context).pop(); }), - _buildActionButton('Continue', ColorsManager.secondaryColor, ColorsManager.whiteColors, () { + _buildActionButton('Continue', ColorsManager.secondaryColor, + ColorsManager.whiteColors, () { Navigator.of(context).pop(); if (widget.onProductsSelected != null) { widget.onProductsSelected!(productCounts); @@ -114,7 +117,11 @@ class _AddDeviceWidgetState extends State { Widget _buildDeviceTypeTile(ProductModel product, Size size) { final selectedProduct = productCounts.firstWhere( (p) => p.productId == product.uuid, - orElse: () => SelectedProduct(productId: product.uuid, count: 0, productName: product.catName, product: product), + orElse: () => SelectedProduct( + productId: product.uuid, + count: 0, + productName: product.catName, + product: product), ); return SizedBox( @@ -143,13 +150,17 @@ class _AddDeviceWidgetState extends State { setState(() { if (newCount > 0) { if (!productCounts.contains(selectedProduct)) { - productCounts - .add(SelectedProduct(productId: product.uuid, count: newCount, productName: product.catName, product: product)); + productCounts.add(SelectedProduct( + productId: product.uuid, + count: newCount, + productName: product.catName, + product: product)); } else { selectedProduct.count = newCount; } } else { - productCounts.removeWhere((p) => p.productId == product.uuid); + productCounts + .removeWhere((p) => p.productId == product.uuid); } if (widget.onProductsSelected != null) { @@ -192,7 +203,8 @@ class _AddDeviceWidgetState extends State { height: size.width > 800 ? 35 : 25, child: Text( product.name ?? '', - style: context.textTheme.bodySmall?.copyWith(color: ColorsManager.blackColor), + style: context.textTheme.bodySmall + ?.copyWith(color: ColorsManager.blackColor), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, diff --git a/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart index 66f1a026..18dec3a1 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart @@ -9,7 +9,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; class BlankCommunityWidget extends StatefulWidget { final List communities; - BlankCommunityWidget({required this.communities}); + const BlankCommunityWidget({super.key, required this.communities}); @override _BlankCommunityWidgetState createState() => _BlankCommunityWidgetState(); @@ -19,7 +19,7 @@ class _BlankCommunityWidgetState extends State { @override Widget build(BuildContext context) { return Expanded( - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, // Parent container with white background child: GridView.builder( diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart index f5188c1e..49a19681 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart @@ -36,7 +36,7 @@ class CommunityStructureHeaderActionButtons extends StatelessWidget { children: [ if (isSave) CommunityStructureHeaderButton( - label: "Save", + label: 'Save', icon: const Icon(Icons.save, size: 18, color: ColorsManager.spaceColor), onPressed: onSave, @@ -44,19 +44,19 @@ class CommunityStructureHeaderActionButtons extends StatelessWidget { ), if (canShowActions) ...[ CommunityStructureHeaderButton( - label: "Edit", + label: 'Edit', svgAsset: Assets.editSpace, onPressed: onEdit, theme: theme, ), CommunityStructureHeaderButton( - label: "Duplicate", + label: 'Duplicate', svgAsset: Assets.duplicate, onPressed: onDuplicate, theme: theme, ), CommunityStructureHeaderButton( - label: "Delete", + label: 'Delete', svgAsset: Assets.spaceDelete, onPressed: onDelete, theme: theme, diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart index 6bc35cca..9a45d76a 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart @@ -14,7 +14,7 @@ class CommunityStructureHeader extends StatefulWidget { final TextEditingController nameController; final VoidCallback onSave; final VoidCallback onDelete; - final VoidCallback onEdit; + final VoidCallback onEdit; final VoidCallback onDuplicate; final VoidCallback onEditName; diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index 4f68fb7e..1e882d8a 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -3,24 +3,23 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - // Syncrow project imports import 'package:syncrow_web/pages/common/buttons/add_space_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/spaces_management/all_spaces/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_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/selected_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/community_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_card_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_container_widget.dart'; @@ -41,7 +40,8 @@ class CommunityStructureArea extends StatefulWidget { final List projectTags; CommunityStructureArea( - {this.selectedCommunity, + {super.key, + this.selectedCommunity, this.selectedSpace, required this.communities, this.products, @@ -120,7 +120,7 @@ class _CommunityStructureAreaState extends State { ); } - Size screenSize = MediaQuery.of(context).size; + final screenSize = MediaQuery.of(context).size; return Expanded( child: GestureDetector( onTap: () { @@ -173,16 +173,16 @@ class _CommunityStructureAreaState extends State { children: [ InteractiveViewer( transformationController: _transformationController, - boundaryMargin: EdgeInsets.all(500), + boundaryMargin: const EdgeInsets.all(500), minScale: 0.5, maxScale: 3.0, constrained: false, - child: Container( + child: SizedBox( width: canvasWidth, height: canvasHeight, child: Stack( children: [ - for (var connection in connections) + for (final connection in connections) Opacity( opacity: ConnectionHelper.isHighlightedConnection( connection, widget.selectedSpace) @@ -191,7 +191,7 @@ class _CommunityStructureAreaState extends State { child: CustomPaint( painter: CurvedLinePainter([connection])), ), - for (var entry in spaces.asMap().entries) + for (final entry in spaces.asMap().entries) if (entry.value.status != SpaceStatus.deleted && entry.value.status != SpaceStatus.parentDeleted) Positioned( @@ -214,7 +214,7 @@ class _CommunityStructureAreaState extends State { _updateNodePosition(entry.value, newPosition); }, buildSpaceContainer: (int index) { - final bool isHighlighted = + final isHighlighted = SpaceHelper.isHighlightedSpace( spaces[index], widget.selectedSpace); @@ -267,9 +267,9 @@ class _CommunityStructureAreaState extends State { canvasHeight += 200; } if (node.position.dx <= 200) { - double shiftAmount = 200; + const double shiftAmount = 200; canvasWidth += shiftAmount; - for (var n in spaces) { + for (final n in spaces) { n.position = Offset(n.position.dx + shiftAmount, n.position.dy); } } @@ -280,7 +280,7 @@ class _CommunityStructureAreaState extends State { } void _adjustCanvasSizeForSpaces() { - for (var space in spaces) { + for (final space in spaces) { if (space.position.dx >= canvasWidth - 200) { canvasWidth = space.position.dx + 200; } @@ -324,7 +324,7 @@ class _CommunityStructureAreaState extends State { position ?? ConnectionHelper.getCenterPosition(screenSize); } - SpaceModel newSpace = SpaceModel( + final newSpace = SpaceModel( name: name, icon: icon, position: newPosition, @@ -336,7 +336,7 @@ class _CommunityStructureAreaState extends State { tags: tags); if (parentIndex != null) { - SpaceModel parentSpace = spaces[parentIndex]; + final parentSpace = spaces[parentIndex]; parentSpace.internalId = spaces[parentIndex].internalId; newSpace.parent = parentSpace; final newConnection = Connection( @@ -406,7 +406,7 @@ class _CommunityStructureAreaState extends State { SpaceStatus.modified; // Mark as modified } - for (var space in spaces) { + for (final space in spaces) { if (space.internalId == widget.selectedSpace?.internalId) { space.status = SpaceStatus.modified; space.subspaces = subspaces; @@ -430,8 +430,8 @@ class _CommunityStructureAreaState extends State { } List flattenSpaces(List spaces) { - List result = []; - Map idToSpace = {}; + final result = []; + final idToSpace = {}; void flatten(SpaceModel space) { if (space.status == SpaceStatus.deleted || @@ -441,16 +441,16 @@ class _CommunityStructureAreaState extends State { result.add(space); idToSpace[space.internalId] = space; - for (var child in space.children) { + for (final child in space.children) { flatten(child); } } - for (var space in spaces) { + for (final space in spaces) { flatten(space); } - for (var space in result) { + for (final space in result) { if (space.parent != null) { space.parent = idToSpace[space.parent!.internalId]; } @@ -460,12 +460,12 @@ class _CommunityStructureAreaState extends State { } List createConnections(List spaces) { - List connections = []; + final connections = []; void addConnections(SpaceModel parent, String direction) { if (parent.status == SpaceStatus.deleted) return; - for (var child in parent.children) { + for (final child in parent.children) { if (child.status == SpaceStatus.deleted) continue; connections.add( @@ -480,8 +480,8 @@ class _CommunityStructureAreaState extends State { } } - for (var space in spaces) { - addConnections(space, "down"); + for (final space in spaces) { + addConnections(space, 'down'); } return connections; @@ -492,7 +492,7 @@ class _CommunityStructureAreaState extends State { return; } - List spacesToSave = spaces.where((space) { + final spacesToSave = spaces.where((space) { return space.status == SpaceStatus.newSpace || space.status == SpaceStatus.modified || space.status == SpaceStatus.deleted; @@ -502,7 +502,7 @@ class _CommunityStructureAreaState extends State { return; } - String communityUuid = widget.selectedCommunity!.uuid; + final communityUuid = widget.selectedCommunity!.uuid; context.read().add(SaveSpacesEvent( context, spaces: spacesToSave, @@ -513,7 +513,7 @@ class _CommunityStructureAreaState extends State { void _onDelete() { if (widget.selectedSpace != null) { setState(() { - for (var space in spaces) { + for (final space in spaces) { if (space.internalId == widget.selectedSpace?.internalId) { space.status = SpaceStatus.deleted; _markChildrenAsDeleted(space); @@ -526,7 +526,7 @@ class _CommunityStructureAreaState extends State { } void _markChildrenAsDeleted(SpaceModel parent) { - for (var child in parent.children) { + for (final child in parent.children) { child.status = SpaceStatus.parentDeleted; _markChildrenAsDeleted(child); @@ -543,11 +543,11 @@ class _CommunityStructureAreaState extends State { } void _moveToSpace(SpaceModel space) { - final double viewportWidth = MediaQuery.of(context).size.width; - final double viewportHeight = MediaQuery.of(context).size.height; + final viewportWidth = MediaQuery.of(context).size.width; + final viewportHeight = MediaQuery.of(context).size.height; - final double dx = -space.position.dx + (viewportWidth / 2) - 400; - final double dy = -space.position.dy + (viewportHeight / 2) - 300; + final dx = -space.position.dx + (viewportWidth / 2) - 400; + final dy = -space.position.dy + (viewportHeight / 2) - 300; _transformationController.value = Matrix4.identity() ..translate(dx, dy) @@ -578,10 +578,10 @@ class _CommunityStructureAreaState extends State { return Offset(parent.position.dx, parent.position.dy + verticalGap); } else { // More children → arrange them spaced horizontally - double totalWidth = (parent.children.length) * (nodeWidth + 60); - double startX = parent.position.dx - (totalWidth / 2); + final totalWidth = (parent.children.length) * (nodeWidth + 60); + final startX = parent.position.dx - (totalWidth / 2); - double childX = startX + (parent.children.length * (nodeWidth + 60)); + final childX = startX + (parent.children.length * (nodeWidth + 60)); return Offset(childX, parent.position.dy + verticalGap); } } @@ -599,15 +599,15 @@ class _CommunityStructureAreaState extends State { double calculateSubtreeWidth(SpaceModel node) { if (node.children.isEmpty) return nodeWidth; double totalWidth = 0; - for (var child in node.children) { + for (final child in node.children) { totalWidth += calculateSubtreeWidth(child) + horizontalGap; } return totalWidth - horizontalGap; } void layoutSubtree(SpaceModel node, double startX, double y) { - double subtreeWidth = calculateSubtreeWidth(node); - double centerX = startX + subtreeWidth / 2 - nodeWidth / 2; + final subtreeWidth = calculateSubtreeWidth(node); + final centerX = startX + subtreeWidth / 2 - nodeWidth / 2; node.position = Offset(centerX, y); canvasRightEdge = max(canvasRightEdge, centerX + nodeWidth); @@ -617,9 +617,9 @@ class _CommunityStructureAreaState extends State { final child = node.children.first; layoutSubtree(child, centerX, y + verticalGap); } else { - double childX = startX; - for (var child in node.children) { - double childWidth = calculateSubtreeWidth(child); + var childX = startX; + for (final child in node.children) { + final childWidth = calculateSubtreeWidth(child); layoutSubtree(child, childX, y + verticalGap); childX += childWidth + horizontalGap; } @@ -627,7 +627,7 @@ class _CommunityStructureAreaState extends State { } // ⚡ New: layout each root separately - final List roots = spaces + final roots = spaces .where((s) => s.parent == null && s.status != SpaceStatus.deleted && @@ -635,11 +635,11 @@ class _CommunityStructureAreaState extends State { .toList(); double currentX = 100; // start some margin from left - double currentY = 100; // top margin + const double currentY = 100; // top margin - for (var root in roots) { + for (final root in roots) { layoutSubtree(root, currentX, currentY); - double rootWidth = calculateSubtreeWidth(root); + final rootWidth = calculateSubtreeWidth(root); currentX += rootWidth + rootGap; } @@ -659,7 +659,7 @@ class _CommunityStructureAreaState extends State { return AlertDialog( backgroundColor: ColorsManager.whiteColors, title: Text( - "Duplicate Space", + 'Duplicate Space', textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -671,11 +671,11 @@ class _CommunityStructureAreaState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text("Are you sure you want to duplicate?", + Text('Are you sure you want to duplicate?', textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineSmall), const SizedBox(height: 15), - Text("All the child spaces will be duplicated.", + Text('All the child spaces will be duplicated.', textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -693,7 +693,7 @@ class _CommunityStructureAreaState extends State { onPressed: () { Navigator.of(context).pop(); }, - label: "Cancel", + label: 'Cancel', ), ), const SizedBox(width: 10), @@ -731,16 +731,16 @@ class _CommunityStructureAreaState extends State { void _duplicateSpace(SpaceModel space) { setState(() { - SpaceModel? parent = space.parent; + final parent = space.parent; - SpaceModel duplicated = _deepCloneSpaceTree(space, parent: parent); + final duplicated = _deepCloneSpaceTree(space, parent: parent); duplicated.position = Offset(space.position.dx + 300, space.position.dy + 100); - List duplicatedSubtree = []; + final duplicatedSubtree = []; void collectSubtree(SpaceModel node) { duplicatedSubtree.add(node); - for (var child in node.children) { + for (final child in node.children) { collectSubtree(child); } } @@ -782,7 +782,7 @@ class _CommunityStructureAreaState extends State { parent: parent, ); - for (var child in original.children) { + for (final child in original.children) { final duplicatedChild = _deepCloneSpaceTree(child, parent: newSpace); newSpace.children.add(duplicatedChild); diff --git a/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart index 2289819b..bd8c0a98 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart @@ -7,11 +7,10 @@ class CounterWidget extends StatefulWidget { final bool isCreate; const CounterWidget( - {Key? key, + {super.key, this.initialCount = 0, required this.onCountChanged, - required this.isCreate}) - : super(key: key); + required this.isCreate}); @override State createState() => _CounterWidgetState(); @@ -55,7 +54,8 @@ class _CounterWidgetState extends State { child: Row( mainAxisSize: MainAxisSize.min, children: [ - _buildCounterButton(Icons.remove, _decrementCounter,!widget.isCreate ), + _buildCounterButton( + Icons.remove, _decrementCounter, !widget.isCreate), const SizedBox(width: 8), Text( '$_counter', @@ -69,12 +69,15 @@ class _CounterWidgetState extends State { ); } - Widget _buildCounterButton(IconData icon, VoidCallback onPressed, bool isDisabled) { + Widget _buildCounterButton( + IconData icon, VoidCallback onPressed, bool isDisabled) { return GestureDetector( - onTap: isDisabled? null: onPressed, + onTap: isDisabled ? null : onPressed, child: Icon( icon, - color: isDisabled? ColorsManager.spaceColor.withOpacity(0.3): ColorsManager.spaceColor, + color: isDisabled + ? ColorsManager.spaceColor.withValues(alpha: 0.3) + : ColorsManager.spaceColor, size: 18, ), ); diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart index 94896554..caa71183 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; - -import '../../../../../common/edit_chip.dart'; -import '../../../../../utils/color_manager.dart'; -import '../../../helper/tag_helper.dart'; -import '../../../space_model/widgets/button_content_widget.dart'; -import '../../model/subspace_model.dart'; -import '../../model/tag.dart'; +import 'package:syncrow_web/common/edit_chip.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; class DevicesPartWidget extends StatelessWidget { const DevicesPartWidget({ @@ -28,73 +27,73 @@ class DevicesPartWidget extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - (tags?.isNotEmpty == true || - subspaces?.any( - (subspace) => subspace.tags?.isNotEmpty == true) == - true) - ? SizedBox( - width: screenWidth * 0.25, - child: Container( - padding: const EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: ColorsManager.textFieldGreyColor, - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: ColorsManager.textFieldGreyColor, - width: 3.0, // Border width - ), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - // Combine tags from spaceModel and subspaces - ...TagHelper.groupTags([ - ...?tags, - ...?subspaces?.expand((subspace) => subspace.tags ?? []) - ]).entries.map( - (entry) => Chip( - avatar: SizedBox( - width: 24, - height: 24, - child: SvgPicture.asset( - entry.key.icon ?? 'assets/icons/gateway.svg', - fit: BoxFit.contain, - ), - ), - label: Text( - 'x${entry.value}', // Show count - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(color: ColorsManager.spaceColor), - ), - backgroundColor: ColorsManager.whiteColors, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - side: const BorderSide( - color: ColorsManager.spaceColor, - ), - ), + if (tags?.isNotEmpty == true || + subspaces?.any((subspace) => subspace.tags?.isNotEmpty == true) == + true) + SizedBox( + width: screenWidth * 0.25, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: ColorsManager.textFieldGreyColor, + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: ColorsManager.textFieldGreyColor, + width: 3.0, // Border width + ), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + // Combine tags from spaceModel and subspaces + ...TagHelper.groupTags([ + ...?tags, + ...?subspaces?.expand((subspace) => subspace.tags ?? []) + ]).entries.map( + (entry) => Chip( + avatar: SizedBox( + width: 24, + height: 24, + child: SvgPicture.asset( + entry.key.icon ?? 'assets/icons/gateway.svg', + fit: BoxFit.contain, ), ), + label: Text( + 'x${entry.value}', // Show count + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: ColorsManager.spaceColor), + ), + backgroundColor: ColorsManager.whiteColors, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: const BorderSide( + color: ColorsManager.spaceColor, + ), + ), + ), + ), - EditChip(onTap: onEditChip) - ], - ), - ), - ) - : TextButton( - onPressed: onTextButtonPressed, - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - ), - child: ButtonContentWidget( - icon: Icons.add, - label: 'Add Devices', - disabled: isTagsAndSubspaceModelDisabled, - ), - ) + EditChip(onTap: onEditChip) + ], + ), + ), + ) + else + TextButton( + onPressed: onTextButtonPressed, + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + ), + child: ButtonContentWidget( + icon: Icons.add, + label: 'Add Devices', + disabled: isTagsAndSubspaceModelDisabled, + ), + ) ], ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart index 59a100a3..94467180 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; -import '../../../../../utils/color_manager.dart'; -import '../../../../../utils/constants/assets.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; class IconChoosePartWidget extends StatelessWidget { const IconChoosePartWidget({ diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart index cd9ae470..ceedad63 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart @@ -1,9 +1,8 @@ import 'package:flutter/material.dart'; - -import '../../../../../utils/color_manager.dart'; -import '../../../../../utils/constants/assets.dart'; -import '../../../space_model/models/space_template_model.dart'; -import '../../../space_model/widgets/button_content_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; class SpaceModelLinkingWidget extends StatelessWidget { const SpaceModelLinkingWidget({ @@ -23,66 +22,67 @@ class SpaceModelLinkingWidget extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - selectedSpaceModel == null - ? TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - ), - onPressed: onPressed, - child: ButtonContentWidget( - svgAssets: Assets.link, - label: 'Link a space model', - disabled: isSpaceModelDisabled, - ), - ) - : Container( - width: screenWidth * 0.25, - padding: const EdgeInsets.symmetric( - vertical: 10.0, horizontal: 16.0), - decoration: BoxDecoration( - color: ColorsManager.boxColor, - borderRadius: BorderRadius.circular(10), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - Chip( - label: Text( - selectedSpaceModel?.modelName ?? '', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: ColorsManager.spaceColor), + if (selectedSpaceModel == null) + TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + ), + onPressed: onPressed, + child: ButtonContentWidget( + svgAssets: Assets.link, + label: 'Link a space model', + disabled: isSpaceModelDisabled, + ), + ) + else + Container( + width: screenWidth * 0.25, + padding: + const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0), + decoration: BoxDecoration( + color: ColorsManager.boxColor, + borderRadius: BorderRadius.circular(10), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + Chip( + label: Text( + selectedSpaceModel?.modelName ?? '', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: ColorsManager.spaceColor), + ), + backgroundColor: ColorsManager.whiteColors, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: const BorderSide( + color: ColorsManager.transparentColor, + width: 0, + ), + ), + deleteIcon: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: ColorsManager.lightGrayColor, + width: 1.5, ), - backgroundColor: ColorsManager.whiteColors, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - side: const BorderSide( - color: ColorsManager.transparentColor, - width: 0, - ), - ), - deleteIcon: Container( - width: 24, - height: 24, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.lightGrayColor, - width: 1.5, - ), - ), - child: const Icon( - Icons.close, - size: 16, - color: ColorsManager.lightGrayColor, - ), - ), - onDeleted: onDeleted), - ], - ), - ), + ), + child: const Icon( + Icons.close, + size: 16, + color: ColorsManager.lightGrayColor, + ), + ), + onDeleted: onDeleted), + ], + ), + ), ], ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart index 600cb8ad..5700b9c5 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../../../utils/color_manager.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; class SpaceNameTextfieldWidget extends StatelessWidget { SpaceNameTextfieldWidget({ diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart index e518877a..868eefe5 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; - -import '../../../../../common/edit_chip.dart'; -import '../../../../../utils/color_manager.dart'; -import '../../../space_model/widgets/button_content_widget.dart'; -import '../../../space_model/widgets/subspace_name_label_widget.dart'; -import '../../model/subspace_model.dart'; +import 'package:syncrow_web/common/edit_chip.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; class SubSpacePartWidget extends StatefulWidget { SubSpacePartWidget({ @@ -30,71 +29,72 @@ class _SubSpacePartWidgetState extends State { Widget build(BuildContext context) { return Column( children: [ - widget.subspaces == null || widget.subspaces!.isEmpty - ? TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - overlayColor: ColorsManager.transparentColor, + if (widget.subspaces == null || widget.subspaces!.isEmpty) + TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + overlayColor: ColorsManager.transparentColor, + ), + onPressed: widget.onPressed, + child: ButtonContentWidget( + icon: Icons.add, + label: 'Create Sub Spaces', + disabled: widget.isTagsAndSubspaceModelDisabled, + ), + ) + else + SizedBox( + width: widget.screenWidth * 0.25, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: ColorsManager.textFieldGreyColor, + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: ColorsManager.textFieldGreyColor, + width: 3.0, // Border width ), - onPressed: widget.onPressed, - child: ButtonContentWidget( - icon: Icons.add, - label: 'Create Sub Spaces', - disabled: widget.isTagsAndSubspaceModelDisabled, - ), - ) - : SizedBox( - width: widget.screenWidth * 0.25, - child: Container( - padding: const EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: ColorsManager.textFieldGreyColor, - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: ColorsManager.textFieldGreyColor, - width: 3.0, // Border width - ), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - if (widget.subspaces != null) - ...widget.subspaces!.map((subspace) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SubspaceNameDisplayWidget( - text: subspace.subspaceName, - validateName: (updatedName) { - bool nameExists = widget.subspaces!.any((s) { - bool isSameId = - s.internalId == subspace.internalId; - bool isSameName = - s.subspaceName.trim().toLowerCase() == - updatedName.trim().toLowerCase(); + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + if (widget.subspaces != null) + ...widget.subspaces!.map((subspace) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SubspaceNameDisplayWidget( + text: subspace.subspaceName, + validateName: (updatedName) { + final nameExists = widget.subspaces!.any((s) { + final isSameId = + s.internalId == subspace.internalId; + final isSameName = + s.subspaceName.trim().toLowerCase() == + updatedName.trim().toLowerCase(); - return !isSameId && isSameName; - }); + return !isSameId && isSameName; + }); - return !nameExists; - }, - onNameChanged: (updatedName) { - setState(() { - subspace.subspaceName = updatedName; - }); - }, - ), - ], - ); - }), - EditChip( - onTap: widget.editChipOnTap, - ) - ], - ), - ), - ) + return !nameExists; + }, + onNameChanged: (updatedName) { + setState(() { + subspace.subspaceName = updatedName; + }); + }, + ), + ], + ); + }), + EditChip( + onTap: widget.editChipOnTap, + ) + ], + ), + ), + ) ], ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart index d8291110..d0c3bd83 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart @@ -19,15 +19,11 @@ class CurvedLinePainter extends CustomPainter { return; // Nothing to paint if there are no connections } - for (var connection in connections) { + for (final connection in connections) { // Ensure positions are valid before drawing lines - if (connection.endSpace.position == null) { - continue; - } - - Offset start = connection.startSpace.position + + final start = connection.startSpace.position + const Offset(75, 60); // Center bottom of start space - Offset end = connection.endSpace.position + + final end = connection.endSpace.position + const Offset(75, 0); // Center top of end space // Curved line for down connections diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index 8cf30f7c..f6f7bded 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -9,7 +9,6 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_mo import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart'; @@ -99,9 +98,9 @@ class CreateSpaceDialogState extends State { @override Widget build(BuildContext context) { - bool isSpaceModelDisabled = (tags != null && tags!.isNotEmpty || - subspaces != null && subspaces!.isNotEmpty); - bool isTagsAndSubspaceModelDisabled = (selectedSpaceModel != null); + final isSpaceModelDisabled = tags != null && tags!.isNotEmpty || + subspaces != null && subspaces!.isNotEmpty; + final isTagsAndSubspaceModelDisabled = (selectedSpaceModel != null); final screenWidth = MediaQuery.of(context).size.width; return AlertDialog( @@ -298,7 +297,7 @@ class CreateSpaceDialogState extends State { } else if (isNameFieldExist) { return; } else { - String newName = enteredName.isNotEmpty + final newName = enteredName.isNotEmpty ? enteredName : (widget.name ?? ''); if (newName.isNotEmpty) { @@ -381,7 +380,7 @@ class CreateSpaceDialogState extends State { products: products, existingSubSpaces: existingSubSpaces, onSave: (slectedSubspaces, updatedSubSpaces) { - final List tagsToAppendToSpace = []; + final tagsToAppendToSpace = []; if (slectedSubspaces != null && slectedSubspaces.isNotEmpty) { final updatedIds = @@ -390,11 +389,11 @@ class CreateSpaceDialogState extends State { final deletedSubspaces = existingSubSpaces .where((s) => !updatedIds.contains(s.internalId)) .toList(); - for (var s in deletedSubspaces) { + for (final s in deletedSubspaces) { if (s.tags != null) { - s.tags!.forEach( - (tag) => tag.location = null, - ); + for (final tag in s.tags!) { + tag.location = null; + } tagsToAppendToSpace.addAll(s.tags!); } } @@ -403,11 +402,11 @@ class CreateSpaceDialogState extends State { if (existingSubSpaces != null) { final deletedSubspaces = existingSubSpaces; - for (var s in deletedSubspaces) { + for (final s in deletedSubspaces) { if (s.tags != null) { - s.tags!.forEach( - (tag) => tag.location = null, - ); + for (final tag in s.tags!) { + tag.location = null; + } tagsToAppendToSpace.addAll(s.tags!); } } diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart index 27275be1..dd04bec6 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart @@ -2,9 +2,10 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -void showDeleteConfirmationDialog(BuildContext context, VoidCallback onConfirm, bool isSpace) { - final String title = isSpace ? 'Delete Space' : 'Delete Community'; - final String subtitle = isSpace +void showDeleteConfirmationDialog( + BuildContext context, VoidCallback onConfirm, bool isSpace) { + final title = isSpace ? 'Delete Space' : 'Delete Community'; + final subtitle = isSpace ? 'All the data in the space will be lost' : 'All the data in the community will be lost'; @@ -13,7 +14,8 @@ void showDeleteConfirmationDialog(BuildContext context, VoidCallback onConfirm, barrierDismissible: false, builder: (BuildContext context) { return Dialog( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), child: SizedBox( width: 500, child: Container( @@ -41,7 +43,8 @@ void showDeleteConfirmationDialog(BuildContext context, VoidCallback onConfirm, showProcessingPopup(context, isSpace, onConfirm); }, style: _dialogButtonStyle(ColorsManager.spaceColor), - child: const Text('Continue', style: TextStyle(color: ColorsManager.whiteColors)), + child: const Text('Continue', + style: TextStyle(color: ColorsManager.whiteColors)), ), ], ), @@ -54,15 +57,17 @@ void showDeleteConfirmationDialog(BuildContext context, VoidCallback onConfirm, ); } -void showProcessingPopup(BuildContext context, bool isSpace, VoidCallback onDelete) { - final String title = isSpace ? 'Delete Space' : 'Delete Community'; +void showProcessingPopup( + BuildContext context, bool isSpace, VoidCallback onDelete) { + final title = isSpace ? 'Delete Space' : 'Delete Community'; showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return Dialog( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), child: SizedBox( width: 500, child: Container( @@ -75,7 +80,8 @@ void showProcessingPopup(BuildContext context, bool isSpace, VoidCallback onDele const SizedBox(height: 20), _buildDialogTitle(context, title), const SizedBox(height: 10), - _buildDialogSubtitle(context, 'Are you sure you want to delete?'), + _buildDialogSubtitle( + context, 'Are you sure you want to delete?'), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -83,7 +89,8 @@ void showProcessingPopup(BuildContext context, bool isSpace, VoidCallback onDele ElevatedButton( onPressed: onDelete, style: _dialogButtonStyle(ColorsManager.warningRed), - child: const Text('Delete', style: TextStyle(color: ColorsManager.whiteColors)), + child: const Text('Delete', + style: TextStyle(color: ColorsManager.whiteColors)), ), CancelButton( label: 'Cancel', @@ -104,7 +111,7 @@ Widget _buildWarningIcon() { return Container( width: 50, height: 50, - decoration: BoxDecoration( + decoration: const BoxDecoration( color: ColorsManager.warningRed, shape: BoxShape.circle, ), @@ -123,7 +130,10 @@ Widget _buildDialogSubtitle(BuildContext context, String subtitle) { return Text( subtitle, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: ColorsManager.grayColor), + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(color: ColorsManager.grayColor), ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart index 1f719b1a..f3c7dda6 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart @@ -4,8 +4,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; class DuplicateProcessDialog extends StatefulWidget { final VoidCallback onDuplicate; - const DuplicateProcessDialog({required this.onDuplicate, Key? key}) - : super(key: key); + const DuplicateProcessDialog({required this.onDuplicate, super.key}); @override _DuplicateProcessDialogState createState() => _DuplicateProcessDialogState(); @@ -20,7 +19,7 @@ class _DuplicateProcessDialogState extends State { _startDuplication(); } - void _startDuplication() async { + Future _startDuplication() async { WidgetsBinding.instance.addPostFrameCallback((_) { widget.onDuplicate(); }); @@ -55,7 +54,7 @@ class _DuplicateProcessDialogState extends State { ), const SizedBox(height: 15), Text( - "Duplicating in progress", + 'Duplicating in progress', style: Theme.of(context) .textTheme .headlineSmall @@ -70,7 +69,7 @@ class _DuplicateProcessDialogState extends State { ), const SizedBox(height: 15), Text( - "Duplicating successful", + 'Duplicating successful', textAlign: TextAlign.center, style: Theme.of(context) .textTheme diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart index b2a01988..71b9efef 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart @@ -7,10 +7,10 @@ class IconSelectionDialog extends StatelessWidget { final Function(String selectedIcon) onIconSelected; const IconSelectionDialog({ - Key? key, + super.key, required this.spaceIconList, required this.onIconSelected, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -21,21 +21,23 @@ class IconSelectionDialog extends StatelessWidget { elevation: 0, backgroundColor: ColorsManager.transparentColor, child: Container( - width: screenWidth * 0.44, + width: screenWidth * 0.44, height: screenHeight * 0.45, decoration: BoxDecoration( color: ColorsManager.whiteColors, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( - color: ColorsManager.blackColor.withOpacity(0.2), // Shadow color + color: ColorsManager.blackColor + .withValues(alpha: 0.2), // Shadow color blurRadius: 20, // Spread of the blur offset: const Offset(0, 8), // Offset of the shadow ), ], ), child: AlertDialog( - title: Text('Space Icon',style: Theme.of(context).textTheme.headlineMedium), + title: Text('Space Icon', + style: Theme.of(context).textTheme.headlineMedium), backgroundColor: ColorsManager.whiteColors, content: Container( width: screenWidth * 0.4, diff --git a/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart index e1d4e11b..e0ca8827 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart @@ -28,7 +28,7 @@ class GradientCanvasBorderWidget extends StatelessWidget { begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ - ColorsManager.semiTransparentBlackColor.withOpacity(0.1), + ColorsManager.semiTransparentBlackColor.withValues(alpha: 0.1), ColorsManager.transparentColor, ], ), diff --git a/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart b/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart index 49a863b6..e545f26b 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart @@ -8,11 +8,11 @@ class HoverableButton extends StatefulWidget { final VoidCallback onTap; const HoverableButton({ - Key? key, + super.key, required this.iconPath, required this.text, required this.onTap, - }) : super(key: key); + }); @override State createState() => _HoverableButtonState(); @@ -34,14 +34,17 @@ class _HoverableButtonState extends State { child: SizedBox( width: screenWidth * .07, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 8), + padding: + const EdgeInsets.symmetric(horizontal: 13, vertical: 8), decoration: BoxDecoration( - color: isHovered ? ColorsManager.warningRed : ColorsManager.whiteColors, + color: isHovered + ? ColorsManager.warningRed + : ColorsManager.whiteColors, borderRadius: BorderRadius.circular(16), boxShadow: [ if (isHovered) BoxShadow( - color: ColorsManager.warningRed.withOpacity(0.4), + color: ColorsManager.warningRed.withValues(alpha: 0.4), blurRadius: 8, offset: const Offset(0, 4), ), diff --git a/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart index d2c72fa7..d2a7c3de 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart @@ -81,49 +81,51 @@ class _LoadedSpaceViewState extends State { return Stack( clipBehavior: Clip.none, children: [ - widget.shouldNavigateToSpaceModelPage - ? Row( - children: [ - SizedBox(width: 300, child: SpaceTreeView(onSelect: () {})), - Expanded( - child: BlocProvider( - create: (context) => SpaceModelBloc( - BlocProvider.of(context), - api: SpaceModelManagementApi(), - initialSpaceModels: widget.spaceModels ?? [], - ), - child: SpaceModelPage( - products: widget.products, - onSpaceModelsUpdated: _onSpaceModelsUpdated, - projectTags: widget.projectTags, - ), - ), + if (widget.shouldNavigateToSpaceModelPage) + Row( + children: [ + SizedBox(width: 300, child: SpaceTreeView(onSelect: () {})), + Expanded( + child: BlocProvider( + create: (context) => SpaceModelBloc( + BlocProvider.of(context), + api: SpaceModelManagementApi(), + initialSpaceModels: widget.spaceModels ?? [], ), - ], - ) - : Row( - children: [ - SidebarWidget( - communities: widget.communities, - selectedSpaceUuid: - widget.selectedSpace?.uuid ?? widget.selectedCommunity?.uuid ?? '', - onCreateCommunity: (name, description) { - context.read().add( - CreateCommunityEvent(name, description, context), - ); - }, - ), - CommunityStructureArea( - selectedCommunity: widget.selectedCommunity, - selectedSpace: widget.selectedSpace, - spaces: widget.selectedCommunity?.spaces ?? [], + child: SpaceModelPage( products: widget.products, - communities: widget.communities, - spaceModels: _spaceModels, + onSpaceModelsUpdated: _onSpaceModelsUpdated, projectTags: widget.projectTags, ), - ], + ), ), + ], + ) + else + Row( + children: [ + SidebarWidget( + communities: widget.communities, + selectedSpaceUuid: widget.selectedSpace?.uuid ?? + widget.selectedCommunity?.uuid ?? + '', + onCreateCommunity: (name, description) { + context.read().add( + CreateCommunityEvent(name, description, context), + ); + }, + ), + CommunityStructureArea( + selectedCommunity: widget.selectedCommunity, + selectedSpace: widget.selectedSpace, + spaces: widget.selectedCommunity?.spaces ?? [], + products: widget.products, + communities: widget.communities, + spaceModels: _spaceModels, + projectTags: widget.projectTags, + ), + ], + ), const GradientCanvasBorderWidget(), ], ); diff --git a/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart index 7076a580..283bffac 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart @@ -13,12 +13,12 @@ class SelectedProductsButtons extends StatelessWidget { final BuildContext context; const SelectedProductsButtons({ - Key? key, + super.key, required this.products, required this.selectedProducts, required this.onProductsUpdated, required this.context, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -86,9 +86,7 @@ class SelectedProductsButtons extends StatelessWidget { builder: (context) => AddDeviceWidget( products: products, initialSelectedProducts: selectedProducts, - onProductsSelected: (selectedProductsMap) { - onProductsUpdated(selectedProductsMap); - }, + onProductsSelected: onProductsUpdated, ), ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart index 6149dbda..3e2ad4dd 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart @@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/common/widgets/search_bar.dart'; import 'package:syncrow_web/common/widgets/sidebar_communities_list.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/space_tree/bloc/space_tree_state.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_event.dart'; @@ -18,8 +19,6 @@ import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/cent import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_event.dart'; import 'package:syncrow_web/utils/style.dart'; -import '../../../space_tree/bloc/space_tree_event.dart'; - class SidebarWidget extends StatefulWidget { final List communities; final String? selectedSpaceUuid; @@ -55,13 +54,15 @@ class _SidebarWidgetState extends State { } void _onScroll() { - if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 100) { + if (_scrollController.position.pixels >= + _scrollController.position.maxScrollExtent - 100) { // Trigger pagination event final bloc = context.read(); - if (!bloc.state.paginationIsLoading && bloc.state.paginationModel?.hasNext == true) { + if (!bloc.state.paginationIsLoading && + bloc.state.paginationModel.hasNext == true) { bloc.add( PaginationEvent( - bloc.state.paginationModel!, + bloc.state.paginationModel, bloc.state.communityList, ), ); @@ -134,24 +135,28 @@ class _SidebarWidgetState extends State { communities: filteredCommunities, itemBuilder: (context, index) { if (index == filteredCommunities.length) { - final spaceTreeState = context.read().state; + final spaceTreeState = + context.read().state; if (spaceTreeState.paginationIsLoading) { return const Padding( padding: EdgeInsets.all(8.0), - child: Center(child: CircularProgressIndicator()), + child: + Center(child: CircularProgressIndicator()), ); } else { return const SizedBox.shrink(); } } - return _buildCommunityTile(context, filteredCommunities[index]); + return _buildCommunityTile( + context, filteredCommunities[index]); }, ); }, ), ), - if (spaceTreeState.paginationIsLoading || spaceTreeState.isSearching) - Center( + if (spaceTreeState.paginationIsLoading || + spaceTreeState.isSearching) + const Center( child: CircularProgressIndicator(), ) ], @@ -214,7 +219,8 @@ class _SidebarWidgetState extends State { }); context.read().add( - SelectSpaceEvent(selectedCommunity: community, selectedSpace: space), + SelectSpaceEvent( + selectedCommunity: community, selectedSpace: space), ); }, children: space.children @@ -229,8 +235,9 @@ class _SidebarWidgetState extends State { ); } - void _onAddCommunity() => - _selectedId?.isNotEmpty ?? true ? _clearSelection() : _showCreateCommunityDialog(); + void _onAddCommunity() => _selectedId?.isNotEmpty ?? true + ? _clearSelection() + : _showCreateCommunityDialog(); void _clearSelection() { setState(() => _selectedId = ''); diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart index 7e6e132f..344eddd3 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'plus_button_widget.dart'; // Make sure to import your PlusButtonWidget +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart'; // Make sure to import your PlusButtonWidget class SpaceCardWidget extends StatelessWidget { final int index; diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart index 6f52eb50..e43bccd3 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart @@ -78,7 +78,7 @@ class SpaceContainerWidget extends StatelessWidget { borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: ColorsManager.lightGrayColor.withOpacity(0.5), + color: ColorsManager.lightGrayColor.withValues(alpha: 0.5), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3), // Shadow position diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart index 62d8197c..1e805cb3 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart @@ -27,7 +27,7 @@ class SpaceWidget extends StatelessWidget { borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( - color: ColorsManager.lightGrayColor.withOpacity(0.5), + color: ColorsManager.lightGrayColor.withValues(alpha: 0.5), spreadRadius: 5, blurRadius: 7, offset: const Offset(0, 3), diff --git a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart index afc0c852..7496eb16 100644 --- a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart +++ b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart @@ -11,7 +11,7 @@ class AssignTagBloc extends Bloc { final initialTags = event.initialTags ?? []; final existingTagCounts = {}; - for (var tag in initialTags) { + for (final tag in initialTags) { if (tag.product != null) { existingTagCounts[tag.product!.uuid] = (existingTagCounts[tag.product!.uuid] ?? 0) + 1; @@ -20,7 +20,7 @@ class AssignTagBloc extends Bloc { final tags = []; - for (var selectedProduct in event.addedProducts) { + for (final selectedProduct in event.addedProducts) { final existingCount = existingTagCounts[selectedProduct.productId] ?? 0; if (selectedProduct.count == 0 || @@ -171,7 +171,7 @@ class AssignTagBloc extends Bloc { List _calculateAvailableTags(List allTags, List selectedTags) { final selectedTagSet = selectedTags - .where((tag) => (tag.tag?.trim().isNotEmpty ?? false)) + .where((tag) => tag.tag?.trim().isNotEmpty ?? false) .map((tag) => tag.tag!.trim()) .toSet(); diff --git a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart index 7d81ffdb..b79fb699 100644 --- a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart +++ b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart @@ -1,6 +1,6 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; abstract class AssignTagEvent extends Equatable { const AssignTagEvent(); diff --git a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart index 53700a33..3fda79bf 100644 --- a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart +++ b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart @@ -27,7 +27,8 @@ class AssignTagLoaded extends AssignTagState { }); @override - List get props => [tags, updatedTags, isSaveEnabled, errorMessage ?? '']; + List get props => + [tags, updatedTags, isSaveEnabled, errorMessage ?? '']; } class AssignTagError extends AssignTagState { diff --git a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart index 21ba141c..809dff64 100644 --- a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart +++ b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart @@ -7,11 +7,10 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart'; +import 'package:syncrow_web/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'widgets/save_add_device_row_widget.dart'; - class AssignTagDialog extends StatelessWidget { final List? products; final List? subspaces; @@ -39,7 +38,7 @@ class AssignTagDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final List locations = (subspaces ?? []) + final locations = (subspaces ?? []) .map((subspace) => subspace.subspaceName) .toList() ..add('Main Space'); diff --git a/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart b/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart index a81b7ad0..c5b164cf 100644 --- a/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart +++ b/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart @@ -1,14 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; +import 'package:syncrow_web/pages/spaces_management/add_device_type/views/add_device_type_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/spaces_management/helper/tag_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import '../../../add_device_type/views/add_device_type_widget.dart'; -import '../../../helper/tag_helper.dart'; - class SaveAddDeviceRowWidget extends StatelessWidget { const SaveAddDeviceRowWidget({ super.key, diff --git a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart index 7df82b5e..4a6548f8 100644 --- a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart +++ b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart @@ -3,7 +3,8 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart'; -class AssignTagModelBloc extends Bloc { +class AssignTagModelBloc + extends Bloc { final List projectTags; AssignTagModelBloc(this.projectTags) : super(AssignTagModelInitial()) { @@ -11,25 +12,29 @@ class AssignTagModelBloc extends Bloc final initialTags = event.initialTags; final existingTagCounts = {}; - for (var tag in initialTags) { + for (final tag in initialTags) { if (tag.product != null) { - existingTagCounts[tag.product!.uuid] = (existingTagCounts[tag.product!.uuid] ?? 0) + 1; + existingTagCounts[tag.product!.uuid] = + (existingTagCounts[tag.product!.uuid] ?? 0) + 1; } } final tags = []; - for (var selectedProduct in event.addedProducts) { + for (final selectedProduct in event.addedProducts) { final existingCount = existingTagCounts[selectedProduct.productId] ?? 0; - if (selectedProduct.count == 0 || selectedProduct.count <= existingCount) { - tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId)); + if (selectedProduct.count == 0 || + selectedProduct.count <= existingCount) { + tags.addAll(initialTags + .where((tag) => tag.product?.uuid == selectedProduct.productId)); continue; } final missingCount = selectedProduct.count - existingCount; - tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId)); + tags.addAll(initialTags + .where((tag) => tag.product?.uuid == selectedProduct.productId)); if (missingCount > 0) { tags.addAll(List.generate( @@ -54,7 +59,8 @@ class AssignTagModelBloc extends Bloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { + if (currentState is AssignTagModelLoaded && + currentState.tags.isNotEmpty) { final tags = List.from(currentState.tags); if (event.index < 0 || event.index >= tags.length) return; @@ -81,10 +87,12 @@ class AssignTagModelBloc extends Bloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { + if (currentState is AssignTagModelLoaded && + currentState.tags.isNotEmpty) { final tags = List.from(currentState.tags); // Use copyWith for immutability - tags[event.index] = tags[event.index].copyWith(location: event.location); + tags[event.index] = + tags[event.index].copyWith(location: event.location); final updatedTags = _calculateAvailableTags(projectTags, tags); @@ -100,7 +108,8 @@ class AssignTagModelBloc extends Bloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { + if (currentState is AssignTagModelLoaded && + currentState.tags.isNotEmpty) { final tags = List.from(currentState.tags); emit(AssignTagModelLoaded( @@ -115,8 +124,10 @@ class AssignTagModelBloc extends Bloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { - final tags = List.from(currentState.tags)..remove(event.tagToDelete); + if (currentState is AssignTagModelLoaded && + currentState.tags.isNotEmpty) { + final tags = List.from(currentState.tags) + ..remove(event.tagToDelete); final updatedTags = _calculateAvailableTags(projectTags, tags); @@ -140,8 +151,10 @@ class AssignTagModelBloc extends Bloc String? _getValidationError(List tags) { // Check for duplicate tags - final nonEmptyTags = - tags.map((tag) => tag.tag?.trim() ?? '').where((tag) => tag.isNotEmpty).toList(); + final nonEmptyTags = tags + .map((tag) => tag.tag?.trim() ?? '') + .where((tag) => tag.isNotEmpty) + .toList(); final duplicateTags = nonEmptyTags .fold>({}, (map, tag) { @@ -162,12 +175,13 @@ class AssignTagModelBloc extends Bloc List _calculateAvailableTags(List allTags, List selectedTags) { final selectedTagSet = selectedTags - .where((tag) => (tag.tag?.trim().isNotEmpty ?? false)) + .where((tag) => tag.tag?.trim().isNotEmpty ?? false) .map((tag) => tag.tag!.trim()) .toSet(); final availableTags = allTags - .where((tag) => tag.tag != null && !selectedTagSet.contains(tag.tag!.trim())) + .where((tag) => + tag.tag != null && !selectedTagSet.contains(tag.tag!.trim())) .toList(); return availableTags; diff --git a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart index cb878bde..d62e1523 100644 --- a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart +++ b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart @@ -1,6 +1,6 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; abstract class AssignTagModelEvent extends Equatable { const AssignTagModelEvent(); diff --git a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart index 57ed93df..4f0fcee5 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart @@ -6,13 +6,12 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart'; +import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart'; +import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.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/subspace_template_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'widgets/RowOfCancelSaveWidget.dart'; -import 'widgets/assign_tags_tables_widget.dart'; - class AssignTagModelsDialog extends StatelessWidget { final List? products; final List? subspaces; @@ -30,7 +29,7 @@ class AssignTagModelsDialog extends StatelessWidget { final List projectTags; const AssignTagModelsDialog( - {Key? key, + {super.key, required this.products, required this.subspaces, required this.addedProducts, @@ -43,12 +42,11 @@ class AssignTagModelsDialog extends StatelessWidget { this.otherSpaceModels, this.spaceModel, this.allSpaceModels, - required this.projectTags}) - : super(key: key); + required this.projectTags}); @override Widget build(BuildContext context) { - final List locations = (subspaces ?? []) + final locations = (subspaces ?? []) .map((subspace) => subspace.subspaceName) .toList() ..add('Main Space'); diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart index 9b2a1367..72f8be87 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart @@ -1,18 +1,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - -import '../../../../../utils/color_manager.dart'; -import '../../../../common/buttons/cancel_button.dart'; -import '../../../../common/buttons/default_button.dart'; -import '../../../all_spaces/model/product_model.dart'; -import '../../../all_spaces/model/tag.dart'; -import '../../../helper/tag_helper.dart'; -import '../../../space_model/models/space_template_model.dart'; -import '../../../space_model/models/subspace_template_model.dart'; -import '../../../space_model/widgets/dialog/create_space_model_dialog.dart'; -import '../../../tag_model/views/add_device_type_model_widget.dart'; -import '../../bloc/assign_tag_model_bloc.dart'; -import '../../bloc/assign_tag_model_state.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/spaces_management/all_spaces/model/product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart'; +import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.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/subspace_template_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart'; +import 'package:syncrow_web/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; class RowOfSaveCancelWidget extends StatelessWidget { const RowOfSaveCancelWidget({ diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart index 0e17a0d7..ee335637 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart @@ -1,11 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:syncrow_web/common/dialog_dropdown.dart'; +import 'package:syncrow_web/common/tag_dialog_textfield_dropdown.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; import 'package:uuid/uuid.dart'; -import '../../../../../common/dialog_dropdown.dart'; -import '../../../../../common/tag_dialog_textfield_dropdown.dart'; -import '../../../../../utils/color_manager.dart'; - class AssignTagsTable extends StatelessWidget { const AssignTagsTable({ super.key, diff --git a/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart b/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart index 724ed51a..e52f09bf 100644 --- a/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart +++ b/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart @@ -1,8 +1,9 @@ import 'package:flutter_bloc/flutter_bloc.dart'; -import 'community_dialog_event.dart'; -import 'community_dialog_state.dart'; +import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_event.dart'; +import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_state.dart'; -class CommunityDialogBloc extends Bloc { +class CommunityDialogBloc + extends Bloc { final List existingCommunityNames; CommunityDialogBloc(this.existingCommunityNames) diff --git a/lib/pages/spaces_management/create_community/view/create_community_dialog.dart b/lib/pages/spaces_management/create_community/view/create_community_dialog.dart index 13e676b5..9321cc1e 100644 --- a/lib/pages/spaces_management/create_community/view/create_community_dialog.dart +++ b/lib/pages/spaces_management/create_community/view/create_community_dialog.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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/spaces_management/create_community/bloc/community_dialog_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_event.dart'; import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_state.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; -import 'package:syncrow_web/pages/common/buttons/default_button.dart'; class CreateCommunityDialog extends StatelessWidget { final Function(String name, String description) onCreateCommunity; @@ -43,7 +43,7 @@ class CreateCommunityDialog extends StatelessWidget { borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( - color: ColorsManager.blackColor.withOpacity(0.25), + color: ColorsManager.blackColor.withValues(alpha: 0.25), blurRadius: 20, spreadRadius: 5, offset: const Offset(0, 5), @@ -53,8 +53,8 @@ class CreateCommunityDialog extends StatelessWidget { child: SingleChildScrollView( child: BlocBuilder( builder: (context, state) { - bool isNameValid = true; - bool isNameEmpty = false; + var isNameValid = true; + var isNameEmpty = false; if (state is CommunityNameValidationState) { isNameValid = state.isNameValid; @@ -139,7 +139,7 @@ class CreateCommunityDialog extends StatelessWidget { if (isNameValid && !isNameEmpty) { onCreateCommunity( nameController.text.trim(), - "", + '', ); Navigator.of(context).pop(); } diff --git a/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart b/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart index a2d44553..bd14ff61 100644 --- a/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart +++ b/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart @@ -1,10 +1,9 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_state.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart'; -import 'subspace_event.dart'; -import 'subspace_state.dart'; - class SubSpaceBloc extends Bloc { SubSpaceBloc() : super(SubSpaceState([], [], '', {})) { on((event, emit) { @@ -77,7 +76,7 @@ class SubSpaceBloc extends Bloc { emit(SubSpaceState( updatedSubSpaces, updatedSubspaceModels, - errorMessage , + errorMessage, updatedDuplicates, )); }); diff --git a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart index 82df866a..3e54288d 100644 --- a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart +++ b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart @@ -5,12 +5,11 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_mo import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_state.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; -import 'widgets/ok_cancel_sub_space_widget.dart'; -import 'widgets/textfield_sub_space_dialog_widget.dart'; - class CreateSubSpaceDialog extends StatefulWidget { final String dialogTitle; final List? existingSubSpaces; diff --git a/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart index 3952e105..65bd0193 100644 --- a/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart +++ b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; - -import '../../bloc/subspace_bloc.dart'; -import '../../bloc/subspace_event.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; class OkCancelSubSpaceWidget extends StatelessWidget { const OkCancelSubSpaceWidget({ diff --git a/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart b/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart index f655e178..7375a228 100644 --- a/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart +++ b/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart @@ -1,14 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; -import '../../../../../utils/color_manager.dart'; -import '../../../all_spaces/model/subspace_model.dart'; -import '../../../create_subspace_model/widgets/subspace_chip.dart'; -import '../../../space_model/models/subspace_template_model.dart'; -import '../../bloc/subspace_bloc.dart'; -import '../../bloc/subspace_event.dart'; - class TextFieldSubSpaceDialogWidget extends StatelessWidget { const TextFieldSubSpaceDialogWidget({ super.key, diff --git a/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart b/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart index a331aed2..3337ce04 100644 --- a/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart +++ b/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart @@ -60,7 +60,7 @@ class SubSpaceModelBloc extends Bloc { if (event.subSpace.uuid?.isNotEmpty ?? false) { updatedSubspaceModels.add(UpdateSubspaceTemplateModel( action: Action.delete, - uuid: event.subSpace.uuid!, + uuid: event.subSpace.uuid, )); } @@ -104,7 +104,7 @@ class SubSpaceModelBloc extends Bloc { updatedSubspaceModels.add(UpdateSubspaceTemplateModel( action: Action.update, - uuid: event.updatedSubSpace.uuid!, + uuid: event.updatedSubSpace.uuid, )); emit(SubSpaceModelState( diff --git a/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart b/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart index 098b4804..0a9c9610 100644 --- a/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart +++ b/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart @@ -28,7 +28,8 @@ class SubspaceChip extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), side: BorderSide( - color: isDuplicate ? ColorsManager.red : ColorsManager.transparentColor, + color: + isDuplicate ? ColorsManager.red : ColorsManager.transparentColor, width: 0, ), ), diff --git a/lib/pages/spaces_management/helper/space_helper.dart b/lib/pages/spaces_management/helper/space_helper.dart index 4049eb7e..45ee9777 100644 --- a/lib/pages/spaces_management/helper/space_helper.dart +++ b/lib/pages/spaces_management/helper/space_helper.dart @@ -2,18 +2,20 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_m import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; class SpaceHelper { - static SpaceModel? findSpaceByUuid(String? uuid, List communities) { - for (var community in communities) { - for (var space in community.spaces) { + static SpaceModel? findSpaceByUuid( + String? uuid, List communities) { + for (final community in communities) { + for (final space in community.spaces) { if (space.uuid == uuid) return space; } } return null; } - static SpaceModel? findSpaceByInternalId(String? internalId, List spaces) { + static SpaceModel? findSpaceByInternalId( + String? internalId, List spaces) { if (internalId != null) { - for (var space in spaces) { + for (final space in spaces) { if (space.internalId == internalId) return space; } } @@ -21,21 +23,22 @@ class SpaceHelper { return null; } - static String generateUniqueSpaceName(String originalName, List spaces) { + static String generateUniqueSpaceName( + String originalName, List spaces) { final baseName = originalName.replaceAll(RegExp(r'\(\d+\)$'), '').trim(); - int maxNumber = 0; + var maxNumber = 0; - for (var space in spaces) { + for (final space in spaces) { final match = RegExp(r'^(.*?)\((\d+)\)$').firstMatch(space.name); if (match != null && match.group(1)?.trim() == baseName) { - int existingNumber = int.parse(match.group(2)!); + final existingNumber = int.parse(match.group(2)!); if (existingNumber > maxNumber) { maxNumber = existingNumber; } } } - return "$baseName(${maxNumber + 1})"; + return '$baseName(${maxNumber + 1})'; } static bool isSave(List spaces) { @@ -51,10 +54,13 @@ class SpaceHelper { return space == selectedSpace || selectedSpace.parent?.internalId == space.internalId || - selectedSpace.children?.any((child) => child.internalId == space.internalId) == true; + selectedSpace.children + .any((child) => child.internalId == space.internalId) == + true; } - static bool isNameConflict(String value, SpaceModel? parentSpace, SpaceModel? editSpace) { + static bool isNameConflict( + String value, SpaceModel? parentSpace, SpaceModel? editSpace) { final siblings = parentSpace?.children .where((child) => child.internalId != editSpace?.internalId) .toList() ?? @@ -65,17 +71,19 @@ class SpaceHelper { .toList() ?? []; - final editSiblingConflict = editSiblings.any((child) => child.name == value); + final editSiblingConflict = + editSiblings.any((child) => child.name == value); final siblingConflict = siblings.any((child) => child.name == value); - final parentConflict = - parentSpace?.name == value && parentSpace?.internalId != editSpace?.internalId; + final parentConflict = parentSpace?.name == value && + parentSpace?.internalId != editSpace?.internalId; - final parentOfEditSpaceConflict = - editSpace?.parent?.name == value && editSpace?.parent?.internalId != editSpace?.internalId; + final parentOfEditSpaceConflict = editSpace?.parent?.name == value && + editSpace?.parent?.internalId != editSpace?.internalId; - final childConflict = editSpace?.children.any((child) => child.name == value) ?? false; + final childConflict = + editSpace?.children.any((child) => child.name == value) ?? false; return siblingConflict || parentConflict || diff --git a/lib/pages/spaces_management/helper/tag_helper.dart b/lib/pages/spaces_management/helper/tag_helper.dart index e1dc3cc3..f810b8ba 100644 --- a/lib/pages/spaces_management/helper/tag_helper.dart +++ b/lib/pages/spaces_management/helper/tag_helper.dart @@ -24,7 +24,7 @@ class TagHelper { final modifiedSubspaces = List.from(subspaces ?? []); if (subspaces != null) { - for (var subspace in subspaces) { + for (final subspace in subspaces) { getSubspaceTags(subspace)?.removeWhere( (tag) => !modifiedTags.any( (updatedTag) => getInternalId(updatedTag) == getInternalId(tag)), @@ -32,7 +32,7 @@ class TagHelper { } } - for (var tag in modifiedTags.toList()) { + for (final tag in modifiedTags.toList()) { if (modifiedSubspaces.isEmpty) continue; final prevIndice = checkTagExistInSubspace(tag, modifiedSubspaces); @@ -131,8 +131,7 @@ class TagHelper { static List getAvailableTagModels( List allTags, List currentTags, Tag currentTag) { - List availableTagsForTagModel = - TagHelper.getAvailableTags( + final availableTagsForTagModel = TagHelper.getAvailableTags( allTags: allTags, currentTags: currentTags, currentTag: currentTag, @@ -145,14 +144,14 @@ class TagHelper { List? spaceTagModels, List? subspaces, }) { - final List initialTags = []; + final initialTags = []; if (spaceTagModels != null) { initialTags.addAll(spaceTagModels); } if (subspaces != null) { - for (var subspace in subspaces) { + for (final subspace in subspaces) { if (subspace.tags != null) { initialTags.addAll( subspace.tags!.map( @@ -174,14 +173,14 @@ class TagHelper { List? spaceTags, List? subspaces, }) { - final List initialTags = []; + final initialTags = []; if (spaceTags != null) { initialTags.addAll(spaceTags); } if (subspaces != null) { - for (var subspace in subspaces) { + for (final subspace in subspaces) { if (subspace.tags != null) { initialTags.addAll( subspace.tags!.map( @@ -200,8 +199,8 @@ class TagHelper { } static Map groupTags(List tags) { - final Map groupedTags = {}; - for (var tag in tags) { + final groupedTags = {}; + for (final tag in tags) { if (tag.product != null) { final product = tag.product!; groupedTags[product] = (groupedTags[product] ?? 0) + 1; @@ -212,10 +211,10 @@ class TagHelper { static List createInitialSelectedProducts( List? tags, List? subspaces) { - final Map productCounts = {}; + final productCounts = {}; if (tags != null) { - for (var tag in tags) { + for (final tag in tags) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; } @@ -223,9 +222,9 @@ class TagHelper { } if (subspaces != null) { - for (var subspace in subspaces) { + for (final subspace in subspaces) { if (subspace.tags != null) { - for (var tag in subspace.tags!) { + for (final tag in subspace.tags!) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; @@ -247,10 +246,10 @@ class TagHelper { static List createInitialSelectedProductsForTags( List? tags, List? subspaces) { - final Map productCounts = {}; + final productCounts = {}; if (tags != null) { - for (var tag in tags) { + for (final tag in tags) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; } @@ -258,9 +257,9 @@ class TagHelper { } if (subspaces != null) { - for (var subspace in subspaces) { + for (final subspace in subspaces) { if (subspace.tags != null) { - for (var tag in subspace.tags!) { + for (final tag in subspace.tags!) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; @@ -280,14 +279,13 @@ class TagHelper { .toList(); } - static int? checkTagExistInSubspaceModels( - Tag tag, List? subspaces) { + static int? checkTagExistInSubspaceModels(Tag tag, List? subspaces) { if (subspaces == null) return null; - for (int i = 0; i < subspaces.length; i++) { + for (var i = 0; i < subspaces.length; i++) { final subspace = subspaces[i] as SubspaceTemplateModel; // Explicit cast if (subspace.tags == null) continue; - for (var t in subspace.tags!) { + for (final t in subspace.tags!) { if (tag.internalId == t.internalId) { return i; } @@ -314,11 +312,11 @@ class TagHelper { final processedSubspaces = List.from(result['subspaces'] as List); - for (var subspace in processedSubspaces) { + for (final subspace in processedSubspaces) { final subspaceTags = subspace.tags; if (subspaceTags != null) { - for (int i = 0; i < subspaceTags.length; i++) { + for (var i = 0; i < subspaceTags.length; i++) { final tag = subspaceTags[i]; // Find the updated tag inside processedTags @@ -341,10 +339,10 @@ class TagHelper { static int? checkTagExistInSubspace(Tag tag, List? subspaces) { if (subspaces == null) return null; - for (int i = 0; i < subspaces.length; i++) { + for (var i = 0; i < subspaces.length; i++) { final subspace = subspaces[i]; if (subspace.tags == null) continue; - for (var t in subspace.tags!) { + for (final t in subspace.tags!) { if (tag.internalId == t.internalId) { return i; } @@ -371,11 +369,11 @@ class TagHelper { final processedSubspaces = List.from(result['subspaces'] as List); - for (var subspace in processedSubspaces) { + for (final subspace in processedSubspaces) { final subspaceTags = subspace.tags; if (subspaceTags != null) { - for (int i = 0; i < subspaceTags.length; i++) { + for (var i = 0; i < subspaceTags.length; i++) { final tag = subspaceTags[i]; final changedTag = updatedTags.firstWhere( @@ -397,10 +395,10 @@ class TagHelper { static List getAllTagValues( List communities, List? spaceModels) { - final Set allTags = {}; + final allTags = {}; if (spaceModels != null) { - for (var model in spaceModels) { + for (final model in spaceModels) { allTags.addAll(model.listAllTagValues()); } } diff --git a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart index 5b85e17e..aab51b59 100644 --- a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart +++ b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart @@ -26,27 +26,27 @@ class LinkSpaceToModelBloc Future _getSpaceIds(LinkSpaceModelSelectedIdsEvent event, Emitter emit) async { try { - BuildContext context = NavigationService.navigatorKey.currentContext!; - var spaceBloc = context.read(); - spacesListIds.clear(); - for (var communityId in spaceBloc.state.selectedCommunities) { - List spacesList = + final context = NavigationService.navigatorKey.currentContext!; + final spaceBloc = context.read(); + spacesListIds.clear(); + for (final communityId in spaceBloc.state.selectedCommunities) { + final spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - spacesListIds.addAll(spacesList); + spacesListIds.addAll(spacesList); } hasSelectedSpaces = spaceBloc.state.selectedCommunities.any((communityId) { - List spacesList = + final spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; return spacesList.isNotEmpty; }); if (hasSelectedSpaces) { - debugPrint("At least one space is selected."); + debugPrint('At least one space is selected.'); } else { - debugPrint("No spaces selected."); + debugPrint('No spaces selected.'); } } catch (e) { - debugPrint("Error in _getSpaceIds: $e"); + debugPrint('Error in _getSpaceIds: $e'); } } diff --git a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart index ad18b3c7..ec358985 100644 --- a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart +++ b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart @@ -5,8 +5,8 @@ abstract class LinkSpaceToModelState { class SpaceModelInitial extends LinkSpaceToModelState {} class SpaceModelLoading extends LinkSpaceToModelState {} -class LinkSpaceModelLoading extends LinkSpaceToModelState {} +class LinkSpaceModelLoading extends LinkSpaceToModelState {} class SpaceModelSelectedState extends LinkSpaceToModelState { final int selectedIndex; diff --git a/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart b/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart index bbd0de36..9e50b881 100644 --- a/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart +++ b/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart @@ -15,11 +15,11 @@ class LinkSpaceModelDialog extends StatelessWidget { final List spaceModels; const LinkSpaceModelDialog({ - Key? key, + super.key, this.onSave, this.initialSelectedIndex, required this.spaceModels, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -39,9 +39,10 @@ class LinkSpaceModelDialog extends StatelessWidget { color: ColorsManager.textFieldGreyColor, width: MediaQuery.of(context).size.width * 0.7, height: MediaQuery.of(context).size.height * 0.6, - child: BlocBuilder( + child: BlocBuilder( builder: (context, state) { - int selectedIndex = -1; + var selectedIndex = -1; if (state is SpaceModelSelectedState) { selectedIndex = state.selectedIndex; } @@ -72,7 +73,9 @@ class LinkSpaceModelDialog extends StatelessWidget { ), borderRadius: BorderRadius.circular(8.0), ), - child: SpaceModelCardWidget(model: model,), + child: SpaceModelCardWidget( + model: model, + ), ), ); }, diff --git a/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart b/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart index 5428c343..e386b186 100644 --- a/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart +++ b/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart @@ -5,7 +5,6 @@ import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_spac 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/space_template_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_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/utils/constants/action_enum.dart'; @@ -21,7 +20,7 @@ class CreateSpaceModelBloc try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - late SpaceTemplateModel spaceTemplate = event.spaceTemplate; + late final spaceTemplate = event.spaceTemplate; final tagBodyModels = spaceTemplate.tags?.map((tag) => tag.toTagBodyModel()).toList() ?? @@ -55,7 +54,7 @@ class CreateSpaceModelBloc } } } catch (e) { - emit(CreateSpaceModelError('Error creating space model')); + emit(const CreateSpaceModelError('Error creating space model')); } }); @@ -65,14 +64,14 @@ class CreateSpaceModelBloc if (_space != null) { emit(CreateSpaceModelLoaded(_space!)); } else { - emit(CreateSpaceModelError("No space template found")); + emit(const CreateSpaceModelError('No space template found')); } }); }); on((event, emit) { _space = event.spaceTemplate; - final String? errorMessage = _checkDuplicateModelName( + final errorMessage = _checkDuplicateModelName( event.allModels ?? [], event.spaceTemplate.modelName); emit(CreateSpaceModelLoaded(_space!, errorMessage: errorMessage)); }); @@ -94,9 +93,8 @@ class CreateSpaceModelBloc orElse: () => subspace, ); - final updatedTags = [ - ...?subspace.tags?.map((tag) { + ...subspace.tags?.map((tag) { final matchingTag = matchingEventSubspace.tags?.firstWhere( (e) => e.internalId == tag.internalId, @@ -108,7 +106,7 @@ class CreateSpaceModelBloc : tag; }) ?? [], - ...?matchingEventSubspace.tags?.where( + ...matchingEventSubspace.tags?.where( (e) => subspace.tags ?.every((t) => t.internalId != e.internalId) ?? @@ -127,9 +125,7 @@ class CreateSpaceModelBloc event.subspaces .where((e) => updatedSubspaces.every((s) => s.internalId != e.internalId)) - .forEach((newSubspace) { - updatedSubspaces.add(newSubspace); - }); + .forEach(updatedSubspaces.add); final updatedSpace = currentState.space.copyWith(subspaceModels: updatedSubspaces); @@ -137,7 +133,7 @@ class CreateSpaceModelBloc emit(CreateSpaceModelLoaded(updatedSpace, errorMessage: currentState.errorMessage)); } else { - emit(CreateSpaceModelError("Space template not initialized")); + emit(const CreateSpaceModelError('Space template not initialized')); } }); @@ -163,14 +159,12 @@ class CreateSpaceModelBloc event.tags .where( (e) => updatedTags.every((t) => t.internalId != e.internalId)) - .forEach((e) { - updatedTags.add(e); - }); + .forEach(updatedTags.add); emit(CreateSpaceModelLoaded( currentState.space.copyWith(tags: updatedTags))); } else { - emit(CreateSpaceModelError("Space template not initialized")); + emit(const CreateSpaceModelError('Space template not initialized')); } }); @@ -180,12 +174,12 @@ class CreateSpaceModelBloc if (event.allModels.contains(event.name) == true) { emit(CreateSpaceModelLoaded( currentState.space, - errorMessage: "Duplicate Model name", + errorMessage: 'Duplicate Model name', )); } else if (event.name.trim().isEmpty) { emit(CreateSpaceModelLoaded( currentState.space, - errorMessage: "Model name cannot be empty", + errorMessage: 'Model name cannot be empty', )); } else { final updatedSpaceModel = @@ -194,7 +188,7 @@ class CreateSpaceModelBloc emit(CreateSpaceModelLoaded(updatedSpaceModel)); } } else { - emit(CreateSpaceModelError("Space template not initialized")); + emit(const CreateSpaceModelError('Space template not initialized')); } }); @@ -211,19 +205,17 @@ class CreateSpaceModelBloc if (prevSpaceModel?.modelName != newSpaceModel.modelName) { spaceModelName = newSpaceModel.modelName; } - List tagUpdates = []; - final List subspaceUpdates = []; - final List? prevSubspaces = - prevSpaceModel?.subspaceModels; - final List? newSubspaces = - newSpaceModel.subspaceModels; + var tagUpdates = []; + final subspaceUpdates = []; + final prevSubspaces = prevSpaceModel?.subspaceModels; + final newSubspaces = newSpaceModel.subspaceModels; tagUpdates = processTagUpdates(prevSpaceModel?.tags, newSpaceModel.tags); if (prevSubspaces != null || newSubspaces != null) { if (prevSubspaces != null && newSubspaces != null) { - for (var prevSubspace in prevSubspaces) { + for (final prevSubspace in prevSubspaces) { final existsInNew = newSubspaces .any((subspace) => subspace.uuid == prevSubspace.uuid); if (!existsInNew) { @@ -232,20 +224,20 @@ class CreateSpaceModelBloc } } } else if (prevSubspaces != null && newSubspaces == null) { - for (var prevSubspace in prevSubspaces) { + for (final prevSubspace in prevSubspaces) { subspaceUpdates.add(UpdateSubspaceTemplateModel( action: Action.delete, uuid: prevSubspace.uuid)); } } if (newSubspaces != null) { - for (var newSubspace in newSubspaces) { + for (final newSubspace in newSubspaces) { // Tag without UUID - if ((newSubspace.uuid == null || newSubspace.uuid!.isEmpty)) { - final List tagUpdates = []; + if (newSubspace.uuid == null || newSubspace.uuid!.isEmpty) { + final tagUpdates = []; if (newSubspace.tags != null) { - for (var tag in newSubspace.tags!) { + for (final tag in newSubspace.tags!) { tagUpdates.add(TagModelUpdate( action: Action.add, newTagUuid: tag.uuid == '' ? null : tag.uuid, @@ -263,14 +255,14 @@ class CreateSpaceModelBloc if (prevSubspaces != null && newSubspaces != null) { final newSubspaceMap = { - for (var subspace in newSubspaces) subspace.uuid: subspace + for (final subspace in newSubspaces) subspace.uuid: subspace }; - for (var prevSubspace in prevSubspaces) { + for (final prevSubspace in prevSubspaces) { final newSubspace = newSubspaceMap[prevSubspace.uuid]; if (newSubspace != null) { - final List tagSubspaceUpdates = + final tagSubspaceUpdates = processTagUpdates(prevSubspace.tags, newSubspace.tags); subspaceUpdates.add(UpdateSubspaceTemplateModel( action: Action.update, @@ -298,7 +290,7 @@ class CreateSpaceModelBloc } } } catch (e) { - emit(CreateSpaceModelError('Error creating space model')); + emit(const CreateSpaceModelError('Error creating space model')); } }); } @@ -307,11 +299,11 @@ class CreateSpaceModelBloc List? prevTags, List? newTags, ) { - final List tagUpdates = []; + final tagUpdates = []; final processedTags = {}; if (prevTags == null && newTags != null) { - for (var newTag in newTags) { + for (final newTag in newTags) { tagUpdates.add(TagModelUpdate( action: Action.add, tag: newTag.tag, @@ -325,7 +317,7 @@ class CreateSpaceModelBloc if (newTags != null || prevTags != null) { // Case 1: Tags deleted if (prevTags != null && newTags != null) { - for (var prevTag in prevTags) { + for (final prevTag in prevTags) { final existsInNew = newTags.any((newTag) => newTag.uuid == prevTag.uuid); if (!existsInNew) { @@ -334,7 +326,7 @@ class CreateSpaceModelBloc } } } else if (prevTags != null && newTags == null) { - for (var prevTag in prevTags) { + for (final prevTag in prevTags) { tagUpdates .add(TagModelUpdate(action: Action.delete, uuid: prevTag.uuid)); } @@ -344,7 +336,7 @@ class CreateSpaceModelBloc if (newTags != null) { final prevTagUuids = prevTags?.map((t) => t.uuid).toSet() ?? {}; - for (var newTag in newTags) { + for (final newTag in newTags) { // Tag without UUID if ((newTag.uuid == null || !prevTagUuids.contains(newTag.uuid)) && !processedTags.contains(newTag.tag)) { @@ -360,9 +352,9 @@ class CreateSpaceModelBloc // Case 3: Tags updated if (prevTags != null && newTags != null) { - final newTagMap = {for (var tag in newTags) tag.uuid: tag}; + final newTagMap = {for (final tag in newTags) tag.uuid: tag}; - for (var prevTag in prevTags) { + for (final prevTag in prevTags) { final newTag = newTagMap[prevTag.uuid]; if (newTag != null) { tagUpdates.add(TagModelUpdate( @@ -381,7 +373,7 @@ class CreateSpaceModelBloc String? _checkDuplicateModelName(List allModels, String name) { if (allModels.contains(name)) { - return "Duplicate Model name"; + return 'Duplicate Model name'; } return null; } diff --git a/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart b/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart index 0d2a3a4f..897bc59c 100644 --- a/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart +++ b/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart @@ -16,7 +16,7 @@ class UpdateSpaceTemplate extends CreateSpaceModelEvent { final SpaceTemplateModel spaceTemplate; List? allModels; - UpdateSpaceTemplate(this.spaceTemplate,this.allModels); + UpdateSpaceTemplate(this.spaceTemplate, this.allModels); } class CreateSpaceTemplate extends CreateSpaceModelEvent { @@ -36,7 +36,7 @@ class UpdateSpaceTemplateName extends CreateSpaceModelEvent { final String name; final List allModels; - UpdateSpaceTemplateName({required this.name, required this.allModels}); + const UpdateSpaceTemplateName({required this.name, required this.allModels}); @override List get props => [name, allModels]; @@ -45,19 +45,19 @@ class UpdateSpaceTemplateName extends CreateSpaceModelEvent { class AddSubspacesToSpaceTemplate extends CreateSpaceModelEvent { final List subspaces; - AddSubspacesToSpaceTemplate(this.subspaces); + const AddSubspacesToSpaceTemplate(this.subspaces); } class AddTagsToSpaceTemplate extends CreateSpaceModelEvent { final List tags; - AddTagsToSpaceTemplate(this.tags); + const AddTagsToSpaceTemplate(this.tags); } class ValidateSpaceTemplateName extends CreateSpaceModelEvent { final String name; - ValidateSpaceTemplateName({required this.name}); + const ValidateSpaceTemplateName({required this.name}); } class ModifySpaceTemplate extends CreateSpaceModelEvent { @@ -65,7 +65,7 @@ class ModifySpaceTemplate extends CreateSpaceModelEvent { final SpaceTemplateModel updatedSpaceTemplate; final Function(SpaceTemplateModel)? onUpdate; - ModifySpaceTemplate( + const ModifySpaceTemplate( {required this.spaceTemplate, required this.updatedSpaceTemplate, this.onUpdate}); diff --git a/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart b/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart index 0fc5c48d..d28913b5 100644 --- a/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart +++ b/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart @@ -16,7 +16,7 @@ class CreateSpaceModelLoaded extends CreateSpaceModelState { final SpaceTemplateModel space; final String? errorMessage; - CreateSpaceModelLoaded(this.space, {this.errorMessage}); + const CreateSpaceModelLoaded(this.space, {this.errorMessage}); @override List get props => [space, errorMessage]; @@ -25,5 +25,5 @@ class CreateSpaceModelLoaded extends CreateSpaceModelState { class CreateSpaceModelError extends CreateSpaceModelState { final String message; - CreateSpaceModelError(this.message); + const CreateSpaceModelError(this.message); } diff --git a/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart b/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart index 37a8c0a9..0450d4ec 100644 --- a/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart +++ b/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart @@ -21,18 +21,21 @@ class SpaceModelBloc extends Bloc { on(_onDeleteSpaceModel); } - Future _onCreateSpaceModel(CreateSpaceModel event, Emitter emit) async { + Future _onCreateSpaceModel( + CreateSpaceModel event, Emitter emit) async { final currentState = state; if (currentState is SpaceModelLoaded) { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final newSpaceModel = await api.getSpaceModel(event.newSpaceModel.uuid ?? '', projectUuid); + final newSpaceModel = await api.getSpaceModel( + event.newSpaceModel.uuid ?? '', projectUuid); if (newSpaceModel != null) { - final updatedSpaceModels = List.from(currentState.spaceModels) - ..add(newSpaceModel); + final updatedSpaceModels = + List.from(currentState.spaceModels) + ..add(newSpaceModel); emit(SpaceModelLoaded(spaceModels: updatedSpaceModels)); } } catch (e) { @@ -41,13 +44,15 @@ class SpaceModelBloc extends Bloc { } } - Future _onUpdateSpaceModel(UpdateSpaceModel event, Emitter emit) async { + Future _onUpdateSpaceModel( + UpdateSpaceModel event, Emitter emit) async { final currentState = state; if (currentState is SpaceModelLoaded) { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final newSpaceModel = await api.getSpaceModel(event.spaceModelUuid, projectUuid); + final newSpaceModel = + await api.getSpaceModel(event.spaceModelUuid, projectUuid); if (newSpaceModel != null) { final updatedSpaceModels = currentState.spaceModels.map((model) { return model.uuid == event.spaceModelUuid ? newSpaceModel : model; @@ -61,14 +66,16 @@ class SpaceModelBloc extends Bloc { } } - Future _onDeleteSpaceModel(DeleteSpaceModel event, Emitter emit) async { + Future _onDeleteSpaceModel( + DeleteSpaceModel event, Emitter emit) async { final currentState = state; if (currentState is SpaceModelLoaded) { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final deletedSuccessfully = await api.deleteSpaceModel(event.spaceModelUuid, projectUuid); + final deletedSuccessfully = + await api.deleteSpaceModel(event.spaceModelUuid, projectUuid); if (deletedSuccessfully) { final updatedSpaceModels = currentState.spaceModels diff --git a/lib/pages/spaces_management/space_model/models/space_template_model.dart b/lib/pages/spaces_management/space_model/models/space_template_model.dart index f8926051..1481dec4 100644 --- a/lib/pages/spaces_management/space_model/models/space_template_model.dart +++ b/lib/pages/spaces_management/space_model/models/space_template_model.dart @@ -30,19 +30,18 @@ class SpaceTemplateModel extends Equatable { return SpaceTemplateModel( uuid: json['uuid'] ?? '', createdAt: json['createdAt'] != null - ? DateTime.tryParse(json['createdAt']) + ? DateTime.tryParse(json['createdAt']) : null, internalId: internalId, modelName: json['modelName'] ?? '', subspaceModels: (json['subspaceModels'] as List?) - ?.where((e) => e is Map) - .map((e) => - SubspaceTemplateModel.fromJson(e as Map)) + ?.whereType>() + .map(SubspaceTemplateModel.fromJson) .toList() ?? [], tags: (json['tags'] as List?) - ?.where((item) => item is Map) // Validate type - .map((item) => Tag.fromJson(item as Map)) + ?.whereType>() // Validate type + .map(Tag.fromJson) .toList() ?? [], ); @@ -109,7 +108,7 @@ class UpdateSubspaceTemplateModel { extension SpaceTemplateExtensions on SpaceTemplateModel { List listAllTagValues() { - final List tagValues = []; + final tagValues = []; if (tags != null) { tagValues.addAll( diff --git a/lib/pages/spaces_management/space_model/view/space_model_page.dart b/lib/pages/spaces_management/space_model/view/space_model_page.dart index eef196be..69829f4a 100644 --- a/lib/pages/spaces_management/space_model/view/space_model_page.dart +++ b/lib/pages/spaces_management/space_model/view/space_model_page.dart @@ -18,8 +18,10 @@ class SpaceModelPage extends StatelessWidget { final List projectTags; const SpaceModelPage( - {Key? key, this.products, this.onSpaceModelsUpdated, required this.projectTags}) - : super(key: key); + {super.key, + this.products, + this.onSpaceModelsUpdated, + required this.projectTags}); @override Widget build(BuildContext context) { @@ -77,7 +79,8 @@ class SpaceModelPage extends StatelessWidget { } // Render existing space model final model = spaceModels[index]; - final otherModel = List.from(allSpaceModelNames); + final otherModel = + List.from(allSpaceModelNames); otherModel.remove(model.modelName); return GestureDetector( onTap: () { @@ -115,8 +118,10 @@ class SpaceModelPage extends StatelessWidget { return Center( child: Text( 'Error: ${state.message}', - style: - Theme.of(context).textTheme.bodySmall?.copyWith(color: ColorsManager.warningRed), + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: ColorsManager.warningRed), ), ); } @@ -126,7 +131,7 @@ class SpaceModelPage extends StatelessWidget { } double _calculateChildAspectRatio(BuildContext context) { - double screenWidth = MediaQuery.of(context).size.width; + final screenWidth = MediaQuery.of(context).size.width; if (screenWidth > 1600) { return 1.5; // Decrease to make cards taller } @@ -140,7 +145,7 @@ class SpaceModelPage extends StatelessWidget { } List _getAllTagValues(List spaceModels) { - final List allTags = []; + final allTags = []; for (final spaceModel in spaceModels) { if (spaceModel.tags != null) { allTags.addAll(spaceModel.listAllTagValues()); @@ -150,7 +155,7 @@ class SpaceModelPage extends StatelessWidget { } List _getAllSpaceModelName(List spaceModels) { - final List names = []; + final names = []; for (final spaceModel in spaceModels) { names.add(spaceModel.modelName); } diff --git a/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart b/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart index 20876a39..23377f7d 100644 --- a/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class AddSpaceModelWidget extends StatelessWidget { - const AddSpaceModelWidget({Key? key}) : super(key: key); + const AddSpaceModelWidget({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart b/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart index 2cd338e4..303ef187 100644 --- a/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart @@ -9,12 +9,12 @@ class ButtonContentWidget extends StatelessWidget { final bool disabled; const ButtonContentWidget({ - Key? key, + super.key, this.icon, required this.label, this.svgAssets, this.disabled = false, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart index 2a39d67b..8079ad4a 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart @@ -45,7 +45,7 @@ class ConfirmMergeDialog extends StatelessWidget { elevation: 3, ), child: Text( - "Cancel", + 'Cancel', style: Theme.of(context) .textTheme .bodyMedium @@ -66,7 +66,7 @@ class ConfirmMergeDialog extends StatelessWidget { elevation: 3, ), child: Text( - "Ok", + 'Ok', style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, fontSize: 16, diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart index 0497b570..51a555a3 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart @@ -56,7 +56,7 @@ class ConfirmOverwriteDialog extends StatelessWidget { elevation: 3, ), child: Text( - "Cancel", + 'Cancel', style: Theme.of(context) .textTheme .bodyMedium @@ -86,7 +86,7 @@ class ConfirmOverwriteDialog extends StatelessWidget { elevation: 3, ), child: Text( - "Ok", + 'Ok', style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, fontSize: 16, diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart index 70dde231..1a429d4c 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart @@ -9,13 +9,12 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_bloc.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/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/widgets/tag_chips_display_widget.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; - +import 'package:syncrow_web/pages/spaces_management/space_model/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/widgets/subspace_model_create_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart'; import 'package:syncrow_web/services/space_model_mang_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -29,22 +28,21 @@ class CreateSpaceModelDialog extends StatelessWidget { final List projectTags; const CreateSpaceModelDialog( - {Key? key, + {super.key, this.products, this.allTags, this.spaceModel, this.pageContext, this.otherSpaceModels, this.allSpaceModels, - required this.projectTags}) - : super(key: key); + required this.projectTags}); @override Widget build(BuildContext context) { - final SpaceModelManagementApi _spaceModelApi = SpaceModelManagementApi(); + final spaceModelApi = SpaceModelManagementApi(); final screenWidth = MediaQuery.of(context).size.width; - final TextEditingController spaceNameController = TextEditingController( + final spaceNameController = TextEditingController( text: spaceModel?.modelName ?? '', ); @@ -56,7 +54,7 @@ class CreateSpaceModelDialog extends StatelessWidget { child: BlocProvider( create: (_) { final bloc = CreateSpaceModelBloc( - _spaceModelApi, + spaceModelApi, ); if (spaceModel != null) { bloc.add(UpdateSpaceTemplate(spaceModel!, otherSpaceModels)); @@ -71,7 +69,8 @@ class CreateSpaceModelDialog extends StatelessWidget { spaceNameController.addListener(() { bloc.add(UpdateSpaceTemplateName( - name: spaceNameController.text, allModels: otherSpaceModels ?? [])); + name: spaceNameController.text, + allModels: otherSpaceModels ?? [])); }); return bloc; @@ -89,7 +88,9 @@ class CreateSpaceModelDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text( - spaceModel?.uuid == null ? 'Create New Space Model' : 'Edit Space Model', + spaceModel?.uuid == null + ? 'Create New Space Model' + : 'Edit Space Model', style: Theme.of(context) .textTheme .headlineLarge @@ -101,8 +102,10 @@ class CreateSpaceModelDialog extends StatelessWidget { child: TextField( controller: spaceNameController, onChanged: (value) { - context.read().add(UpdateSpaceTemplateName( - name: value, allModels: otherSpaceModels ?? [])); + context.read().add( + UpdateSpaceTemplateName( + name: value, + allModels: otherSpaceModels ?? [])); }, style: Theme.of(context) .textTheme @@ -176,55 +179,84 @@ class CreateSpaceModelDialog extends StatelessWidget { !isNameValid) ? null : () { - final updatedSpaceTemplate = updatedSpaceModel.copyWith( - modelName: spaceNameController.text.trim(), + final updatedSpaceTemplate = + updatedSpaceModel.copyWith( + modelName: + spaceNameController.text.trim(), ); if (updatedSpaceModel.uuid == null) { - context.read().add( + context + .read() + .add( CreateSpaceTemplate( - spaceTemplate: updatedSpaceTemplate, + spaceTemplate: + updatedSpaceTemplate, onCreate: (newModel) { if (pageContext != null) { - pageContext!.read().add( - CreateSpaceModel(newSpaceModel: newModel)); pageContext! - .read() - .add(UpdateSpaceModelCache(newModel)); + .read() + .add(CreateSpaceModel( + newSpaceModel: + newModel)); + pageContext! + .read< + SpaceManagementBloc>() + .add( + UpdateSpaceModelCache( + newModel)); } - Navigator.of(context).pop(); // Close the dialog + Navigator.of(context) + .pop(); // Close the dialog }, ), ); } else { if (pageContext != null) { - final currentState = - pageContext!.read().state; - if (currentState is SpaceModelLoaded) { - final spaceModels = List.from( - currentState.spaceModels); + final currentState = pageContext! + .read() + .state; + if (currentState + is SpaceModelLoaded) { + final spaceModels = + List.from( + currentState.spaceModels); - final SpaceTemplateModel? currentSpaceModel = - spaceModels.cast().firstWhere( - (sm) => sm?.uuid == updatedSpaceModel.uuid, + final currentSpaceModel = + spaceModels + .cast() + .firstWhere( + (sm) => + sm?.uuid == + updatedSpaceModel + .uuid, orElse: () => null, ); if (currentSpaceModel != null) { context .read() .add(ModifySpaceTemplate( - spaceTemplate: currentSpaceModel, - updatedSpaceTemplate: updatedSpaceTemplate, + spaceTemplate: + currentSpaceModel, + updatedSpaceTemplate: + updatedSpaceTemplate, onUpdate: (newModel) { - if (pageContext != null) { - pageContext!.read().add( - UpdateSpaceModel( - spaceModelUuid: - newModel.uuid ?? '')); + if (pageContext != + null) { pageContext! - .read() - .add(UpdateSpaceModelCache(newModel)); + .read< + SpaceModelBloc>() + .add(UpdateSpaceModel( + spaceModelUuid: + newModel.uuid ?? + '')); + pageContext! + .read< + SpaceManagementBloc>() + .add(UpdateSpaceModelCache( + newModel)); } - Navigator.of(context).pop(); + Navigator.of(context) + .pop(); })); } } @@ -233,11 +265,11 @@ class CreateSpaceModelDialog extends StatelessWidget { }, backgroundColor: ColorsManager.secondaryColor, borderRadius: 10, - foregroundColor: - ((state.errorMessage != null && state.errorMessage != '') || - !isNameValid) - ? ColorsManager.whiteColorsWithOpacity - : ColorsManager.whiteColors, + foregroundColor: ((state.errorMessage != null && + state.errorMessage != '') || + !isNameValid) + ? ColorsManager.whiteColorsWithOpacity + : ColorsManager.whiteColors, child: const Text('OK'), ), ), diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart index e0260887..8313360c 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart @@ -1,9 +1,10 @@ import 'dart:math'; -import 'package:flutter/material.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart'; +import 'package:flutter/material.dart'; class CustomLoadingIndicator extends StatefulWidget { + const CustomLoadingIndicator({super.key}); + @override _CustomLoadingIndicatorState createState() => _CustomLoadingIndicatorState(); } @@ -50,22 +51,22 @@ class _CustomLoadingIndicatorState extends State class LoadingPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final Paint paint = Paint() + final paint = Paint() ..strokeWidth = 5 ..strokeCap = StrokeCap.round ..style = PaintingStyle.stroke; - final double radius = size.width / 2; - final Offset center = Offset(size.width / 2, size.height / 2); + final radius = size.width / 2; + final center = Offset(size.width / 2, size.height / 2); - for (int i = 0; i < 12; i++) { - final double angle = (i * 30) * (pi / 180); - final double startX = center.dx + radius * cos(angle); - final double startY = center.dy + radius * sin(angle); - final double endX = center.dx + (radius - 8) * cos(angle); - final double endY = center.dy + (radius - 8) * sin(angle); + for (var i = 0; i < 12; i++) { + final angle = (i * 30) * (pi / 180); + final startX = center.dx + radius * cos(angle); + final startY = center.dy + radius * sin(angle); + final endX = center.dx + (radius - 8) * cos(angle); + final endY = center.dy + (radius - 8) * sin(angle); - paint.color = Colors.blue.withOpacity(i / 12); // Gradient effect + paint.color = Colors.blue.withValues(alpha: i / 12); // Gradient effect canvas.drawLine(Offset(startX, startY), Offset(endX, endY), paint); } } diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart index 8349baa4..c5a11c4a 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart @@ -6,8 +6,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; class DeleteSpaceModelDialog extends StatelessWidget { final VoidCallback onConfirmDelete; - const DeleteSpaceModelDialog({Key? key, required this.onConfirmDelete}) - : super(key: key); + const DeleteSpaceModelDialog({super.key, required this.onConfirmDelete}); @override Widget build(BuildContext context) { @@ -20,7 +19,7 @@ class DeleteSpaceModelDialog extends StatelessWidget { backgroundColor: ColorsManager.whiteColors, title: Center( child: Text( - "Delete Space Model", + 'Delete Space Model', textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -34,13 +33,13 @@ class DeleteSpaceModelDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text( - "Are you sure you want to delete?", + 'Are you sure you want to delete?', textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 15), Text( - "The existing sub-spaces, devices, and routines will remain associated with the spaces, but the connection will be removed.", + 'The existing sub-spaces, devices, and routines will remain associated with the spaces, but the connection will be removed.', textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -60,7 +59,7 @@ class DeleteSpaceModelDialog extends StatelessWidget { onPressed: () { Navigator.of(context).pop(); // Close dialog }, - label: "Cancel", + label: 'Cancel', ), ), const SizedBox(width: 10), diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart index 4da0c642..8a4b1a67 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart @@ -47,9 +47,9 @@ class _LinkSpaceModelSpacesDialogState Widget _buildDialogContent() { widget.spaceModel.createdAt.toString(); - String formattedDate = + final formattedDate = DateFormat('yyyy-MM-dd').format(widget.spaceModel.createdAt!); - String formattedTime = + final formattedTime = DateFormat('HH:mm:ss').format(widget.spaceModel.createdAt!); return Expanded( @@ -70,7 +70,7 @@ class _LinkSpaceModelSpacesDialogState children: [ const Center( child: Text( - "Link Space Model to Spaces", + 'Link Space Model to Spaces', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, @@ -81,22 +81,21 @@ class _LinkSpaceModelSpacesDialogState const Divider(), const SizedBox(height: 16), _buildDetailRow( - "Space model name:", widget.spaceModel.modelName), + 'Space model name:', widget.spaceModel.modelName), Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( children: [ const Expanded( child: Text( - "Creation date and time:", - style: const TextStyle( - fontWeight: FontWeight.bold), + 'Creation date and time:', + style: TextStyle(fontWeight: FontWeight.bold), ), ), const SizedBox(width: 8), Expanded( child: Text( - "$formattedDate $formattedTime", + '$formattedDate $formattedTime', style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.black), @@ -107,14 +106,14 @@ class _LinkSpaceModelSpacesDialogState ), // _buildDetailRow("Creation date and time:", // widget.spaceModel.createdAt.toString()), - _buildDetailRow("Created by:", "Admin"), + _buildDetailRow('Created by:', 'Admin'), const SizedBox(height: 12), const Text( - "Link to:", + 'Link to:', style: TextStyle(fontWeight: FontWeight.bold), ), const Text( - "Please select all the spaces where you would like to link the Routine.", + 'Please select all the spaces where you would like to link the Routine.', style: TextStyle(fontSize: 12, color: Colors.grey), ), const SizedBox(height: 8), @@ -124,7 +123,7 @@ class _LinkSpaceModelSpacesDialogState children: [ Expanded( flex: 7, - child: Container( + child: ColoredBox( color: ColorsManager.whiteColors, child: SpaceTreeView( isSide: true, @@ -170,7 +169,7 @@ class _LinkSpaceModelSpacesDialogState ), ), ), - child: _buildButton("Cancel", Colors.grey, () { + child: _buildButton('Cancel', Colors.grey, () { Navigator.of(context).pop(); }), ), @@ -191,14 +190,14 @@ class _LinkSpaceModelSpacesDialogState ), ), child: _buildButton( - "Confirm", + 'Confirm', ColorsManager.onSecondaryColor, () { final spaceModelBloc = context.read(); if (!spaceModelBloc.hasSelectedSpaces) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( - content: Text("Please select at least one space")), + content: Text('Please select at least one space')), ); return; } else { diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart index 15d92029..d16f2c7e 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart @@ -62,7 +62,7 @@ class LinkingAttentionDialog extends StatelessWidget { elevation: 3, ), child: Text( - "Overwrite", + 'Overwrite', style: Theme.of(context) .textTheme .bodyMedium @@ -93,7 +93,7 @@ class LinkingAttentionDialog extends StatelessWidget { elevation: 3, ), child: Text( - "Merge", + 'Merge', style: Theme.of(context) .textTheme .bodyMedium diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart index 9f57a4b1..ca8f3aeb 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart @@ -23,7 +23,7 @@ void showOverwriteDialog( mainAxisSize: MainAxisSize.min, children: [ const Text( - "Overwrite", + 'Overwrite', style: TextStyle( fontSize: 22, fontWeight: FontWeight.bold, @@ -32,13 +32,13 @@ void showOverwriteDialog( ), const SizedBox(height: 15), const Text( - "Are you sure you want to overwrite?", + 'Are you sure you want to overwrite?', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), textAlign: TextAlign.center, ), const SizedBox(height: 5), Text( - "Selected spaces already have linked space model / sub-spaces and devices", + 'Selected spaces already have linked space model / sub-spaces and devices', style: TextStyle( fontSize: 14, color: Colors.grey[600], @@ -61,7 +61,7 @@ void showOverwriteDialog( elevation: 0, ), child: const Text( - "Cancel", + 'Cancel', style: TextStyle( fontSize: 16, color: Colors.black, @@ -88,7 +88,7 @@ void showOverwriteDialog( elevation: 3, ), child: const Text( - "OK", + 'OK', style: TextStyle( fontSize: 16, color: Colors.white, diff --git a/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart b/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart index 4f42e3bf..475b24ed 100644 --- a/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart @@ -10,28 +10,28 @@ class DynamicProductWidget extends StatelessWidget { final double maxHeight; const DynamicProductWidget({ - Key? key, + super.key, required this.productTagCount, required this.maxWidth, required this.maxHeight, - }) : super(key: key); + }); @override Widget build(BuildContext context) { - const double itemSpacing = 8.0; - const double lineSpacing = 8.0; - const double textPadding = 16.0; - const double itemHeight = 40.0; + const itemSpacing = 8.0; + const lineSpacing = 8.0; + const textPadding = 16.0; + const itemHeight = 40.0; - List productWidgets = []; - double currentLineWidth = 0.0; - double currentHeight = itemHeight; + final productWidgets = []; + var currentLineWidth = 0.0; + var currentHeight = itemHeight; for (final product in productTagCount.entries) { - final String prodType = product.key; - final int count = product.value; + final prodType = product.key; + final count = product.value; - final TextPainter textPainter = TextPainter( + final textPainter = TextPainter( text: TextSpan( text: 'x$count', style: Theme.of(context) @@ -42,7 +42,7 @@ class DynamicProductWidget extends StatelessWidget { textDirection: TextDirection.ltr, )..layout(); - final double itemWidth = textPainter.width + textPadding + 20; + final itemWidth = textPainter.width + textPadding + 20; if (currentLineWidth + itemWidth + itemSpacing > maxWidth) { currentHeight += itemHeight + lineSpacing; diff --git a/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart b/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart index f3da4122..d9610ff9 100644 --- a/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart @@ -8,38 +8,37 @@ class DynamicRoomWidget extends StatelessWidget { final double maxHeight; const DynamicRoomWidget({ - Key? key, + super.key, required this.subspaceModels, required this.maxWidth, required this.maxHeight, - }) : super(key: key); + }); @override Widget build(BuildContext context) { - const double itemSpacing = 8.0; - const double lineSpacing = 8.0; - const double textPadding = 16.0; - const double itemHeight = 30.0; + const itemSpacing = 8.0; + const lineSpacing = 8.0; + const textPadding = 16.0; + const itemHeight = 30.0; - List roomWidgets = []; - double currentLineWidth = 0.0; - double currentHeight = itemHeight; + final roomWidgets = []; + var currentLineWidth = 0.0; + var currentHeight = itemHeight; for (final subspace in subspaceModels!) { - final TextPainter textPainter = TextPainter( + final textPainter = TextPainter( text: TextSpan( - text: subspace.subspaceName, - style: Theme.of(context).textTheme.bodyMedium - ), + text: subspace.subspaceName, + style: Theme.of(context).textTheme.bodyMedium), textDirection: TextDirection.ltr, )..layout(); - final double itemWidth = textPainter.width + textPadding; + final itemWidth = textPainter.width + textPadding; if (currentLineWidth + itemWidth + itemSpacing > maxWidth) { currentHeight += itemHeight + lineSpacing; if (currentHeight > maxHeight) { - roomWidgets.add(const RoomNameWidget(name: "...")); + roomWidgets.add(const RoomNameWidget(name: '...')); break; } currentLineWidth = 0.0; diff --git a/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart b/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart index 7ede09a7..8b3f2965 100644 --- a/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class EllipsisItemWidget extends StatelessWidget { - const EllipsisItemWidget({Key? key}) : super(key: key); + const EllipsisItemWidget({super.key}); @override Widget build(BuildContext context) { @@ -14,7 +14,7 @@ class EllipsisItemWidget extends StatelessWidget { border: Border.all(color: ColorsManager.transparentColor), ), child: Text( - "...", + '...', style: Theme.of(context) .textTheme .bodySmall diff --git a/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart b/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart index c28a82b8..aea3b56a 100644 --- a/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart @@ -7,10 +7,10 @@ class FlexibleItemWidget extends StatelessWidget { final int count; const FlexibleItemWidget({ - Key? key, + super.key, required this.prodType, required this.count, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart b/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart index d59f8c1e..7ba1b095 100644 --- a/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart @@ -4,7 +4,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; class RoomNameWidget extends StatelessWidget { final String name; - const RoomNameWidget({Key? key, required this.name}) : super(key: key); + const RoomNameWidget({super.key, required this.name}); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart index 4d72a419..67a72268 100644 --- a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.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_event.dart'; import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_to_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.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_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -27,27 +27,27 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { final bool topActionsDisabled; const SpaceModelCardWidget({ - Key? key, + super.key, required this.model, this.pageContext, this.topActionsDisabled = true, - }) : super(key: key); + }); @override Widget build(BuildContext context) { - final Map productTagCount = {}; + final productTagCount = {}; if (model.tags != null) { - for (var tag in model.tags!) { + for (final tag in model.tags!) { final prodIcon = tag.product?.icon ?? 'Unknown'; productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1; } } if (model.subspaceModels != null) { - for (var subspace in model.subspaceModels!) { + for (final subspace in model.subspaceModels!) { if (subspace.tags != null) { - for (var tag in subspace.tags!) { + for (final tag in subspace.tags!) { final prodIcon = tag.product?.icon ?? 'Unknown'; productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1; } @@ -57,7 +57,7 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { return LayoutBuilder( builder: (context, constraints) { - bool showOnlyName = constraints.maxWidth < 250; + final showOnlyName = constraints.maxWidth < 250; return Container( padding: const EdgeInsets.all(16.0), decoration: BoxDecoration( @@ -65,7 +65,7 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.5), + color: Colors.grey.withValues(alpha: 0.5), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3), @@ -81,11 +81,12 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { Expanded( child: Text( StringUtils.capitalizeFirstLetter(model.modelName), - style: Theme.of(context).textTheme.headlineMedium?.copyWith( - color: ColorsManager.blackColor, - fontWeight: FontWeight.bold, - fontSize: isSmallScreenSize(context) ? 13 : 20, - ), + style: + Theme.of(context).textTheme.headlineMedium?.copyWith( + color: ColorsManager.blackColor, + fontWeight: FontWeight.bold, + fontSize: isSmallScreenSize(context) ? 13 : 20, + ), maxLines: 2, overflow: TextOverflow.ellipsis, ), @@ -100,12 +101,15 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { builder: (BuildContext dialogContext) { return BlocProvider( create: (_) => LinkSpaceToModelBloc(), - child: BlocListener( + child: BlocListener( listenWhen: (previous, current) { return previous != current; }, listener: (context, state) { - final _bloc = BlocProvider.of(context); + final bloc = + BlocProvider.of( + context); if (state is SpaceModelLoading) { showDialog( context: context, @@ -113,14 +117,18 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { builder: (BuildContext context) { return Dialog( shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20)), + borderRadius: + BorderRadius.circular( + 20)), elevation: 10, backgroundColor: Colors.white, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 30, horizontal: 50), + child: const Padding( + padding: EdgeInsets.symmetric( + vertical: 30, + horizontal: 50), child: Column( - mainAxisSize: MainAxisSize.min, + mainAxisSize: + MainAxisSize.min, children: [ CustomLoadingIndicator(), ], @@ -129,14 +137,19 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { ); }, ); - } else if (state is AlreadyHaveLinkedState) { + } else if (state + is AlreadyHaveLinkedState) { Navigator.of(dialogContext).pop(); - showOverwriteDialog(context, _bloc, model); - } else if (state is SpaceValidationSuccess) { - _bloc.add(LinkSpaceModelEvent( - isOverWrite: false, selectedSpaceMode: model.uuid)); + showOverwriteDialog( + context, bloc, model); + } else if (state + is SpaceValidationSuccess) { + bloc.add(LinkSpaceModelEvent( + isOverWrite: false, + selectedSpaceMode: model.uuid)); - Future.delayed(const Duration(seconds: 1), () { + Future.delayed( + const Duration(seconds: 1), () { Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop(); @@ -144,23 +157,29 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { showDialog( context: context, - builder: (BuildContext dialogContext) { + builder: + (BuildContext dialogContext) { return const LinkingSuccessful(); }, ).then((v) { - Future.delayed(const Duration(seconds: 2), () { + Future.delayed( + const Duration(seconds: 2), () { Navigator.of(dialogContext).pop(); }); }); - } else if (state is SpaceModelLinkSuccess) { + } else if (state + is SpaceModelLinkSuccess) { Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop(); showDialog( context: context, barrierDismissible: false, - builder: (BuildContext successDialogContext) { - Future.delayed(const Duration(seconds: 2), () { - Navigator.of(successDialogContext).pop(); + builder: (BuildContext + successDialogContext) { + Future.delayed( + const Duration(seconds: 2), () { + Navigator.of(successDialogContext) + .pop(); }); return const LinkingSuccessful(); @@ -218,7 +237,8 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { ), ), ), - if (productTagCount.isNotEmpty && model.subspaceModels != null) + if (productTagCount.isNotEmpty && + model.subspaceModels != null) Container( width: 1.0, color: ColorsManager.softGray, diff --git a/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart b/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart index 70ac6e24..0d66dbac 100644 --- a/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart @@ -5,9 +5,9 @@ class SubspaceChipWidget extends StatelessWidget { final String subspace; const SubspaceChipWidget({ - Key? key, + super.key, required this.subspace, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart b/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart index 4ebd65df..5cb4a9ff 100644 --- a/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/common/edit_chip.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace_model/views/create_subspace_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace_model/views/create_subspace_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -15,11 +15,11 @@ class SubspaceModelCreate extends StatefulWidget { final List tags; const SubspaceModelCreate({ - Key? key, + super.key, required this.subspaces, this.onSpaceModelUpdate, required this.tags, - }) : super(key: key); + }); @override _SubspaceModelCreateState createState() => _SubspaceModelCreateState(); @@ -117,9 +117,9 @@ class _SubspaceModelCreateState extends State { .where((s) => !updatedIds.contains(s.internalId)) .toList(); - final List tagsToAppendToSpace = []; + final tagsToAppendToSpace = []; - for (var s in deletedSubspaces) { + for (final s in deletedSubspaces) { if (s.tags != null) { tagsToAppendToSpace.addAll(s.tags!); } diff --git a/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart b/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart index 6a6aec44..c27a1436 100644 --- a/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart @@ -12,7 +12,7 @@ class SubspaceNameDisplayWidget extends StatefulWidget { final bool Function(String updatedName) validateName; const SubspaceNameDisplayWidget({ - Key? key, + super.key, required this.text, this.textStyle, this.backgroundColor = ColorsManager.whiteColors, @@ -21,7 +21,7 @@ class SubspaceNameDisplayWidget extends StatefulWidget { this.borderRadius = const BorderRadius.all(Radius.circular(10)), required this.onNameChanged, required this.validateName, - }) : super(key: key); + }); @override _SubspaceNameDisplayWidgetState createState() => diff --git a/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart b/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart index 86f99e02..2ff1b085 100644 --- a/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart @@ -50,7 +50,8 @@ class TagChipDisplay extends StatelessWidget { Widget build(BuildContext context) { final hasTags = spaceModel?.tags?.isNotEmpty ?? false; final hasSubspaceTags = - spaceModel?.subspaceModels?.any((e) => e.tags?.isNotEmpty ?? false) ?? false; + spaceModel?.subspaceModels?.any((e) => e.tags?.isNotEmpty ?? false) ?? + false; if (hasTags || hasSubspaceTags) { return Container( diff --git a/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart b/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart index 1de2ae13..23cfb1d9 100644 --- a/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart +++ b/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart @@ -13,7 +13,7 @@ class CenterBodyBloc extends Bloc { emit(SpaceModelState()); }); - on((event, emit) { + on((event, emit) { emit(CommunitySelectedState()); }); } diff --git a/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart b/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart index 72cdbd1c..d70a0b55 100644 --- a/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart +++ b/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart @@ -5,4 +5,4 @@ class CommunityStructureSelectedEvent extends CenterBodyEvent {} class SpaceModelSelectedEvent extends CenterBodyEvent {} -class CommunitySelectedEvent extends CenterBodyEvent {} \ No newline at end of file +class CommunitySelectedEvent extends CenterBodyEvent {} diff --git a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart index dbc6c7ef..6b0ff481 100644 --- a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart +++ b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_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_event.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_event.dart'; import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_state.dart'; -import '../bloc/center_body_bloc.dart'; class CenterBodyWidget extends StatelessWidget { + const CenterBodyWidget({super.key}); + @override Widget build(BuildContext context) { return BlocBuilder( @@ -52,7 +54,7 @@ class CenterBodyWidget extends StatelessWidget { .textTheme .bodyLarge! .color! - .withOpacity(0.5), + .withValues(alpha: 0.5), ), ), ), @@ -73,7 +75,7 @@ class CenterBodyWidget extends StatelessWidget { // .textTheme // .bodyLarge! // .color! - // .withOpacity(0.5), + // .withValues(alpha:0.5), // ), // ), // ), diff --git a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart index 27f183a6..5ee52b08 100644 --- a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart +++ b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart @@ -1,5 +1,4 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; @@ -13,7 +12,7 @@ abstract class AddDeviceTypeModelEvent extends Equatable { class UpdateProductCountEvent extends AddDeviceTypeModelEvent { final SelectedProduct selectedProduct; - UpdateProductCountEvent({required this.selectedProduct}); + const UpdateProductCountEvent({required this.selectedProduct}); @override List get props => [selectedProduct]; diff --git a/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart b/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart index c0226ba8..e9823fee 100644 --- a/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart +++ b/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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/spaces_management/all_spaces/model/tag.dart'; -import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.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/subspace_template_model.dart'; @@ -80,7 +80,8 @@ class AddDeviceTypeModelWidget extends StatelessWidget { const SizedBox(height: 16), Expanded( child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), + padding: + const EdgeInsets.symmetric(horizontal: 20.0), child: ScrollableGridViewWidget( isCreate: isCreate, products: products, @@ -152,10 +153,11 @@ class AddDeviceTypeModelWidget extends StatelessWidget { ), SizedBox( width: 140, - child: BlocBuilder( + child: + BlocBuilder( builder: (context, state) { - final isDisabled = - state is AddDeviceModelLoaded && state.selectedProducts.isEmpty; + final isDisabled = state is AddDeviceModelLoaded && + state.selectedProducts.isEmpty; return DefaultButton( backgroundColor: ColorsManager.secondaryColor, @@ -168,13 +170,15 @@ class AddDeviceTypeModelWidget extends StatelessWidget { : () async { if (state is AddDeviceModelLoaded && state.selectedProducts.isNotEmpty) { - final initialTags = TagHelper.generateInitialTags( + final initialTags = + TagHelper.generateInitialTags( spaceTagModels: spaceTagModels, subspaces: subspaces, ); - final dialogTitle = - initialTags.isNotEmpty ? 'Edit Device' : 'Assign Tags'; + final dialogTitle = initialTags.isNotEmpty + ? 'Edit Device' + : 'Assign Tags'; Navigator.of(context).pop(); await showDialog( context: context, diff --git a/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart b/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart index d1775c66..8a64fe41 100644 --- a/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart +++ b/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart @@ -12,13 +12,12 @@ class ScrollableGridViewWidget extends StatelessWidget { final List? initialProductCounts; final bool isCreate; - const ScrollableGridViewWidget({ - super.key, - required this.products, - required this.crossAxisCount, - this.initialProductCounts, - required this.isCreate - }); + const ScrollableGridViewWidget( + {super.key, + required this.products, + required this.crossAxisCount, + this.initialProductCounts, + required this.isCreate}); @override Widget build(BuildContext context) { diff --git a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart index 438b1abf..6bcd8b62 100644 --- a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart +++ b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart @@ -14,14 +14,10 @@ import 'package:syncrow_web/pages/visitor_password/model/schedule_model.dart'; import 'package:syncrow_web/services/access_mang_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; -import 'package:syncrow_web/utils/constants/strings_manager.dart'; -import 'package:syncrow_web/utils/constants/temp_const.dart'; -import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; class VisitorPasswordBloc extends Bloc { - VisitorPasswordBloc() : super(VisitorPasswordInitial()) { on(selectUsageFrequency); on(_onFetchDevice); @@ -71,13 +67,13 @@ class VisitorPasswordBloc String startTimeAccess = 'Start Time'; String endTimeAccess = 'End Time'; PasswordStatus? passwordStatus; - selectAccessType( + void selectAccessType( SelectPasswordType event, Emitter emit) { accessTypeSelected = event.type; emit(PasswordTypeSelected(event.type)); } - selectUsageFrequency( + void selectUsageFrequency( SelectUsageFrequency event, Emitter emit) { usageFrequencySelected = event.usageType; emit(UsageFrequencySelected(event.usageType)); @@ -87,7 +83,7 @@ class VisitorPasswordBloc SelectTimeVisitorPassword event, Emitter emit, ) async { - final DateTime? picked = await showDatePicker( + final picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), firstDate: DateTime(2015, 8), @@ -95,7 +91,7 @@ class VisitorPasswordBloc ); if (picked != null) { - final TimeOfDay? timePicked = await showTimePicker( + final timePicked = await showTimePicker( context: event.context, initialTime: TimeOfDay.now(), builder: (context, child) { @@ -164,13 +160,13 @@ class VisitorPasswordBloc } List> days = [ - {"day": "Sun", "key": "Sun"}, - {"day": "Mon", "key": "Mon"}, - {"day": "Tue", "key": "Tue"}, - {"day": "Wed", "key": "Wed"}, - {"day": "Thu", "key": "Thu"}, - {"day": "Fri", "key": "Fri"}, - {"day": "Sat", "key": "Sat"}, + {'day': 'Sun', 'key': 'Sun'}, + {'day': 'Mon', 'key': 'Mon'}, + {'day': 'Tue', 'key': 'Tue'}, + {'day': 'Wed', 'key': 'Wed'}, + {'day': 'Thu', 'key': 'Thu'}, + {'day': 'Fri', 'key': 'Fri'}, + {'day': 'Sat', 'key': 'Sat'}, ]; List selectedDays = []; @@ -192,12 +188,12 @@ class VisitorPasswordBloc FetchDevice event, Emitter emit) async { try { emit(DeviceLoaded()); - final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; data = await AccessMangApi().fetchDoorLockDeviceList(projectUuid); emit(TableLoaded(data)); } catch (e) { - print("error: $e"); + print('error: $e'); emit(FailedState(e.toString())); } } @@ -208,7 +204,7 @@ class VisitorPasswordBloc try { emit(LoadingInitialState()); generate7DigitNumber(); - var res = await AccessMangApi().postOnlineOneTime( + final res = await AccessMangApi().postOnlineOneTime( email: event.email, password: passwordController, devicesUuid: selectedDevices, @@ -222,8 +218,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - String errorMessage = errorData['message']; - emit(FailedState(errorMessage.toString())); + final String errorMessage = errorData['message']; + emit(FailedState(errorMessage)); } } @@ -234,13 +230,12 @@ class VisitorPasswordBloc emit(LoadingInitialState()); await generate7DigitNumber(); - var res = await AccessMangApi().postOnlineMultipleTime( + final res = await AccessMangApi().postOnlineMultipleTime( scheduleList: [ if (repeat) Schedule( effectiveTime: getTimeFromDateTimeString(effectiveTime), - invalidTime: - getTimeFromDateTimeString(expirationTime).toString(), + invalidTime: getTimeFromDateTimeString(expirationTime), workingDay: selectedDays, ), ], @@ -257,8 +252,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - String errorMessage = errorData['message']; - emit(FailedState(errorMessage.toString())); + final String errorMessage = errorData['message']; + emit(FailedState(errorMessage)); } } @@ -268,7 +263,7 @@ class VisitorPasswordBloc try { emit(LoadingInitialState()); await generate7DigitNumber(); - var res = await AccessMangApi().postOffLineOneTime( + final res = await AccessMangApi().postOffLineOneTime( email: event.email, devicesUuid: selectedDevices, passwordName: event.passwordName); @@ -279,8 +274,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - String errorMessage = errorData['message']; - emit(FailedState(errorMessage.toString())); + final String errorMessage = errorData['message']; + emit(FailedState(errorMessage)); } } @@ -290,7 +285,7 @@ class VisitorPasswordBloc try { emit(LoadingInitialState()); await generate7DigitNumber(); - var res = await AccessMangApi().postOffLineMultipleTime( + final res = await AccessMangApi().postOffLineMultipleTime( email: event.email, devicesUuid: selectedDevices, passwordName: event.passwordName, @@ -304,8 +299,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - String errorMessage = errorData['message']; - emit(FailedState(errorMessage.toString())); + final String errorMessage = errorData['message']; + emit(FailedState(errorMessage)); } } @@ -327,9 +322,9 @@ class VisitorPasswordBloc Future generate7DigitNumber() async { passwordController = ''; - Random random = Random(); - int min = 1000000; - int max = 9999999; + final random = Random(); + const min = 1000000; + const max = 9999999; passwordController = (min + random.nextInt(max - min + 1)).toString(); return passwordController; } @@ -365,7 +360,7 @@ class VisitorPasswordBloc emit(TableLoaded(event.filteredData)); } - addDeviceToList(context) { + void addDeviceToList(context) { selectedDevices = selectedDeviceIds; Navigator.of(context).pop(selectedDevices); } @@ -373,14 +368,14 @@ class VisitorPasswordBloc Future selectTimeOfLinePassword( SelectTimeEvent event, Emitter emit) async { emit(ChangeTimeState()); - final DateTime? picked = await showDatePicker( + final picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 2095)), ); if (picked != null) { - final TimeOfDay? timePicked = await showHourPicker( + final timePicked = await showHourPicker( context: event.context, initialTime: TimeOfDay.now(), ); @@ -405,7 +400,7 @@ class VisitorPasswordBloc if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) { accessPeriodValidate = - "Effective Time cannot be later than Expiration Time."; + 'Effective Time cannot be later than Expiration Time.'; } else { accessPeriodValidate = ''; effectiveTime = selectedDateTime.toString().split('.').first; @@ -427,7 +422,7 @@ class VisitorPasswordBloc } } - changeTime(ChangeTimeEvent event, Emitter emit) { + void changeTime(ChangeTimeEvent event, Emitter emit) { if (event.isStartEndTime == true) { startTime = event.val; } else { @@ -437,8 +432,8 @@ class VisitorPasswordBloc DateTime? convertStringToDateTime(String dateTimeString) { try { - final DateFormat inputFormat = DateFormat('yyyy-MM-dd HH:mm:ss'); - DateTime dateTime = inputFormat.parse(dateTimeString); + final inputFormat = DateFormat('yyyy-MM-dd HH:mm:ss'); + final dateTime = inputFormat.parse(dateTimeString); return dateTime; } catch (e) { return null; @@ -446,7 +441,7 @@ class VisitorPasswordBloc } String getTimeFromDateTimeString(String dateTimeString) { - DateTime? dateTime = convertStringToDateTime(dateTimeString); + final dateTime = convertStringToDateTime(dateTimeString); if (dateTime == null) return ''; return DateFormat('HH:mm').format(dateTime); } diff --git a/lib/pages/visitor_password/bloc/visitor_password_event.dart b/lib/pages/visitor_password/bloc/visitor_password_event.dart index 6ecae200..6e7b056b 100644 --- a/lib/pages/visitor_password/bloc/visitor_password_event.dart +++ b/lib/pages/visitor_password/bloc/visitor_password_event.dart @@ -140,7 +140,7 @@ class FilterDataEvent extends VisitorPasswordEvent { class UpdateFilteredDevicesEvent extends VisitorPasswordEvent { final List filteredData; - UpdateFilteredDevicesEvent(this.filteredData); + const UpdateFilteredDevicesEvent(this.filteredData); } class SelectTimeEvent extends VisitorPasswordEvent { diff --git a/lib/pages/visitor_password/model/device_model.dart b/lib/pages/visitor_password/model/device_model.dart index f9711eed..dc6c4858 100644 --- a/lib/pages/visitor_password/model/device_model.dart +++ b/lib/pages/visitor_password/model/device_model.dart @@ -51,8 +51,8 @@ class DeviceModel { // Deserialize from JSON factory DeviceModel.fromJson(Map json) { - String tempIcon = ''; - DeviceType type = devicesTypesMap[json['productType']] ?? DeviceType.Other; + var tempIcon = ''; + final type = devicesTypesMap[json['productType']] ?? DeviceType.Other; if (type == DeviceType.LightBulb) { tempIcon = Assets.lightBulb; } else if (type == DeviceType.CeilingSensor || diff --git a/lib/pages/visitor_password/model/failed_operation.dart b/lib/pages/visitor_password/model/failed_operation.dart index 223f9ac5..02bd6802 100644 --- a/lib/pages/visitor_password/model/failed_operation.dart +++ b/lib/pages/visitor_password/model/failed_operation.dart @@ -26,8 +26,6 @@ class FailedOperation { } } - - class SuccessOperation { final bool success; // final Result result; @@ -92,8 +90,6 @@ class SuccessOperation { // } // } - - class PasswordStatus { final List successOperations; final List failedOperations; @@ -121,4 +117,3 @@ class PasswordStatus { }; } } - diff --git a/lib/pages/visitor_password/view/add_device_dialog.dart b/lib/pages/visitor_password/view/add_device_dialog.dart index d69aa21d..68f970b3 100644 --- a/lib/pages/visitor_password/view/add_device_dialog.dart +++ b/lib/pages/visitor_password/view/add_device_dialog.dart @@ -2,15 +2,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/common/access_device_table.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.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/text_field/custom_web_textfield.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/app_enum.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/style.dart'; class AddDeviceDialog extends StatelessWidget { @@ -18,15 +17,14 @@ class AddDeviceDialog extends StatelessWidget { const AddDeviceDialog({super.key, this.selectedDeviceIds}); @override Widget build(BuildContext context) { - Size size = MediaQuery.of(context).size; + final size = MediaQuery.of(context).size; return BlocProvider( - create: (context) => - VisitorPasswordBloc()..add(FetchDevice()), + create: (context) => VisitorPasswordBloc()..add(FetchDevice()), child: BlocBuilder( builder: (BuildContext context, VisitorPasswordState state) { final visitorBloc = BlocProvider.of(context); if (state is TableLoaded) { - for (var device in selectedDeviceIds!) { + for (final device in selectedDeviceIds!) { if (selectedDeviceIds!.contains(device)) { visitorBloc.add(SelectDeviceEvent(device)); } @@ -54,7 +52,7 @@ class AddDeviceDialog extends StatelessWidget { padding: const EdgeInsets.all(15), decoration: containerDecoration.copyWith( color: ColorsManager.worningColor, - border: Border.all(color: Color(0xffFFD22F)), + border: Border.all(color: const Color(0xffFFD22F)), boxShadow: []), child: Row( children: [ @@ -128,9 +126,7 @@ class AddDeviceDialog extends StatelessWidget { width: size.width * 0.06, child: Center( child: DefaultButton( - onPressed: () { - visitorBloc.filterDevices(); - }, + onPressed: visitorBloc.filterDevices, borderRadius: 9, child: const Text('Search'), ), @@ -141,7 +137,7 @@ class AddDeviceDialog extends StatelessWidget { const SizedBox(width: 10), Expanded( flex: 2, - child: Container( + child: SizedBox( width: size.width * 0.06, child: DefaultButton( backgroundColor: ColorsManager.whiteColors, @@ -177,7 +173,7 @@ class AddDeviceDialog extends StatelessWidget { isEmpty: visitorBloc.data.isEmpty, selectAll: (p0) { visitorBloc.selectedDeviceIds.clear(); - for (var item in state.data) { + for (final item in state.data) { visitorBloc .add(SelectDeviceEvent(item.uuid)); } @@ -201,7 +197,7 @@ class AddDeviceDialog extends StatelessWidget { item.uuid.toString(), item.productType.toString(), item.spaceName.toString(), - item.online.value.toString(), + item.online.value, ]; }).toList(), ) @@ -223,7 +219,7 @@ class AddDeviceDialog extends StatelessWidget { backgroundColor: Colors.white, child: Text( 'Cancel', - style: Theme.of(context).textTheme.bodyMedium!, + style: Theme.of(context).textTheme.bodyMedium, ), ), ), @@ -235,7 +231,7 @@ class AddDeviceDialog extends StatelessWidget { visitorBloc.addDeviceToList(context); }, borderRadius: 8, - child: Text('Ok'), + child: const Text('Ok'), ), ), ], diff --git a/lib/pages/visitor_password/view/repeat_widget.dart b/lib/pages/visitor_password/view/repeat_widget.dart index 8b40b580..621dbbba 100644 --- a/lib/pages/visitor_password/view/repeat_widget.dart +++ b/lib/pages/visitor_password/view/repeat_widget.dart @@ -14,7 +14,7 @@ class RepeatWidget extends StatelessWidget { @override Widget build(BuildContext context) { - Size size = MediaQuery.of(context).size; + final size = MediaQuery.of(context).size; return BlocBuilder( builder: (context, state) { final visitorBloc = BlocProvider.of(context); @@ -29,7 +29,7 @@ class RepeatWidget extends StatelessWidget { children: visitorBloc.days.map((day) { return Container( width: 70, // Adjust width as needed - margin: EdgeInsets.all(5), + margin: const EdgeInsets.all(5), child: CheckboxListTile( contentPadding: EdgeInsets.zero, title: Text( diff --git a/lib/pages/visitor_password/view/visitor_password_dialog.dart b/lib/pages/visitor_password/view/visitor_password_dialog.dart index 1e43af46..1849ccf2 100644 --- a/lib/pages/visitor_password/view/visitor_password_dialog.dart +++ b/lib/pages/visitor_password/view/visitor_password_dialog.dart @@ -2,7 +2,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:syncrow_web/pages/common/bloc/project_manager.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/text_field/custom_web_textfield.dart'; @@ -20,8 +19,11 @@ class VisitorPasswordDialog extends StatelessWidget { @override Widget build(BuildContext context) { - Size size = MediaQuery.of(context).size; - var text = Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black, fontSize: 13); + final size = MediaQuery.of(context).size; + final text = Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.black, fontSize: 13); return BlocProvider( create: (context) => VisitorPasswordBloc(), child: BlocListener( @@ -35,7 +37,8 @@ class VisitorPasswordDialog extends StatelessWidget { title: 'Sent Successfully', widgeta: Column( children: [ - if (visitorBloc.passwordStatus!.failedOperations.isNotEmpty) + if (visitorBloc + .passwordStatus!.failedOperations.isNotEmpty) Column( children: [ const Text('Failed Devices'), @@ -45,22 +48,26 @@ class VisitorPasswordDialog extends StatelessWidget { child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, - itemCount: visitorBloc.passwordStatus!.failedOperations.length, + itemCount: visitorBloc + .passwordStatus!.failedOperations.length, itemBuilder: (context, index) { return Container( - margin: EdgeInsets.all(5), + margin: const EdgeInsets.all(5), decoration: containerDecoration, height: 45, child: Center( child: Text(visitorBloc - .passwordStatus!.failedOperations[index].deviceUuid)), + .passwordStatus! + .failedOperations[index] + .deviceUuid)), ); }, ), ), ], ), - if (visitorBloc.passwordStatus!.successOperations.isNotEmpty) + if (visitorBloc + .passwordStatus!.successOperations.isNotEmpty) Column( children: [ const Text('Success Devices'), @@ -70,15 +77,18 @@ class VisitorPasswordDialog extends StatelessWidget { child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, - itemCount: visitorBloc.passwordStatus!.successOperations.length, + itemCount: visitorBloc + .passwordStatus!.successOperations.length, itemBuilder: (context, index) { return Container( - margin: EdgeInsets.all(5), + margin: const EdgeInsets.all(5), decoration: containerDecoration, height: 45, child: Center( - child: Text(visitorBloc.passwordStatus! - .successOperations[index].deviceUuid)), + child: Text(visitorBloc + .passwordStatus! + .successOperations[index] + .deviceUuid)), ); }, ), @@ -89,7 +99,6 @@ class VisitorPasswordDialog extends StatelessWidget { )) .then((v) { Navigator.of(context).pop(true); - }); } else if (state is FailedState) { visitorBloc.stateDialog( @@ -102,15 +111,16 @@ class VisitorPasswordDialog extends StatelessWidget { child: BlocBuilder( builder: (BuildContext context, VisitorPasswordState state) { final visitorBloc = BlocProvider.of(context); - bool isRepeat = state is IsRepeatState ? state.repeat : visitorBloc.repeat; + final isRepeat = + state is IsRepeatState ? state.repeat : visitorBloc.repeat; return AlertDialog( backgroundColor: Colors.white, title: Text( 'Create visitor password', - style: Theme.of(context) - .textTheme - .headlineLarge! - .copyWith(fontWeight: FontWeight.w400, fontSize: 24, color: Colors.black), + style: Theme.of(context).textTheme.headlineLarge!.copyWith( + fontWeight: FontWeight.w400, + fontSize: 24, + color: Colors.black), ), content: state is LoadingInitialState ? const Center(child: CircularProgressIndicator()) @@ -128,7 +138,8 @@ class VisitorPasswordDialog extends StatelessWidget { flex: 2, child: CustomWebTextField( validator: visitorBloc.validate, - controller: visitorBloc.userNameController, + controller: + visitorBloc.userNameController, isRequired: true, textFieldName: 'Name', description: '', @@ -177,20 +188,26 @@ class VisitorPasswordDialog extends StatelessWidget { SizedBox( width: size.width * 0.12, child: RadioListTile( - contentPadding: EdgeInsets.zero, + contentPadding: + EdgeInsets.zero, title: Text( 'Online Password', style: text, ), value: 'Online Password', - groupValue: (state is PasswordTypeSelected) + groupValue: (state + is PasswordTypeSelected) ? state.selectedType - : visitorBloc.accessTypeSelected, + : visitorBloc + .accessTypeSelected, onChanged: (String? value) { if (value != null) { context - .read() - .add(SelectPasswordType(value)); + .read< + VisitorPasswordBloc>() + .add( + SelectPasswordType( + value)); } }, ), @@ -198,17 +215,25 @@ class VisitorPasswordDialog extends StatelessWidget { SizedBox( width: size.width * 0.12, child: RadioListTile( - contentPadding: EdgeInsets.zero, - title: Text('Offline Password', style: text), + contentPadding: + EdgeInsets.zero, + title: Text( + 'Offline Password', + style: text), value: 'Offline Password', - groupValue: (state is PasswordTypeSelected) + groupValue: (state + is PasswordTypeSelected) ? state.selectedType - : visitorBloc.accessTypeSelected, + : visitorBloc + .accessTypeSelected, onChanged: (String? value) { if (value != null) { context - .read() - .add(SelectPasswordType(value)); + .read< + VisitorPasswordBloc>() + .add( + SelectPasswordType( + value)); } }, ), @@ -242,21 +267,29 @@ class VisitorPasswordDialog extends StatelessWidget { ), ], ), - if (visitorBloc.accessTypeSelected == 'Online Password') + if (visitorBloc.accessTypeSelected == + 'Online Password') Text( 'Only currently online devices can be selected. It is recommended to use when the device network is stable, and the system randomly generates a digital password', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.grayColor, - fontSize: 9), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.grayColor, + fontSize: 9), ), - if (visitorBloc.accessTypeSelected == 'Offline Password') + if (visitorBloc.accessTypeSelected == + 'Offline Password') Text( 'Unaffected by the online status of the device, you can select online or offline device, and the system randomly generates a digital password', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.grayColor, - fontSize: 9), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.grayColor, + fontSize: 9), ), // if (visitorBloc.accessTypeSelected == 'Dynamic Password') // Text( @@ -271,143 +304,206 @@ class VisitorPasswordDialog extends StatelessWidget { ) ], ), - visitorBloc.accessTypeSelected == 'Dynamic Password' - ? const SizedBox() - : Column( - crossAxisAlignment: CrossAxisAlignment.start, + if (visitorBloc.accessTypeSelected == + 'Dynamic Password') + const SizedBox() + else + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( children: [ - Row( - children: [ - Text( - '* ', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: Colors.red), - ), - Text( - 'Usage Frequency', - style: text, - ), - ], + Text( + '* ', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.red), ), - Row( - children: [ - SizedBox( - width: size.width * 0.12, - child: RadioListTile( - contentPadding: EdgeInsets.zero, - title: Text( - 'One-Time', - style: text, - ), - value: 'One-Time', - groupValue: (state is UsageFrequencySelected) - ? state.selectedFrequency - : visitorBloc.usageFrequencySelected, - onChanged: (String? value) { - if (value != null) { - context - .read() - .add(SelectUsageFrequency(value)); - } - }, - ), - ), - SizedBox( - width: size.width * 0.12, - child: RadioListTile( - contentPadding: EdgeInsets.zero, - title: Text('Periodic', style: text), - value: 'Periodic', - groupValue: (state is UsageFrequencySelected) - ? state.selectedFrequency - : visitorBloc.usageFrequencySelected, - onChanged: (String? value) { - if (value != null) { - context.read() - .add(SelectUsageFrequency(value)); - } - }, - ), - ), - ], + Text( + 'Usage Frequency', + style: text, ), - - //One-Time - if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == 'Online Password') - Text( - 'Within the validity period, each device can be unlocked only once.', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.grayColor, fontSize: 9), - ), - if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == 'Offline Password') - Text( - 'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.grayColor, fontSize: 9), - ), - - // Periodic - if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') - Text( - 'Within the validity period, there is no limit to the number of times each device can be unlocked, and it should be used at least once within 24 hours after the entry into force.', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.grayColor, fontSize: 9), - ), - - if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Online Password') - Text( - 'Within the validity period, there is no limit to the number of times each device can be unlocked.', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.grayColor, fontSize: 9), - ), ], ), + Row( + children: [ + SizedBox( + width: size.width * 0.12, + child: RadioListTile( + contentPadding: EdgeInsets.zero, + title: Text( + 'One-Time', + style: text, + ), + value: 'One-Time', + groupValue: (state + is UsageFrequencySelected) + ? state.selectedFrequency + : visitorBloc + .usageFrequencySelected, + onChanged: (String? value) { + if (value != null) { + context + .read() + .add(SelectUsageFrequency( + value)); + } + }, + ), + ), + SizedBox( + width: size.width * 0.12, + child: RadioListTile( + contentPadding: EdgeInsets.zero, + title: + Text('Periodic', style: text), + value: 'Periodic', + groupValue: (state + is UsageFrequencySelected) + ? state.selectedFrequency + : visitorBloc + .usageFrequencySelected, + onChanged: (String? value) { + if (value != null) { + context + .read() + .add(SelectUsageFrequency( + value)); + } + }, + ), + ), + ], + ), + + //One-Time + if (visitorBloc.usageFrequencySelected == + 'One-Time' && + visitorBloc.accessTypeSelected == + 'Online Password') + Text( + 'Within the validity period, each device can be unlocked only once.', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: ColorsManager.grayColor, + fontSize: 9), + ), + if (visitorBloc.usageFrequencySelected == + 'One-Time' && + visitorBloc.accessTypeSelected == + 'Offline Password') + Text( + 'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: ColorsManager.grayColor, + fontSize: 9), + ), + + // Periodic + if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Offline Password') + Text( + 'Within the validity period, there is no limit to the number of times each device can be unlocked, and it should be used at least once within 24 hours after the entry into force.', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: ColorsManager.grayColor, + fontSize: 9), + ), + + if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Online Password') + Text( + 'Within the validity period, there is no limit to the number of times each device can be unlocked.', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: ColorsManager.grayColor, + fontSize: 9), + ), + ], + ), const SizedBox( height: 20, ), - if ((visitorBloc.usageFrequencySelected != 'One-Time' || - visitorBloc.accessTypeSelected != 'Offline Password') && + if ((visitorBloc.usageFrequencySelected != + 'One-Time' || + visitorBloc.accessTypeSelected != + 'Offline Password') && (visitorBloc.usageFrequencySelected != '')) DateTimeWebWidget( isRequired: true, title: 'Access Period', size: size, endTime: () { - if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') { - visitorBloc.add(SelectTimeEvent(context: context, isEffective: false)); + if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Offline Password') { + visitorBloc.add(SelectTimeEvent( + context: context, + isEffective: false)); } else { - visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false, isRepeat: false)); + visitorBloc.add( + SelectTimeVisitorPassword( + context: context, + isStart: false, + isRepeat: false)); } }, startTime: () { - if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') { - visitorBloc.add( - SelectTimeEvent(context: context, isEffective: true)); + if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Offline Password') { + visitorBloc.add(SelectTimeEvent( + context: context, + isEffective: true)); } else { - visitorBloc.add(SelectTimeVisitorPassword( - context: context, isStart: true, isRepeat: false)); + visitorBloc.add( + SelectTimeVisitorPassword( + context: context, + isStart: true, + isRepeat: false)); } }, - firstString: (visitorBloc.usageFrequencySelected == - 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') + firstString: (visitorBloc + .usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Offline Password') ? visitorBloc.effectiveTime - : visitorBloc.startTimeAccess.toString(), - secondString: (visitorBloc.usageFrequencySelected == - 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') + : visitorBloc.startTimeAccess, + secondString: (visitorBloc + .usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Offline Password') ? visitorBloc.expirationTime - : visitorBloc.endTimeAccess.toString(), + : visitorBloc.endTimeAccess, icon: Assets.calendarIcon), - const SizedBox(height: 10,), - Text(visitorBloc.accessPeriodValidate, - style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: ColorsManager.red),), + const SizedBox( + height: 10, + ), + Text( + visitorBloc.accessPeriodValidate, + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: ColorsManager.red), + ), const SizedBox( height: 20, ), @@ -431,16 +527,21 @@ class VisitorPasswordDialog extends StatelessWidget { ), Text( 'Within the validity period, each device can be unlocked only once.', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.grayColor, - fontSize: 9), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.grayColor, + fontSize: 9), ), const SizedBox( height: 20, ), - if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Online Password') + if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Online Password') SizedBox( width: 100, child: Column( @@ -451,7 +552,8 @@ class VisitorPasswordDialog extends StatelessWidget { child: CupertinoSwitch( value: visitorBloc.repeat, onChanged: (value) { - visitorBloc.add(ToggleRepeatEvent()); + visitorBloc + .add(ToggleRepeatEvent()); }, applyTheme: true, ), @@ -459,9 +561,13 @@ class VisitorPasswordDialog extends StatelessWidget { ], ), ), - if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Online Password') - isRepeat ? const RepeatWidget() : const SizedBox(), + if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Online Password') + isRepeat + ? const RepeatWidget() + : const SizedBox(), Container( decoration: containerDecoration, width: size.width / 9, @@ -472,22 +578,28 @@ class VisitorPasswordDialog extends StatelessWidget { barrierDismissible: false, builder: (BuildContext context) { return AddDeviceDialog( - selectedDeviceIds: visitorBloc.selectedDevices, + selectedDeviceIds: + visitorBloc.selectedDevices, ); }, ).then((listDevice) { if (listDevice != null) { - visitorBloc.selectedDevices = listDevice; + visitorBloc.selectedDevices = + listDevice; } }); }, borderRadius: 8, child: Text( '+ Add Device', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.whiteColors, - fontSize: 12), + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + fontWeight: FontWeight.w400, + color: + ColorsManager.whiteColors, + fontSize: 12), ), ), ), @@ -525,30 +637,35 @@ class VisitorPasswordDialog extends StatelessWidget { onPressed: () { if (visitorBloc.forgetFormKey.currentState!.validate()) { if (visitorBloc.selectedDevices.isNotEmpty) { - if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == 'Offline Password') { + if (visitorBloc.usageFrequencySelected == + 'One-Time' && + visitorBloc.accessTypeSelected == + 'Offline Password') { setPasswordFunction(context, size, visitorBloc); - } else if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') { + } else if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Offline Password') { if (visitorBloc.expirationTime != 'End Time' && - visitorBloc.effectiveTime != 'Start Time' ) { + visitorBloc.effectiveTime != 'Start Time') { setPasswordFunction(context, size, visitorBloc); - }else{ + } else { visitorBloc.stateDialog( context: context, - message: 'Please select Access Period to continue', + message: + 'Please select Access Period to continue', title: 'Access Period'); } - } else if( - visitorBloc.endTimeAccess.toString()!='End Time' - &&visitorBloc.startTimeAccess.toString()!='Start Time') { + } else if (visitorBloc.endTimeAccess != 'End Time' && + visitorBloc.startTimeAccess != 'Start Time') { if (visitorBloc.effectiveTimeTimeStamp != null && visitorBloc.expirationTimeTimeStamp != null) { if (isRepeat == true) { if (visitorBloc.expirationTime != 'End Time' && visitorBloc.effectiveTime != 'Start Time' && visitorBloc.selectedDays.isNotEmpty) { - setPasswordFunction(context, size, visitorBloc); + setPasswordFunction( + context, size, visitorBloc); } else { visitorBloc.stateDialog( context: context, @@ -562,14 +679,16 @@ class VisitorPasswordDialog extends StatelessWidget { } else { visitorBloc.stateDialog( context: context, - message: 'Please select Access Period to continue', + message: + 'Please select Access Period to continue', title: 'Access Period'); } - }else{ - visitorBloc.stateDialog( - context: context, - message: 'Please select Access Period to continue', - title: 'Access Period'); + } else { + visitorBloc.stateDialog( + context: context, + message: + 'Please select Access Period to continue', + title: 'Access Period'); } } else { visitorBloc.stateDialog( @@ -614,8 +733,9 @@ class VisitorPasswordDialog extends StatelessWidget { alignment: Alignment.center, content: SizedBox( height: size.height * 0.25, - child: Center( - child: CircularProgressIndicator(), // Display a loading spinner + child: const Center( + child: + CircularProgressIndicator(), // Display a loading spinner ), ), ); @@ -639,7 +759,10 @@ class VisitorPasswordDialog extends StatelessWidget { ), Text( 'Set Password', - style: Theme.of(context).textTheme.headlineLarge!.copyWith( + style: Theme.of(context) + .textTheme + .headlineLarge! + .copyWith( fontSize: 30, fontWeight: FontWeight.w400, color: Colors.black, @@ -689,37 +812,45 @@ class VisitorPasswordDialog extends StatelessWidget { onPressed: () { Navigator.pop(context); if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == 'Online Password') { + visitorBloc.accessTypeSelected == + 'Online Password') { visitorBloc.add(OnlineOneTimePasswordEvent( context: context, passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, )); - } - else if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Online Password') { + } else if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Online Password') { visitorBloc.add(OnlineMultipleTimePasswordEvent( passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, - effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), - invalidTime: visitorBloc.expirationTimeTimeStamp.toString(), + effectiveTime: + visitorBloc.effectiveTimeTimeStamp.toString(), + invalidTime: + visitorBloc.expirationTimeTimeStamp.toString(), )); - } - else if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == 'Offline Password') { + } else if (visitorBloc.usageFrequencySelected == + 'One-Time' && + visitorBloc.accessTypeSelected == + 'Offline Password') { visitorBloc.add(OfflineOneTimePasswordEvent( context: context, passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, )); - } - else if (visitorBloc.usageFrequencySelected == 'Periodic' && - visitorBloc.accessTypeSelected == 'Offline Password') { + } else if (visitorBloc.usageFrequencySelected == + 'Periodic' && + visitorBloc.accessTypeSelected == + 'Offline Password') { visitorBloc.add(OfflineMultipleTimePasswordEvent( passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, - effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), - invalidTime: visitorBloc.expirationTimeTimeStamp.toString(), + effectiveTime: + visitorBloc.effectiveTimeTimeStamp.toString(), + invalidTime: + visitorBloc.expirationTimeTimeStamp.toString(), )); } }, diff --git a/lib/services/access_mang_api.dart b/lib/services/access_mang_api.dart index a780a12b..a10292c5 100644 --- a/lib/services/access_mang_api.dart +++ b/lib/services/access_mang_api.dart @@ -12,7 +12,8 @@ class AccessMangApi { void _validateEndpoints() { if (!ApiEndpoints.getDevices.contains('{projectId}')) { - throw Exception("Endpoint 'getDevices' must contain '{projectId}' placeholder."); + throw Exception( + "Endpoint 'getDevices' must contain '{projectId}' placeholder."); } } @@ -22,8 +23,8 @@ class AccessMangApi { path: ApiEndpoints.visitorPassword, showServerMessage: true, expectedResponseModel: (json) { - List jsonData = json['data'] ?? []; - List passwordList = jsonData.map((jsonItem) { + final List jsonData = json['data'] ?? []; + final passwordList = jsonData.map((jsonItem) { return PasswordModel.fromJson(jsonItem); }).toList(); return passwordList; @@ -46,8 +47,8 @@ class AccessMangApi { }, showServerMessage: true, expectedResponseModel: (json) { - List jsonData = json['data'] ?? []; - List deviceList = jsonData.map((jsonItem) { + final List jsonData = json['data'] ?? []; + final deviceList = jsonData.map((jsonItem) { return DeviceModel.fromJson(jsonItem); }).toList(); return deviceList; @@ -69,13 +70,13 @@ class AccessMangApi { final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, body: jsonEncode({ - "email": email, - "passwordName": passwordName, - "password": password, - "devicesUuid": devicesUuid, - "effectiveTime": effectiveTime, - "invalidTime": invalidTime, - "operationType": "ONLINE_ONE_TIME", + 'email': email, + 'passwordName': passwordName, + 'password': password, + 'devicesUuid': devicesUuid, + 'effectiveTime': effectiveTime, + 'invalidTime': invalidTime, + 'operationType': 'ONLINE_ONE_TIME', }), showServerMessage: true, expectedResponseModel: (json) { @@ -93,17 +94,18 @@ class AccessMangApi { String? passwordName, List? scheduleList, List? devicesUuid}) async { - Map body = { - "email": email, - "devicesUuid": devicesUuid, - "passwordName": passwordName, - "password": password, - "effectiveTime": effectiveTime, - "invalidTime": invalidTime, - "operationType": "ONLINE_MULTIPLE_TIME", + final body = { + 'email': email, + 'devicesUuid': devicesUuid, + 'passwordName': passwordName, + 'password': password, + 'effectiveTime': effectiveTime, + 'invalidTime': invalidTime, + 'operationType': 'ONLINE_MULTIPLE_TIME', }; if (scheduleList != null) { - body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList(); + body['scheduleList'] = + scheduleList.map((schedule) => schedule.toJson()).toList(); } final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, @@ -123,10 +125,10 @@ class AccessMangApi { final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, body: jsonEncode({ - "operationType": "OFFLINE_ONE_TIME", - "email": email, - "passwordName": passwordName, - "devicesUuid": devicesUuid + 'operationType': 'OFFLINE_ONE_TIME', + 'email': email, + 'passwordName': passwordName, + 'devicesUuid': devicesUuid }), showServerMessage: true, expectedResponseModel: (json) { @@ -145,12 +147,12 @@ class AccessMangApi { final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, body: jsonEncode({ - "email": email, - "devicesUuid": devicesUuid, - "passwordName": passwordName, - "effectiveTime": effectiveTime, - "invalidTime": invalidTime, - "operationType": "OFFLINE_MULTIPLE_TIME", + 'email': email, + 'devicesUuid': devicesUuid, + 'passwordName': passwordName, + 'effectiveTime': effectiveTime, + 'invalidTime': invalidTime, + 'operationType': 'OFFLINE_MULTIPLE_TIME', }), showServerMessage: true, expectedResponseModel: (json) { diff --git a/lib/services/api/http_interceptor.dart b/lib/services/api/http_interceptor.dart index bef8d804..f6762daf 100644 --- a/lib/services/api/http_interceptor.dart +++ b/lib/services/api/http_interceptor.dart @@ -1,10 +1,10 @@ +import 'dart:async'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:syncrow_web/pages/auth/model/token.dart'; import 'package:syncrow_web/services/api/network_exception.dart'; -import 'dart:async'; import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; @@ -18,7 +18,8 @@ class HTTPInterceptor extends InterceptorsWrapper { ]; @override - void onResponse(Response response, ResponseInterceptorHandler handler) async { + Future onResponse( + Response response, ResponseInterceptorHandler handler) async { if (await validateResponse(response)) { super.onResponse(response, handler); } else { @@ -28,26 +29,27 @@ class HTTPInterceptor extends InterceptorsWrapper { } @override - void onRequest( + Future onRequest( RequestOptions options, RequestInterceptorHandler handler) async { - var storage = const FlutterSecureStorage(); - var token = await storage.read(key: Token.loginAccessTokenKey); + const storage = FlutterSecureStorage(); + final token = await storage.read(key: Token.loginAccessTokenKey); if (checkHeaderExclusionListOfAddedParameters(options.path)) { options.headers - .putIfAbsent(HttpHeaders.authorizationHeader, () => "Bearer $token"); + .putIfAbsent(HttpHeaders.authorizationHeader, () => 'Bearer $token'); } // options.headers['Authorization'] = 'Bearer ${'${token!}123'}'; super.onRequest(options, handler); } @override - void onError(DioException err, ErrorInterceptorHandler handler) async { - ServerFailure failure = ServerFailure.fromDioError(err); + Future onError( + DioException err, ErrorInterceptorHandler handler) async { + final failure = ServerFailure.fromDioError(err); if (failure.toString().isNotEmpty) { CustomSnackBar.displaySnackBar(failure.toString()); } - var storage = const FlutterSecureStorage(); - var token = await storage.read(key: Token.loginAccessTokenKey); + const storage = FlutterSecureStorage(); + final token = await storage.read(key: Token.loginAccessTokenKey); if (err.response?.statusCode == 401 && token != null) { // await AuthCubit.get(NavigationService.navigatorKey.currentContext!).logout(); } @@ -72,10 +74,10 @@ class HTTPInterceptor extends InterceptorsWrapper { } } - checkHeaderExclusionListOfAddedParameters(String path) { - bool shouldAddHeader = true; + bool checkHeaderExclusionListOfAddedParameters(String path) { + var shouldAddHeader = true; - for (var urlConstant in headerExclusionListOfAddedParameters) { + for (final urlConstant in headerExclusionListOfAddedParameters) { if (path.contains(urlConstant)) { shouldAddHeader = false; } diff --git a/lib/services/api/http_service.dart b/lib/services/api/http_service.dart index c76291bf..8e0d0616 100644 --- a/lib/services/api/http_service.dart +++ b/lib/services/api/http_service.dart @@ -8,10 +8,10 @@ class HTTPService { // final navigatorKey = GlobalKey(); - String certificateString = ""; + String certificateString = ''; static Dio setupDioClient() { - Dio client = Dio( + final client = Dio( BaseOptions( baseUrl: ApiEndpoints.baseUrl, receiveDataWhenStatusError: true, diff --git a/lib/services/api/network_exception.dart b/lib/services/api/network_exception.dart index d85ef27c..9ebc8486 100644 --- a/lib/services/api/network_exception.dart +++ b/lib/services/api/network_exception.dart @@ -17,34 +17,34 @@ class ServerFailure extends Failure { factory ServerFailure.fromDioError(DioException dioError) { switch (dioError.type) { case DioExceptionType.connectionTimeout: - return ServerFailure("Connection timeout with the Server."); + return ServerFailure('Connection timeout with the Server.'); case DioExceptionType.sendTimeout: - return ServerFailure("Send timeout with the Server."); + return ServerFailure('Send timeout with the Server.'); case DioExceptionType.receiveTimeout: - return ServerFailure("Receive timeout with the Server."); + return ServerFailure('Receive timeout with the Server.'); case DioExceptionType.badCertificate: - return ServerFailure("Bad certificate!"); + return ServerFailure('Bad certificate!'); case DioExceptionType.badResponse: { // var document = parser.parse(dioError.response!.data.toString()); // var message = document.body!.text; - return ServerFailure.fromResponse(dioError.response!.statusCode!, - dioError.response?.data['message'] ?? "Error"); + return ServerFailure.fromResponse(dioError.response!.statusCode, + dioError.response?.data['message'] ?? 'Error'); } case DioExceptionType.cancel: - return ServerFailure("The request to ApiServer was canceled"); + return ServerFailure('The request to ApiServer was canceled'); case DioExceptionType.connectionError: - return ServerFailure("No Internet Connection"); + return ServerFailure('No Internet Connection'); case DioExceptionType.unknown: - return ServerFailure("Unexpected Error, Please try again!"); + return ServerFailure('Unexpected Error, Please try again!'); default: - return ServerFailure("Unexpected Error, Please try again!"); + return ServerFailure('Unexpected Error, Please try again!'); } } @@ -54,9 +54,9 @@ class ServerFailure extends Failure { case 403: return ServerFailure(responseMessage); case 400: - List errors = []; + final errors = []; if (responseMessage is List) { - for (var error in responseMessage) { + for (final error in responseMessage) { errors.add(error); } } else { @@ -64,11 +64,11 @@ class ServerFailure extends Failure { } return ServerFailure(errors.join('\n')); case 404: - return ServerFailure(""); + return ServerFailure(''); case 500: return ServerFailure(responseMessage); default: - return ServerFailure("Opps there was an Error, Please try again!"); + return ServerFailure('Opps there was an Error, Please try again!'); } } } diff --git a/lib/services/auth_api.dart b/lib/services/auth_api.dart index 18d951c1..ad4fec5f 100644 --- a/lib/services/auth_api.dart +++ b/lib/services/auth_api.dart @@ -31,7 +31,7 @@ class AuthenticationAPI { try { final response = await HTTPService().post( path: ApiEndpoints.forgetPassword, - body: {"email": email, "password": password, "otpCode": otpCode}, + body: {'email': email, 'password': password, 'otpCode': otpCode}, showServerMessage: true, expectedResponseModel: (json) {}); return response; @@ -45,7 +45,7 @@ class AuthenticationAPI { static Future sendOtp({required String email}) async { final response = await HTTPService().post( path: ApiEndpoints.sendOtp, - body: {"email": email, "type": "PASSWORD"}, + body: {'email': email, 'type': 'PASSWORD'}, showServerMessage: true, expectedResponseModel: (json) { return json['data']['cooldown']; @@ -58,7 +58,7 @@ class AuthenticationAPI { try { final response = await HTTPService().post( path: ApiEndpoints.verifyOtp, - body: {"email": email, "type": "PASSWORD", "otpCode": otpCode}, + body: {'email': email, 'type': 'PASSWORD', 'otpCode': otpCode}, showServerMessage: true, expectedResponseModel: (json) { if (json['message'] == 'Otp Verified Successfully') { diff --git a/lib/services/batch_control_devices_service.dart b/lib/services/batch_control_devices_service.dart index f78cdef4..16542c8c 100644 --- a/lib/services/batch_control_devices_service.dart +++ b/lib/services/batch_control_devices_service.dart @@ -11,7 +11,8 @@ abstract interface class BatchControlDevicesService { }); } -final class RemoteBatchControlDevicesService implements BatchControlDevicesService { +final class RemoteBatchControlDevicesService + implements BatchControlDevicesService { @override Future batchControlDevices({ required List uuids, diff --git a/lib/services/devices_mang_api.dart b/lib/services/devices_mang_api.dart index 6f60e34f..06fe635c 100644 --- a/lib/services/devices_mang_api.dart +++ b/lib/services/devices_mang_api.dart @@ -23,8 +23,8 @@ class DevicesManagementApi { : ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId), showServerMessage: true, expectedResponseModel: (json) { - List jsonData = json['data']; - List devicesList = jsonData.map((jsonItem) { + final List jsonData = json['data']; + final devicesList = jsonData.map((jsonItem) { return AllDevicesModel.fromJson(jsonItem); }).toList(); return devicesList; @@ -123,11 +123,11 @@ class DevicesManagementApi { path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId), showServerMessage: false, expectedResponseModel: (json) { - List devices = []; + final devices = []; if (json == null || json.isEmpty || json == []) { return devices; } - for (var device in json['data']['devices']) { + for (final device in json['data']['devices']) { devices.add(DeviceModel.fromJson(device)); } return devices; @@ -203,7 +203,7 @@ class DevicesManagementApi { } } - getPowerStatus(List uuids) async { + Future getPowerStatus(List uuids) async { try { final queryParameters = { 'devicesUuid': uuids.join(','), @@ -254,8 +254,8 @@ class DevicesManagementApi { .replaceAll('{category}', category), showServerMessage: true, expectedResponseModel: (json) { - List schedules = []; - for (var schedule in json) { + final schedules = []; + for (final schedule in json) { schedules.add(ScheduleModel.fromMap(schedule)); } return schedules; @@ -350,7 +350,7 @@ class DevicesManagementApi { try { final response = await HTTPService().put( path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), - body: {"deviceName": deviceName}, + body: {'deviceName': deviceName}, expectedResponseModel: (json) { return json['data']; }, @@ -378,7 +378,7 @@ class DevicesManagementApi { path: ApiEndpoints.resetDevice.replaceAll('{deviceUuid}', devicesUuid!), showServerMessage: false, body: { - "devicesUuid": [devicesUuid] + 'devicesUuid': [devicesUuid] }, expectedResponseModel: (json) { return json; diff --git a/lib/services/locator.dart b/lib/services/locator.dart index 055deb05..27f78ab9 100644 --- a/lib/services/locator.dart +++ b/lib/services/locator.dart @@ -5,7 +5,7 @@ import 'package:syncrow_web/services/api/http_service.dart'; final GetIt serviceLocator = GetIt.instance; //setupLocator() // to search for dependency injection in flutter -initialSetup() { +void initialSetup() { serviceLocator.registerSingleton(HTTPInterceptor()); //Base classes serviceLocator.registerSingleton(HTTPService.setupDioClient()); diff --git a/lib/services/product_api.dart b/lib/services/product_api.dart index 02c9f143..90dab310 100644 --- a/lib/services/product_api.dart +++ b/lib/services/product_api.dart @@ -9,9 +9,9 @@ class ProductApi { final response = await HTTPService().get( path: ApiEndpoints.listProducts, expectedResponseModel: (json) { - List jsonData = json['data']; + final List jsonData = json['data']; - List productList = jsonData.map((jsonItem) { + final productList = jsonData.map((jsonItem) { return ProductModel.fromMap(jsonItem); }).toList(); return productList; diff --git a/lib/services/routines_api.dart b/lib/services/routines_api.dart index bdc46ac1..f0d0b52a 100644 --- a/lib/services/routines_api.dart +++ b/lib/services/routines_api.dart @@ -29,7 +29,7 @@ class SceneApi { debugPrint('create scene response: $response'); return response; } on DioException catch (e) { - String errorMessage = + final String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -52,7 +52,7 @@ class SceneApi { debugPrint('create automation response: $response'); return response; } on DioException catch (e) { - String errorMessage = + final String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -63,7 +63,7 @@ class SceneApi { path: ApiEndpoints.getIconScene, showServerMessage: false, expectedResponseModel: (json) { - List iconsList = []; + final iconsList = []; json.forEach((element) { iconsList.add(IconModel.fromJson(element)); }); @@ -89,8 +89,8 @@ class SceneApi { expectedResponseModel: (json) { final scenesJson = json['data'] as List; - List scenes = []; - for (var scene in scenesJson) { + final scenes = []; + for (final scene in scenesJson) { scenes.add(ScenesModel.fromJson(scene, isAutomation: false)); } return scenes; @@ -114,8 +114,8 @@ class SceneApi { .replaceAll('{projectId}', projectId), showServerMessage: false, expectedResponseModel: (json) { - List scenes = []; - for (var scene in json) { + final scenes = []; + for (final scene in json) { scenes.add(ScenesModel.fromJson(scene, isAutomation: true)); } return scenes; @@ -158,7 +158,8 @@ class SceneApi { } //update Scene - static updateScene(CreateSceneModel createSceneModel, String sceneId) async { + static Future updateScene( + CreateSceneModel createSceneModel, String sceneId) async { try { final response = await _httpService.put( path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId), @@ -170,14 +171,14 @@ class SceneApi { ); return response; } on DioException catch (e) { - String errorMessage = + final String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } } //update automation - static updateAutomation(CreateAutomationModel createAutomationModel, + static Future updateAutomation(CreateAutomationModel createAutomationModel, String automationId, String projectId) async { try { final response = await _httpService.put( @@ -192,7 +193,7 @@ class SceneApi { ); return response; } on DioException catch (e) { - String errorMessage = + final String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -226,7 +227,7 @@ class SceneApi { ); return response; } on DioException catch (e) { - String errorMessage = + final String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -247,7 +248,7 @@ class SceneApi { ); return response; } on DioException catch (e) { - String errorMessage = + final String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -295,8 +296,8 @@ class SceneApi { .replaceAll('{projectId}', projectId), showServerMessage: false, expectedResponseModel: (json) { - List scenes = []; - for (var scene in json) { + final scenes = []; + for (final scene in json) { scenes.add(ScenesModel.fromJson(scene)); } return scenes; diff --git a/lib/services/space_mana_api.dart b/lib/services/space_mana_api.dart index 14902bca..901d623f 100644 --- a/lib/services/space_mana_api.dart +++ b/lib/services/space_mana_api.dart @@ -5,22 +5,19 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_m import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_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_response_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/tag_body_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/utils/constants/api_const.dart'; -import '../pages/spaces_management/all_spaces/model/subspace_model.dart'; - class CommunitySpaceManagementApi { // Community Management APIs Future> fetchCommunities(String projectId, {int page = 1}) async { try { - List allCommunities = []; - bool hasNext = true; + final allCommunities = []; + var hasNext = true; while (hasNext) { await HTTPService().get( @@ -31,10 +28,10 @@ class CommunitySpaceManagementApi { }, expectedResponseModel: (json) { try { - List jsonData = json['data'] ?? []; + final List jsonData = json['data'] ?? []; hasNext = json['hasNext'] ?? false; - int currentPage = json['page'] ?? 1; - List communityList = jsonData.map((jsonItem) { + final int currentPage = json['page'] ?? 1; + final communityList = jsonData.map((jsonItem) { return CommunityModel.fromJson(jsonItem); }).toList(); allCommunities.addAll(communityList); @@ -56,10 +53,10 @@ class CommunitySpaceManagementApi { Future fetchCommunitiesAndSpaces( {required String projectId, int page = 1, String search = ''}) async { - PaginationModel paginationModel = const PaginationModel.emptyConstructor(); + var paginationModel = const PaginationModel.emptyConstructor(); try { - bool hasNext = false; + var hasNext = false; await HTTPService().get( path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId), @@ -71,10 +68,10 @@ class CommunitySpaceManagementApi { }, expectedResponseModel: (json) { try { - List jsonData = json['data'] ?? []; + final List jsonData = json['data'] ?? []; hasNext = json['hasNext'] ?? false; - int currentPage = json['page'] ?? 1; - List communityList = jsonData.map((jsonItem) { + final int currentPage = json['page'] ?? 1; + final communityList = jsonData.map((jsonItem) { return CommunityModel.fromJson(jsonItem); }).toList(); @@ -379,12 +376,12 @@ class CommunitySpaceManagementApi { final response = await HTTPService().get( path: path, - queryParameters: {"page": 1, "pageSize": 10}, + queryParameters: {'page': 1, 'pageSize': 10}, showServerMessage: false, expectedResponseModel: (json) { - List rooms = []; + final rooms = []; if (json['data'] != null) { - for (var subspace in json['data']) { + for (final subspace in json['data']) { rooms.add(SubSpaceModel.fromJson(subspace)); } } @@ -393,7 +390,7 @@ class CommunitySpaceManagementApi { ); return response; - } catch (error, stackTrace) { + } catch (error) { return []; } } diff --git a/lib/services/space_model_mang_api.dart b/lib/services/space_model_mang_api.dart index cbb9cfeb..c6fff07d 100644 --- a/lib/services/space_model_mang_api.dart +++ b/lib/services/space_model_mang_api.dart @@ -79,7 +79,7 @@ class SpaceModelManagementApi { .replaceAll('{projectId}', projectId) .replaceAll('{spaceModelUuid}', spaceModelUuid), showServerMessage: true, - body: {"spaceUuids": spaceUuids, "overwrite": isOverWrite}, + body: {'spaceUuids': spaceUuids, 'overwrite': isOverWrite}, expectedResponseModel: (json) { return json; }, @@ -92,7 +92,7 @@ class SpaceModelManagementApi { path: ApiEndpoints.validateSpaceModel .replaceAll('{projectId}', projectId), showServerMessage: true, - body: {"spacesUuids": spaceUuids}, + body: {'spacesUuids': spaceUuids}, expectedResponseModel: (json) { return json; }); @@ -116,7 +116,7 @@ class SpaceModelManagementApi { final response = await HTTPService().get( path: ApiEndpoints.listTags.replaceAll('{projectId}', projectId), expectedResponseModel: (json) { - List jsonData = json['data']; + final List jsonData = json['data']; return jsonData.map((jsonItem) { return Tag.fromJson(jsonItem); }).toList(); diff --git a/lib/services/user_permission.dart b/lib/services/user_permission.dart index 3f02663d..881f92df 100644 --- a/lib/services/user_permission.dart +++ b/lib/services/user_permission.dart @@ -23,18 +23,18 @@ class UserPermissionApi { }, ); return response; - } catch (e, stackTrace) { + } catch (e) { debugPrint('Error in fetchUsers: $e'); rethrow; } } - fetchRoles() async { + Future> fetchRoles() async { final response = await _httpService.get( path: ApiEndpoints.roleTypes, showServerMessage: true, expectedResponseModel: (json) { - final List fetchedRoles = (json['data'] as List) + final fetchedRoles = (json['data'] as List) .map((item) => RoleTypeModel.fromJson(item)) .toList(); return fetchedRoles; @@ -45,7 +45,7 @@ class UserPermissionApi { Future> fetchPermission(roleUuid) async { final response = await _httpService.get( - path: ApiEndpoints.permission.replaceAll("roleUuid", roleUuid), + path: ApiEndpoints.permission.replaceAll('roleUuid', roleUuid), showServerMessage: true, expectedResponseModel: (json) { return (json as List) @@ -68,14 +68,14 @@ class UserPermissionApi { }) async { try { final body = { - "firstName": firstName, - "lastName": lastName, - "email": email, - "jobTitle": jobTitle != '' ? jobTitle : null, - "phoneNumber": phoneNumber != '' ? phoneNumber : null, - "roleUuid": roleUuid, - "projectUuid": projectUuid, - "spaceUuids": spaceUuids, + 'firstName': firstName, + 'lastName': lastName, + 'email': email, + 'jobTitle': jobTitle != '' ? jobTitle : null, + 'phoneNumber': phoneNumber != '' ? phoneNumber : null, + 'roleUuid': roleUuid, + 'projectUuid': projectUuid, + 'spaceUuids': spaceUuids, }; final response = await _httpService.post( path: ApiEndpoints.inviteUser, @@ -83,7 +83,7 @@ class UserPermissionApi { body: jsonEncode(body), expectedResponseModel: (json) { if (json['statusCode'] != 400) { - return json["success"]; + return json['success']; } else { return false; } @@ -91,7 +91,7 @@ class UserPermissionApi { ); return response ?? []; - } on DioException catch (e) { + } on DioException { return false; } catch (e) { return false; @@ -103,10 +103,10 @@ class UserPermissionApi { final response = await _httpService.post( path: ApiEndpoints.checkEmail, showServerMessage: true, - body: {"email": email}, + body: {'email': email}, expectedResponseModel: (json) { if (json['statusCode'] != 400) { - var message = json["message"]; + final message = json['message']; if (message is String) { return message; } else { @@ -128,11 +128,11 @@ class UserPermissionApi { Future fetchUserById(userUuid, String projectId) async { final response = await _httpService.get( path: ApiEndpoints.getUserById - .replaceAll("{userUuid}", userUuid) - .replaceAll("{projectId}", projectId), + .replaceAll('{userUuid}', userUuid) + .replaceAll('{projectId}', projectId), showServerMessage: true, expectedResponseModel: (json) { - EditUserModel res = EditUserModel.fromJson(json['data']); + final res = EditUserModel.fromJson(json['data']); return res; }, ); @@ -151,27 +151,27 @@ class UserPermissionApi { }) async { try { final body = { - "firstName": firstName, - "lastName": lastName, - "jobTitle": jobTitle != '' ? jobTitle : " ", - "phoneNumber": phoneNumber != '' ? phoneNumber : " ", - "roleUuid": roleUuid, - "projectUuid": projectUuid, - "spaceUuids": spaceUuids, + 'firstName': firstName, + 'lastName': lastName, + 'jobTitle': jobTitle != '' ? jobTitle : ' ', + 'phoneNumber': phoneNumber != '' ? phoneNumber : ' ', + 'roleUuid': roleUuid, + 'projectUuid': projectUuid, + 'spaceUuids': spaceUuids, }; final response = await _httpService.put( path: ApiEndpoints.editUser.replaceAll('{inviteUserUuid}', userId!), body: jsonEncode(body), expectedResponseModel: (json) { if (json['statusCode'] != 400) { - return json["success"]; + return json['success']; } else { return false; } }, ); return response; - } on DioException catch (e) { + } on DioException { return false; } catch (e) { return false; @@ -181,7 +181,7 @@ class UserPermissionApi { Future deleteUserById(userUuid) async { try { final response = await _httpService.delete( - path: ApiEndpoints.deleteUser.replaceAll("{inviteUserUuid}", userUuid), + path: ApiEndpoints.deleteUser.replaceAll('{inviteUserUuid}', userUuid), showServerMessage: true, expectedResponseModel: (json) { return json['success']; @@ -193,16 +193,17 @@ class UserPermissionApi { } } - Future changeUserStatusById(userUuid, status, String projectUuid) async { + Future changeUserStatusById( + userUuid, status, String projectUuid) async { try { - Map bodya = { - "disable": status, - "projectUuid": projectUuid + final bodya = { + 'disable': status, + 'projectUuid': projectUuid }; final response = await _httpService.put( path: ApiEndpoints.changeUserStatus - .replaceAll("{invitedUserUuid}", userUuid), + .replaceAll('{invitedUserUuid}', userUuid), body: bodya, expectedResponseModel: (json) { return json['success']; diff --git a/lib/utils/color_manager.dart b/lib/utils/color_manager.dart index 50170ed9..2b164590 100644 --- a/lib/utils/color_manager.dart +++ b/lib/utils/color_manager.dart @@ -6,15 +6,15 @@ abstract class ColorsManager { static const Color primaryColor = Color(0xFF0030CB); //023DFE static const Color secondaryTextColor = Color(0xFF848484); static Color primaryColorWithOpacity = - const Color(0xFF023DFE).withOpacity(0.6); + const Color(0xFF023DFE).withValues(alpha: 0.6); static const Color whiteColors = Colors.white; - static Color whiteColorsWithOpacity = Colors.white.withOpacity(0.6); + static Color whiteColorsWithOpacity = Colors.white.withValues(alpha: 0.6); static const Color secondaryColor = Color(0xFF023DFE); static const Color onSecondaryColor = Color(0xFF023DFE); - static Color shadowBlackColor = Colors.black.withOpacity(0.2); + static Color shadowBlackColor = Colors.black.withValues(alpha: 0.2); - static Color dialogBlueTitle = const Color(0xFF023DFE).withOpacity(0.6); + static Color dialogBlueTitle = const Color(0xFF023DFE).withValues(alpha: 0.6); static const Color primaryTextColor = Colors.black; @@ -83,7 +83,5 @@ abstract class ColorsManager { static const Color maxPurpleDot = Color(0xFF5F00BD); static const Color minBlue = Color(0xFF93AAFD); static const Color minBlueDot = Color(0xFF023DFE); - static const Color grey25 = Color(0xFFF9F9F9); - - + static const Color grey25 = Color(0xFFF9F9F9); } diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index 411e72a5..bfdb729d 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -1,7 +1,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; abstract class ApiEndpoints { - static const String projectUuid = "0e62577c-06fa-41b9-8a92-99a21fbaf51c"; + static const String projectUuid = '0e62577c-06fa-41b9-8a92-99a21fbaf51c'; static String baseUrl = dotenv.env['BASE_URL'] ?? ''; static const String signUp = '/authentication/user/signup'; static const String login = '/authentication/user/login'; diff --git a/lib/utils/constants/app_enum.dart b/lib/utils/constants/app_enum.dart index d603c3ea..ec5aeb2d 100644 --- a/lib/utils/constants/app_enum.dart +++ b/lib/utils/constants/app_enum.dart @@ -9,28 +9,28 @@ extension AccessTypeExtension on AccessType { String get value { switch (this) { case AccessType.onlineOnetime: - return "Online Password"; + return 'Online Password'; case AccessType.onlineMultiple: - return "online Multiple Password"; + return 'online Multiple Password'; case AccessType.offlineOnetime: - return "Offline Onetime Password"; + return 'Offline Onetime Password'; case AccessType.offlineMultiple: - return "Offline Multiple Password"; + return 'Offline Multiple Password'; } } static AccessType fromString(String value) { switch (value) { - case "ONLINE_ONETIME": + case 'ONLINE_ONETIME': return AccessType.onlineOnetime; - case "ONLINE_MULTIPLE": + case 'ONLINE_MULTIPLE': return AccessType.onlineMultiple; - case "OFFLINE_ONETIME": + case 'OFFLINE_ONETIME': return AccessType.offlineOnetime; - case "OFFLINE_MULTIPLE": + case 'OFFLINE_MULTIPLE': return AccessType.offlineMultiple; default: - throw ArgumentError("Invalid access type: $value"); + throw ArgumentError('Invalid access type: $value'); } } } @@ -44,9 +44,9 @@ extension OnlineTypeExtension on DeviseStatus { String get value { switch (this) { case DeviseStatus.online: - return "Online"; + return 'Online'; case DeviseStatus.offline: - return "Offline"; + return 'Offline'; } } @@ -57,7 +57,7 @@ extension OnlineTypeExtension on DeviseStatus { case true: return DeviseStatus.online; default: - throw ArgumentError("Invalid access type: $value"); + throw ArgumentError('Invalid access type: $value'); } } } @@ -72,24 +72,24 @@ extension AccessStatusExtension on AccessStatus { String get value { switch (this) { case AccessStatus.expired: - return "Expired"; + return 'Expired'; case AccessStatus.effective: - return "Effective"; + return 'Effective'; case AccessStatus.toBeEffective: - return "To be effective"; + return 'To be effective'; } } static AccessStatus fromString(String value) { switch (value) { - case "EXPIRED": + case 'EXPIRED': return AccessStatus.expired; - case "EFFECTIVE": + case 'EFFECTIVE': return AccessStatus.effective; - case "TO_BE_EFFECTIVE": + case 'TO_BE_EFFECTIVE': return AccessStatus.toBeEffective; default: - throw ArgumentError("Invalid access type: $value"); + throw ArgumentError('Invalid access type: $value'); } } } diff --git a/lib/utils/constants/assets.dart b/lib/utils/constants/assets.dart index dfc0b394..5f030841 100644 --- a/lib/utils/constants/assets.dart +++ b/lib/utils/constants/assets.dart @@ -1,138 +1,138 @@ class Assets { Assets._(); - static const String background = "assets/images/Background.png"; - static const String webBackground = "assets/images/web_Background.svg"; - static const String webBackgroundPng = "assets/images/web_Background.png"; - static const String blackLogo = "assets/images/black-logo.png"; - static const String logo = "assets/images/Logo.svg"; - static const String logoHorizontal = "assets/images/logo_horizontal.png"; - static const String vector = "assets/images/Vector.png"; - static const String loginLogo = "assets/images/login_logo.svg"; - static const String whiteLogo = "assets/images/white-logo.png"; - static const String window = "assets/images/Window.png"; - static const String liftLine = "assets/images/lift_line.png"; - static const String rightLine = "assets/images/right_line.png"; - static const String google = "assets/images/google.svg"; - static const String facebook = "assets/images/facebook.svg"; + static const String background = 'assets/images/Background.png'; + static const String webBackground = 'assets/images/web_Background.svg'; + static const String webBackgroundPng = 'assets/images/web_Background.png'; + static const String blackLogo = 'assets/images/black-logo.png'; + static const String logo = 'assets/images/Logo.svg'; + static const String logoHorizontal = 'assets/images/logo_horizontal.png'; + static const String vector = 'assets/images/Vector.png'; + static const String loginLogo = 'assets/images/login_logo.svg'; + static const String whiteLogo = 'assets/images/white-logo.png'; + static const String window = 'assets/images/Window.png'; + static const String liftLine = 'assets/images/lift_line.png'; + static const String rightLine = 'assets/images/right_line.png'; + static const String google = 'assets/images/google.svg'; + static const String facebook = 'assets/images/facebook.svg'; static const String invisiblePassword = - "assets/images/Password_invisible.svg"; - static const String visiblePassword = "assets/images/password_visible.svg"; - static const String accessIcon = "assets/images/access_icon.svg"; + 'assets/images/Password_invisible.svg'; + static const String visiblePassword = 'assets/images/password_visible.svg'; + static const String accessIcon = 'assets/images/access_icon.svg'; static const String spaseManagementIcon = - "assets/images/spase_management_icon.svg"; - static const String devicesIcon = "assets/images/devices_icon.svg"; - static const String analyticsIcon = "assets/icons/landing_analytics.svg"; + 'assets/images/spase_management_icon.svg'; + static const String devicesIcon = 'assets/images/devices_icon.svg'; + static const String analyticsIcon = 'assets/icons/landing_analytics.svg'; - static const String moveinIcon = "assets/images/movein_icon.svg"; - static const String constructionIcon = "assets/images/construction_icon.svg"; - static const String energyIcon = "assets/images/energy_icon.svg"; - static const String integrationsIcon = "assets/images/Integrations_icon.svg"; - static const String assetIcon = "assets/images/asset_icon.svg"; - static const String calendarIcon = "assets/images/calendar_icon.svg"; - static const String deviceNoteIcon = "assets/images/device_note.svg"; - static const String timeIcon = "assets/images/time_icon.svg"; - static const String emptyTable = "assets/images/empty_table.svg"; + static const String moveinIcon = 'assets/images/movein_icon.svg'; + static const String constructionIcon = 'assets/images/construction_icon.svg'; + static const String energyIcon = 'assets/images/energy_icon.svg'; + static const String integrationsIcon = 'assets/images/Integrations_icon.svg'; + static const String assetIcon = 'assets/images/asset_icon.svg'; + static const String calendarIcon = 'assets/images/calendar_icon.svg'; + static const String deviceNoteIcon = 'assets/images/device_note.svg'; + static const String timeIcon = 'assets/images/time_icon.svg'; + static const String emptyTable = 'assets/images/empty_table.svg'; // General assets static const String motionlessDetection = - "assets/icons/motionless_detection.svg"; - static const String acHeating = "assets/icons/ac_heating.svg"; - static const String acPowerOff = "assets/icons/ac_power_off.svg"; - static const String acFanMiddle = "assets/icons/ac_fan_middle.svg"; - static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg"; - static const String resetOff = "assets/icons/reset_off.svg"; + 'assets/icons/motionless_detection.svg'; + static const String acHeating = 'assets/icons/ac_heating.svg'; + static const String acPowerOff = 'assets/icons/ac_power_off.svg'; + static const String acFanMiddle = 'assets/icons/ac_fan_middle.svg'; + static const String switchAlarmSound = 'assets/icons/switch_alarm_sound.svg'; + static const String resetOff = 'assets/icons/reset_off.svg'; static const String sensitivityOperationIcon = - "assets/icons/sesitivity_operation_icon.svg"; - static const String motionDetection = "assets/icons/motion_detection.svg"; - static const String freezing = "assets/icons/freezing.svg"; - static const String indicator = "assets/icons/indicator.svg"; - static const String sceneRefresh = "assets/icons/scene_refresh.svg"; - static const String temperature = "assets/icons/tempreture.svg"; - static const String acFanHigh = "assets/icons/ac_fan_high.svg"; - static const String fanSpeed = "assets/icons/fan_speed.svg"; - static const String acFanLow = "assets/icons/ac_fan_low.svg"; - static const String sensitivity = "assets/icons/sensitivity.svg"; - static const String lightCountdown = "assets/icons/light_countdown.svg"; - static const String farDetection = "assets/icons/far_detection.svg"; - static const String sceneChildUnlock = "assets/icons/scene_child_unlock.svg"; - static const String acFanAuto = "assets/icons/ac_fan_auto.svg"; - static const String childLock = "assets/icons/child_lock.svg"; - static const String factoryReset = "assets/icons/factory_reset.svg"; - static const String acCooling = "assets/icons/ac_cooling.svg"; - static const String sceneChildLock = "assets/icons/scene_child_lock.svg"; - static const String celsiusDegrees = "assets/icons/celsius_degrees.svg"; - static const String masterState = "assets/icons/master_state.svg"; - static const String acPower = "assets/icons/ac_power.svg"; + 'assets/icons/sesitivity_operation_icon.svg'; + static const String motionDetection = 'assets/icons/motion_detection.svg'; + static const String freezing = 'assets/icons/freezing.svg'; + static const String indicator = 'assets/icons/indicator.svg'; + static const String sceneRefresh = 'assets/icons/scene_refresh.svg'; + static const String temperature = 'assets/icons/tempreture.svg'; + static const String acFanHigh = 'assets/icons/ac_fan_high.svg'; + static const String fanSpeed = 'assets/icons/fan_speed.svg'; + static const String acFanLow = 'assets/icons/ac_fan_low.svg'; + static const String sensitivity = 'assets/icons/sensitivity.svg'; + static const String lightCountdown = 'assets/icons/light_countdown.svg'; + static const String farDetection = 'assets/icons/far_detection.svg'; + static const String sceneChildUnlock = 'assets/icons/scene_child_unlock.svg'; + static const String acFanAuto = 'assets/icons/ac_fan_auto.svg'; + static const String childLock = 'assets/icons/child_lock.svg'; + static const String factoryReset = 'assets/icons/factory_reset.svg'; + static const String acCooling = 'assets/icons/ac_cooling.svg'; + static const String sceneChildLock = 'assets/icons/scene_child_lock.svg'; + static const String celsiusDegrees = 'assets/icons/celsius_degrees.svg'; + static const String masterState = 'assets/icons/master_state.svg'; + static const String acPower = 'assets/icons/ac_power.svg'; static const String farDetectionFunction = - "assets/icons/far_detection_function.svg"; - static const String nobodyTime = "assets/icons/nobody_time.svg"; + 'assets/icons/far_detection_function.svg'; + static const String nobodyTime = 'assets/icons/nobody_time.svg'; // Automation functions static const String tempPasswordUnlock = - "assets/icons/automation_functions/temp_password_unlock.svg"; + 'assets/icons/automation_functions/temp_password_unlock.svg'; static const String doorlockNormalOpen = - "assets/icons/automation_functions/doorlock_normal_open.svg"; + 'assets/icons/automation_functions/doorlock_normal_open.svg'; static const String doorbell = - "assets/icons/automation_functions/doorbell.svg"; + 'assets/icons/automation_functions/doorbell.svg'; static const String remoteUnlockViaApp = - "assets/icons/automation_functions/remote_unlock_via_app.svg"; + 'assets/icons/automation_functions/remote_unlock_via_app.svg'; static const String doubleLock = - "assets/icons/automation_functions/double_lock.svg"; + 'assets/icons/automation_functions/double_lock.svg'; static const String selfTestResult = - "assets/icons/automation_functions/self_test_result.svg"; + 'assets/icons/automation_functions/self_test_result.svg'; static const String lockAlarm = - "assets/icons/automation_functions/lock_alarm.svg"; + 'assets/icons/automation_functions/lock_alarm.svg'; static const String presenceState = - "assets/icons/automation_functions/presence_state.svg"; + 'assets/icons/automation_functions/presence_state.svg'; static const String currentTemp = - "assets/icons/automation_functions/current_temp.svg"; + 'assets/icons/automation_functions/current_temp.svg'; static const String presence = - "assets/icons/automation_functions/presence.svg"; + 'assets/icons/automation_functions/presence.svg'; static const String residualElectricity = - "assets/icons/automation_functions/residual_electricity.svg"; + 'assets/icons/automation_functions/residual_electricity.svg'; static const String hijackAlarm = - "assets/icons/automation_functions/hijack_alarm.svg"; + 'assets/icons/automation_functions/hijack_alarm.svg'; static const String passwordUnlock = - "assets/icons/automation_functions/password_unlock.svg"; + 'assets/icons/automation_functions/password_unlock.svg'; static const String remoteUnlockRequest = - "assets/icons/automation_functions/remote_unlock_req.svg"; + 'assets/icons/automation_functions/remote_unlock_req.svg'; static const String cardUnlock = - "assets/icons/automation_functions/card_unlock.svg"; - static const String motion = "assets/icons/automation_functions/motion.svg"; + 'assets/icons/automation_functions/card_unlock.svg'; + static const String motion = 'assets/icons/automation_functions/motion.svg'; static const String fingerprintUnlock = - "assets/icons/automation_functions/fingerprint_unlock.svg"; + 'assets/icons/automation_functions/fingerprint_unlock.svg'; // Presence Sensor Assets - static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg"; + static const String sensorMotionIcon = 'assets/icons/sensor_motion_ic.svg'; static const String sensorPresenceIcon = - "assets/icons/sensor_presence_ic.svg"; - static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg"; + 'assets/icons/sensor_presence_ic.svg'; + static const String sensorVacantIcon = 'assets/icons/sensor_vacant_ic.svg'; static const String illuminanceRecordIcon = - "assets/icons/illuminance_record_ic.svg"; + 'assets/icons/illuminance_record_ic.svg'; static const String presenceRecordIcon = - "assets/icons/presence_record_ic.svg"; + 'assets/icons/presence_record_ic.svg'; static const String helpDescriptionIcon = - "assets/icons/help_description_ic.svg"; + 'assets/icons/help_description_ic.svg'; - static const String lightPulp = "assets/icons/light_pulb.svg"; - static const String acDevice = "assets/icons/ac_device.svg"; - static const String acAirConditioner = "assets/icons/ac_air.svg"; - static const String acSun = "assets/icons/ac_sun.svg"; + static const String lightPulp = 'assets/icons/light_pulb.svg'; + static const String acDevice = 'assets/icons/ac_device.svg'; + static const String acAirConditioner = 'assets/icons/ac_air.svg'; + static const String acSun = 'assets/icons/ac_sun.svg'; //assets/icons/3GangSwitch.svg - static const String gangSwitch = "assets/icons/3GangSwitch.svg"; + static const String gangSwitch = 'assets/icons/3GangSwitch.svg'; //assets/icons/AC.svg - static const String ac = "assets/icons/AC.svg"; + static const String ac = 'assets/icons/AC.svg'; //assets/icons/Curtain.svg - static const String curtain = "assets/icons/Curtain.svg"; + static const String curtain = 'assets/icons/Curtain.svg'; //assets/icons/doorLock.svg - static const String doorLock = "assets/icons/doorLock.svg"; + static const String doorLock = 'assets/icons/doorLock.svg'; //assets/icons/Gateway.svg - static const String gateway = "assets/icons/Gateway.svg"; + static const String gateway = 'assets/icons/Gateway.svg'; //assets/icons/Light.svg - static const String lightBulb = "assets/icons/Light.svg"; + static const String lightBulb = 'assets/icons/Light.svg'; //assets/icons/sensors.svg - static const String sensors = "assets/icons/sensors.svg"; + static const String sensors = 'assets/icons/sensors.svg'; //assets/icons/door_un_look_ic.svg static const String doorUnlock = 'assets/icons/door_un_look_ic.svg'; @@ -175,7 +175,7 @@ class Assets { static const String Gang1SwitchIcon = 'assets/icons/1_Gang_switch_icon.svg'; static const String DoorLockIcon = 'assets/icons/door_lock.svg'; static const String SmartGatewayIcon = 'assets/icons/smart_gateway_icon.svg'; - static const String curtainIcon = "assets/images/curtain.svg"; + static const String curtainIcon = 'assets/images/curtain.svg'; static const String unlock = 'assets/icons/unlock_ic.svg'; static const String firmware = 'assets/icons/firmware.svg'; //assets/images/scheduling.svg @@ -227,12 +227,12 @@ class Assets { //assets/icons/2gang.svg static const String twoGang = 'assets/icons/2gang.svg'; - static const String frequencyIcon = "assets/icons/frequency_icon.svg"; - static const String voltMeterIcon = "assets/icons/volt_meter_icon.svg"; - static const String powerActiveIcon = "assets/icons/power_active_icon.svg"; - static const String searchIcon = "assets/icons/search_icon.svg"; - static const String voltageIcon = "assets/icons/voltage_icon.svg"; - static const String speedoMeter = "assets/icons/speedo_meter.svg"; + static const String frequencyIcon = 'assets/icons/frequency_icon.svg'; + static const String voltMeterIcon = 'assets/icons/volt_meter_icon.svg'; + static const String powerActiveIcon = 'assets/icons/power_active_icon.svg'; + static const String searchIcon = 'assets/icons/search_icon.svg'; + static const String voltageIcon = 'assets/icons/voltage_icon.svg'; + static const String speedoMeter = 'assets/icons/speedo_meter.svg'; //assets/icons/account_setting.svg static const String accountSetting = 'assets/icons/account_setting.svg'; @@ -284,99 +284,99 @@ class Assets { // Assets for functions_icons static const String assetsSensitivityFunction = - "assets/icons/functions_icons/sensitivity.svg"; + 'assets/icons/functions_icons/sensitivity.svg'; static const String assetsSensitivityOperationIcon = - "assets/icons/functions_icons/sesitivity_operation_icon.svg"; + 'assets/icons/functions_icons/sesitivity_operation_icon.svg'; static const String assetsAcPower = - "assets/icons/functions_icons/ac_power.svg"; + 'assets/icons/functions_icons/ac_power.svg'; static const String assetsAcPowerOFF = - "assets/icons/functions_icons/ac_power_off.svg"; + 'assets/icons/functions_icons/ac_power_off.svg'; static const String assetsChildLock = - "assets/icons/functions_icons/child_lock.svg"; + 'assets/icons/functions_icons/child_lock.svg'; static const String assetsFreezing = - "assets/icons/functions_icons/freezing.svg"; + 'assets/icons/functions_icons/freezing.svg'; static const String assetsFanSpeed = - "assets/icons/functions_icons/fan_speed.svg"; + 'assets/icons/functions_icons/fan_speed.svg'; static const String assetsAcCooling = - "assets/icons/functions_icons/ac_cooling.svg"; + 'assets/icons/functions_icons/ac_cooling.svg'; static const String assetsAcHeating = - "assets/icons/functions_icons/ac_heating.svg"; + 'assets/icons/functions_icons/ac_heating.svg'; static const String assetsCelsiusDegrees = - "assets/icons/functions_icons/celsius_degrees.svg"; + 'assets/icons/functions_icons/celsius_degrees.svg'; static const String assetsTempreture = - "assets/icons/functions_icons/tempreture.svg"; + 'assets/icons/functions_icons/tempreture.svg'; static const String assetsAcFanLow = - "assets/icons/functions_icons/ac_fan_low.svg"; + 'assets/icons/functions_icons/ac_fan_low.svg'; static const String assetsAcFanMiddle = - "assets/icons/functions_icons/ac_fan_middle.svg"; + 'assets/icons/functions_icons/ac_fan_middle.svg'; static const String assetsAcFanHigh = - "assets/icons/functions_icons/ac_fan_high.svg"; + 'assets/icons/functions_icons/ac_fan_high.svg'; static const String assetsAcFanAuto = - "assets/icons/functions_icons/ac_fan_auto.svg"; + 'assets/icons/functions_icons/ac_fan_auto.svg'; static const String assetsSceneChildLock = - "assets/icons/functions_icons/scene_child_lock.svg"; + 'assets/icons/functions_icons/scene_child_lock.svg'; static const String assetsSceneChildUnlock = - "assets/icons/functions_icons/scene_child_unlock.svg"; + 'assets/icons/functions_icons/scene_child_unlock.svg'; static const String assetsSceneRefresh = - "assets/icons/functions_icons/scene_refresh.svg"; + 'assets/icons/functions_icons/scene_refresh.svg'; static const String assetsLightCountdown = - "assets/icons/functions_icons/light_countdown.svg"; + 'assets/icons/functions_icons/light_countdown.svg'; static const String assetsFarDetection = - "assets/icons/functions_icons/far_detection.svg"; + 'assets/icons/functions_icons/far_detection.svg'; static const String assetsFarDetectionFunction = - "assets/icons/functions_icons/far_detection_function.svg"; + 'assets/icons/functions_icons/far_detection_function.svg'; static const String assetsIndicator = - "assets/icons/functions_icons/indicator.svg"; + 'assets/icons/functions_icons/indicator.svg'; static const String assetsMotionDetection = - "assets/icons/functions_icons/motion_detection.svg"; + 'assets/icons/functions_icons/motion_detection.svg'; static const String assetsMotionlessDetection = - "assets/icons/functions_icons/motionless_detection.svg"; + 'assets/icons/functions_icons/motionless_detection.svg'; static const String assetsNobodyTime = - "assets/icons/functions_icons/nobody_time.svg"; + 'assets/icons/functions_icons/nobody_time.svg'; static const String assetsFactoryReset = - "assets/icons/functions_icons/factory_reset.svg"; + 'assets/icons/functions_icons/factory_reset.svg'; static const String assetsMasterState = - "assets/icons/functions_icons/master_state.svg"; + 'assets/icons/functions_icons/master_state.svg'; static const String assetsSwitchAlarmSound = - "assets/icons/functions_icons/switch_alarm_sound.svg"; + 'assets/icons/functions_icons/switch_alarm_sound.svg'; static const String assetsResetOff = - "assets/icons/functions_icons/reset_off.svg"; + 'assets/icons/functions_icons/reset_off.svg'; // Assets for automation_functions static const String assetsCardUnlock = - "assets/icons/functions_icons/automation_functions/card_unlock.svg"; + 'assets/icons/functions_icons/automation_functions/card_unlock.svg'; static const String assetsDoorbell = - "assets/icons/functions_icons/automation_functions/doorbell.svg"; + 'assets/icons/functions_icons/automation_functions/doorbell.svg'; static const String assetsDoorlockNormalOpen = - "assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg"; + 'assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg'; static const String assetsDoubleLock = - "assets/icons/functions_icons/automation_functions/double_lock.svg"; + 'assets/icons/functions_icons/automation_functions/double_lock.svg'; static const String assetsFingerprintUnlock = - "assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg"; + 'assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg'; static const String assetsHijackAlarm = - "assets/icons/functions_icons/automation_functions/hijack_alarm.svg"; + 'assets/icons/functions_icons/automation_functions/hijack_alarm.svg'; static const String assetsLockAlarm = - "assets/icons/functions_icons/automation_functions/lock_alarm.svg"; + 'assets/icons/functions_icons/automation_functions/lock_alarm.svg'; static const String assetsPasswordUnlock = - "assets/icons/functions_icons/automation_functions/password_unlock.svg"; + 'assets/icons/functions_icons/automation_functions/password_unlock.svg'; static const String assetsRemoteUnlockReq = - "assets/icons/functions_icons/automation_functions/remote_unlock_req.svg"; + 'assets/icons/functions_icons/automation_functions/remote_unlock_req.svg'; static const String assetsRemoteUnlockViaApp = - "assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg"; + 'assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg'; static const String assetsResidualElectricity = - "assets/icons/functions_icons/automation_functions/residual_electricity.svg"; + 'assets/icons/functions_icons/automation_functions/residual_electricity.svg'; static const String assetsTempPasswordUnlock = - "assets/icons/functions_icons/automation_functions/temp_password_unlock.svg"; + 'assets/icons/functions_icons/automation_functions/temp_password_unlock.svg'; static const String assetsSelfTestResult = - "assets/icons/functions_icons/automation_functions/self_test_result.svg"; + 'assets/icons/functions_icons/automation_functions/self_test_result.svg'; static const String assetsPresence = - "assets/icons/functions_icons/automation_functions/presence.svg"; + 'assets/icons/functions_icons/automation_functions/presence.svg'; static const String assetsMotion = - "assets/icons/functions_icons/automation_functions/motion.svg"; + 'assets/icons/functions_icons/automation_functions/motion.svg'; static const String assetsCurrentTemp = - "assets/icons/functions_icons/automation_functions/current_temp.svg"; + 'assets/icons/functions_icons/automation_functions/current_temp.svg'; static const String assetsPresenceState = - "assets/icons/functions_icons/automation_functions/presence_state.svg"; + 'assets/icons/functions_icons/automation_functions/presence_state.svg'; //assets/icons/routine/automation.svg static const String automation = 'assets/icons/routine/automation.svg'; static const String searchIconUser = 'assets/icons/search_icon_user.svg'; diff --git a/lib/utils/constants/strings_manager.dart b/lib/utils/constants/strings_manager.dart index 2ea63fe4..3f70b347 100644 --- a/lib/utils/constants/strings_manager.dart +++ b/lib/utils/constants/strings_manager.dart @@ -22,13 +22,13 @@ class StringsManager { static const String on = 'ON'; static const String off = 'OFF'; static const String timer = 'Timer'; - static const String dimmerAndColor = "Dimmer & color"; - static const String recentlyUsed = "Recently used colors"; - static const String lightingModes = "Lighting modes"; - static const String doze = "Doze"; - static const String relax = "Relax"; - static const String reading = "Reading"; - static const String energizing = "Energizing"; + static const String dimmerAndColor = 'Dimmer & color'; + static const String recentlyUsed = 'Recently used colors'; + static const String lightingModes = 'Lighting modes'; + static const String doze = 'Doze'; + static const String relax = 'Relax'; + static const String reading = 'Reading'; + static const String energizing = 'Energizing'; static const String createScene = 'Create Scene'; static const String tapToRun = 'Launch: Tap - To - Run'; static const String turnOffAllLights = @@ -36,8 +36,8 @@ class StringsManager { static const String whenDeviceStatusChanges = 'When device status changes'; static const String whenUnusualActivityIsDetected = 'Example: when an unusual activity is detected.'; - static const String functions = "Functions"; - static const String firstLaunch = "firstLaunch"; + static const String functions = 'Functions'; + static const String firstLaunch = 'firstLaunch'; static const String deleteScene = 'Delete Scene'; static const String deleteAutomation = 'Delete Automation'; static const String projectKey = 'selected_project_uuid'; diff --git a/lib/utils/enum/device_types.dart b/lib/utils/enum/device_types.dart index 9bfd322f..0af5510b 100644 --- a/lib/utils/enum/device_types.dart +++ b/lib/utils/enum/device_types.dart @@ -43,20 +43,20 @@ enum DeviceType { */ Map devicesTypesMap = { - "AC": DeviceType.AC, - "GW": DeviceType.Gateway, - "CPS": DeviceType.CeilingSensor, - "DL": DeviceType.DoorLock, - "WPS": DeviceType.WallSensor, - "3G": DeviceType.ThreeGang, - "2G": DeviceType.TwoGang, - "1G": DeviceType.OneGang, - "CUR": DeviceType.Curtain, - "WH": DeviceType.WH, + 'AC': DeviceType.AC, + 'GW': DeviceType.Gateway, + 'CPS': DeviceType.CeilingSensor, + 'DL': DeviceType.DoorLock, + 'WPS': DeviceType.WallSensor, + '3G': DeviceType.ThreeGang, + '2G': DeviceType.TwoGang, + '1G': DeviceType.OneGang, + 'CUR': DeviceType.Curtain, + 'WH': DeviceType.WH, 'DS': DeviceType.DoorSensor, - "1GT": DeviceType.OneGang, - "2GT": DeviceType.TwoGang, - "3GT": DeviceType.ThreeGang, + '1GT': DeviceType.OneGang, + '2GT': DeviceType.TwoGang, + '3GT': DeviceType.ThreeGang, 'GD': DeviceType.GarageDoor, 'WL': DeviceType.WaterLeak, 'NCPS': DeviceType.NCPS, diff --git a/lib/utils/extension/build_context_x.dart b/lib/utils/extension/build_context_x.dart index 0abd16a1..1c3a5dbc 100644 --- a/lib/utils/extension/build_context_x.dart +++ b/lib/utils/extension/build_context_x.dart @@ -22,14 +22,14 @@ extension BuildContextExt on BuildContext { required VoidCallback onConfirm, VoidCallback? onDismiss, bool? hideConfirmButton, - final double? dialogWidth, + double? dialogWidth, TextStyle? titleStyle, String? onDismissText, String? onConfirmText, Color? onDismissColor, Color? onConfirmColor, }) { - showDialog( + showDialog( context: this, builder: (BuildContext context) { return AlertDialog( @@ -74,58 +74,59 @@ extension BuildContextExt on BuildContext { width: double.infinity, color: ColorsManager.greyColor, ), - hideConfirmButton != true - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: onDismiss ?? - () { - Navigator.pop(context); - }, - child: Center( - child: Text( - onDismissText ?? 'Cancel', - style: context.textTheme.bodyMedium!.copyWith( - color: onDismissColor ?? - ColorsManager.greyColor), - ), - ), - ), - Container( - height: 50, - width: 1, - color: ColorsManager.greyColor, - ), - GestureDetector( - onTap: onConfirm, - child: Center( - child: Text( - onConfirmText ?? 'Confirm', - style: context.textTheme.bodyMedium!.copyWith( - color: onConfirmColor ?? - ColorsManager.primaryColorWithOpacity), - ), - ), - ), - ], - ) - : Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: GestureDetector( - onTap: onDismiss ?? - () { - Navigator.pop(context); - }, - child: Center( - child: Text( - 'Cancel', - style: context.textTheme.bodyMedium! - .copyWith(color: ColorsManager.greyColor), - ), + if (hideConfirmButton != true) + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: onDismiss ?? + () { + Navigator.pop(context); + }, + child: Center( + child: Text( + onDismissText ?? 'Cancel', + style: context.textTheme.bodyMedium!.copyWith( + color: + onDismissColor ?? ColorsManager.greyColor), ), ), ), + Container( + height: 50, + width: 1, + color: ColorsManager.greyColor, + ), + GestureDetector( + onTap: onConfirm, + child: Center( + child: Text( + onConfirmText ?? 'Confirm', + style: context.textTheme.bodyMedium!.copyWith( + color: onConfirmColor ?? + ColorsManager.primaryColorWithOpacity), + ), + ), + ), + ], + ) + else + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: GestureDetector( + onTap: onDismiss ?? + () { + Navigator.pop(context); + }, + child: Center( + child: Text( + 'Cancel', + style: context.textTheme.bodyMedium! + .copyWith(color: ColorsManager.greyColor), + ), + ), + ), + ), ], ), ), diff --git a/lib/utils/format_date_time.dart b/lib/utils/format_date_time.dart index 98d0eb5e..2b63b1d4 100644 --- a/lib/utils/format_date_time.dart +++ b/lib/utils/format_date_time.dart @@ -5,8 +5,8 @@ String formatDateTime(DateTime? dateTime) { if (dateTime == null) { return '-'; } - final DateFormat dateFormatter = DateFormat('dd/MM/yyyy'); - final DateFormat timeFormatter = DateFormat('HH:mm'); + final dateFormatter = DateFormat('dd/MM/yyyy'); + final timeFormatter = DateFormat('HH:mm'); return '${dateFormatter.format(dateTime)} ${timeFormatter.format(dateTime)}'; } diff --git a/lib/utils/helpers/decodeBase64.dart b/lib/utils/helpers/decodeBase64.dart index e0473992..d94bd090 100644 --- a/lib/utils/helpers/decodeBase64.dart +++ b/lib/utils/helpers/decodeBase64.dart @@ -2,7 +2,7 @@ import 'dart:convert'; String decodeBase64(String str) { //'-', '+' 62nd char of encoding, '_', '/' 63rd char of encoding - String output = str.replaceAll('-', '+').replaceAll('_', '/'); + var output = str.replaceAll('-', '+').replaceAll('_', '/'); switch (output.length % 4) { // Pad with trailing '=' case 0: // No pad chars in this case diff --git a/lib/utils/helpers/shared_preferences_helper.dart b/lib/utils/helpers/shared_preferences_helper.dart index b9c7e0f4..97a504e0 100644 --- a/lib/utils/helpers/shared_preferences_helper.dart +++ b/lib/utils/helpers/shared_preferences_helper.dart @@ -1,52 +1,52 @@ import 'package:shared_preferences/shared_preferences.dart'; class SharedPreferencesHelper { - static saveStringToSP(String key, String value) async { + static Future saveStringToSP(String key, String value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(key, value); } - static saveBoolToSP(String key, bool value) async { + static Future saveBoolToSP(String key, bool value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool(key, value); } - static saveIntToSP(String key, int value) async { + static Future saveIntToSP(String key, int value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setInt(key, value); } - static saveDoubleToSP(String key, double value) async { + static Future saveDoubleToSP(String key, double value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setDouble(key, value); } - static saveStringListToSP(String key, List value) async { + static Future saveStringListToSP(String key, List value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setStringList(key, value); } static Future readStringFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - String value = prefs.getString(key) ?? ''; + final value = prefs.getString(key) ?? ''; return value; } static Future readBoolFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - bool? value = prefs.getBool(key); + final value = prefs.getBool(key); return value; } static Future readIntFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - int value = prefs.getInt(key) ?? 0; + final value = prefs.getInt(key) ?? 0; return value; } static Future> readStringListFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - List? value = prefs.getStringList(key) ?? []; + final value = prefs.getStringList(key) ?? []; return value; } diff --git a/lib/utils/navigation_service.dart b/lib/utils/navigation_service.dart index c9d654e6..c0b12167 100644 --- a/lib/utils/navigation_service.dart +++ b/lib/utils/navigation_service.dart @@ -5,6 +5,3 @@ class NavigationService { static GlobalKey? snackbarKey = GlobalKey(); } - - - diff --git a/lib/utils/snack_bar.dart b/lib/utils/snack_bar.dart index 0a312e5a..ae65541d 100644 --- a/lib/utils/snack_bar.dart +++ b/lib/utils/snack_bar.dart @@ -3,7 +3,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/navigation_service.dart'; class CustomSnackBar { - static displaySnackBar(String message) { + static void displaySnackBar(String message) { final key = NavigationService.snackbarKey; if (key != null) { final snackBar = SnackBar(content: Text(message)); @@ -12,9 +12,9 @@ class CustomSnackBar { } } - static redSnackBar(String message) { + static void redSnackBar(String message) { final key = NavigationService.snackbarKey; - BuildContext? currentContext = key?.currentContext; + final currentContext = key?.currentContext; if (key != null && currentContext != null) { final snackBar = SnackBar( padding: const EdgeInsets.all(16), @@ -30,10 +30,8 @@ class CustomSnackBar { ), Text( message, - style: Theme.of(currentContext) - .textTheme - .bodySmall! - .copyWith(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), + style: Theme.of(currentContext).textTheme.bodySmall!.copyWith( + fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), ) ]), ); @@ -41,9 +39,9 @@ class CustomSnackBar { } } - static greenSnackBar(String message) { + static void greenSnackBar(String message) { final key = NavigationService.snackbarKey; - BuildContext? currentContext = key?.currentContext; + final currentContext = key?.currentContext; if (key != null && currentContext != null) { final snackBar = SnackBar( padding: const EdgeInsets.all(16), @@ -59,10 +57,8 @@ class CustomSnackBar { ), Text( message, - style: Theme.of(currentContext) - .textTheme - .bodySmall! - .copyWith(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), + style: Theme.of(currentContext).textTheme.bodySmall!.copyWith( + fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), ) ]), ); diff --git a/lib/utils/style.dart b/lib/utils/style.dart index 905bb7a8..9964cf41 100644 --- a/lib/utils/style.dart +++ b/lib/utils/style.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; -import 'color_manager.dart'; - -InputDecoration? textBoxDecoration({bool suffixIcon = false, double radios = 8}) => +InputDecoration? textBoxDecoration( + {bool suffixIcon = false, double radios = 8}) => InputDecoration( focusColor: ColorsManager.grayColor, suffixIcon: suffixIcon ? const Icon(Icons.search) : null, @@ -34,7 +34,7 @@ InputDecoration? textBoxDecoration({bool suffixIcon = false, double radios = 8}) BoxDecoration containerDecoration = BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.3), + color: Colors.grey.withValues(alpha: 0.3), spreadRadius: 2, blurRadius: 4, offset: const Offset(0, 5), // changes position of shadow @@ -46,7 +46,7 @@ BoxDecoration containerDecoration = BoxDecoration( BoxDecoration containerWhiteDecoration = BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.3), + color: Colors.grey.withValues(alpha: 0.3), spreadRadius: 2, blurRadius: 4, offset: const Offset(0, 5), // changes position of shadow @@ -59,7 +59,7 @@ BoxDecoration subSectionContainerDecoration = BoxDecoration( color: ColorsManager.whiteColors, boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.1), + color: Colors.black.withValues(alpha: 0.1), blurRadius: 10, spreadRadius: 1, offset: const Offset(0, 2), @@ -70,7 +70,7 @@ BoxDecoration subSectionContainerDecoration = BoxDecoration( final secondarySection = BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.1), + color: Colors.black.withValues(alpha: 0.1), spreadRadius: 1, blurRadius: 7, offset: const Offset(0, 10), diff --git a/lib/utils/theme/theme.dart b/lib/utils/theme/theme.dart index 5ac61afa..27ddd487 100644 --- a/lib/utils/theme/theme.dart +++ b/lib/utils/theme/theme.dart @@ -34,7 +34,7 @@ final myTheme = ThemeData( }), trackColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { - return ColorsManager.blueColor.withOpacity(0.5); + return ColorsManager.blueColor.withValues(alpha: 0.5); } return ColorsManager.whiteColors; }), diff --git a/lib/utils/user_drop_down_menu.dart b/lib/utils/user_drop_down_menu.dart index 15da1f3a..f70b90c1 100644 --- a/lib/utils/user_drop_down_menu.dart +++ b/lib/utils/user_drop_down_menu.dart @@ -1,10 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.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/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -66,9 +64,9 @@ class _UserDropdownMenuState extends State { } Future _showPopupMenu(BuildContext context) async { - final RenderBox overlay = - Overlay.of(context).context.findRenderObject() as RenderBox; - final RelativeRect position = RelativeRect.fromRect( + final overlay = + Overlay.of(context).context.findRenderObject()! as RenderBox; + final position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width, 75, @@ -106,7 +104,7 @@ class _UserDropdownMenuState extends State { child: ListTile( leading: SvgPicture.asset(Assets.userManagement), title: Text( - "User Management", + 'User Management', style: context.textTheme.bodyMedium, ), ), @@ -255,7 +253,7 @@ class _UserDropdownMenuState extends State { child: ListTile( leading: SvgPicture.asset(Assets.signOut), title: Text( - "Log Out", + 'Log Out', style: context.textTheme.bodyMedium, ), ), diff --git a/lib/web_layout/default_container.dart b/lib/web_layout/default_container.dart index e0a71b04..c156ecd5 100644 --- a/lib/web_layout/default_container.dart +++ b/lib/web_layout/default_container.dart @@ -21,7 +21,7 @@ class DefaultContainer extends StatelessWidget { final EdgeInsets? margin; final EdgeInsets? padding; final Color? color; - final Function()? onTap; + final void Function()? onTap; final BorderRadius? borderRadius; @override Widget build(BuildContext context) { diff --git a/lib/web_layout/web_app_bar.dart b/lib/web_layout/web_app_bar.dart index 3cfe171e..03e2e8a8 100644 --- a/lib/web_layout/web_app_bar.dart +++ b/lib/web_layout/web_app_bar.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_web/pages/auth/model/user_model.dart'; import 'package:syncrow_web/pages/home/bloc/home_bloc.dart'; import 'package:syncrow_web/pages/home/bloc/home_state.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -49,7 +50,7 @@ class DesktopAppBar extends StatelessWidget { final Widget? title; final Widget? centerBody; final Widget? rightBody; - final dynamic user; + final UserModel? user; const DesktopAppBar({ super.key, @@ -75,7 +76,7 @@ class DesktopAppBar extends StatelessWidget { if (centerBody != null) Padding( padding: const EdgeInsets.only(left: 80), - child: centerBody!, + child: centerBody, ), ], ), @@ -102,7 +103,7 @@ class TabletAppBar extends StatelessWidget { final Widget? title; final Widget? centerBody; final Widget? rightBody; - final dynamic user; + final UserModel? user; const TabletAppBar({ super.key, @@ -149,7 +150,7 @@ class MobileAppBar extends StatelessWidget { final Widget? title; final Widget? centerBody; final Widget? rightBody; - final dynamic user; + final UserModel? user; const MobileAppBar({ super.key, @@ -182,12 +183,12 @@ class MobileAppBar extends StatelessWidget { if (centerBody != null) Padding( padding: const EdgeInsets.only(top: 8), - child: centerBody!, + child: centerBody, ), if (rightBody != null) Padding( padding: const EdgeInsets.only(top: 8), - child: rightBody!, + child: rightBody, ), ], ), diff --git a/lib/web_layout/web_scaffold.dart b/lib/web_layout/web_scaffold.dart index a37727db..812ea49e 100644 --- a/lib/web_layout/web_scaffold.dart +++ b/lib/web_layout/web_scaffold.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.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/web_layout/menu_sidebar.dart'; import 'package:syncrow_web/web_layout/web_app_bar.dart'; -import 'menu_sidebar.dart'; - class WebScaffold extends StatelessWidget with HelperResponsiveLayout { final bool enableMenuSidebar; final Widget? appBarTitle; diff --git a/test/widget_test.dart b/test/widget_test.dart index e69de29b..8b137891 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -0,0 +1 @@ + From c642ba26444172e8bcce649886a7cf01268a8edc Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 12 Jun 2025 16:04:49 +0300 Subject: [PATCH 82/82] Revert "formatted all files." This reverts commit 04250ebc98fc0b59b40711d75d0861a6552eed53. --- lib/common/dialog_dropdown.dart | 22 +- lib/common/edit_chip.dart | 13 +- lib/common/tag_dialog_textfield_dropdown.dart | 6 +- lib/common/widgets/custom_expansion_tile.dart | 3 +- lib/common/widgets/search_bar.dart | 6 +- lib/firebase_options_prod.dart | 3 +- lib/main.dart | 2 +- lib/main_dev.dart | 8 +- lib/main_staging.dart | 8 +- .../access_management/bloc/access_bloc.dart | 56 +- .../access_management/bloc/access_state.dart | 2 +- .../model/password_model.dart | 2 +- .../helpers/dashed_border_painter.dart | 17 +- .../helpers/get_month_name_from_int.dart | 2 +- .../models/air_quality_data_model.dart | 5 +- .../analytics/models/analytics_device.dart | 9 +- lib/pages/analytics/models/occupacy.dart | 3 +- .../models/occupancy_heat_map_model.dart | 3 +- .../air_quality_distribution_bloc.dart | 6 +- .../device_location/device_location_bloc.dart | 3 +- .../blocs/range_of_aqi/range_of_aqi_bloc.dart | 3 +- .../helpers/range_of_aqi_charts_helper.dart | 3 +- .../air_quality/widgets/aqi_device_info.dart | 3 +- .../widgets/aqi_distribution_chart.dart | 23 +- .../widgets/aqi_sub_value_widget.dart | 2 +- .../widgets/aqi_type_dropdown.dart | 3 +- .../widgets/range_of_aqi_chart.dart | 5 +- .../widgets/range_of_aqi_chart_box.dart | 3 +- .../analytics_devices_event.dart | 3 +- .../analytics_tab/analytics_tab_event.dart | 2 +- .../air_quality_data_loading_strategy.dart | 8 +- ...alytics_data_loading_strategy_factory.dart | 3 +- ...ergy_management_data_loading_strategy.dart | 6 +- .../occupancy_data_loading_strategy.dart | 5 +- .../analytics_communities_sidebar.dart | 3 +- .../widgets/analytics_date_filter_button.dart | 2 +- .../widgets/analytics_page_tab_button.dart | 9 +- .../widgets/month_picker_widget.dart | 37 +- .../sidebar/analytics_space_tree_view.dart | 20 +- .../analytics/widgets/year_picker_widget.dart | 13 +- .../energy_consumption_by_phases_bloc.dart | 15 +- .../energy_consumption_by_phases_event.dart | 6 +- .../energy_consumption_per_device_bloc.dart | 12 +- .../power_clamp_info_bloc.dart | 8 +- .../power_clamp_info_event.dart | 3 +- .../realtime_device_changes_event.dart | 2 +- .../total_energy_consumption_bloc.dart | 2 +- .../total_energy_consumption_event.dart | 6 +- .../energy_management_charts_helper.dart | 6 +- .../fetch_energy_management_data_helper.dart | 3 +- .../analytics_energy_management_view.dart | 3 +- .../widgets/analytics_device_dropdown.dart | 3 +- .../energy_consumption_by_phases_chart.dart | 11 +- ...nergy_consumption_by_phases_chart_box.dart | 3 +- .../energy_consumption_per_device_chart.dart | 1 + ...ergy_consumption_per_device_chart_box.dart | 6 +- .../power_clamp_energy_data_widget.dart | 12 +- .../power_clamp_phases_data_widget.dart | 12 +- .../total_energy_consumption_chart.dart | 1 + .../total_energy_consumption_chart_box.dart | 3 +- .../blocs/occupancy/occupancy_bloc.dart | 6 +- .../helpers/fetch_occupancy_data_helper.dart | 12 +- .../views/analytics_occupancy_view.dart | 9 +- .../occupancy/widgets/occupancy_chart.dart | 9 +- .../widgets/occupancy_chart_box.dart | 6 +- .../widgets/occupancy_heat_map_box.dart | 6 +- .../occupancy/widgets/occupancy_painter.dart | 28 +- ...fake_air_quality_distribution_service.dart | 6 +- ...mote_air_quality_distribution_service.dart | 3 +- .../analytics_devices_service_delagate.dart | 3 +- ..._management_analytics_devices_service.dart | 6 +- ...e_occupancy_analytics_devices_service.dart | 18 +- ...ce_location_details_service_decorator.dart | 2 +- ..._energy_consumption_by_phases_service.dart | 6 +- ...energy_consumption_per_device_service.dart | 9 +- .../occupacy/remote_occupancy_service.dart | 3 +- .../remote_occupancy_heat_map_service.dart | 9 +- .../remote_power_clamp_info_service.dart | 3 +- .../fake_range_of_aqi_service.dart | 22 +- .../range_of_aqi/range_of_aqi_service.dart | 2 +- .../realtime_device_service.dart | 2 +- ...mote_total_energy_consumption_service.dart | 6 +- .../widgets/analytics_sidebar_header.dart | 3 +- lib/pages/auth/bloc/auth_bloc.dart | 65 +-- lib/pages/auth/bloc/auth_event.dart | 3 +- lib/pages/auth/bloc/auth_state.dart | 5 +- .../auth/model/login_with_email_model.dart | 4 +- lib/pages/auth/model/token.dart | 18 +- lib/pages/auth/model/user_model.dart | 27 +- .../auth/view/forget_password_web_page.dart | 236 +++----- lib/pages/auth/view/login_mobile_page.dart | 82 +-- lib/pages/auth/view/login_web_page.dart | 88 ++- lib/pages/common/access_device_table.dart | 96 ++-- lib/pages/common/buttons/cancel_button.dart | 14 +- lib/pages/common/buttons/default_button.dart | 2 +- lib/pages/common/curtain_toggle.dart | 4 +- lib/pages/common/custom_dialog.dart | 12 +- lib/pages/common/custom_table.dart | 23 +- lib/pages/common/filter/filter_widget.dart | 4 +- lib/pages/common/hour_picker_dialog.dart | 12 +- lib/pages/common/info_dialog.dart | 3 +- .../device_managment/ac/bloc/ac_bloc.dart | 38 +- .../device_managment/ac/bloc/ac_event.dart | 7 +- .../device_managment/ac/bloc/ac_state.dart | 3 +- .../device_managment/ac/model/ac_model.dart | 8 +- .../ac/view/ac_device_batch_control.dart | 10 +- .../ac/view/ac_device_control.dart | 2 +- .../batch_current_temp.dart | 63 +-- .../ac/view/control_list/ac_toggle.dart | 2 +- .../ac/view/control_list/current_temp.dart | 19 +- .../device_managment_bloc.dart | 35 +- .../helper/route_controls_based_code.dart | 100 +--- .../all_devices/models/device_sub_space.dart | 7 +- .../all_devices/models/devices_model.dart | 48 +- .../models/factory_reset_model.dart | 5 +- .../widgets/device_managment_body.dart | 37 +- .../widgets/device_search_filters.dart | 4 +- .../ceiling_sensor/bloc/ceiling_bloc.dart | 11 +- .../ceiling_sensor/bloc/ceiling_event.dart | 2 + .../model/ceiling_sensor_model.dart | 67 +-- .../view/ceiling_sensor_batch_control.dart | 17 +- .../curtain/bloc/curtain_bloc.dart | 8 +- .../curtain/bloc/curtain_event.dart | 3 +- .../curtain/bloc/curtain_state.dart | 3 +- .../curtain/model/curtain_model.dart | 4 +- .../view/curtain_batch_status_view.dart | 7 +- .../bloc/setting_bloc_bloc.dart | 19 +- .../device_setting/device_settings_panel.dart | 32 +- .../settings_model/sub_space_model.dart | 4 +- .../device_setting/sub_space_dialog.dart | 8 +- .../door_lock/bloc/door_lock_bloc.dart | 12 +- .../door_lock/bloc/door_lock_state.dart | 1 + .../models/door_lock_status_model.dart | 2 +- .../view/door_lock_batch_control_view.dart | 3 +- .../door_lock/widget/door_button.dart | 2 +- .../flush_mounted_presence_sensor_bloc.dart | 18 +- .../flush_mounted_presence_sensor_event.dart | 3 +- .../flush_mounted_presence_sensor_state.dart | 12 +- ..._mounted_presence_sensor_bloc_factory.dart | 6 +- .../flush_mounted_presence_sensor_model.dart | 26 +- ...ed_presence_sensor_batch_control_view.dart | 49 +- ..._mounted_presence_sensor_control_view.dart | 53 +- .../garage_door/bloc/garage_door_bloc.dart | 48 +- .../helper/garage_door_helper.dart | 78 +-- .../garage_door/models/garage_door_model.dart | 4 +- .../view/garage_door_batch_control_view.dart | 8 +- .../opening_clsoing_time_dialog_body.dart | 4 +- .../widgets/schedule__garage_table.dart | 52 +- .../widgets/schedule_garage_managment_ui.dart | 2 +- .../schedule_garage_mode_selector.dart | 3 +- .../garage_door/widgets/seconds_picker.dart | 3 +- .../widgets/time_out_alarm_dialog_body.dart | 2 +- .../gateway/bloc/gate_way_bloc.dart | 9 +- .../gateway/view/gateway_batch_control.dart | 6 +- .../gateway/view/gateway_view.dart | 6 +- .../bloc/main_door_sensor_bloc.dart | 12 +- .../bloc/main_door_sensor_event.dart | 5 +- .../models/main_door_status_model.dart | 6 +- .../view/main_door_control_view.dart | 27 +- .../view/main_door_sensor_batch_view.dart | 3 +- .../widgets/notification_dialog.dart | 2 +- .../bloc/one_gang_glass_switch_bloc.dart | 18 +- .../models/once_gang_glass_status_model.dart | 5 +- .../one_gang_glass_batch_control_view.dart | 14 +- .../one_gang_glass_switch_control_view.dart | 11 +- .../bloc/wall_light_switch_bloc.dart | 14 +- .../models/wall_light_status_model.dart | 2 +- .../view/wall_light_batch_control.dart | 17 +- .../power_clamp/bloc/smart_power_bloc.dart | 86 ++- .../power_clamp/bloc/smart_power_event.dart | 10 +- .../power_clamp/models/device_event.dart | 3 +- .../models/power_clamp_batch_model.dart | 6 +- .../power_clamp/models/power_clamp_model.dart | 3 +- .../power_clamp/view/phase_widget.dart | 48 +- .../power_clamp/view/power_chart.dart | 22 +- .../view/power_clamp_batch_control_view.dart | 12 +- .../power_clamp/view/power_info_card.dart | 4 +- .../view/smart_power_device_control.dart | 9 +- .../shared/device_batch_control_dialog.dart | 39 +- .../shared/device_control_dialog.dart | 8 +- .../shared/device_controls_container.dart | 5 +- .../presence_display_data.dart | 13 +- .../sensors_widgets/presence_space_type.dart | 8 +- .../presence_static_widget.dart | 7 +- .../sensors_widgets/presence_status.dart | 8 +- .../sensors_widgets/presense_nobody_time.dart | 10 +- .../shared/table/report_table.dart | 36 +- .../shared/toggle_widget.dart | 39 +- .../sos/bloc/sos_device_bloc.dart | 35 +- .../sos/models/sos_status_model.dart | 2 +- .../sos/view/sos_device_control_view.dart | 7 +- .../sos/widgets/sos_notification_dialog.dart | 2 +- .../bloc/three_gang_glass_switch_bloc.dart | 15 +- .../models/three_gang_glass_switch.dart | 2 +- ..._gang_glass_switch_batch_control_view.dart | 20 +- .../three_gang_glass_switch_control_view.dart | 18 +- .../bloc/living_room_bloc.dart | 13 +- .../models/living_room_model.dart | 2 +- .../view/living_room_batch_controls.dart | 14 +- .../view/living_room_device_control.dart | 2 +- .../widgets/cieling_light.dart | 11 +- .../three_gang_switch/widgets/spot_light.dart | 11 +- .../three_gang_switch/widgets/wall_light.dart | 11 +- .../bloc/two_gang_glass_switch_bloc.dart | 16 +- .../models/two_gang_glass_status_model.dart | 2 +- ..._gang_glass_switch_batch_control_view.dart | 14 +- .../two_gang_glass_switch_control_view.dart | 5 +- .../bloc/two_gang_switch_bloc.dart | 10 +- .../bloc/two_gang_switch_state.dart | 2 +- .../models/two_gang_status_model.dart | 2 +- .../view/wall_light_batch_control.dart | 11 +- .../wall_sensor/bloc/wall_bloc.dart | 7 +- .../wall_sensor/model/wall_sensor_model.dart | 56 +- .../view/wall_sensor_batch_control.dart | 32 +- .../view/wall_sensor_conrtols.dart | 53 +- .../water_heater/bloc/water_heater_bloc.dart | 58 +- .../water_heater/bloc/water_heater_event.dart | 2 + .../helper/add_schedule_dialog_helper.dart | 43 +- .../water_heater/models/schedule_entry.dart | 8 +- .../water_heater/models/schedule_model.dart | 7 +- .../models/water_heater_status_model.dart | 14 +- .../view/water_heater_batch_control.dart | 3 +- .../view/water_heater_device_control.dart | 3 +- .../widgets/count_down_button.dart | 2 +- .../widgets/inching_mode_buttons.dart | 6 +- .../widgets/schedule_managment_ui.dart | 2 +- .../widgets/schedule_mode_selector.dart | 2 +- .../water_heater/widgets/schedule_table.dart | 7 +- .../water_leak/bloc/water_leak_bloc.dart | 23 +- .../view/water_leak_batch_control_view.dart | 12 +- .../view/water_leak_control_view.dart | 29 +- .../widgets/water_leak_notifi_dialog.dart | 5 +- lib/pages/home/bloc/home_bloc.dart | 16 +- .../view/agreement_and_privacy_dialog.dart | 12 +- lib/pages/home/view/home_page.dart | 2 +- lib/pages/home/view/home_page_mobile.dart | 12 +- lib/pages/home/view/home_page_web.dart | 4 +- lib/pages/home/view/tree_page.dart | 2 +- .../bloc/roles_permission_bloc.dart | 2 +- .../model/role_type_model.dart | 2 +- .../model/roles_user_model.dart | 8 +- .../add_user_dialog/bloc/users_bloc.dart | 107 ++-- .../add_user_dialog/bloc/users_event.dart | 2 +- .../model/permission_option_model.dart | 2 +- .../model/tree_node_model.dart | 2 +- .../add_user_dialog/view/add_user_dialog.dart | 62 +- .../add_user_dialog/view/basics_view.dart | 61 +- .../add_user_dialog/view/build_tree_view.dart | 7 +- .../view/delete_user_dialog.dart | 7 +- .../view/edit_user_dialog.dart | 68 +-- .../view/permission_management.dart | 77 +-- .../view/popup_menu_filter.dart | 17 +- .../add_user_dialog/view/role_dropdown.dart | 6 +- .../view/roles_and_permission.dart | 19 +- .../view/spaces_access_view.dart | 12 +- .../users_table/bloc/user_table_bloc.dart | 92 +-- .../users_table/bloc/user_table_event.dart | 12 +- .../users_table/bloc/user_table_state.dart | 2 - .../view/creation_date_filter.dart | 13 +- .../users_table/view/de_activate_filter.dart | 13 +- .../users_table/view/name_filter.dart | 13 +- .../users_table/view/user_table.dart | 18 +- .../users_table/view/users_page.dart | 223 ++++---- .../view/create_role_card.dart | 1 - .../roles_and_permission/view/role_card.dart | 5 +- .../view/roles_and_permission_page.dart | 9 +- .../roles_and_permission/view/roles_page.dart | 9 +- .../automation_status_update.dart | 17 +- .../create_routine_bloc.dart | 5 +- .../create_routine_event.dart | 3 +- .../create_routine_state.dart | 4 +- .../effective_period/effect_period_bloc.dart | 24 +- .../effective_period/effect_period_state.dart | 9 +- .../bloc/routine_bloc/routine_bloc.dart | 116 ++-- .../bloc/routine_bloc/routine_event.dart | 13 +- .../bloc/setting_bloc/setting_bloc.dart | 19 +- .../create_new_routines/commu_dropdown.dart | 4 +- .../create_new_routines.dart | 12 +- .../dropdown_menu_content.dart | 9 +- .../create_new_routines/space_dropdown.dart | 8 +- .../space_tree_dropdown_bloc.dart | 2 +- .../space_tree_dropdown_event.dart | 2 +- .../space_tree_dropdown_state.dart | 2 +- .../routines/helper/save_routine_helper.dart | 54 +- lib/pages/routines/models/ac/ac_function.dart | 43 +- .../ceiling_presence_sensor_functions.dart | 78 +-- .../create_scene_model.dart | 4 +- .../models/delay/delay_fucntions.dart | 2 +- .../models/flush/flush_functions.dart | 60 +- .../one_gang_switch/one_gang_switch.dart | 6 +- .../three_gang_switch/three_gang_switch.dart | 60 +- .../two_gang_switch/two_gang_switch.dart | 18 +- lib/pages/routines/models/gateway.dart | 15 +- .../models/pc/energy_clamp_functions.dart | 38 +- .../models/routine_details_model.dart | 17 +- lib/pages/routines/models/routine_model.dart | 34 +- .../water_heater/water_heater_functions.dart | 8 +- .../routines/models/wps/wps_functions.dart | 45 +- .../routines/view/effective_period_view.dart | 2 +- lib/pages/routines/view/routines_view.dart | 4 +- .../routines/widgets/condition_toggle.dart | 8 +- .../widgets/custom_routines_textbox.dart | 36 +- lib/pages/routines/widgets/delete_scene.dart | 13 +- lib/pages/routines/widgets/dragable_card.dart | 39 +- .../routines/widgets/function_slider.dart | 7 +- lib/pages/routines/widgets/if_container.dart | 2 +- .../fetch_routine_scenes_automation.dart | 11 +- .../main_routine_view/routine_view_card.dart | 90 ++- lib/pages/routines/widgets/period_option.dart | 20 +- lib/pages/routines/widgets/repeat_days.dart | 15 +- .../routines/widgets/routine_devices.dart | 8 +- .../widgets/routine_dialogs/ac_dialog.dart | 5 +- .../routine_dialogs/automation_dialog.dart | 13 +- .../cps_dialog_value_selector.dart | 3 +- .../ceiling_sensor/cps_functions_list.dart | 2 +- .../ceiling_sensor/cps_slider_helpers.dart | 8 +- .../widgets/routine_dialogs/delay_dialog.dart | 11 +- .../routine_dialogs/discard_dialog.dart | 6 +- .../effictive_period_dialog.dart | 29 +- .../flush_value_selector_widget.dart | 5 +- .../flush_presence_sensor/time_wheel.dart | 4 +- .../gateway_dialog_value_selector.dart | 3 +- .../one_gang_switch_dialog.dart | 7 +- .../enargy_operational_values_list.dart | 2 + .../energy_value_selector_widget.dart | 12 +- .../routine_dialogs/setting_dialog.dart | 236 +++----- .../three_gang_switch_dialog.dart | 3 +- .../two_gang_switch_dialog.dart | 11 +- .../wall_sensor/time_wheel.dart | 4 +- .../wall_sensor/wall_presence_sensor.dart | 3 +- .../wps_operational_values_list.dart | 6 +- .../water_heater_operational_values_list.dart | 1 + .../water_heater_value_selector_widget.dart | 17 +- .../widgets/routine_search_and_buttons.dart | 140 ++--- .../widgets/scenes_and_automations.dart | 6 +- .../widgets/search_bar_condition_title.dart | 3 +- .../routines/widgets/then_container.dart | 231 ++++---- lib/pages/routines/widgets/value_display.dart | 2 +- .../space_tree/bloc/space_tree_bloc.dart | 141 +++-- .../space_tree/bloc/space_tree_state.dart | 7 +- .../bloc/add_device_model_bloc.dart | 2 +- .../bloc/add_device_type_model_event.dart | 3 +- .../views/add_device_type_widget.dart | 7 +- .../bloc/space_management_bloc.dart | 146 ++--- .../bloc/space_management_event.dart | 4 +- .../bloc/space_management_state.dart | 5 +- .../all_spaces/model/base_tag.dart | 2 +- .../all_spaces/model/community_model.dart | 11 +- .../all_spaces/model/product_model.dart | 3 +- .../model/selected_product_model.dart | 8 +- .../all_spaces/model/space_model.dart | 16 +- .../model/space_response_model.dart | 3 +- .../all_spaces/model/subspace_model.dart | 3 +- .../all_spaces/model/tag.dart | 19 +- .../view/spaces_management_page.dart | 4 +- .../widgets/add_device_type_widget.dart | 30 +- .../widgets/blank_community_widget.dart | 4 +- ...munity_structure_header_action_button.dart | 8 +- .../community_structure_header_widget.dart | 2 +- .../widgets/community_structure_widget.dart | 112 ++-- .../all_spaces/widgets/counter_widget.dart | 17 +- .../devices_part_widget.dart | 141 ++--- .../icon_choose_part_widget.dart | 4 +- .../space_model_linking_widget.dart | 128 ++--- .../space_name_textfield_widget.dart | 2 +- .../sub_space_part_widget.dart | 136 ++--- .../widgets/curved_line_painter.dart | 10 +- .../widgets/dialogs/create_space_dialog.dart | 27 +- .../widgets/dialogs/delete_dialogue.dart | 34 +- .../dialogs/duplicate_process_dialog.dart | 9 +- .../dialogs/icon_selection_dialog.dart | 12 +- .../gradient_canvas_border_widget.dart | 2 +- .../all_spaces/widgets/hoverable_button.dart | 13 +- .../widgets/loaded_space_widget.dart | 78 ++- .../selected_products_button_widget.dart | 8 +- .../all_spaces/widgets/sidebar_widget.dart | 33 +- .../all_spaces/widgets/space_card_widget.dart | 2 +- .../widgets/space_container_widget.dart | 2 +- .../all_spaces/widgets/space_widget.dart | 2 +- .../assign_tag/bloc/assign_tag_bloc.dart | 6 +- .../assign_tag/bloc/assign_tag_event.dart | 2 +- .../assign_tag/bloc/assign_tag_state.dart | 3 +- .../assign_tag/views/assign_tag_dialog.dart | 5 +- .../widgets/save_add_device_row_widget.dart | 9 +- .../bloc/assign_tag_model_bloc.dart | 48 +- .../bloc/assign_tag_model_event.dart | 2 +- .../views/assign_tag_models_dialog.dart | 12 +- .../views/widgets/RowOfCancelSaveWidget.dart | 25 +- .../widgets/assign_tags_tables_widget.dart | 7 +- .../bloc/community_dialog_bloc.dart | 7 +- .../view/create_community_dialog.dart | 12 +- .../create_subspace/bloc/subspace_bloc.dart | 7 +- .../views/create_subspace_model_dialog.dart | 5 +- .../widgets/ok_cancel_sub_space_widget.dart | 9 +- .../textfield_sub_space_dialog_widget.dart | 13 +- .../bloc/subspace_model_bloc.dart | 4 +- .../widgets/subspace_chip.dart | 3 +- .../helper/space_helper.dart | 44 +- .../spaces_management/helper/tag_helper.dart | 58 +- .../bloc/link_space_to_model_bloc.dart | 20 +- .../bloc/link_space_to_model_state.dart | 2 +- .../view/link_space_model_dialog.dart | 13 +- .../bloc/create_space_model_bloc.dart | 78 +-- .../bloc/create_space_model_event.dart | 12 +- .../bloc/create_space_model_state.dart | 4 +- .../space_model/bloc/space_model_bloc.dart | 23 +- .../models/space_template_model.dart | 13 +- .../space_model/view/space_model_page.dart | 21 +- .../widgets/add_space_model_widget.dart | 2 +- .../widgets/button_content_widget.dart | 4 +- .../widgets/dialog/confirm_merge_dialog.dart | 4 +- .../dialog/confirm_overwrite_dialog.dart | 4 +- .../dialog/create_space_model_dialog.dart | 122 ++-- .../widgets/dialog/custom_loading_dialog.dart | 25 +- .../dialog/delete_space_model_dialog.dart | 11 +- .../link_space_model_spaces_dialog.dart | 29 +- .../dialog/linking_attention_dialog.dart | 4 +- .../widgets/dialog/overwrite_dialog.dart | 10 +- .../widgets/dynamic_product_widget.dart | 26 +- .../widgets/dynamic_room_widget.dart | 29 +- .../widgets/ellipsis_item_widget.dart | 4 +- .../widgets/flexible_item_widget.dart | 4 +- .../space_model/widgets/room_name_widget.dart | 2 +- .../widgets/space_model_card_widget.dart | 92 ++- .../widgets/subspace_chip_widget.dart | 4 +- .../widgets/subspace_model_create_widget.dart | 10 +- .../widgets/subspace_name_label_widget.dart | 4 +- .../widgets/tag_chips_display_widget.dart | 3 +- .../bloc/center_body_bloc.dart | 2 +- .../bloc/center_body_event.dart | 2 +- .../view/center_body_widget.dart | 8 +- .../bloc/add_device_type_model_event.dart | 3 +- .../views/add_device_type_model_widget.dart | 22 +- .../widgets/scrollable_grid_view_widget.dart | 13 +- .../bloc/visitor_password_bloc.dart | 79 +-- .../bloc/visitor_password_event.dart | 2 +- .../visitor_password/model/device_model.dart | 4 +- .../model/failed_operation.dart | 5 + .../view/add_device_dialog.dart | 28 +- .../visitor_password/view/repeat_widget.dart | 4 +- .../view/visitor_password_dialog.dart | 533 +++++++----------- lib/services/access_mang_api.dart | 64 +-- lib/services/api/http_interceptor.dart | 28 +- lib/services/api/http_service.dart | 4 +- lib/services/api/network_exception.dart | 28 +- lib/services/auth_api.dart | 6 +- .../batch_control_devices_service.dart | 3 +- lib/services/devices_mang_api.dart | 18 +- lib/services/locator.dart | 2 +- lib/services/product_api.dart | 4 +- lib/services/routines_api.dart | 31 +- lib/services/space_mana_api.dart | 33 +- lib/services/space_model_mang_api.dart | 6 +- lib/services/user_permission.dart | 69 ++- lib/utils/color_manager.dart | 12 +- lib/utils/constants/api_const.dart | 2 +- lib/utils/constants/app_enum.dart | 38 +- lib/utils/constants/assets.dart | 290 +++++----- lib/utils/constants/strings_manager.dart | 18 +- lib/utils/enum/device_types.dart | 26 +- lib/utils/extension/build_context_x.dart | 103 ++-- lib/utils/format_date_time.dart | 4 +- lib/utils/helpers/decodeBase64.dart | 2 +- .../helpers/shared_preferences_helper.dart | 18 +- lib/utils/navigation_service.dart | 3 + lib/utils/snack_bar.dart | 22 +- lib/utils/style.dart | 14 +- lib/utils/theme/theme.dart | 2 +- lib/utils/user_drop_down_menu.dart | 12 +- lib/web_layout/default_container.dart | 2 +- lib/web_layout/web_app_bar.dart | 13 +- lib/web_layout/web_scaffold.dart | 3 +- test/widget_test.dart | 1 - 473 files changed, 4335 insertions(+), 5417 deletions(-) diff --git a/lib/common/dialog_dropdown.dart b/lib/common/dialog_dropdown.dart index 2d1c3f43..7274b3c0 100644 --- a/lib/common/dialog_dropdown.dart +++ b/lib/common/dialog_dropdown.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/utils/extension/build_context_x.dart'; class DialogDropdown extends StatefulWidget { final List items; @@ -8,14 +7,14 @@ class DialogDropdown extends StatefulWidget { final String? selectedValue; const DialogDropdown({ - super.key, + Key? key, required this.items, required this.onSelected, this.selectedValue, - }); + }) : super(key: key); @override - State createState() => _DialogDropdownState(); + _DialogDropdownState createState() => _DialogDropdownState(); } class _DialogDropdownState extends State { @@ -47,14 +46,16 @@ class _DialogDropdownState extends State { } OverlayEntry _createOverlayEntry() { - final renderBox = context.findRenderObject()! as RenderBox; + final renderBox = context.findRenderObject() as RenderBox; final size = renderBox.size; final offset = renderBox.localToGlobal(Offset.zero); return OverlayEntry( builder: (context) { return GestureDetector( - onTap: _closeDropdown, + onTap: () { + _closeDropdown(); + }, behavior: HitTestBehavior.translucent, child: Stack( children: [ @@ -86,9 +87,12 @@ class _DialogDropdownState extends State { child: ListTile( title: Text( item, - style: context.textTheme.bodyMedium?.copyWith( - color: ColorsManager.textPrimaryColor, - ), + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith( + color: ColorsManager.textPrimaryColor, + ), ), onTap: () { widget.onSelected(item); diff --git a/lib/common/edit_chip.dart b/lib/common/edit_chip.dart index ecda643e..1643b414 100644 --- a/lib/common/edit_chip.dart +++ b/lib/common/edit_chip.dart @@ -10,25 +10,24 @@ class EditChip extends StatelessWidget { final double borderRadius; const EditChip({ - super.key, + Key? key, this.label = 'Edit', required this.onTap, this.labelColor = ColorsManager.spaceColor, this.backgroundColor = ColorsManager.whiteColors, this.borderColor = ColorsManager.spaceColor, this.borderRadius = 16.0, - }); + }) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Chip( - label: Text(label, - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: labelColor)), + label: Text( + label, + style: Theme.of(context).textTheme.bodySmall!.copyWith(color: labelColor) + ), backgroundColor: backgroundColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(borderRadius), diff --git a/lib/common/tag_dialog_textfield_dropdown.dart b/lib/common/tag_dialog_textfield_dropdown.dart index 45d05614..9fa85284 100644 --- a/lib/common/tag_dialog_textfield_dropdown.dart +++ b/lib/common/tag_dialog_textfield_dropdown.dart @@ -9,12 +9,12 @@ class TagDialogTextfieldDropdown extends StatefulWidget { final String product; const TagDialogTextfieldDropdown({ - super.key, + Key? key, required this.items, required this.onSelected, this.initialValue, required this.product, - }); + }) : super(key: key); @override _DialogTextfieldDropdownState createState() => @@ -79,7 +79,7 @@ class _DialogTextfieldDropdownState extends State { } OverlayEntry _createOverlayEntry() { - final renderBox = context.findRenderObject()! as RenderBox; + final renderBox = context.findRenderObject() as RenderBox; final size = renderBox.size; final offset = renderBox.localToGlobal(Offset.zero); diff --git a/lib/common/widgets/custom_expansion_tile.dart b/lib/common/widgets/custom_expansion_tile.dart index bbe6a074..74151ca2 100644 --- a/lib/common/widgets/custom_expansion_tile.dart +++ b/lib/common/widgets/custom_expansion_tile.dart @@ -10,8 +10,7 @@ class CustomExpansionTile extends StatefulWidget { final ValueChanged? onExpansionChanged; // Notify when expansion changes final VoidCallback? onItemSelected; // Callback for selecting the item - const CustomExpansionTile({ - super.key, + CustomExpansionTile({ required this.title, this.children, this.initiallyExpanded = false, diff --git a/lib/common/widgets/search_bar.dart b/lib/common/widgets/search_bar.dart index a706f155..a99ac510 100644 --- a/lib/common/widgets/search_bar.dart +++ b/lib/common/widgets/search_bar.dart @@ -7,7 +7,7 @@ class CustomSearchBar extends StatefulWidget { final TextEditingController? controller; final String hintText; final String? searchQuery; - final void Function(String)? onSearchChanged; + final Function(String)? onSearchChanged; // Callback for search input changes const CustomSearchBar({ super.key, @@ -37,7 +37,7 @@ class _CustomSearchBarState extends State { color: ColorsManager.whiteColors, boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.2), + color: Colors.black.withOpacity(0.2), spreadRadius: 0, blurRadius: 8, offset: const Offset(0, 4), @@ -57,7 +57,7 @@ class _CustomSearchBarState extends State { style: const TextStyle( color: Colors.black, ), - onChanged: widget.onSearchChanged, + onChanged: widget.onSearchChanged, // Call the callback on text change decoration: InputDecoration( filled: true, fillColor: ColorsManager.textFieldGreyColor, diff --git a/lib/firebase_options_prod.dart b/lib/firebase_options_prod.dart index 0d9ac673..485696b8 100644 --- a/lib/firebase_options_prod.dart +++ b/lib/firebase_options_prod.dart @@ -1,8 +1,7 @@ // 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; +import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb, TargetPlatform; /// Default [FirebaseOptions] for use with your Firebase apps. /// diff --git a/lib/main.dart b/lib/main.dart index f875cc04..8eb6ce38 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -40,7 +40,7 @@ class MyApp extends StatelessWidget { initialLocation: RoutesConst.auth, routes: AppRoutes.getRoutes(), redirect: (context, state) async { - final checkToken = await AuthBloc.getTokenAndValidate(); + String checkToken = await AuthBloc.getTokenAndValidate(); final loggedIn = checkToken == 'Success'; final goingToLogin = state.uri.toString() == RoutesConst.auth; diff --git a/lib/main_dev.dart b/lib/main_dev.dart index 81c71a5f..578b2c30 100644 --- a/lib/main_dev.dart +++ b/lib/main_dev.dart @@ -21,8 +21,7 @@ import 'package:syncrow_web/utils/theme/theme.dart'; Future main() async { try { - const environment = - String.fromEnvironment('FLAVOR', defaultValue: 'development'); + const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development'); await dotenv.load(fileName: '.env.$environment'); WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( @@ -40,7 +39,7 @@ class MyApp extends StatelessWidget { initialLocation: RoutesConst.auth, routes: AppRoutes.getRoutes(), redirect: (context, state) async { - final checkToken = await AuthBloc.getTokenAndValidate(); + String checkToken = await AuthBloc.getTokenAndValidate(); final loggedIn = checkToken == 'Success'; final goingToLogin = state.uri.toString() == RoutesConst.auth; @@ -58,8 +57,7 @@ class MyApp extends StatelessWidget { BlocProvider( create: (context) => CreateRoutineBloc(), ), - BlocProvider( - create: (context) => HomeBloc()..add(const FetchUserInfo())), + BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())), BlocProvider( create: (context) => VisitorPasswordBloc(), ), diff --git a/lib/main_staging.dart b/lib/main_staging.dart index afccae74..e7f95c57 100644 --- a/lib/main_staging.dart +++ b/lib/main_staging.dart @@ -21,8 +21,7 @@ import 'package:syncrow_web/utils/theme/theme.dart'; Future main() async { try { - const environment = - String.fromEnvironment('FLAVOR', defaultValue: 'staging'); + const environment = String.fromEnvironment('FLAVOR', defaultValue: 'staging'); await dotenv.load(fileName: '.env.$environment'); WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( @@ -40,7 +39,7 @@ class MyApp extends StatelessWidget { initialLocation: RoutesConst.auth, routes: AppRoutes.getRoutes(), redirect: (context, state) async { - final checkToken = await AuthBloc.getTokenAndValidate(); + String checkToken = await AuthBloc.getTokenAndValidate(); final loggedIn = checkToken == 'Success'; final goingToLogin = state.uri.toString() == RoutesConst.auth; @@ -58,8 +57,7 @@ class MyApp extends StatelessWidget { BlocProvider( create: (context) => CreateRoutineBloc(), ), - BlocProvider( - create: (context) => HomeBloc()..add(const FetchUserInfo())), + BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())), BlocProvider( create: (context) => VisitorPasswordBloc(), ), diff --git a/lib/pages/access_management/bloc/access_bloc.dart b/lib/pages/access_management/bloc/access_bloc.dart index 8b216f04..dd82d739 100644 --- a/lib/pages/access_management/bloc/access_bloc.dart +++ b/lib/pages/access_management/bloc/access_bloc.dart @@ -11,7 +11,7 @@ import 'package:syncrow_web/utils/constants/app_enum.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; class AccessBloc extends Bloc { - AccessBloc() : super(AccessInitial()) { + AccessBloc() : super((AccessInitial())) { on(_onFetchTableData); on(selectTime); on(_filterData); @@ -43,12 +43,12 @@ class AccessBloc extends Bloc { } void updateTabsCount() { - final toBeEffectiveCount = data + int toBeEffectiveCount = data .where((item) => item.passwordStatus.value == 'To be effective') .length; - final effectiveCount = + int effectiveCount = data.where((item) => item.passwordStatus.value == 'Effective').length; - final expiredCount = + int expiredCount = data.where((item) => item.passwordStatus.value == 'Expired').length; tabs[1] = 'To Be Effective ($toBeEffectiveCount)'; tabs[2] = 'Effective ($effectiveCount)'; @@ -81,7 +81,7 @@ class AccessBloc extends Bloc { Emitter emit, ) async { emit(AccessLoaded()); - final picked = await showDatePicker( + final DateTime? picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), firstDate: DateTime.now().add(const Duration(days: -5095)), @@ -89,7 +89,7 @@ class AccessBloc extends Bloc { builder: (BuildContext context, Widget? child) { return Theme( data: ThemeData.light().copyWith( - colorScheme: const ColorScheme.light( + colorScheme: ColorScheme.light( primary: ColorsManager.blackColor, onPrimary: Colors.white, onSurface: ColorsManager.grayColor, @@ -105,20 +105,20 @@ class AccessBloc extends Bloc { }, ); if (picked != null) { - final timePicked = await showHourPicker( + final TimeOfDay? timePicked = await showHourPicker( context: event.context, initialTime: TimeOfDay.now(), ); if (timePicked != null) { - final selectedDateTime = DateTime( + final DateTime selectedDateTime = DateTime( picked.year, picked.month, picked.day, timePicked.hour, timePicked.minute, ); - final selectedTimestamp = + final int selectedTimestamp = selectedDateTime.millisecondsSinceEpoch ~/ 1000; if (event.isStart) { if (expirationTimeTimeStamp != null && @@ -152,35 +152,39 @@ class AccessBloc extends Bloc { final searchText = event.passwordName?.toLowerCase() ?? ''; final searchEmailText = event.emailAuthorizer?.toLowerCase() ?? ''; filteredData = data.where((item) { - var matchesCriteria = true; + bool matchesCriteria = true; // Convert timestamp to DateTime and extract date component - final effectiveDate = DateTime.fromMillisecondsSinceEpoch( + DateTime effectiveDate = DateTime.fromMillisecondsSinceEpoch( int.parse(item.effectiveTime.toString()) * 1000) .toUtc() .toLocal(); - final invalidDate = DateTime.fromMillisecondsSinceEpoch( + DateTime invalidDate = DateTime.fromMillisecondsSinceEpoch( int.parse(item.invalidTime.toString()) * 1000) .toUtc() .toLocal(); - final effectiveDateAndTime = DateTime( + DateTime effectiveDateAndTime = DateTime( effectiveDate.year, effectiveDate.month, effectiveDate.day, effectiveDate.hour, effectiveDate.minute); - final invalidDateAndTime = DateTime(invalidDate.year, invalidDate.month, - invalidDate.day, invalidDate.hour, invalidDate.minute); + DateTime invalidDateAndTime = DateTime( + invalidDate.year, + invalidDate.month, + invalidDate.day, + invalidDate.hour, + invalidDate.minute); // Filter by password name, making the search case-insensitive if (searchText.isNotEmpty) { - final matchesName = + final bool matchesName = item.passwordName.toString().toLowerCase().contains(searchText); if (!matchesName) { matchesCriteria = false; } } if (searchEmailText.isNotEmpty) { - final matchesName = item.authorizerEmail + final bool matchesName = item.authorizerEmail .toString() .toLowerCase() .contains(searchEmailText); @@ -190,7 +194,7 @@ class AccessBloc extends Bloc { } // Filter by start date only if (event.startTime != null && event.endTime == null) { - var startDateTime = + DateTime startDateTime = DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000) .toUtc() .toLocal(); @@ -202,7 +206,7 @@ class AccessBloc extends Bloc { } // Filter by end date only if (event.endTime != null && event.startTime == null) { - var startDateTime = + DateTime startDateTime = DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000) .toUtc() .toLocal(); @@ -215,11 +219,11 @@ class AccessBloc extends Bloc { // Filter by both start date and end date if (event.startTime != null && event.endTime != null) { - var startDateTime = + DateTime startDateTime = DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000) .toUtc() .toLocal(); - var endDateTime = + DateTime endDateTime = DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000) .toUtc() .toLocal(); @@ -254,7 +258,7 @@ class AccessBloc extends Bloc { } } - Future resetSearch(ResetSearch event, Emitter emit) async { + resetSearch(ResetSearch event, Emitter emit) async { emit(AccessLoaded()); startTime = 'Start Time'; endTime = 'End Time'; @@ -268,7 +272,7 @@ class AccessBloc extends Bloc { } String timestampToDate(dynamic timestamp) { - final dateTime = + DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(int.parse(timestamp) * 1000); return "${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')} " " ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}"; @@ -285,17 +289,17 @@ class AccessBloc extends Bloc { break; case 1: // To Be Effective filteredData = data - .where((item) => item.passwordStatus.value == 'To Be Effective') + .where((item) => item.passwordStatus.value == "To Be Effective") .toList(); break; case 2: // Effective filteredData = data - .where((item) => item.passwordStatus.value == 'Effective') + .where((item) => item.passwordStatus.value == "Effective") .toList(); break; case 3: // Expired filteredData = data - .where((item) => item.passwordStatus.value == 'Expired') + .where((item) => item.passwordStatus.value == "Expired") .toList(); break; default: diff --git a/lib/pages/access_management/bloc/access_state.dart b/lib/pages/access_management/bloc/access_state.dart index 122e16ad..0790a735 100644 --- a/lib/pages/access_management/bloc/access_state.dart +++ b/lib/pages/access_management/bloc/access_state.dart @@ -15,7 +15,7 @@ class AccessLoaded extends AccessState {} class FailedState extends AccessState { final String message; - const FailedState(this.message); + FailedState(this.message); @override List get props => [message]; diff --git a/lib/pages/access_management/model/password_model.dart b/lib/pages/access_management/model/password_model.dart index ccff1cb8..0ce4426a 100644 --- a/lib/pages/access_management/model/password_model.dart +++ b/lib/pages/access_management/model/password_model.dart @@ -36,7 +36,7 @@ class PasswordModel { effectiveTime: json['effectiveTime'], passwordCreated: json['passwordCreated'], createdTime: json['createdTime'], - passwordName: json['passwordName'] ?? 'No Name', + passwordName: json['passwordName']??'No Name', passwordStatus: AccessStatusExtension.fromString(json['passwordStatus']), passwordType: AccessTypeExtension.fromString(json['passwordType']), deviceUuid: json['deviceUuid'], diff --git a/lib/pages/analytics/helpers/dashed_border_painter.dart b/lib/pages/analytics/helpers/dashed_border_painter.dart index f32741fc..410cadfd 100644 --- a/lib/pages/analytics/helpers/dashed_border_painter.dart +++ b/lib/pages/analytics/helpers/dashed_border_painter.dart @@ -1,3 +1,5 @@ +import 'dart:ui'; + import 'package:flutter/material.dart'; class DashedBorderPainter extends CustomPainter { @@ -18,28 +20,27 @@ class DashedBorderPainter extends CustomPainter { ..strokeWidth = 0.5 ..style = PaintingStyle.stroke; - final topPath = Path() + final Path topPath = Path() ..moveTo(0, 0) ..lineTo(size.width, 0); - final bottomPath = Path() + final Path bottomPath = Path() ..moveTo(0, size.height) ..lineTo(size.width, size.height); final dashedTopPath = _createDashedPath(topPath, dashWidth, dashSpace); - final dashedBottomPath = - _createDashedPath(bottomPath, dashWidth, dashSpace); + final dashedBottomPath = _createDashedPath(bottomPath, dashWidth, dashSpace); canvas.drawPath(dashedTopPath, paint); canvas.drawPath(dashedBottomPath, paint); } Path _createDashedPath(Path source, double dashWidth, double dashSpace) { - final dashedPath = Path(); - for (final pathMetric in source.computeMetrics()) { - var distance = 0.0; + final Path dashedPath = Path(); + for (PathMetric pathMetric in source.computeMetrics()) { + double distance = 0.0; while (distance < pathMetric.length) { - final nextDistance = distance + dashWidth; + final double nextDistance = distance + dashWidth; dashedPath.addPath( pathMetric.extractPath(distance, nextDistance), Offset.zero, diff --git a/lib/pages/analytics/helpers/get_month_name_from_int.dart b/lib/pages/analytics/helpers/get_month_name_from_int.dart index 0ee35a38..54b0fa87 100644 --- a/lib/pages/analytics/helpers/get_month_name_from_int.dart +++ b/lib/pages/analytics/helpers/get_month_name_from_int.dart @@ -16,4 +16,4 @@ extension GetMonthNameFromNumber on num { _ => 'N/A' }; } -} +} \ No newline at end of file diff --git a/lib/pages/analytics/models/air_quality_data_model.dart b/lib/pages/analytics/models/air_quality_data_model.dart index 95de21c2..2eab2ddb 100644 --- a/lib/pages/analytics/models/air_quality_data_model.dart +++ b/lib/pages/analytics/models/air_quality_data_model.dart @@ -15,8 +15,7 @@ class AirQualityDataModel extends Equatable { return AirQualityDataModel( date: DateTime.parse(json['date'] as String), data: (json['data'] as List) - .map((e) => - AirQualityPercentageData.fromJson(e as Map)) + .map((e) => AirQualityPercentageData.fromJson(e as Map)) .toList(), ); } @@ -47,7 +46,7 @@ class AirQualityPercentageData extends Equatable { factory AirQualityPercentageData.fromJson(Map json) { return AirQualityPercentageData( - type: json['type'] as String? ?? '', + type: json['type'] as String? ?? '', name: json['name'] as String? ?? '', percentage: (json['percentage'] as num?)?.toDouble() ?? 0, ); diff --git a/lib/pages/analytics/models/analytics_device.dart b/lib/pages/analytics/models/analytics_device.dart index 0a36362a..3340a41d 100644 --- a/lib/pages/analytics/models/analytics_device.dart +++ b/lib/pages/analytics/models/analytics_device.dart @@ -36,14 +36,11 @@ class AnalyticsDevice { deviceTuyaUuid: json['deviceTuyaUuid'] as String?, isActive: json['isActive'] as bool?, productDevice: json['productDevice'] != null - ? ProductDevice.fromJson( - json['productDevice'] as Map) + ? ProductDevice.fromJson(json['productDevice'] as Map) : null, spaceUuid: json['spaceUuid'] as String?, - latitude: - json['lat'] != null ? double.parse(json['lat'] as String) : null, - longitude: - json['lon'] != null ? double.parse(json['lon'] as String) : null, + latitude: json['lat'] != null ? double.parse(json['lat'] as String) : null, + longitude: json['lon'] != null ? double.parse(json['lon'] as String) : null, ); } } diff --git a/lib/pages/analytics/models/occupacy.dart b/lib/pages/analytics/models/occupacy.dart index 1d158869..b4b8dac9 100644 --- a/lib/pages/analytics/models/occupacy.dart +++ b/lib/pages/analytics/models/occupacy.dart @@ -15,8 +15,7 @@ class Occupacy extends Equatable { factory Occupacy.fromJson(Map json) { return Occupacy( - date: - DateTime.parse(json['event_date'] as String? ?? '${DateTime.now()}'), + date: DateTime.parse(json['event_date'] as String? ?? '${DateTime.now()}'), occupancy: (json['occupancy_percentage'] ?? 0).toString(), spaceUuid: json['space_uuid'] as String? ?? '', occupiedSeconds: json['occupied_seconds'] as int? ?? 0, diff --git a/lib/pages/analytics/models/occupancy_heat_map_model.dart b/lib/pages/analytics/models/occupancy_heat_map_model.dart index a5fa3ba7..73e7d5d7 100644 --- a/lib/pages/analytics/models/occupancy_heat_map_model.dart +++ b/lib/pages/analytics/models/occupancy_heat_map_model.dart @@ -19,8 +19,7 @@ class OccupancyHeatMapModel extends Equatable { eventDate: DateTime.parse( json['event_date'] as String? ?? '${DateTime.now()}', ), - countTotalPresenceDetected: - json['count_total_presence_detected'] as int? ?? 0, + countTotalPresenceDetected: json['count_total_presence_detected'] as int? ?? 0, ); } diff --git a/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart index 6d9f1c52..fb7e2352 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart @@ -33,8 +33,7 @@ class AirQualityDistributionBloc state.copyWith( status: AirQualityDistributionStatus.success, chartData: result, - filteredChartData: - _arrangeChartDataByType(result, state.selectedAqiType), + filteredChartData: _arrangeChartDataByType(result, state.selectedAqiType), ), ); } catch (e) { @@ -62,8 +61,7 @@ class AirQualityDistributionBloc emit( state.copyWith( selectedAqiType: event.aqiType, - filteredChartData: - _arrangeChartDataByType(state.chartData, event.aqiType), + filteredChartData: _arrangeChartDataByType(state.chartData, event.aqiType), ), ); } diff --git a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart index 9bac8120..4f41eb0c 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart @@ -7,8 +7,7 @@ import 'package:syncrow_web/pages/analytics/services/device_location/device_loca part 'device_location_event.dart'; part 'device_location_state.dart'; -class DeviceLocationBloc - extends Bloc { +class DeviceLocationBloc extends Bloc { DeviceLocationBloc( this._deviceLocationService, ) : super(const DeviceLocationState()) { diff --git a/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart index cb959051..88c3715e 100644 --- a/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart +++ b/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart @@ -53,8 +53,7 @@ class RangeOfAqiBloc extends Bloc { emit( state.copyWith( selectedAqiType: event.aqiType, - filteredRangeOfAqi: - _arrangeChartDataByType(state.rangeOfAqi, event.aqiType), + filteredRangeOfAqi: _arrangeChartDataByType(state.rangeOfAqi, event.aqiType), ), ); } diff --git a/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart b/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart index 889936c4..21cb2a9e 100644 --- a/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart +++ b/lib/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart @@ -105,8 +105,7 @@ abstract final class RangeOfAqiChartsHelper { tooltipRoundedRadius: 16, showOnTopOfTheChartBoxArea: false, tooltipPadding: const EdgeInsets.all(8), - getTooltipItems: (touchedSpots) => - RangeOfAqiChartsHelper.getTooltipItems( + getTooltipItems: (touchedSpots) => RangeOfAqiChartsHelper.getTooltipItems( touchedSpots, chartData, ), diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart index 634c86ab..ebe88614 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_device_info.dart @@ -81,8 +81,7 @@ class AqiDeviceInfo extends StatelessWidget { aqiLevel: status .firstWhere( (e) => e.code == 'air_quality_index', - orElse: () => - Status(code: 'air_quality_index', value: ''), + orElse: () => Status(code: 'air_quality_index', value: ''), ) .value .toString(), diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart index 36346cb6..373e36ca 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart.dart @@ -36,25 +36,23 @@ class AqiDistributionChart extends StatelessWidget { ); } - List _buildBarGroups( - List sortedData) { + List _buildBarGroups(List sortedData) { return List.generate(sortedData.length, (index) { final data = sortedData[index]; final stackItems = []; double currentY = 0; - var isFirstElement = true; + bool isFirstElement = true; // Sort data by type to ensure consistent order - final sortedPercentageData = - List.from(data.data) - ..sort((a, b) => a.type.compareTo(b.type)); + final sortedPercentageData = List.from(data.data) + ..sort((a, b) => a.type.compareTo(b.type)); for (final percentageData in sortedPercentageData) { stackItems.add( BarChartRodData( fromY: currentY, - toY: currentY + percentageData.percentage, - color: AirQualityDataModel.metricColors[percentageData.name], + toY: currentY + percentageData.percentage , + color: AirQualityDataModel.metricColors[percentageData.name]!, borderRadius: isFirstElement ? const BorderRadius.only( topLeft: Radius.circular(22), @@ -86,9 +84,9 @@ class AqiDistributionChart extends StatelessWidget { tooltipRoundedRadius: 16, tooltipPadding: const EdgeInsets.all(8), getTooltipItem: (group, groupIndex, rod, rodIndex) { - final data = chartData[group.x]; + final data = chartData[group.x.toInt()]; - final children = []; + final List children = []; final textStyle = context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, @@ -96,9 +94,8 @@ class AqiDistributionChart extends StatelessWidget { ); // Sort data by type to ensure consistent order - final sortedPercentageData = - List.from(data.data) - ..sort((a, b) => a.type.compareTo(b.type)); + final sortedPercentageData = List.from(data.data) + ..sort((a, b) => a.type.compareTo(b.type)); for (final percentageData in sortedPercentageData) { children.add(TextSpan( diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart index 6f2eb198..5a8e6e6c 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart @@ -49,7 +49,7 @@ class AqiSubValueWidget extends StatelessWidget { int _getActiveSegmentByRange(double value, (double min, double max) range) { final ranges = _getRangesForValue(range); - for (var i = 0; i < ranges.length; i++) { + for (int i = 0; i < ranges.length; i++) { if (value <= ranges[i].max) return i; } return ranges.length - 1; diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart index 242c5d4b..60a686ff 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart @@ -29,8 +29,7 @@ class AqiTypeDropdown extends StatefulWidget { class _AqiTypeDropdownState extends State { AqiType? _selectedItem = AqiType.aqi; - void _updateSelectedItem(AqiType? item) => - setState(() => _selectedItem = item); + void _updateSelectedItem(AqiType? item) => setState(() => _selectedItem = item); @override Widget build(BuildContext context) { diff --git a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart index a392dc2e..fc63e413 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart.dart @@ -63,7 +63,7 @@ class RangeOfAqiChart extends StatelessWidget { gradient: LinearGradient( begin: Alignment.bottomCenter, end: Alignment.topCenter, - stops: const [0.0, 0.2, 0.4, 0.6, 0.8, 1.0], + stops: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0], colors: RangeOfAqiChartsHelper.gradientData.map((e) { final (color, _) = e; return color.withValues(alpha: 0.6); @@ -99,8 +99,7 @@ class RangeOfAqiChart extends StatelessWidget { }) { const invisibleDot = FlDotData(show: false); return LineChartBarData( - spots: - List.generate(values.length, (i) => FlSpot(i.toDouble(), values[i])), + spots: List.generate(values.length, (i) => FlSpot(i.toDouble(), values[i])), isCurved: true, color: color, barWidth: 4, diff --git a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart index 3885ffc2..6548c696 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart @@ -32,8 +32,7 @@ class RangeOfAqiChartBox extends StatelessWidget { const SizedBox(height: 10), const Divider(), const SizedBox(height: 20), - Expanded( - child: RangeOfAqiChart(chartData: state.filteredRangeOfAqi)), + Expanded(child: RangeOfAqiChart(chartData: state.filteredRangeOfAqi)), ], ), ); diff --git a/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart b/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart index 723df1c3..fb61e73b 100644 --- a/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart +++ b/lib/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_event.dart @@ -8,8 +8,7 @@ sealed class AnalyticsDevicesEvent extends Equatable { } final class LoadAnalyticsDevicesEvent extends AnalyticsDevicesEvent { - const LoadAnalyticsDevicesEvent( - {required this.param, required this.onSuccess}); + const LoadAnalyticsDevicesEvent({required this.param, required this.onSuccess}); final GetAnalyticsDevicesParam param; final void Function(AnalyticsDevice device) onSuccess; diff --git a/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart b/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart index 20eddb43..0ae7d8c5 100644 --- a/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart +++ b/lib/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_event.dart @@ -7,7 +7,7 @@ sealed class AnalyticsTabEvent extends Equatable { List get props => []; } -class UpdateAnalyticsTabEvent extends AnalyticsTabEvent { +class UpdateAnalyticsTabEvent extends AnalyticsTabEvent { const UpdateAnalyticsTabEvent(this.analyticsTab); final AnalyticsPageTab analyticsTab; diff --git a/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart b/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart index 2614ea28..8b1802af 100644 --- a/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart +++ b/lib/pages/analytics/modules/analytics/strategies/air_quality_data_loading_strategy.dart @@ -8,8 +8,7 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; -final class AirQualityDataLoadingStrategy - implements AnalyticsDataLoadingStrategy { +final class AirQualityDataLoadingStrategy implements AnalyticsDataLoadingStrategy { @override void onCommunitySelected( BuildContext context, @@ -26,8 +25,7 @@ final class AirQualityDataLoadingStrategy SpaceModel space, ) { final spaceTreeBloc = context.read(); - final isSpaceSelected = - spaceTreeBloc.state.selectedSpaces.contains(space.uuid); + final isSpaceSelected = spaceTreeBloc.state.selectedSpaces.contains(space.uuid); final hasSelectedSpaces = spaceTreeBloc.state.selectedSpaces.isNotEmpty; if (hasSelectedSpaces) clearData(context); @@ -36,7 +34,7 @@ final class AirQualityDataLoadingStrategy spaceTreeBloc ..add(const SpaceTreeClearSelectionEvent()) - ..add(OnSpaceSelected(community, space.uuid ?? '', const [])); + ..add(OnSpaceSelected(community, space.uuid ?? '', [])); FetchAirQualityDataHelper.loadAirQualityData( context, diff --git a/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart b/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart index f48fd7f2..19b0aff2 100644 --- a/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart +++ b/lib/pages/analytics/modules/analytics/strategies/analytics_data_loading_strategy_factory.dart @@ -8,8 +8,7 @@ abstract final class AnalyticsDataLoadingStrategyFactory { const AnalyticsDataLoadingStrategyFactory._(); static AnalyticsDataLoadingStrategy getStrategy(AnalyticsPageTab tab) { return switch (tab) { - AnalyticsPageTab.energyManagement => - EnergyManagementDataLoadingStrategy(), + AnalyticsPageTab.energyManagement => EnergyManagementDataLoadingStrategy(), AnalyticsPageTab.occupancy => OccupancyDataLoadingStrategy(), AnalyticsPageTab.airQuality => AirQualityDataLoadingStrategy(), }; diff --git a/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart b/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart index 14e27515..757b2a9a 100644 --- a/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart +++ b/lib/pages/analytics/modules/analytics/strategies/energy_management_data_loading_strategy.dart @@ -7,8 +7,7 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; -class EnergyManagementDataLoadingStrategy - implements AnalyticsDataLoadingStrategy { +class EnergyManagementDataLoadingStrategy implements AnalyticsDataLoadingStrategy { @override void onCommunitySelected( BuildContext context, @@ -32,8 +31,7 @@ class EnergyManagementDataLoadingStrategy SpaceModel space, ) { final spaceTreeBloc = context.read(); - final isSpaceSelected = - spaceTreeBloc.state.selectedSpaces.contains(space.uuid); + final isSpaceSelected = spaceTreeBloc.state.selectedSpaces.contains(space.uuid); final hasSelectedSpaces = spaceTreeBloc.state.selectedSpaces.isNotEmpty; if (isSpaceSelected) { diff --git a/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart b/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart index e7055b61..9bffe3b4 100644 --- a/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart +++ b/lib/pages/analytics/modules/analytics/strategies/occupancy_data_loading_strategy.dart @@ -24,8 +24,7 @@ class OccupancyDataLoadingStrategy implements AnalyticsDataLoadingStrategy { SpaceModel space, ) { final spaceTreeBloc = context.read(); - final isSpaceSelected = - spaceTreeBloc.state.selectedSpaces.contains(space.uuid); + final isSpaceSelected = spaceTreeBloc.state.selectedSpaces.contains(space.uuid); final hasSelectedSpaces = spaceTreeBloc.state.selectedSpaces.isNotEmpty; if (hasSelectedSpaces) clearData(context); @@ -34,7 +33,7 @@ class OccupancyDataLoadingStrategy implements AnalyticsDataLoadingStrategy { spaceTreeBloc ..add(const SpaceTreeClearSelectionEvent()) - ..add(OnSpaceSelected(community, space.uuid ?? '', const [])); + ..add(OnSpaceSelected(community, space.uuid ?? '', [])); FetchOccupancyDataHelper.loadOccupancyData( context, diff --git a/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart b/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart index a8b43943..ab07737a 100644 --- a/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart +++ b/lib/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart @@ -10,8 +10,7 @@ class AnalyticsCommunitiesSidebar extends StatelessWidget { @override Widget build(BuildContext context) { final selectedTab = context.watch().state; - final strategy = - AnalyticsDataLoadingStrategyFactory.getStrategy(selectedTab); + final strategy = AnalyticsDataLoadingStrategyFactory.getStrategy(selectedTab); return Expanded( child: AnalyticsSpaceTreeView( diff --git a/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart b/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart index ab41c7d7..af70cd86 100644 --- a/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart +++ b/lib/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart @@ -20,7 +20,7 @@ class AnalyticsDateFilterButton extends StatefulWidget { final void Function(DateTime)? onDateSelected; final DatePickerType datePickerType; - static final Color _color = ColorsManager.blackColor.withValues(alpha: 0.8); + static final _color = ColorsManager.blackColor.withValues(alpha: 0.8); @override State createState() => diff --git a/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart b/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart index abc688fc..9ff98ef2 100644 --- a/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart +++ b/lib/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart @@ -21,8 +21,8 @@ class AnalyticsPageTabButton extends StatelessWidget { onPressed: () { AnalyticsDataLoadingStrategyFactory.getStrategy(tab).clearData(context); context.read().add( - UpdateAnalyticsTabEvent(tab), - ); + UpdateAnalyticsTabEvent(tab), + ); }, child: Text( tab.title, @@ -33,9 +33,8 @@ class AnalyticsPageTabButton extends StatelessWidget { style: TextStyle( fontWeight: isSelected ? FontWeight.w700 : FontWeight.w400, fontSize: 16, - color: isSelected - ? ColorsManager.slidingBlueColor - : ColorsManager.textGray, + color: + isSelected ? ColorsManager.slidingBlueColor : ColorsManager.textGray, ), ), ); diff --git a/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart b/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart index 41dcd108..57133b02 100644 --- a/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart +++ b/lib/pages/analytics/modules/analytics/widgets/month_picker_widget.dart @@ -21,18 +21,18 @@ class _MonthPickerWidgetState extends State { int? _selectedMonth; static const _monthNames = [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December', + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", ]; @override @@ -189,19 +189,14 @@ class _MonthPickerWidgetState extends State { final isFutureMonth = isCurrentYear && index > currentDate.month - 1; return InkWell( - onTap: isFutureMonth - ? null - : () => setState(() => _selectedMonth = index), + onTap: isFutureMonth ? null : () => setState(() => _selectedMonth = index), child: DecoratedBox( decoration: BoxDecoration( color: const Color(0xFFEDF2F7), borderRadius: BorderRadius.only( - topLeft: - index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - bottomLeft: - index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - topRight: - index % 3 == 2 ? const Radius.circular(16) : Radius.zero, + topLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + bottomLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + topRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, bottomRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, ), diff --git a/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart b/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart index 9521ab24..f900a040 100644 --- a/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart +++ b/lib/pages/analytics/modules/analytics/widgets/sidebar/analytics_space_tree_view.dart @@ -53,8 +53,7 @@ class _AnalyticsSpaceTreeViewState extends State { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { + return BlocBuilder(builder: (context, state) { final communities = state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList; @@ -77,10 +76,9 @@ class _AnalyticsSpaceTreeViewState extends State { ), ), CustomSearchBar( - onSearchChanged: (query) => - context.read().add( - SearchQueryEvent(query), - ), + onSearchChanged: (query) => context.read().add( + SearchQueryEvent(query), + ), ), const SizedBox(height: 16), Expanded( @@ -115,8 +113,7 @@ class _AnalyticsSpaceTreeViewState extends State { isExpanded: state.expandedCommunities.contains( communities[index].uuid, ), - onItemSelected: () => - widget.onSelectCommunity?.call( + onItemSelected: () => widget.onSelectCommunity?.call( communities[index], communities[index].spaces, ), @@ -124,8 +121,8 @@ class _AnalyticsSpaceTreeViewState extends State { (space) { return CustomExpansionTileSpaceTree( title: space.name, - isExpanded: state.expandedSpaces - .contains(space.uuid), + isExpanded: + state.expandedSpaces.contains(space.uuid), onItemSelected: () => widget.onSelectSpace?.call( communities[index], @@ -156,8 +153,7 @@ class _AnalyticsSpaceTreeViewState extends State { }, ), ), - if (state.paginationIsLoading) - const CircularProgressIndicator(), + if (state.paginationIsLoading) const CircularProgressIndicator(), ], ), ); diff --git a/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart b/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart index 711d1ccd..22eb6646 100644 --- a/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart +++ b/lib/pages/analytics/modules/analytics/widgets/year_picker_widget.dart @@ -19,9 +19,9 @@ class YearPickerWidget extends StatefulWidget { class _YearPickerWidgetState extends State { late int _currentYear; - static final List years = List.generate( + static final years = List.generate( DateTime.now().year - (DateTime.now().year - 5) + 1, - (index) => 2020 + index, + (index) => (2020 + index), ).where((year) => year <= DateTime.now().year).toList(); @override @@ -123,12 +123,9 @@ class _YearPickerWidgetState extends State { decoration: BoxDecoration( color: const Color(0xFFEDF2F7), borderRadius: BorderRadius.only( - topLeft: - index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - bottomLeft: - index % 3 == 0 ? const Radius.circular(16) : Radius.zero, - topRight: - index % 3 == 2 ? const Radius.circular(16) : Radius.zero, + topLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + bottomLeft: index % 3 == 0 ? const Radius.circular(16) : Radius.zero, + topRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, bottomRight: index % 3 == 2 ? const Radius.circular(16) : Radius.zero, ), diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart index a3f21f44..1acf7df5 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart @@ -8,15 +8,13 @@ import 'package:syncrow_web/services/api/api_exception.dart'; part 'energy_consumption_by_phases_event.dart'; part 'energy_consumption_by_phases_state.dart'; -class EnergyConsumptionByPhasesBloc extends Bloc { +class EnergyConsumptionByPhasesBloc + extends Bloc { EnergyConsumptionByPhasesBloc( this._energyConsumptionByPhasesService, ) : super(const EnergyConsumptionByPhasesState()) { - on( - _onLoadEnergyConsumptionByPhasesEvent); - on( - _onClearEnergyConsumptionByPhasesEvent); + on(_onLoadEnergyConsumptionByPhasesEvent); + on(_onClearEnergyConsumptionByPhasesEvent); } final EnergyConsumptionByPhasesService _energyConsumptionByPhasesService; @@ -27,8 +25,7 @@ class EnergyConsumptionByPhasesBloc extends Bloc _onClearEnergyConsumptionByPhasesEvent( + void _onClearEnergyConsumptionByPhasesEvent( ClearEnergyConsumptionByPhasesEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart index 0c1248ae..87bcf447 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_event.dart @@ -7,8 +7,7 @@ sealed class EnergyConsumptionByPhasesEvent extends Equatable { List get props => []; } -class LoadEnergyConsumptionByPhasesEvent - extends EnergyConsumptionByPhasesEvent { +class LoadEnergyConsumptionByPhasesEvent extends EnergyConsumptionByPhasesEvent { const LoadEnergyConsumptionByPhasesEvent({ required this.param, }); @@ -19,7 +18,6 @@ class LoadEnergyConsumptionByPhasesEvent List get props => [param]; } -final class ClearEnergyConsumptionByPhasesEvent - extends EnergyConsumptionByPhasesEvent { +final class ClearEnergyConsumptionByPhasesEvent extends EnergyConsumptionByPhasesEvent { const ClearEnergyConsumptionByPhasesEvent(); } diff --git a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart index 3f0806a1..97d182c5 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart @@ -8,13 +8,12 @@ import 'package:syncrow_web/services/api/api_exception.dart'; part 'energy_consumption_per_device_event.dart'; part 'energy_consumption_per_device_state.dart'; -class EnergyConsumptionPerDeviceBloc extends Bloc< - EnergyConsumptionPerDeviceEvent, EnergyConsumptionPerDeviceState> { +class EnergyConsumptionPerDeviceBloc + extends Bloc { EnergyConsumptionPerDeviceBloc( this._energyConsumptionPerDeviceService, ) : super(const EnergyConsumptionPerDeviceState()) { - on( - _onLoadEnergyConsumptionPerDeviceEvent); + on(_onLoadEnergyConsumptionPerDeviceEvent); on( _onClearEnergyConsumptionPerDeviceEvent); } @@ -27,8 +26,7 @@ class EnergyConsumptionPerDeviceBloc extends Bloc< ) async { emit(state.copyWith(status: EnergyConsumptionPerDeviceStatus.loading)); try { - final chartData = - await _energyConsumptionPerDeviceService.load(event.param); + final chartData = await _energyConsumptionPerDeviceService.load(event.param); emit( state.copyWith( status: EnergyConsumptionPerDeviceStatus.loaded, @@ -52,7 +50,7 @@ class EnergyConsumptionPerDeviceBloc extends Bloc< } } - Future _onClearEnergyConsumptionPerDeviceEvent( + void _onClearEnergyConsumptionPerDeviceEvent( ClearEnergyConsumptionPerDeviceEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart index aa37078b..2aefd798 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart @@ -8,8 +8,7 @@ import 'package:syncrow_web/services/api/api_exception.dart'; part 'power_clamp_info_event.dart'; part 'power_clamp_info_state.dart'; -class PowerClampInfoBloc - extends Bloc { +class PowerClampInfoBloc extends Bloc { PowerClampInfoBloc( this._powerClampInfoService, ) : super(const PowerClampInfoState()) { @@ -26,8 +25,7 @@ class PowerClampInfoBloc ) async { emit(state.copyWith(status: PowerClampInfoStatus.loading)); try { - final powerClampModel = - await _powerClampInfoService.getInfo(event.deviceId); + final powerClampModel = await _powerClampInfoService.getInfo(event.deviceId); emit( state.copyWith( status: PowerClampInfoStatus.loaded, @@ -51,7 +49,7 @@ class PowerClampInfoBloc } } - Future _onUpdatePowerClampStatusEvent( + void _onUpdatePowerClampStatusEvent( UpdatePowerClampStatusEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart index dc20f6f7..b69a2556 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_event.dart @@ -16,6 +16,7 @@ final class LoadPowerClampInfoEvent extends PowerClampInfoEvent { List get props => [deviceId]; } + final class UpdatePowerClampStatusEvent extends PowerClampInfoEvent { const UpdatePowerClampStatusEvent(this.statusList); @@ -27,4 +28,4 @@ final class UpdatePowerClampStatusEvent extends PowerClampInfoEvent { final class ClearPowerClampInfoEvent extends PowerClampInfoEvent { const ClearPowerClampInfoEvent(); -} +} \ No newline at end of file diff --git a/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart b/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart index c56588b8..1eba8f7e 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_event.dart @@ -24,4 +24,4 @@ class _RealtimeDeviceChangesUpdated extends RealtimeDeviceChangesEvent { final List deviceStatusList; const _RealtimeDeviceChangesUpdated(this.deviceStatusList); -} +} \ No newline at end of file diff --git a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart index 578899f9..f51d20cf 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart @@ -49,7 +49,7 @@ class TotalEnergyConsumptionBloc } } - Future _onClearTotalEnergyConsumptionEvent( + void _onClearTotalEnergyConsumptionEvent( ClearTotalEnergyConsumptionEvent event, Emitter emit, ) async { diff --git a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart index 7240b669..f9510737 100644 --- a/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart +++ b/lib/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_event.dart @@ -7,8 +7,7 @@ sealed class TotalEnergyConsumptionEvent extends Equatable { List get props => []; } -final class TotalEnergyConsumptionLoadEvent - extends TotalEnergyConsumptionEvent { +final class TotalEnergyConsumptionLoadEvent extends TotalEnergyConsumptionEvent { const TotalEnergyConsumptionLoadEvent({required this.param}); final GetTotalEnergyConsumptionParam param; @@ -17,7 +16,6 @@ final class TotalEnergyConsumptionLoadEvent List get props => [param]; } -final class ClearTotalEnergyConsumptionEvent - extends TotalEnergyConsumptionEvent { +final class ClearTotalEnergyConsumptionEvent extends TotalEnergyConsumptionEvent { const ClearTotalEnergyConsumptionEvent(); } diff --git a/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart b/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart index 6de1e278..2ed68e76 100644 --- a/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart +++ b/lib/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart @@ -69,8 +69,7 @@ abstract final class EnergyManagementChartsHelper { return labels.where((element) => element.isNotEmpty).join(', '); } - static List getTooltipItems( - List touchedSpots) { + static List getTooltipItems(List touchedSpots) { return touchedSpots.map((spot) { return LineTooltipItem( getToolTipLabel(spot.x, spot.y), @@ -86,8 +85,7 @@ abstract final class EnergyManagementChartsHelper { static LineTouchTooltipData lineTouchTooltipData() { return LineTouchTooltipData( getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors, - tooltipBorder: - const BorderSide(color: ColorsManager.semiTransparentBlack), + tooltipBorder: const BorderSide(color: ColorsManager.semiTransparentBlack), tooltipRoundedRadius: 16, showOnTopOfTheChartBoxArea: false, tooltipPadding: const EdgeInsets.all(8), diff --git a/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart b/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart index f2796671..8de92098 100644 --- a/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart +++ b/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart @@ -122,8 +122,7 @@ abstract final class FetchEnergyManagementDataHelper { final selectedDevice = getSelectedDevice(context); context.read().add( - RealtimeDeviceChangesStarted( - deviceUuid ?? selectedDevice?.uuid ?? ''), + RealtimeDeviceChangesStarted(deviceUuid ?? selectedDevice?.uuid ?? ''), ); } diff --git a/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart b/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart index 797821a4..f88febcc 100644 --- a/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart +++ b/lib/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart @@ -51,8 +51,7 @@ class AnalyticsEnergyManagementView extends StatelessWidget { spacing: 20, children: [ Expanded(child: TotalEnergyConsumptionChartBox()), - Expanded( - child: EnergyConsumptionPerDeviceChartBox()), + Expanded(child: EnergyConsumptionPerDeviceChartBox()), ], ), ), diff --git a/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart b/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart index 5d7f37a9..f7b33309 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart @@ -52,8 +52,7 @@ class AnalyticsDeviceDropdown extends StatelessWidget { ); } - Widget _buildDevicesDropdown( - BuildContext context, AnalyticsDevicesState state) { + Widget _buildDevicesDropdown(BuildContext context, AnalyticsDevicesState state) { final spaceUuid = state.selectedDevice?.spaceUuid; return DropdownButton( value: state.selectedDevice, diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart index e169d660..52c6f591 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart @@ -18,6 +18,7 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { Widget build(BuildContext context) { return BarChart( BarChartData( + gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, horizontalInterval: 250, @@ -99,11 +100,11 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { }) { final data = energyData; - final date = DateFormat('dd/MM/yyyy').format(data[group.x].date); - final phaseA = data[group.x].energyConsumedA; - final phaseB = data[group.x].energyConsumedB; - final phaseC = data[group.x].energyConsumedC; - final total = data[group.x].energyConsumedKw; + final date = DateFormat('dd/MM/yyyy').format(data[group.x.toInt()].date); + final phaseA = data[group.x.toInt()].energyConsumedA; + final phaseB = data[group.x.toInt()].energyConsumedB; + final phaseC = data[group.x.toInt()].energyConsumedC; + final total = data[group.x.toInt()].energyConsumedKw; return BarTooltipItem( '$date\n', diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart index 0c4e972d..1bd1ed9e 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart @@ -22,8 +22,7 @@ class EnergyConsumptionByPhasesChartBox extends StatelessWidget { children: [ AnalyticsErrorWidget(state.errorMessage), EnergyConsumptionByPhasesTitle( - isLoading: - state.status == EnergyConsumptionByPhasesStatus.loading, + isLoading: state.status == EnergyConsumptionByPhasesStatus.loading, ), const SizedBox(height: 20), Expanded( diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart index 4bed5682..1e74ad31 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart @@ -17,6 +17,7 @@ class EnergyConsumptionPerDeviceChart extends StatelessWidget { context, leftTitlesInterval: 250, ), + gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, horizontalInterval: 250, diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart index 5fd6b8d6..be5faf57 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart @@ -46,8 +46,7 @@ class EnergyConsumptionPerDeviceChartBox extends StatelessWidget { flex: 2, child: EnergyConsumptionPerDeviceDevicesList( chartData: state.chartData, - devices: - context.watch().state.devices, + devices: context.watch().state.devices, ), ), ], @@ -56,8 +55,7 @@ class EnergyConsumptionPerDeviceChartBox extends StatelessWidget { const Divider(height: 0), const SizedBox(height: 20), Expanded( - child: - EnergyConsumptionPerDeviceChart(chartData: state.chartData), + child: EnergyConsumptionPerDeviceChart(chartData: state.chartData), ), ], ), diff --git a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart index 3feda916..f95ff7d1 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart @@ -43,14 +43,11 @@ class PowerClampEnergyDataWidget extends StatelessWidget { title: 'Smart Power Clamp', showSpaceUuidInDevicesDropdown: true, onChanged: (device) { - FetchEnergyManagementDataHelper - .loadEnergyConsumptionByPhases( + FetchEnergyManagementDataHelper.loadEnergyConsumptionByPhases( context, powerClampUuid: device.uuid, - selectedDate: context - .read() - .state - .monthlyDate, + selectedDate: + context.read().state.monthlyDate, ); }, ), @@ -94,8 +91,7 @@ class PowerClampEnergyDataWidget extends StatelessWidget { ), ), const SizedBox(height: 14), - const Expanded( - flex: 3, child: EnergyConsumptionByPhasesChartBox()), + const Expanded(flex: 3, child: EnergyConsumptionByPhasesChartBox()), ], ), ); diff --git a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart index e1cc4238..a96a7298 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart @@ -140,9 +140,9 @@ class PowerClampPhasesDataWidget extends StatelessWidget { String _formatCurrentValue(String? value) { if (value == null) return '--'; - var str = value; + String str = value; if (str.isEmpty || str == '--') return '--'; - str = str.replaceAll(RegExp('[^0-9]'), ''); + str = str.replaceAll(RegExp(r'[^0-9]'), ''); if (str.isEmpty) return '--'; if (str.length == 1) return '${str[0]}.0'; return '${str[0]}.${str.substring(1)}'; @@ -150,9 +150,9 @@ class PowerClampPhasesDataWidget extends StatelessWidget { String _formatPowerFactor(String? value) { if (value == null) return '--'; - var str = value; + String str = value; if (str.isEmpty || str == '--') return '--'; - str = str.replaceAll(RegExp('[^0-9]'), ''); + str = str.replaceAll(RegExp(r'[^0-9]'), ''); if (str.isEmpty) return '--'; final intValue = int.tryParse(str); if (intValue == null) return '--'; @@ -162,9 +162,9 @@ class PowerClampPhasesDataWidget extends StatelessWidget { String _formatVoltage(String? value) { if (value == null) return '--'; - var str = value; + String str = value; if (str.isEmpty || str == '--') return '--'; - str = str.replaceAll(RegExp('[^0-9]'), ''); + str = str.replaceAll(RegExp(r'[^0-9]'), ''); if (str.isEmpty) return '--'; if (str.length == 1) return '0.${str[0]}'; return '${str.substring(0, str.length - 1)}.${str.substring(str.length - 1)}'; diff --git a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart index 9ce6295b..85b95c29 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart @@ -29,6 +29,7 @@ class TotalEnergyConsumptionChart extends StatelessWidget { ), duration: Duration.zero, curve: Curves.easeIn, + ), ); } diff --git a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart index 7596c7d0..e197c297 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart @@ -25,8 +25,7 @@ class TotalEnergyConsumptionChartBox extends StatelessWidget { Row( children: [ ChartsLoadingWidget( - isLoading: - state.status == TotalEnergyConsumptionStatus.loading, + isLoading: state.status == TotalEnergyConsumptionStatus.loading, ), const Expanded( flex: 3, diff --git a/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart b/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart index c6966c7e..110f3c60 100644 --- a/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart +++ b/lib/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart @@ -23,11 +23,9 @@ class OccupancyBloc extends Bloc { emit(state.copyWith(status: OccupancyStatus.loading)); try { final chartData = await _occupacyService.load(event.param); - emit( - state.copyWith(chartData: chartData, status: OccupancyStatus.loaded)); + emit(state.copyWith(chartData: chartData, status: OccupancyStatus.loaded)); } on APIException catch (e) { - emit(state.copyWith( - status: OccupancyStatus.failure, errorMessage: e.message)); + emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: e.message)); } catch (e) { emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: '$e')); } diff --git a/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart b/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart index a56c0c9f..0b01fda2 100644 --- a/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart +++ b/lib/pages/analytics/modules/occupancy/helpers/fetch_occupancy_data_helper.dart @@ -25,18 +25,15 @@ abstract final class FetchOccupancyDataHelper { final datePickerState = context.read().state; - loadAnalyticsDevices(context, - communityUuid: communityId, spaceUuid: spaceId); - final selectedDevice = - context.read().state.selectedDevice; + loadAnalyticsDevices(context, communityUuid: communityId, spaceUuid: spaceId); + final selectedDevice = context.read().state.selectedDevice; loadOccupancyChartData( context, spaceUuid: spaceId, date: datePickerState.monthlyDate, ); - loadHeatMapData(context, - spaceUuid: spaceId, year: datePickerState.yearlyDate); + loadHeatMapData(context, spaceUuid: spaceId, year: datePickerState.yearlyDate); if (selectedDevice case final AnalyticsDevice device) { context.read() @@ -67,8 +64,7 @@ abstract final class FetchOccupancyDataHelper { context.read().add( LoadOccupancyEvent( GetOccupancyParam( - monthDate: - '${date.year}-${date.month.toString().padLeft(2, '0')}', + monthDate: '${date.year}-${date.month.toString().padLeft(2, '0')}', spaceUuid: spaceUuid, ), ), diff --git a/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart b/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart index 7db4f90c..679c9927 100644 --- a/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart +++ b/lib/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart @@ -20,12 +20,9 @@ class AnalyticsOccupancyView extends StatelessWidget { child: Column( spacing: 32, children: [ - SizedBox( - height: height * 0.46, child: const OccupancyEndSideBar()), - SizedBox( - height: height * 0.5, child: const OccupancyChartBox()), - SizedBox( - height: height * 0.5, child: const OccupancyHeatMapBox()), + SizedBox(height: height * 0.46, child: const OccupancyEndSideBar()), + SizedBox(height: height * 0.5, child: const OccupancyChartBox()), + SizedBox(height: height * 0.5, child: const OccupancyHeatMapBox()), ], ), ); diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart index d328b972..70087c46 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart.dart @@ -41,8 +41,7 @@ class OccupancyChart extends StatelessWidget { barRods: [ BarChartRodData( toY: 100.0, - fromY: - occupancyValue == 0 ? occupancyValue : occupancyValue + 2.5, + fromY: occupancyValue == 0 ? occupancyValue : occupancyValue + 2.5, color: ColorsManager.graysColor, width: _chartWidth, borderRadius: BorderRadius.circular(10), @@ -89,8 +88,8 @@ class OccupancyChart extends StatelessWidget { }) { final data = chartData; - final occupancyValue = double.parse(data[group.x].occupancy); - final percentage = '${occupancyValue.toStringAsFixed(0)}%'; + final occupancyValue = double.parse(data[group.x.toInt()].occupancy); + final percentage = '${(occupancyValue).toStringAsFixed(0)}%'; return BarTooltipItem( percentage, @@ -117,7 +116,7 @@ class OccupancyChart extends StatelessWidget { alignment: AlignmentDirectional.centerStart, fit: BoxFit.scaleDown, child: Text( - '${value.toStringAsFixed(0)}%', + '${(value).toStringAsFixed(0)}%', style: context.textTheme.bodySmall?.copyWith( fontSize: 12, color: ColorsManager.greyColor, diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart index a950593d..08f7223f 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_chart_box.dart @@ -44,15 +44,13 @@ class OccupancyChartBox extends StatelessWidget { child: AnalyticsDateFilterButton( onDateSelected: (DateTime value) { context.read().add( - UpdateAnalyticsDatePickerEvent( - montlyDate: value), + UpdateAnalyticsDatePickerEvent(montlyDate: value), ); if (spaceTreeState.selectedSpaces.isNotEmpty) { FetchOccupancyDataHelper.loadOccupancyChartData( context, spaceUuid: - spaceTreeState.selectedSpaces.firstOrNull ?? - '', + spaceTreeState.selectedSpaces.firstOrNull ?? '', date: value, ); } diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart index 846b9d30..c3b537e0 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart @@ -44,15 +44,13 @@ class OccupancyHeatMapBox extends StatelessWidget { child: AnalyticsDateFilterButton( onDateSelected: (DateTime value) { context.read().add( - UpdateAnalyticsDatePickerEvent( - yearlyDate: value), + UpdateAnalyticsDatePickerEvent(yearlyDate: value), ); if (spaceTreeState.selectedSpaces.isNotEmpty) { FetchOccupancyDataHelper.loadHeatMapData( context, spaceUuid: - spaceTreeState.selectedSpaces.firstOrNull ?? - '', + spaceTreeState.selectedSpaces.firstOrNull ?? '', year: value, ); } diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart index b57a73e1..633b8c54 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart @@ -28,11 +28,11 @@ class OccupancyPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final fillPaint = Paint(); - final borderPaint = Paint() + final Paint fillPaint = Paint(); + final Paint borderPaint = Paint() ..color = ColorsManager.grayBorder.withValues(alpha: 0.4) ..style = PaintingStyle.stroke; - final hoveredBorderPaint = Paint() + final Paint hoveredBorderPaint = Paint() ..color = Colors.black ..style = PaintingStyle.stroke ..strokeWidth = 1.5; @@ -66,24 +66,24 @@ class OccupancyPainter extends CustomPainter { ); canvas.drawLine(Offset(x, y), Offset(x, y + cellSize), borderPaint); - canvas.drawLine(Offset(x + cellSize, y), - Offset(x + cellSize, y + cellSize), borderPaint); + canvas.drawLine(Offset(x + cellSize, y), Offset(x + cellSize, y + cellSize), + borderPaint); } } } void _drawDashedLine(Canvas canvas, Offset start, Offset end, Paint paint) { - const dashWidth = 2.0; - const dashSpace = 4.0; - final totalLength = (end - start).distance; - final direction = (end - start) / (end - start).distance; + const double dashWidth = 2.0; + const double dashSpace = 4.0; + final double totalLength = (end - start).distance; + final Offset direction = (end - start) / (end - start).distance; - var currentLength = 0.0; + double currentLength = 0.0; while (currentLength < totalLength) { - final dashStart = start + direction * currentLength; - final nextLength = currentLength + dashWidth; - final dashEnd = start + - direction * (nextLength < totalLength ? nextLength : totalLength); + final Offset dashStart = start + direction * currentLength; + final double nextLength = currentLength + dashWidth; + final Offset dashEnd = + start + direction * (nextLength < totalLength ? nextLength : totalLength); canvas.drawLine(dashStart, dashEnd, paint); currentLength = nextLength + dashSpace; } diff --git a/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart b/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart index 69189b60..e0023f53 100644 --- a/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart +++ b/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart @@ -5,8 +5,7 @@ import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_type import 'package:syncrow_web/pages/analytics/params/get_air_quality_distribution_param.dart'; import 'package:syncrow_web/pages/analytics/services/air_quality_distribution/air_quality_distribution_service.dart'; -class FakeAirQualityDistributionService - implements AirQualityDistributionService { +class FakeAirQualityDistributionService implements AirQualityDistributionService { final _random = Random(); @override @@ -44,6 +43,7 @@ class FakeAirQualityDistributionService name: 'poor', percentage: nonNullValues[2], type: AqiType.hcho.code, + ), AirQualityPercentageData( name: 'unhealthy', @@ -71,7 +71,7 @@ class FakeAirQualityDistributionService List nullMask, ) { double nonNullSum = 0; - for (var i = 0; i < originalValues.length; i++) { + for (int i = 0; i < originalValues.length; i++) { if (!nullMask[i]) { nonNullSum += originalValues[i]; } diff --git a/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart b/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart index 7054c97b..dcf00600 100644 --- a/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart +++ b/lib/pages/analytics/services/air_quality_distribution/remote_air_quality_distribution_service.dart @@ -3,8 +3,7 @@ import 'package:syncrow_web/pages/analytics/params/get_air_quality_distribution_ import 'package:syncrow_web/pages/analytics/services/air_quality_distribution/air_quality_distribution_service.dart'; import 'package:syncrow_web/services/api/http_service.dart'; -class RemoteAirQualityDistributionService - implements AirQualityDistributionService { +class RemoteAirQualityDistributionService implements AirQualityDistributionService { RemoteAirQualityDistributionService(this._httpService); final HTTPService _httpService; diff --git a/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart b/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart index ee4fb431..2d735df6 100644 --- a/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart +++ b/lib/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart @@ -16,8 +16,7 @@ class AnalyticsDevicesServiceDelegate implements AnalyticsDevicesService { GetAnalyticsDevicesParam param, ) { return switch (param.requestType) { - AnalyticsDeviceRequestType.occupancy => - _occupancyService.getDevices(param), + AnalyticsDeviceRequestType.occupancy => _occupancyService.getDevices(param), AnalyticsDeviceRequestType.energyManagement => _energyManagementService.getDevices(param), }; diff --git a/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart b/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart index 62c0908b..9ef711e9 100644 --- a/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart +++ b/lib/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart @@ -14,8 +14,7 @@ final class RemoteEnergyManagementAnalyticsDevicesService static const _defaultErrorMessage = 'Failed to load analytics devices'; @override - Future> getDevices( - GetAnalyticsDevicesParam param) async { + Future> getDevices(GetAnalyticsDevicesParam param) async { try { final response = await _httpService.get( path: '/devices-space-community/recursive-child', @@ -38,8 +37,7 @@ final class RemoteEnergyManagementAnalyticsDevicesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { throw APIException('$_defaultErrorMessage: $e'); diff --git a/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart b/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart index 37b9663c..736b0804 100644 --- a/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart +++ b/lib/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart @@ -6,8 +6,7 @@ import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; -class RemoteOccupancyAnalyticsDevicesService - implements AnalyticsDevicesService { +class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService { const RemoteOccupancyAnalyticsDevicesService(this._httpService); final HTTPService _httpService; @@ -15,8 +14,7 @@ class RemoteOccupancyAnalyticsDevicesService static const _defaultErrorMessage = 'Failed to load analytics devices'; @override - Future> getDevices( - GetAnalyticsDevicesParam param) async { + Future> getDevices(GetAnalyticsDevicesParam param) async { try { final requests = await Future.wait>( param.deviceTypes.map((e) { @@ -36,18 +34,15 @@ class RemoteOccupancyAnalyticsDevicesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { - final formattedErrorMessage = - [_defaultErrorMessage, e.toString()].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, e.toString()].join(': '); throw APIException(formattedErrorMessage); } } - Future> _makeRequest( - GetAnalyticsDevicesParam param) async { + Future> _makeRequest(GetAnalyticsDevicesParam param) async { try { final projectUuid = await ProjectManager.getProjectUUID(); @@ -74,8 +69,7 @@ class RemoteOccupancyAnalyticsDevicesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { throw APIException('$_defaultErrorMessage: $e'); diff --git a/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart index eb77fa5a..0239bcb7 100644 --- a/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart +++ b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart @@ -34,7 +34,7 @@ class DeviceLocationDetailsServiceDecorator implements DeviceLocationService { return deviceLocationInfo; } catch (e) { - throw Exception('Failed to load device location info: $e'); + throw Exception('Failed to load device location info: ${e.toString()}'); } } } diff --git a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart index 5546bf65..17f9baff 100644 --- a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart +++ b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart @@ -11,8 +11,7 @@ final class RemoteEnergyConsumptionByPhasesService final HTTPService _httpService; - static const _defaultErrorMessage = - 'Failed to load energy consumption per phase'; + static const _defaultErrorMessage = 'Failed to load energy consumption per phase'; @override Future> load( @@ -37,8 +36,7 @@ final class RemoteEnergyConsumptionByPhasesService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart b/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart index 1845ac6e..82b21b1c 100644 --- a/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart +++ b/lib/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart @@ -13,8 +13,7 @@ class RemoteEnergyConsumptionPerDeviceService final HTTPService _httpService; - static const _defaultErrorMessage = - 'Failed to load energy consumption per device'; + static const _defaultErrorMessage = 'Failed to load energy consumption per device'; @override Future> load( @@ -32,8 +31,7 @@ class RemoteEnergyConsumptionPerDeviceService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); @@ -61,8 +59,7 @@ abstract final class _EnergyConsumptionPerDeviceMapper { final energyJson = data as Map; return EnergyDataModel( date: DateTime.parse(energyJson['date'] as String), - value: - double.parse(energyJson['total_energy_consumed_kw'] as String), + value: double.parse(energyJson['total_energy_consumed_kw'] as String), ); }).toList(), ); diff --git a/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart b/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart index 149ae31c..afd3f79e 100644 --- a/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart +++ b/lib/pages/analytics/services/occupacy/remote_occupancy_service.dart @@ -33,8 +33,7 @@ final class RemoteOccupancyService implements OccupacyService { final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart b/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart index 38865981..0d7f6500 100644 --- a/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart +++ b/lib/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart @@ -13,8 +13,7 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { static const _defaultErrorMessage = 'Failed to load occupancy heat map'; @override - Future> load( - GetOccupancyHeatMapParam param) async { + Future> load(GetOccupancyHeatMapParam param) async { try { final response = await _httpService.get( path: '/occupancy/heat-map/space/${param.spaceUuid}', @@ -25,8 +24,7 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { final dailyData = json['data'] as List? ?? []; final result = dailyData.map( - (json) => - OccupancyHeatMapModel.fromJson(json as Map), + (json) => OccupancyHeatMapModel.fromJson(json as Map), ); return result.toList(); @@ -38,8 +36,7 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService { final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart b/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart index 3930c252..b4bc82c6 100644 --- a/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart +++ b/lib/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart @@ -28,8 +28,7 @@ final class RemotePowerClampInfoService implements PowerClampInfoService { final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart b/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart index 3140cae3..01ad6fa1 100644 --- a/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart +++ b/lib/pages/analytics/services/range_of_aqi/fake_range_of_aqi_service.dart @@ -6,7 +6,7 @@ import 'package:syncrow_web/pages/analytics/services/range_of_aqi/range_of_aqi_s class FakeRangeOfAqiService implements RangeOfAqiService { @override Future> load(GetRangeOfAqiParam param) async { - return Future.delayed(const Duration(milliseconds: 800), () { + return await Future.delayed(const Duration(milliseconds: 800), () { final random = DateTime.now().millisecondsSinceEpoch; return List.generate(30, (index) { @@ -19,20 +19,14 @@ class FakeRangeOfAqiService implements RangeOfAqiService { final avg = (min + avgDelta).clamp(0.0, 301.0); final max = (avg + maxDelta).clamp(0.0, 301.0); - return RangeOfAqi( + return RangeOfAqi( data: [ - RangeOfAqiValue( - type: AqiType.aqi.code, min: min, average: avg, max: max), - RangeOfAqiValue( - type: AqiType.pm25.code, min: min, average: avg, max: max), - RangeOfAqiValue( - type: AqiType.pm10.code, min: min, average: avg, max: max), - RangeOfAqiValue( - type: AqiType.hcho.code, min: min, average: avg, max: max), - RangeOfAqiValue( - type: AqiType.tvoc.code, min: min, average: avg, max: max), - RangeOfAqiValue( - type: AqiType.co2.code, min: min, average: avg, max: max), + RangeOfAqiValue(type: AqiType.aqi.code, min: min, average: avg, max: max), + RangeOfAqiValue(type: AqiType.pm25.code, min: min, average: avg, max: max), + RangeOfAqiValue(type: AqiType.pm10.code, min: min, average: avg, max: max), + RangeOfAqiValue(type: AqiType.hcho.code, min: min, average: avg, max: max), + RangeOfAqiValue(type: AqiType.tvoc.code, min: min, average: avg, max: max), + RangeOfAqiValue(type: AqiType.co2.code, min: min, average: avg, max: max), ], date: date, ); diff --git a/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart b/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart index 6f5f00b1..9e1657e3 100644 --- a/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart +++ b/lib/pages/analytics/services/range_of_aqi/range_of_aqi_service.dart @@ -3,4 +3,4 @@ import 'package:syncrow_web/pages/analytics/params/get_range_of_aqi_param.dart'; abstract interface class RangeOfAqiService { Future> load(GetRangeOfAqiParam param); -} +} \ No newline at end of file diff --git a/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart b/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart index 92c152ca..7afece6a 100644 --- a/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart +++ b/lib/pages/analytics/services/realtime_device_service/realtime_device_service.dart @@ -2,4 +2,4 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_sta abstract interface class RealtimeDeviceService { Stream> subscribe(String deviceId); -} +} \ No newline at end of file diff --git a/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart b/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart index 42cdadbf..838cc5e7 100644 --- a/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart +++ b/lib/pages/analytics/services/total_energy_consumption/remote_total_energy_consumption_service.dart @@ -5,8 +5,7 @@ import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/to import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; -class RemoteTotalEnergyConsumptionService - implements TotalEnergyConsumptionService { +class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionService { const RemoteTotalEnergyConsumptionService(this._httpService); final HTTPService _httpService; @@ -30,8 +29,7 @@ class RemoteTotalEnergyConsumptionService final message = e.response?.data as Map?; final error = message?['error'] as Map?; final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = - [_defaultErrorMessage, errorMessage].join(': '); + final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': '); throw APIException(formattedErrorMessage); } catch (e) { final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); diff --git a/lib/pages/analytics/widgets/analytics_sidebar_header.dart b/lib/pages/analytics/widgets/analytics_sidebar_header.dart index 33f59032..5ff1d042 100644 --- a/lib/pages/analytics/widgets/analytics_sidebar_header.dart +++ b/lib/pages/analytics/widgets/analytics_sidebar_header.dart @@ -75,8 +75,7 @@ class AnalyticsSidebarHeader extends StatelessWidget { ), const SizedBox(height: 6), SelectableText( - context.watch().state.selectedDevice?.uuid ?? - 'N/A', + context.watch().state.selectedDevice?.uuid ?? 'N/A', style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, fontWeight: FontWeight.w400, diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index c2774263..58950089 100644 --- a/lib/pages/auth/bloc/auth_bloc.dart +++ b/lib/pages/auth/bloc/auth_bloc.dart @@ -36,8 +36,7 @@ class AuthBloc extends Bloc { ////////////////////////////// forget password ////////////////////////////////// final TextEditingController forgetEmailController = TextEditingController(); - final TextEditingController forgetPasswordController = - TextEditingController(); + final TextEditingController forgetPasswordController = TextEditingController(); final TextEditingController forgetOtp = TextEditingController(); final forgetFormKey = GlobalKey(); final forgetEmailKey = GlobalKey(); @@ -54,8 +53,7 @@ class AuthBloc extends Bloc { return; } _remainingTime = 1; - add(UpdateTimerEvent( - remainingTime: _remainingTime, isButtonEnabled: false)); + add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false)); try { forgetEmailValidate = ''; _remainingTime = (await AuthenticationAPI.sendOtp( @@ -64,7 +62,7 @@ class AuthBloc extends Bloc { } on DioException catch (e) { if (e.response!.statusCode == 400) { final errorData = e.response!.data; - final String errorMessage = errorData['message']; + String errorMessage = errorData['message']; if (errorMessage == 'User not found') { validate = 'Invalid Credential'; emit(AuthInitialState()); @@ -92,8 +90,7 @@ class AuthBloc extends Bloc { _timer?.cancel(); add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true)); } else { - add(UpdateTimerEvent( - remainingTime: _remainingTime, isButtonEnabled: false)); + add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false)); } }); } @@ -103,11 +100,11 @@ class AuthBloc extends Bloc { emit(const TimerState(isButtonEnabled: true, remainingTime: 0)); } - Future changePassword( +Future changePassword( ChangePasswordEvent event, Emitter emit) async { emit(LoadingForgetState()); try { - final response = await AuthenticationAPI.verifyOtp( + var response = await AuthenticationAPI.verifyOtp( email: forgetEmailController.text, otpCode: forgetOtp.text); if (response == true) { await AuthenticationAPI.forgetPassword( @@ -125,6 +122,7 @@ class AuthBloc extends Bloc { } } + String? validateCode(String? value) { if (value == null || value.isEmpty) { return 'Code is required'; @@ -133,9 +131,7 @@ class AuthBloc extends Bloc { } void _onUpdateTimer(UpdateTimerEvent event, Emitter emit) { - emit(TimerState( - isButtonEnabled: event.isButtonEnabled, - remainingTime: event.remainingTime)); + emit(TimerState(isButtonEnabled: event.isButtonEnabled, remainingTime: event.remainingTime)); } ///////////////////////////////////// login ///////////////////////////////////// @@ -155,7 +151,8 @@ class AuthBloc extends Bloc { static UserModel? user; bool showValidationMessage = false; - Future _login(LoginButtonPressed event, Emitter emit) async { + + void _login(LoginButtonPressed event, Emitter emit) async { emit(AuthLoading()); if (isChecked) { try { @@ -182,7 +179,7 @@ class AuthBloc extends Bloc { } if (token.accessTokenIsNotEmpty) { - const storage = FlutterSecureStorage(); + FlutterSecureStorage storage = const FlutterSecureStorage(); await storage.write( key: Token.loginAccessTokenKey, value: token.accessToken); const FlutterSecureStorage().write( @@ -200,7 +197,8 @@ class AuthBloc extends Bloc { } } - void checkBoxToggle( + + checkBoxToggle( CheckBoxEvent event, Emitter emit, ) { @@ -279,12 +277,12 @@ class AuthBloc extends Bloc { if (value == null || value.isEmpty) { return 'Please enter your password'; } - final validationErrors = []; + List validationErrors = []; - if (!RegExp('^(?=.*[a-z])').hasMatch(value)) { + if (!RegExp(r'^(?=.*[a-z])').hasMatch(value)) { validationErrors.add(' - one lowercase letter'); } - if (!RegExp('^(?=.*[A-Z])').hasMatch(value)) { + if (!RegExp(r'^(?=.*[A-Z])').hasMatch(value)) { validationErrors.add(' - one uppercase letter'); } if (!RegExp(r'^(?=.*\d)').hasMatch(value)) { @@ -306,7 +304,7 @@ class AuthBloc extends Bloc { String? fullNameValidator(String? value) { if (value == null) return 'Full name is required'; - final withoutExtraSpaces = value.replaceAll(RegExp(r'\s+'), ' ').trim(); + final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { return 'Full name must be between 2 and 30 characters long'; } @@ -341,14 +339,12 @@ class AuthBloc extends Bloc { static Future getTokenAndValidate() async { try { const storage = FlutterSecureStorage(); - final firstLaunch = await SharedPreferencesHelper.readBoolFromSP( - StringsManager.firstLaunch) ?? - true; + final firstLaunch = + await SharedPreferencesHelper.readBoolFromSP(StringsManager.firstLaunch) ?? true; if (firstLaunch) { storage.deleteAll(); } - await SharedPreferencesHelper.saveBoolToSP( - StringsManager.firstLaunch, false); + await SharedPreferencesHelper.saveBoolToSP(StringsManager.firstLaunch, false); final value = await storage.read(key: Token.loginAccessTokenKey) ?? ''; if (value.isEmpty) { return 'Token not found'; @@ -370,8 +366,7 @@ class AuthBloc extends Bloc { } } - Future _fetchRegion( - RegionInitialEvent event, Emitter emit) async { + void _fetchRegion(RegionInitialEvent event, Emitter emit) async { try { emit(AuthLoading()); regionList = await AuthenticationAPI.fetchRegion(); @@ -394,17 +389,15 @@ class AuthBloc extends Bloc { } String formattedTime(int time) { - final days = (time / 86400).floor(); // 86400 seconds in a day - final hours = ((time % 86400) / 3600).floor(); - final minutes = (((time % 86400) % 3600) / 60).floor(); - final seconds = ((time % 86400) % 3600) % 60; + final int days = (time / 86400).floor(); // 86400 seconds in a day + final int hours = ((time % 86400) / 3600).floor(); + final int minutes = (((time % 86400) % 3600) / 60).floor(); + final int seconds = (((time % 86400) % 3600) % 60).floor(); - final formattedTime = [ + final String formattedTime = [ if (days > 0) '${days}d', // Append 'd' for days if (days > 0 || hours > 0) - hours - .toString() - .padLeft(2, '0'), // Show hours if there are days or hours + hours.toString().padLeft(2, '0'), // Show hours if there are days or hours minutes.toString().padLeft(2, '0'), seconds.toString().padLeft(2, '0'), ].join(':'); @@ -424,7 +417,7 @@ class AuthBloc extends Bloc { return checkValidate; } - void changeValidate( + changeValidate( ChangeValidateEvent event, Emitter emit, ) { @@ -433,7 +426,7 @@ class AuthBloc extends Bloc { emit(LoginInitial()); } - void changeForgetValidate( + changeForgetValidate( ChangeValidateEvent event, Emitter emit, ) { diff --git a/lib/pages/auth/bloc/auth_event.dart b/lib/pages/auth/bloc/auth_event.dart index 392270e3..2b6a4eef 100644 --- a/lib/pages/auth/bloc/auth_event.dart +++ b/lib/pages/auth/bloc/auth_event.dart @@ -46,8 +46,7 @@ class StopTimerEvent extends AuthEvent {} class UpdateTimerEvent extends AuthEvent { final int remainingTime; final bool isButtonEnabled; - const UpdateTimerEvent( - {required this.remainingTime, required this.isButtonEnabled}); + const UpdateTimerEvent({required this.remainingTime, required this.isButtonEnabled}); } class ChangePasswordEvent extends AuthEvent {} diff --git a/lib/pages/auth/bloc/auth_state.dart b/lib/pages/auth/bloc/auth_state.dart index 05790a7b..f3a95157 100644 --- a/lib/pages/auth/bloc/auth_state.dart +++ b/lib/pages/auth/bloc/auth_state.dart @@ -56,8 +56,7 @@ class TimerState extends AuthState { final bool isButtonEnabled; final int remainingTime; - const TimerState( - {required this.isButtonEnabled, required this.remainingTime}); + const TimerState({required this.isButtonEnabled, required this.remainingTime}); @override List get props => [isButtonEnabled, remainingTime]; @@ -81,7 +80,7 @@ class TimerUpdated extends AuthState { final String formattedTime; final bool isButtonEnabled; - const TimerUpdated({ + TimerUpdated({ required this.formattedTime, required this.isButtonEnabled, }); diff --git a/lib/pages/auth/model/login_with_email_model.dart b/lib/pages/auth/model/login_with_email_model.dart index fcde9f17..dca3f8f9 100644 --- a/lib/pages/auth/model/login_with_email_model.dart +++ b/lib/pages/auth/model/login_with_email_model.dart @@ -21,9 +21,9 @@ class LoginWithEmailModel { return { 'email': email, 'password': password, - 'platform': 'web' + "platform": "web" // 'regionUuid': regionUuid, }; } } -//tst@tst.com +//tst@tst.com \ No newline at end of file diff --git a/lib/pages/auth/model/token.dart b/lib/pages/auth/model/token.dart index 24ee46f2..53c6f401 100644 --- a/lib/pages/auth/model/token.dart +++ b/lib/pages/auth/model/token.dart @@ -11,14 +11,6 @@ class Token { final int iat; final int exp; - Token( - this.accessToken, - this.refreshToken, - this.sessionId, - this.iat, - this.exp, - ); - Token.emptyConstructor() : accessToken = '', refreshToken = '', @@ -32,6 +24,14 @@ class Token { bool get isNotEmpty => accessToken.isNotEmpty && refreshToken.isNotEmpty; + Token( + this.accessToken, + this.refreshToken, + this.sessionId, + this.iat, + this.exp, + ); + Token.refreshToken(this.refreshToken) : accessToken = '', sessionId = '', @@ -40,7 +40,7 @@ class Token { factory Token.fromJson(Map json) { //save token to secure storage - const storage = FlutterSecureStorage(); + var storage = const FlutterSecureStorage(); storage.write( key: loginAccessTokenKey, value: json[loginAccessTokenKey] ?? ''); storage.write( diff --git a/lib/pages/auth/model/user_model.dart b/lib/pages/auth/model/user_model.dart index 98da8bd3..267d0b3e 100644 --- a/lib/pages/auth/model/user_model.dart +++ b/lib/pages/auth/model/user_model.dart @@ -55,21 +55,22 @@ class UserModel { //from token factory UserModel.fromToken(Token token) { - final tempJson = Token.decodeToken(token.accessToken); + Map tempJson = Token.decodeToken(token.accessToken); return UserModel( - hasAcceptedWebAgreement: null, - role: null, - webAgreementAcceptedAt: null, - uuid: tempJson['uuid'].toString(), - email: tempJson['email'], - firstName: null, - lastName: null, - photoUrl: null, - phoneNumber: null, - isEmailVerified: null, - isAgreementAccepted: null, - project: null); + hasAcceptedWebAgreement: null, + role: null, + webAgreementAcceptedAt: null, + uuid: tempJson['uuid'].toString(), + email: tempJson['email'], + firstName: null, + lastName: null, + photoUrl: null, + phoneNumber: null, + isEmailVerified: null, + isAgreementAccepted: null, + project: null + ); } Map toJson() { diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index b32644db..7686ea8f 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -36,18 +36,20 @@ class ForgetPasswordWebPage extends StatelessWidget { ); } }, - builder: _buildForm, + builder: (context, state) { + return _buildForm(context, state); + }, ), ), ); } Widget _buildForm(BuildContext context, AuthState state) { - late ScrollController scrollController; - scrollController = ScrollController(); - void scrollToCenter() { - final middlePosition = scrollController.position.maxScrollExtent / 2; - scrollController.animateTo( + late ScrollController _scrollController; + _scrollController = ScrollController(); + void _scrollToCenter() { + final double middlePosition = _scrollController.position.maxScrollExtent / 2; + _scrollController.animateTo( middlePosition, duration: const Duration(seconds: 1), curve: Curves.easeInOut, @@ -55,25 +57,24 @@ class ForgetPasswordWebPage extends StatelessWidget { } WidgetsBinding.instance.addPostFrameCallback((_) { - scrollToCenter(); + _scrollToCenter(); }); final forgetBloc = BlocProvider.of(context); - final size = MediaQuery.of(context).size; + Size size = MediaQuery.of(context).size; return FirstLayer( second: Center( child: Stack( children: [ - if (state is AuthLoading) - const Center(child: CircularProgressIndicator()), + if (state is AuthLoading) const Center(child: CircularProgressIndicator()), ListView( shrinkWrap: true, - controller: scrollController, + controller: _scrollController, children: [ Container( padding: EdgeInsets.all(size.width * 0.02), margin: EdgeInsets.all(size.width * 0.09), decoration: BoxDecoration( - color: Colors.black.withValues(alpha: 0.3), + color: Colors.black.withOpacity(0.3), borderRadius: const BorderRadius.all(Radius.circular(20)), ), child: Center( @@ -93,22 +94,17 @@ class ForgetPasswordWebPage extends StatelessWidget { flex: 3, child: Container( decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.1), - borderRadius: - const BorderRadius.all(Radius.circular(30)), - border: Border.all( - color: ColorsManager.graysColor - .withValues(alpha: 0.2)), + color: Colors.white.withOpacity(0.1), + borderRadius: const BorderRadius.all(Radius.circular(30)), + border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2)), ), child: Form( key: forgetBloc.forgetFormKey, child: Padding( padding: EdgeInsets.symmetric( - horizontal: size.width * 0.02, - vertical: size.width * 0.003), + horizontal: size.width * 0.02, vertical: size.width * 0.003), child: Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 10), @@ -125,9 +121,7 @@ class ForgetPasswordWebPage extends StatelessWidget { style: Theme.of(context) .textTheme .bodySmall! - .copyWith( - fontSize: 14, - fontWeight: FontWeight.w400), + .copyWith(fontSize: 14, fontWeight: FontWeight.w400), ), const SizedBox(height: 10), // Column( @@ -146,90 +140,69 @@ class ForgetPasswordWebPage extends StatelessWidget { Form( key: forgetBloc.forgetEmailKey, child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Account', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - fontSize: 14, - fontWeight: - FontWeight.w400), + "Account", + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontSize: 14, fontWeight: FontWeight.w400), ), const SizedBox(height: 10), SizedBox( child: TextFormField( - controller: forgetBloc - .forgetEmailController, - validator: - forgetBloc.validateEmail, - decoration: - textBoxDecoration()!.copyWith( + controller: forgetBloc.forgetEmailController, + validator: forgetBloc.validateEmail, + decoration: textBoxDecoration()!.copyWith( hintText: 'Enter your email', hintStyle: Theme.of(context) .textTheme .bodySmall! .copyWith( - color: ColorsManager - .grayColor, - fontWeight: - FontWeight.w400), + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400), ), - style: const TextStyle( - color: Colors.black), + style: const TextStyle(color: Colors.black), ), ), ], )), const SizedBox(height: 20.0), Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'One Time Password', + "One Time Password", style: Theme.of(context) .textTheme .bodySmall! - .copyWith( - fontSize: 14, - fontWeight: FontWeight.w400), + .copyWith(fontSize: 14, fontWeight: FontWeight.w400), ), const SizedBox(height: 10), SizedBox( child: TextFormField( validator: forgetBloc.validateCode, - keyboardType: - TextInputType.visiblePassword, + keyboardType: TextInputType.visiblePassword, controller: forgetBloc.forgetOtp, - decoration: - textBoxDecoration()!.copyWith( + decoration: textBoxDecoration()!.copyWith( hintText: 'Enter Code', hintStyle: Theme.of(context) .textTheme .bodySmall! .copyWith( - color: - ColorsManager.grayColor, - fontWeight: - FontWeight.w400), + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400), suffixIcon: SizedBox( width: 100, child: Center( child: InkWell( onTap: state is TimerState && - !state - .isButtonEnabled && - state.remainingTime != - 1 + !state.isButtonEnabled && + state.remainingTime != 1 ? null - : () { + : + () { if (forgetBloc .forgetEmailKey .currentState! @@ -238,31 +211,27 @@ class ForgetPasswordWebPage extends StatelessWidget { StartTimerEvent()); } }, + child: Text( 'Get Code ${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "(${forgetBloc.formattedTime(state.remainingTime)}) " : ""}', style: TextStyle( - color: state - is TimerState && - !state - .isButtonEnabled + color: state is TimerState && + !state.isButtonEnabled ? Colors.grey - : ColorsManager - .btnColor, + : ColorsManager.btnColor, ), ), ), ), ), ), - style: const TextStyle( - color: Colors.black), + style: const TextStyle(color: Colors.black), ), ), if (forgetBloc.forgetValidate != '') // Check if there is a validation message Padding( - padding: - const EdgeInsets.only(top: 8.0), + padding: const EdgeInsets.only(top: 8.0), child: Text( forgetBloc.forgetValidate, style: const TextStyle( @@ -275,44 +244,34 @@ class ForgetPasswordWebPage extends StatelessWidget { ), const SizedBox(height: 20.0), Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Password', + "Password", style: Theme.of(context) .textTheme .bodySmall! - .copyWith( - fontSize: 14, - fontWeight: FontWeight.w400), + .copyWith(fontSize: 14, fontWeight: FontWeight.w400), ), const SizedBox(height: 10), SizedBox( child: TextFormField( obscureText: forgetBloc.obscureText, - keyboardType: - TextInputType.visiblePassword, - validator: - forgetBloc.passwordValidator, - controller: forgetBloc - .forgetPasswordController, - decoration: - textBoxDecoration()!.copyWith( + keyboardType: TextInputType.visiblePassword, + validator: forgetBloc.passwordValidator, + controller: forgetBloc.forgetPasswordController, + decoration: textBoxDecoration()!.copyWith( suffixIcon: IconButton( onPressed: () { - forgetBloc.add( - PasswordVisibleEvent( - newValue: forgetBloc - .obscureText)); + forgetBloc.add(PasswordVisibleEvent( + newValue: forgetBloc.obscureText)); }, icon: SizedBox( child: SvgPicture.asset( forgetBloc.obscureText ? Assets.visiblePassword - : Assets - .invisiblePassword, + : Assets.invisiblePassword, height: 15, width: 15, ), @@ -323,13 +282,10 @@ class ForgetPasswordWebPage extends StatelessWidget { .textTheme .bodySmall! .copyWith( - color: - ColorsManager.grayColor, - fontWeight: - FontWeight.w400), + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400), ), - style: const TextStyle( - color: Colors.black), + style: const TextStyle(color: Colors.black), ), ), ], @@ -339,31 +295,23 @@ class ForgetPasswordWebPage extends StatelessWidget { ), const SizedBox(height: 20.0), Row( - crossAxisAlignment: - CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: size.width * 0.2, child: DefaultButton( - backgroundColor: - ColorsManager.btnColor, + backgroundColor: ColorsManager.btnColor, child: const Text('Submit'), onPressed: () { - if (forgetBloc - .forgetFormKey.currentState! - .validate() || - forgetBloc.forgetEmailKey - .currentState! + if (forgetBloc.forgetFormKey.currentState!.validate() || + forgetBloc.forgetEmailKey.currentState! .validate()) { - if (forgetBloc.forgetEmailKey - .currentState! + if (forgetBloc.forgetEmailKey.currentState! .validate() && - forgetBloc.forgetFormKey - .currentState! + forgetBloc.forgetFormKey.currentState! .validate()) { - forgetBloc - .add(ChangePasswordEvent()); + forgetBloc.add(ChangePasswordEvent()); } } }, @@ -377,8 +325,7 @@ class ForgetPasswordWebPage extends StatelessWidget { child: Text( forgetBloc.validate, style: const TextStyle( - fontWeight: FontWeight.w700, - color: ColorsManager.red), + fontWeight: FontWeight.w700, color: ColorsManager.red), ), ), ), @@ -390,9 +337,8 @@ class ForgetPasswordWebPage extends StatelessWidget { child: Wrap( children: [ const Text( - 'Do you have an account? ', - style: - TextStyle(color: Colors.white), + "Do you have an account? ", + style: TextStyle(color: Colors.white), ), InkWell( onTap: () { @@ -400,7 +346,7 @@ class ForgetPasswordWebPage extends StatelessWidget { Navigator.pop(context); }, child: const Text( - 'Sign in', + "Sign in", ), ), ], @@ -426,15 +372,14 @@ class ForgetPasswordWebPage extends StatelessWidget { )); } - Widget _buildDropdownField( - BuildContext context, AuthBloc loginBloc, Size size) { - final textEditingController = TextEditingController(); + Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) { + final TextEditingController textEditingController = TextEditingController(); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Country/Region', + "Country/Region", style: Theme.of(context).textTheme.bodySmall!.copyWith( fontSize: 14, fontWeight: FontWeight.w400, @@ -453,13 +398,10 @@ class ForgetPasswordWebPage extends StatelessWidget { builder: (FormFieldState field) { return InputDecorator( decoration: InputDecoration( - contentPadding: - const EdgeInsets.symmetric(horizontal: 2, vertical: 10), + contentPadding: const EdgeInsets.symmetric(horizontal: 2, vertical: 10), errorText: field.errorText, - filled: - true, // Ensure the dropdown is filled with the background color - fillColor: ColorsManager - .boxColor, // Match the dropdown container color + filled: true, // Ensure the dropdown is filled with the background color + fillColor: ColorsManager.boxColor, // Match the dropdown container color border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide( @@ -470,16 +412,14 @@ class ForgetPasswordWebPage extends StatelessWidget { enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide( - color: - field.hasError ? Colors.red : ColorsManager.grayColor, + color: field.hasError ? Colors.red : ColorsManager.grayColor, width: 1.5, ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide( - color: - field.hasError ? Colors.red : ColorsManager.grayColor, + color: field.hasError ? Colors.red : ColorsManager.grayColor, width: 1.5, ), ), @@ -506,11 +446,10 @@ class ForgetPasswordWebPage extends StatelessWidget { return DropdownMenuItem( value: region.id, child: Text( - style: - Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 14, - fontWeight: FontWeight.w400, - ), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontSize: 14, + fontWeight: FontWeight.w400, + ), region.name, overflow: TextOverflow.ellipsis, maxLines: 1, @@ -523,8 +462,7 @@ class ForgetPasswordWebPage extends StatelessWidget { onChanged: (String? value) { if (value != null) { loginBloc.add(SelectRegionEvent(val: value)); - field.didChange( - value); // Notify the form field of the change + field.didChange(value); // Notify the form field of the change } }, buttonStyleData: const ButtonStyleData( @@ -548,8 +486,7 @@ class ForgetPasswordWebPage extends StatelessWidget { searchInnerWidgetHeight: 50, searchInnerWidget: Container( height: 50, - padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 4), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: TextFormField( style: const TextStyle(color: Colors.black), controller: textEditingController, @@ -563,8 +500,7 @@ class ForgetPasswordWebPage extends StatelessWidget { ), ), searchMatchFn: (item, searchValue) { - final regionName = - (item.child as Text).data?.toLowerCase() ?? ''; + final regionName = (item.child as Text).data?.toLowerCase() ?? ''; final search = searchValue.toLowerCase().trim(); return regionName.contains(search); }, diff --git a/lib/pages/auth/view/login_mobile_page.dart b/lib/pages/auth/view/login_mobile_page.dart index a32944dc..4f001bc6 100644 --- a/lib/pages/auth/view/login_mobile_page.dart +++ b/lib/pages/auth/view/login_mobile_page.dart @@ -79,7 +79,7 @@ class LoginMobilePage extends StatelessWidget { child: Container( margin: const EdgeInsets.all(50), decoration: BoxDecoration( - color: Colors.black.withValues(alpha: 0.3), + color: Colors.black.withOpacity(0.3), borderRadius: const BorderRadius.all(Radius.circular(20))), child: Column( mainAxisSize: MainAxisSize.min, @@ -93,15 +93,12 @@ class LoginMobilePage extends StatelessWidget { ), ), Container( - margin: const EdgeInsets.all(30), - padding: const EdgeInsets.all(20), + margin: EdgeInsets.all(30), + padding: EdgeInsets.all(20), decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.1), - borderRadius: - const BorderRadius.all(Radius.circular(30)), - border: Border.all( - color: ColorsManager.graysColor - .withValues(alpha: 0.2))), + color: Colors.white.withOpacity(0.1), + borderRadius: const BorderRadius.all(Radius.circular(30)), + border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2))), child: Form( key: loginBloc.loginFormKey, child: Column( @@ -112,9 +109,7 @@ class LoginMobilePage extends StatelessWidget { const Text( 'Login', style: TextStyle( - color: Colors.white, - fontSize: 24, - fontWeight: FontWeight.bold), + color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold), ), const SizedBox(height: 30), // Column( @@ -160,15 +155,15 @@ class LoginMobilePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Email', + "Email", style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: TextFormField( validator: loginBloc.validateEmail, controller: loginBloc.loginEmailController, - decoration: textBoxDecoration()! - .copyWith(hintText: 'Enter your email'), + decoration: + textBoxDecoration()!.copyWith(hintText: 'Enter your email'), style: const TextStyle(color: Colors.black), ), ), @@ -180,7 +175,7 @@ class LoginMobilePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Password', + "Password", style: Theme.of(context).textTheme.bodySmall, ), SizedBox( @@ -188,8 +183,7 @@ class LoginMobilePage extends StatelessWidget { validator: loginBloc.validatePassword, obscureText: loginBloc.obscureText, keyboardType: TextInputType.visiblePassword, - controller: - loginBloc.loginPasswordController, + controller: loginBloc.loginPasswordController, decoration: textBoxDecoration()!.copyWith( hintText: 'At least 8 characters', ), @@ -207,19 +201,16 @@ class LoginMobilePage extends StatelessWidget { children: [ InkWell( onTap: () { - Navigator.of(context) - .push(MaterialPageRoute( - builder: (context) => - const ForgetPasswordPage(), + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => const ForgetPasswordPage(), )); }, child: Text( - 'Forgot Password?', + "Forgot Password?", style: Theme.of(context) .textTheme .bodySmall! - .copyWith( - color: ColorsManager.blackColor), + .copyWith(color: ColorsManager.blackColor), ), ), ], @@ -230,15 +221,13 @@ class LoginMobilePage extends StatelessWidget { Transform.scale( scale: 1.2, // Adjust the scale as needed child: Checkbox( - fillColor: WidgetStateProperty.all( - Colors.white), + fillColor: MaterialStateProperty.all(Colors.white), activeColor: Colors.white, value: loginBloc.isChecked, checkColor: Colors.black, shape: const CircleBorder(), onChanged: (bool? newValue) { - loginBloc.add( - CheckBoxEvent(newValue: newValue)); + loginBloc.add(CheckBoxEvent(newValue: newValue)); }, ), ), @@ -247,37 +236,30 @@ class LoginMobilePage extends StatelessWidget { child: RichText( text: TextSpan( text: 'Agree to ', - style: - const TextStyle(color: Colors.white), + style: const TextStyle(color: Colors.white), children: [ TextSpan( text: '(Terms of Service)', - style: const TextStyle( - color: Colors.black), + style: const TextStyle(color: Colors.black), recognizer: TapGestureRecognizer() ..onTap = () { - loginBloc.launchURL( - 'https://example.com/terms'); + loginBloc.launchURL('https://example.com/terms'); }, ), TextSpan( text: ' (Legal Statement)', - style: const TextStyle( - color: Colors.black), + style: const TextStyle(color: Colors.black), recognizer: TapGestureRecognizer() ..onTap = () { - loginBloc.launchURL( - 'https://example.com/legal'); + loginBloc.launchURL('https://example.com/legal'); }, ), TextSpan( text: ' (Privacy Statement)', - style: const TextStyle( - color: Colors.black), + style: const TextStyle(color: Colors.black), recognizer: TapGestureRecognizer() ..onTap = () { - loginBloc.launchURL( - 'https://example.com/privacy'); + loginBloc.launchURL('https://example.com/privacy'); }, ), ], @@ -294,14 +276,11 @@ class LoginMobilePage extends StatelessWidget { : ColorsManager.grayColor, child: const Text('Sign in'), onPressed: () { - if (loginBloc.loginFormKey.currentState! - .validate()) { + if (loginBloc.loginFormKey.currentState!.validate()) { loginBloc.add( LoginButtonPressed( - username: - loginBloc.loginEmailController.text, - password: loginBloc - .loginPasswordController.text, + username: loginBloc.loginEmailController.text, + password: loginBloc.loginPasswordController.text, ), ); } @@ -316,11 +295,10 @@ class LoginMobilePage extends StatelessWidget { Flexible( child: Text( "Don't you have an account? ", - style: TextStyle( - color: Colors.white, fontSize: 13), + style: TextStyle(color: Colors.white, fontSize: 13), )), Text( - 'Sign up', + "Sign up", ), ], ), diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index d7416b67..a6de87cf 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -24,8 +24,7 @@ class LoginWebPage extends StatefulWidget { State createState() => _LoginWebPageState(); } -class _LoginWebPageState extends State - with HelperResponsiveLayout { +class _LoginWebPageState extends State with HelperResponsiveLayout { @override Widget build(BuildContext context) { return Scaffold( @@ -43,7 +42,9 @@ class _LoginWebPageState extends State ); } }, - builder: _buildLoginForm, + builder: (context, state) { + return _buildLoginForm(context, state); + }, ), ), ); @@ -53,12 +54,12 @@ class _LoginWebPageState extends State final loginBloc = BlocProvider.of(context); final isSmallScreen = isSmallScreenSize(context); final isMediumScreen = isMediumScreenSize(context); - final size = MediaQuery.of(context).size; + Size size = MediaQuery.of(context).size; late ScrollController scrollController; scrollController = ScrollController(); void scrollToCenter() { - final middlePosition = scrollController.position.maxScrollExtent / 2; + final double middlePosition = scrollController.position.maxScrollExtent / 2; scrollController.animateTo( middlePosition, duration: const Duration(seconds: 1), @@ -83,7 +84,7 @@ class _LoginWebPageState extends State padding: EdgeInsets.all(size.width * 0.02), margin: EdgeInsets.all(size.width * 0.05), decoration: BoxDecoration( - color: Colors.black.withValues(alpha: 0.3), + color: Colors.black.withOpacity(0.3), borderRadius: const BorderRadius.all(Radius.circular(20)), ), child: Center( @@ -120,8 +121,7 @@ class _LoginWebPageState extends State const Spacer(), Expanded( flex: 2, - child: _buildLoginFormFields( - context, loginBloc, size), + child: _buildLoginFormFields(context, loginBloc, size), ), const Spacer(), ], @@ -132,26 +132,23 @@ class _LoginWebPageState extends State ), ), ), - if (state is AuthLoading) - const Center(child: CircularProgressIndicator()) + if (state is AuthLoading) const Center(child: CircularProgressIndicator()) ], ); } - Widget _buildLoginFormFields( - BuildContext context, AuthBloc loginBloc, Size size) { + Widget _buildLoginFormFields(BuildContext context, AuthBloc loginBloc, Size size) { return Container( decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.1), + color: Colors.white.withOpacity(0.1), borderRadius: const BorderRadius.all(Radius.circular(30)), - border: - Border.all(color: ColorsManager.graysColor.withValues(alpha: 0.2)), + border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2)), ), child: Form( key: loginBloc.loginFormKey, child: Padding( - padding: EdgeInsets.symmetric( - horizontal: size.width * 0.02, vertical: size.width * 0.003), + padding: + EdgeInsets.symmetric(horizontal: size.width * 0.02, vertical: size.width * 0.003), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, @@ -179,15 +176,14 @@ class _LoginWebPageState extends State ); } - Widget _buildDropdownField( - BuildContext context, AuthBloc loginBloc, Size size) { - final textEditingController = TextEditingController(); + Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) { + final TextEditingController textEditingController = TextEditingController(); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Country/Region', + "Country/Region", style: Theme.of(context).textTheme.bodySmall!.copyWith( fontSize: 14, fontWeight: FontWeight.w400, @@ -250,8 +246,7 @@ class _LoginWebPageState extends State searchInnerWidgetHeight: 50, searchInnerWidget: Container( height: 50, - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: TextFormField( style: const TextStyle(color: Colors.black), controller: textEditingController, @@ -266,8 +261,7 @@ class _LoginWebPageState extends State ), searchMatchFn: (item, searchValue) { // Use the item's child text (region name) for searching. - final regionName = - (item.child as Text).data?.toLowerCase() ?? ''; + final regionName = (item.child as Text).data?.toLowerCase() ?? ''; final search = searchValue.toLowerCase().trim(); // Debugging print statement to ensure values are captured correctly. // Return true if the region name contains the search term. @@ -292,7 +286,7 @@ class _LoginWebPageState extends State mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Email', + "Email", style: Theme.of(context) .textTheme .bodySmall! @@ -309,9 +303,10 @@ class _LoginWebPageState extends State decoration: textBoxDecoration()!.copyWith( errorStyle: const TextStyle(height: 0), hintText: 'Enter your email address', - hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.grayColor, - fontWeight: FontWeight.w400)), + hintStyle: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400)), style: const TextStyle(color: Colors.black), ), ), @@ -325,7 +320,7 @@ class _LoginWebPageState extends State mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Password', + "Password", style: Theme.of(context) .textTheme .bodySmall! @@ -343,7 +338,7 @@ class _LoginWebPageState extends State controller: loginBloc.loginPasswordController, onFieldSubmitted: (value) { if (loginBloc.loginFormKey.currentState!.validate()) { - loginBloc.add(LoginButtonPressed( + loginBloc.add(LoginButtonPressed( username: loginBloc.loginEmailController.text, password: value, )); @@ -353,18 +348,17 @@ class _LoginWebPageState extends State }, decoration: textBoxDecoration()!.copyWith( hintText: 'At least 8 characters', - hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.grayColor, fontWeight: FontWeight.w400), + hintStyle: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400), suffixIcon: IconButton( onPressed: () { - loginBloc.add( - PasswordVisibleEvent(newValue: loginBloc.obscureText)); + loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText)); }, icon: SizedBox( child: SvgPicture.asset( - loginBloc.obscureText - ? Assets.visiblePassword - : Assets.invisiblePassword, + loginBloc.obscureText ? Assets.visiblePassword : Assets.invisiblePassword, height: 15, width: 15, ), @@ -391,11 +385,11 @@ class _LoginWebPageState extends State )); }, child: Text( - 'Forgot Password?', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: Colors.black, - fontSize: 14, - fontWeight: FontWeight.w400), + "Forgot Password?", + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.black, fontSize: 14, fontWeight: FontWeight.w400), ), ), ], @@ -459,8 +453,7 @@ class _LoginWebPageState extends State ); } - Widget _buildSignInButton( - BuildContext context, AuthBloc loginBloc, Size size) { + Widget _buildSignInButton(BuildContext context, AuthBloc loginBloc, Size size) { return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -474,7 +467,7 @@ class _LoginWebPageState extends State fontSize: 14, color: loginBloc.checkValidate ? ColorsManager.whiteColors - : ColorsManager.whiteColors.withValues(alpha: 0.2), + : ColorsManager.whiteColors.withOpacity(0.2), )), onPressed: () { if (loginBloc.loginFormKey.currentState!.validate()) { @@ -501,8 +494,7 @@ class _LoginWebPageState extends State SizedBox( child: Text( loginBloc.validate, - style: const TextStyle( - fontWeight: FontWeight.w700, color: ColorsManager.red), + style: const TextStyle(fontWeight: FontWeight.w700, color: ColorsManager.red), ), ) ], diff --git a/lib/pages/common/access_device_table.dart b/lib/pages/common/access_device_table.dart index 01aed542..86d4a6b3 100644 --- a/lib/pages/common/access_device_table.dart +++ b/lib/pages/common/access_device_table.dart @@ -108,64 +108,66 @@ class _DynamicTableState extends State { child: Row( children: [ if (widget.withCheckBox) _buildSelectAllCheckbox(), - ...widget.headers.map(_buildTableHeaderCell), + ...widget.headers + .map((header) => _buildTableHeaderCell(header)), ], ), ), - if (widget.isEmpty) - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, + widget.isEmpty + ? Expanded( + child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Column( + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, children: [ - SvgPicture.asset(Assets.emptyTable), - const SizedBox( - height: 15, + Column( + children: [ + SvgPicture.asset(Assets.emptyTable), + const SizedBox( + height: 15, + ), + Text( + // no password + widget.tableName == 'AccessManagement' + ? 'No Password ' + : 'No Devices', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith( + color: ColorsManager.grayColor), + ) + ], ), - Text( - // no password - widget.tableName == 'AccessManagement' - ? 'No Password ' - : 'No Devices', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: ColorsManager.grayColor), - ) ], ), ], ), - ], - ), - ) - else - Expanded( - child: ColoredBox( - color: Colors.white, - child: ListView.builder( - shrinkWrap: true, - itemCount: widget.data.length, - itemBuilder: (context, index) { - final row = widget.data[index]; - return Row( - children: [ - if (widget.withCheckBox) - _buildRowCheckbox( - index, widget.size.height * 0.10), - ...row.map((cell) => _buildTableCell( - cell.toString(), widget.size.height * 0.10)), - ], - ); - }, + ) + : Expanded( + child: Container( + color: Colors.white, + child: ListView.builder( + shrinkWrap: true, + itemCount: widget.data.length, + itemBuilder: (context, index) { + final row = widget.data[index]; + return Row( + children: [ + if (widget.withCheckBox) + _buildRowCheckbox( + index, widget.size.height * 0.10), + ...row.map((cell) => _buildTableCell( + cell.toString(), + widget.size.height * 0.10)), + ], + ); + }, + ), + ), ), - ), - ), ], ), ), @@ -243,7 +245,7 @@ class _DynamicTableState extends State { } Widget _buildTableCell(String content, double size) { - final isBatteryLevel = content.endsWith('%'); + bool isBatteryLevel = content.endsWith('%'); double? batteryLevel; if (isBatteryLevel) { diff --git a/lib/pages/common/buttons/cancel_button.dart b/lib/pages/common/buttons/cancel_button.dart index 2147760e..da6dcdc7 100644 --- a/lib/pages/common/buttons/cancel_button.dart +++ b/lib/pages/common/buttons/cancel_button.dart @@ -22,21 +22,17 @@ class CancelButton extends StatelessWidget { return ElevatedButton( onPressed: onPressed, style: ButtonStyle( - backgroundColor: - WidgetStateProperty.all(ColorsManager.boxColor), // White background - foregroundColor: - WidgetStateProperty.all(Colors.black), // Black text color + backgroundColor: WidgetStateProperty.all(ColorsManager.boxColor), // White background + foregroundColor: WidgetStateProperty.all(Colors.black), // Black text color shape: WidgetStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(borderRadius ?? 10), - side: - const BorderSide(color: ColorsManager.boxColor), // Black border + side: const BorderSide(color: ColorsManager.boxColor), // Black border ), ), - fixedSize: WidgetStateProperty.all( - Size(width ?? 50, height ?? 40)), // Set button height + fixedSize: WidgetStateProperty.all(Size(width ?? 50, height ?? 40)), // Set button height ), child: Text(label), // Dynamic label ); } -} +} \ No newline at end of file diff --git a/lib/pages/common/buttons/default_button.dart b/lib/pages/common/buttons/default_button.dart index 61012434..ecca6138 100644 --- a/lib/pages/common/buttons/default_button.dart +++ b/lib/pages/common/buttons/default_button.dart @@ -64,7 +64,7 @@ class DefaultButton extends StatelessWidget { (Set states) { return enabled ? backgroundColor ?? ColorsManager.primaryColor - : Colors.black.withValues(alpha: 0.2); + : Colors.black.withOpacity(0.2); }), shape: WidgetStateProperty.all( RoundedRectangleBorder( diff --git a/lib/pages/common/curtain_toggle.dart b/lib/pages/common/curtain_toggle.dart index a1c99355..7b1551c5 100644 --- a/lib/pages/common/curtain_toggle.dart +++ b/lib/pages/common/curtain_toggle.dart @@ -34,7 +34,7 @@ class CurtainToggle extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipOval( - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.curtainIcon, @@ -52,7 +52,7 @@ class CurtainToggle extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeTrackColor: ColorsManager.dialogBlueTitle, + activeColor: ColorsManager.dialogBlueTitle, onChanged: onChanged, ), ), diff --git a/lib/pages/common/custom_dialog.dart b/lib/pages/common/custom_dialog.dart index 78c4a43e..9899bda4 100644 --- a/lib/pages/common/custom_dialog.dart +++ b/lib/pages/common/custom_dialog.dart @@ -12,7 +12,7 @@ Future showCustomDialog({ double? iconWidth, VoidCallback? onOkPressed, bool barrierDismissible = false, - List? actions, + List? actions, }) { return showDialog( context: context, @@ -40,20 +40,14 @@ Future showCustomDialog({ style: Theme.of(context) .textTheme .headlineLarge! - .copyWith( - fontSize: 20, - fontWeight: FontWeight.w400, - color: Colors.black), + .copyWith(fontSize: 20, fontWeight: FontWeight.w400, color: Colors.black), ), ), Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( message, - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: Colors.black), + style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.black), textAlign: TextAlign.center, ), ), diff --git a/lib/pages/common/custom_table.dart b/lib/pages/common/custom_table.dart index de6da949..f23daa45 100644 --- a/lib/pages/common/custom_table.dart +++ b/lib/pages/common/custom_table.dart @@ -20,8 +20,8 @@ class DynamicTable extends StatefulWidget { final void Function(int, bool, dynamic)? onRowSelected; final List? initialSelectedIds; final int uuidIndex; - final void Function(dynamic selectedRows)? onSelectionChanged; - final void Function(int rowIndex)? onSettingsPressed; + final Function(dynamic selectedRows)? onSelectionChanged; + final Function(int rowIndex)? onSettingsPressed; const DynamicTable({ super.key, required this.headers, @@ -79,10 +79,10 @@ class _DynamicTableState extends State { // Check if the old and new lists are the same if (oldList.length != newList.length) return false; - for (var i = 0; i < oldList.length; i++) { + for (int i = 0; i < oldList.length; i++) { if (oldList[i].length != newList[i].length) return false; - for (var j = 0; j < oldList[i].length; j++) { + for (int j = 0; j < oldList[i].length; j++) { if (oldList[i][j] != newList[i][j]) return false; } } @@ -162,7 +162,7 @@ class _DynamicTableState extends State { child: SingleChildScrollView( scrollDirection: Axis.horizontal, controller: _horizontalBodyScrollController, - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, child: SizedBox( width: widget.size.width, @@ -184,7 +184,7 @@ class _DynamicTableState extends State { rowIndex: rowIndex, columnIndex: entry.key, ); - }), + }).toList(), ], ); }), @@ -304,13 +304,13 @@ class _DynamicTableState extends State { required int rowIndex, required int columnIndex, }) { - final isBatteryLevel = content.endsWith('%'); + bool isBatteryLevel = content.endsWith('%'); double? batteryLevel; if (isBatteryLevel) { batteryLevel = double.tryParse(content.replaceAll('%', '').trim()); } - final isSettingsColumn = widget.headers[columnIndex] == 'Settings'; + bool isSettingsColumn = widget.headers[columnIndex] == 'Settings'; if (isSettingsColumn) { return buildSettingsIcon( @@ -404,7 +404,7 @@ class _DynamicTableState extends State { borderRadius: BorderRadius.circular(height / 2), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.17), + color: Colors.black.withOpacity(0.17), blurRadius: 14, offset: const Offset(0, 4), ), @@ -416,10 +416,11 @@ class _DynamicTableState extends State { padding: const EdgeInsets.all(8.0), child: Center( child: SvgPicture.asset( - Assets.settings, + Assets.settings, // ضع المسار الصحيح هنا width: 40, height: 22, - color: ColorsManager.primaryColor, + color: ColorsManager + .primaryColor, // نفس لون الأيقونة في الصورة ), ), ), diff --git a/lib/pages/common/filter/filter_widget.dart b/lib/pages/common/filter/filter_widget.dart index afd98eef..1af23045 100644 --- a/lib/pages/common/filter/filter_widget.dart +++ b/lib/pages/common/filter/filter_widget.dart @@ -36,7 +36,7 @@ class FilterWidget extends StatelessWidget { color: ColorsManager.boxColor, border: Border.all( color: isSelected - ? ColorsManager.blueColor.withValues(alpha: 0.8) + ? ColorsManager.blueColor.withOpacity(0.8) : Colors.transparent, width: 2.0, ), @@ -48,7 +48,7 @@ class FilterWidget extends StatelessWidget { tabs[index], style: TextStyle( color: isSelected - ? ColorsManager.blueColor.withValues(alpha: 0.8) + ? ColorsManager.blueColor.withOpacity(0.8) : Colors.black, ), ), diff --git a/lib/pages/common/hour_picker_dialog.dart b/lib/pages/common/hour_picker_dialog.dart index 2c5be850..01a87720 100644 --- a/lib/pages/common/hour_picker_dialog.dart +++ b/lib/pages/common/hour_picker_dialog.dart @@ -1,3 +1,5 @@ + + import 'package:flutter/material.dart'; class HourPickerDialog extends StatefulWidget { @@ -16,7 +18,7 @@ class _HourPickerDialogState extends State { void initState() { super.initState(); // Initialize the selectedHour with the initial time passed to the dialog - selectedHour = '${widget.initialTime.hour.toString().padLeft(2, '0')}:00'; + selectedHour = widget.initialTime.hour.toString().padLeft(2, '0') + ':00'; } @override @@ -26,7 +28,7 @@ class _HourPickerDialogState extends State { content: DropdownButton( value: selectedHour, // Show the currently selected hour items: List.generate(24, (index) { - final hour = index.toString().padLeft(2, '0'); + String hour = index.toString().padLeft(2, '0'); return DropdownMenuItem( value: '$hour:00', child: Text('$hour:00'), @@ -35,16 +37,14 @@ class _HourPickerDialogState extends State { onChanged: (String? newValue) { if (newValue != null) { setState(() { - selectedHour = - newValue; // Update the selected hour without closing the dialog + selectedHour = newValue; // Update the selected hour without closing the dialog }); } }, ), actions: [ TextButton( - onPressed: () => Navigator.of(context) - .pop(null), // Close the dialog without selection + onPressed: () => Navigator.of(context).pop(null), // Close the dialog without selection child: const Text('Cancel'), ), TextButton( diff --git a/lib/pages/common/info_dialog.dart b/lib/pages/common/info_dialog.dart index f2062319..97656418 100644 --- a/lib/pages/common/info_dialog.dart +++ b/lib/pages/common/info_dialog.dart @@ -9,8 +9,7 @@ class InfoDialog extends StatelessWidget { final Size? size; final List? actions; - const InfoDialog({ - super.key, + InfoDialog({ required this.title, required this.content, this.actions, diff --git a/lib/pages/device_managment/ac/bloc/ac_bloc.dart b/lib/pages/device_managment/ac/bloc/ac_bloc.dart index d96a4714..af5a7b0a 100644 --- a/lib/pages/device_managment/ac/bloc/ac_bloc.dart +++ b/lib/pages/device_managment/ac/bloc/ac_bloc.dart @@ -45,8 +45,7 @@ class AcBloc extends Bloc { ) async { emit(AcsLoadingState()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status); if (deviceStatus.countdown1 != 0) { final totalMinutes = deviceStatus.countdown1 * 6; @@ -72,20 +71,21 @@ class AcBloc extends Bloc { void _listenToChanges(deviceId) { try { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - ref.onValue.listen((DatabaseEvent event) async { + final stream = ref.onValue; + + stream.listen((DatabaseEvent event) async { if (event.snapshot.value == null) return; - final usersMap = event.snapshot.value! as Map; + Map usersMap = + event.snapshot.value as Map; - final statusList = []; + List statusList = []; usersMap['status'].forEach((element) { - statusList - .add(Status(code: element['code'], value: element['value'])); + statusList.add(Status(code: element['code'], value: element['value'])); }); - deviceStatus = - AcStatusModel.fromJson(usersMap['productUuid'], statusList); + deviceStatus = AcStatusModel.fromJson(usersMap['productUuid'], statusList); if (!isClosed) { add(AcStatusUpdated(deviceStatus)); } @@ -129,10 +129,8 @@ class AcBloc extends Bloc { ) async { emit(AcsLoadingState()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.devicesIds); - deviceStatus = - AcStatusModel.fromJson(event.devicesIds.first, status.status); + final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); + deviceStatus = AcStatusModel.fromJson(event.devicesIds.first, status.status); emit(ACStatusLoaded(status: deviceStatus)); } catch (e) { emit(AcsFailedState(error: e.toString())); @@ -192,8 +190,8 @@ class AcBloc extends Bloc { void _handleIncreaseTime(IncreaseTimeEvent event, Emitter emit) { if (state is! ACStatusLoaded) return; final currentState = state as ACStatusLoaded; - var newHours = scheduledHours; - var newMinutes = scheduledMinutes + 30; + int newHours = scheduledHours; + int newMinutes = scheduledMinutes + 30; newHours += newMinutes ~/ 60; newMinutes = newMinutes % 60; if (newHours > 23) { @@ -215,7 +213,7 @@ class AcBloc extends Bloc { ) { if (state is! ACStatusLoaded) return; final currentState = state as ACStatusLoaded; - var totalMinutes = (scheduledHours * 60) + scheduledMinutes; + int totalMinutes = (scheduledHours * 60) + scheduledMinutes; totalMinutes = (totalMinutes - 30).clamp(0, 1440); scheduledHours = totalMinutes ~/ 60; scheduledMinutes = totalMinutes % 60; @@ -288,7 +286,7 @@ class AcBloc extends Bloc { void _startCountdownTimer(Emitter emit) { _countdownTimer?.cancel(); - var totalSeconds = (scheduledHours * 3600) + (scheduledMinutes * 60); + int totalSeconds = (scheduledHours * 3600) + (scheduledMinutes * 60); _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (totalSeconds > 0) { @@ -338,26 +336,32 @@ class AcBloc extends Bloc { if (value is bool) { deviceStatus = deviceStatus.copyWith(acSwitch: value); } + break; case 'temp_set': if (value is int) { deviceStatus = deviceStatus.copyWith(tempSet: value); } + break; case 'mode': if (value is String) { deviceStatus = deviceStatus.copyWith(modeString: value); } + break; case 'level': if (value is String) { deviceStatus = deviceStatus.copyWith(fanSpeedsString: value); } + break; case 'child_lock': if (value is bool) { deviceStatus = deviceStatus.copyWith(childLock: value); } + break; case 'countdown_time': if (value is int) { deviceStatus = deviceStatus.copyWith(countdown1: value); } + break; default: break; } diff --git a/lib/pages/device_managment/ac/bloc/ac_event.dart b/lib/pages/device_managment/ac/bloc/ac_event.dart index 217199ea..9764f3ed 100644 --- a/lib/pages/device_managment/ac/bloc/ac_event.dart +++ b/lib/pages/device_managment/ac/bloc/ac_event.dart @@ -22,7 +22,7 @@ class AcFetchDeviceStatusEvent extends AcsEvent { class AcStatusUpdated extends AcsEvent { final AcStatusModel deviceStatus; - const AcStatusUpdated(this.deviceStatus); + AcStatusUpdated(this.deviceStatus); } class AcFetchBatchStatusEvent extends AcsEvent { @@ -77,6 +77,8 @@ class AcFactoryResetEvent extends AcsEvent { List get props => [deviceId, factoryResetModel]; } + + class OnClose extends AcsEvent {} class IncreaseTimeEvent extends AcsEvent { @@ -93,7 +95,8 @@ class ToggleScheduleEvent extends AcsEvent {} class TimerCompletedEvent extends AcsEvent {} -class UpdateTimerEvent extends AcsEvent {} +class UpdateTimerEvent extends AcsEvent { +} class ApiCountdownValueEvent extends AcsEvent { final int apiValue; diff --git a/lib/pages/device_managment/ac/bloc/ac_state.dart b/lib/pages/device_managment/ac/bloc/ac_state.dart index a8985957..3e1e2c68 100644 --- a/lib/pages/device_managment/ac/bloc/ac_state.dart +++ b/lib/pages/device_managment/ac/bloc/ac_state.dart @@ -18,7 +18,6 @@ class ACStatusLoaded extends AcsState { final DateTime timestamp; final int scheduledHours; final int scheduledMinutes; - @override final bool isTimerActive; ACStatusLoaded({ @@ -73,3 +72,5 @@ class TimerRunInProgress extends AcsState { @override List get props => [remainingTime]; } + + diff --git a/lib/pages/device_managment/ac/model/ac_model.dart b/lib/pages/device_managment/ac/model/ac_model.dart index 32a7de0c..6afc778d 100644 --- a/lib/pages/device_managment/ac/model/ac_model.dart +++ b/lib/pages/device_managment/ac/model/ac_model.dart @@ -32,9 +32,9 @@ class AcStatusModel { late int currentTemp; late String fanSpeeds; late bool childLock; - late var countdown1 = 0; + late int _countdown1 = 0; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch': acSwitch = status.value ?? false; @@ -55,7 +55,7 @@ class AcStatusModel { childLock = status.value ?? false; break; case 'countdown_time': - countdown1 = status.value ?? 0; + _countdown1 = status.value ?? 0; break; } } @@ -68,7 +68,7 @@ class AcStatusModel { currentTemp: currentTemp, fanSpeedsString: fanSpeeds, childLock: childLock, - countdown1: countdown1, + countdown1: _countdown1, ); } diff --git a/lib/pages/device_managment/ac/view/ac_device_batch_control.dart b/lib/pages/device_managment/ac/view/ac_device_batch_control.dart index 5b03ae3d..aad0669b 100644 --- a/lib/pages/device_managment/ac/view/ac_device_batch_control.dart +++ b/lib/pages/device_managment/ac/view/ac_device_batch_control.dart @@ -15,8 +15,7 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class AcDeviceBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayout { const AcDeviceBatchControlView({super.key, required this.devicesIds}); final List devicesIds; @@ -101,8 +100,8 @@ class AcDeviceBatchControlView extends StatelessWidget ), Text( 'h', - style: context.textTheme.bodySmall! - .copyWith(color: ColorsManager.blackColor), + style: + context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor), ), Text( '30', @@ -149,8 +148,7 @@ class AcDeviceBatchControlView extends StatelessWidget callFactoryReset: () { context.read().add(AcFactoryResetEvent( deviceId: state.status.uuid, - factoryResetModel: - FactoryResetModel(devicesUuid: devicesIds), + factoryResetModel: FactoryResetModel(devicesUuid: devicesIds), )); }, ), diff --git a/lib/pages/device_managment/ac/view/ac_device_control.dart b/lib/pages/device_managment/ac/view/ac_device_control.dart index b779a5ca..a882e6d5 100644 --- a/lib/pages/device_managment/ac/view/ac_device_control.dart +++ b/lib/pages/device_managment/ac/view/ac_device_control.dart @@ -14,7 +14,7 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout { - const AcDeviceControlsView({super.key, required this.device}); + const AcDeviceControlsView({super.key, required this.device}); final AllDevicesModel device; diff --git a/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart b/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart index 11724f1d..be7441df 100644 --- a/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart +++ b/lib/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart @@ -41,7 +41,7 @@ class _CurrentTempState extends State { double _initialAdjustedValue(dynamic value) { if (value is int || value is double) { - final double doubleValue = value.toDouble(); + double doubleValue = value.toDouble(); return doubleValue > 99 ? doubleValue / 10 : doubleValue; } else { throw ArgumentError('Invalid value type: Expected int or double'); @@ -75,48 +75,35 @@ class _CurrentTempState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (widget.isBatch == true) - Text( - 'Set Temperature', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.grey), - ) - else - Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Current Temperature', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.grey), - ), - const SizedBox( - height: 5, - ), - Row( + widget.isBatch == true + ? Text( + 'Set Temperature', + style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), + ) + : Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - (widget.currentTemp > 99 - ? widget.currentTemp / 10 - : widget.currentTemp) - .toString(), - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.grey), + 'Current Temperature', + style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), + ), + const SizedBox( + height: 5, + ), + Row( + children: [ + Text( + (widget.currentTemp > 99 ? widget.currentTemp / 10 : widget.currentTemp).toString(), + style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), + ), + const CelsiusSymbol( + color: Colors.grey, + ) + ], ), - const CelsiusSymbol( - color: Colors.grey, - ) ], ), - ], - ), const Spacer(), IncrementDecrementWidget( value: _adjustedValue.toString(), diff --git a/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart b/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart index 8e592d48..4e81ec09 100644 --- a/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart +++ b/lib/pages/device_managment/ac/view/control_list/ac_toggle.dart @@ -52,7 +52,7 @@ class AcToggle extends StatelessWidget { height: 20, width: 35, child: CupertinoSwitch( - activeTrackColor: ColorsManager.dialogBlueTitle, + activeColor: ColorsManager.dialogBlueTitle, value: value, onChanged: (newValue) { context.read().add( diff --git a/lib/pages/device_managment/ac/view/control_list/current_temp.dart b/lib/pages/device_managment/ac/view/control_list/current_temp.dart index 7c5f9494..fdd51164 100644 --- a/lib/pages/device_managment/ac/view/control_list/current_temp.dart +++ b/lib/pages/device_managment/ac/view/control_list/current_temp.dart @@ -39,7 +39,7 @@ class _CurrentTempState extends State { double _initialAdjustedValue(dynamic value) { if (value is int || value is double) { - final double doubleValue = value.toDouble(); + double doubleValue = value.toDouble(); return doubleValue > 99 ? doubleValue / 10 : doubleValue; } else { throw ArgumentError('Invalid value type: Expected int or double'); @@ -60,7 +60,6 @@ class _CurrentTempState extends State { ); }); } - @override void didUpdateWidget(CurrentTemp oldWidget) { super.didUpdateWidget(oldWidget); @@ -70,7 +69,6 @@ class _CurrentTempState extends State { }); } } - @override void dispose() { _debounce?.cancel(); @@ -89,10 +87,7 @@ class _CurrentTempState extends State { children: [ Text( 'Current Temperature', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.grey), + style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), ), const SizedBox( height: 5, @@ -100,14 +95,8 @@ class _CurrentTempState extends State { Row( children: [ Text( - (widget.currentTemp > 99 - ? widget.currentTemp / 10 - : widget.currentTemp) - .toString(), - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.grey), + (widget.currentTemp > 99 ? widget.currentTemp / 10 : widget.currentTemp).toString(), + style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), ), const CelsiusSymbol( color: Colors.grey, diff --git a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart index 0cf13036..05e82f1f 100644 --- a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart +++ b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart @@ -16,7 +16,7 @@ class DeviceManagementBloc int _onlineCount = 0; int _offlineCount = 0; int _lowBatteryCount = 0; - final List _selectedDevices = []; + List _selectedDevices = []; List _filteredDevices = []; String currentProductName = ''; String? currentCommunity; @@ -37,21 +37,20 @@ class DeviceManagementBloc FetchDevices event, Emitter emit) async { emit(DeviceManagementLoading()); try { - var devices = []; + List devices = []; _devices.clear(); - final spaceBloc = event.context.read(); - final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + var spaceBloc = event.context.read(); + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; if (spaceBloc.state.selectedCommunities.isEmpty) { - devices = - await DevicesManagementApi().fetchDevices('', '', projectUuid); + devices = await DevicesManagementApi().fetchDevices('', '', projectUuid); } else { - for (final community in spaceBloc.state.selectedCommunities) { - final spacesList = + for (var community in spaceBloc.state.selectedCommunities) { + List spacesList = spaceBloc.state.selectedCommunityAndSpaces[community] ?? []; - for (final space in spacesList) { - devices.addAll(await DevicesManagementApi() - .fetchDevices(community, space, projectUuid)); + for (var space in spacesList) { + devices.addAll(await DevicesManagementApi().fetchDevices( + community, space, projectUuid)); } } } @@ -74,7 +73,7 @@ class DeviceManagementBloc } } - Future _onFilterDevices( + void _onFilterDevices( FilterDevices event, Emitter emit) async { if (_devices.isNotEmpty) { _filteredDevices = List.from(_devices.where((device) { @@ -166,9 +165,9 @@ class DeviceManagementBloc _selectedDevices.add(event.selectedDevice); } - final clonedSelectedDevices = List.from(_selectedDevices); + List clonedSelectedDevices = List.from(_selectedDevices); - final isControlButtonEnabled = + bool isControlButtonEnabled = _checkIfControlButtonEnabled(clonedSelectedDevices); if (state is DeviceManagementLoaded) { @@ -198,8 +197,8 @@ class DeviceManagementBloc void _onUpdateSelection( UpdateSelection event, Emitter emit) { - final selectedDevices = []; - var devicesToSelectFrom = []; + List selectedDevices = []; + List devicesToSelectFrom = []; if (state is DeviceManagementLoaded) { devicesToSelectFrom = (state as DeviceManagementLoaded).devices; @@ -207,7 +206,7 @@ class DeviceManagementBloc devicesToSelectFrom = (state as DeviceManagementFiltered).filteredDevices; } - for (var i = 0; i < event.selectedRows.length; i++) { + for (int i = 0; i < event.selectedRows.length; i++) { if (event.selectedRows[i]) { selectedDevices.add(devicesToSelectFrom[i]); } @@ -295,7 +294,7 @@ class DeviceManagementBloc currentCommunity = event.community; currentUnitName = event.unitName; - final devicesToSearch = _filteredDevices; + List devicesToSearch = _filteredDevices; if (devicesToSearch.isNotEmpty) { final filteredDevices = devicesToSearch.where((device) { diff --git a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart index 25a8342b..5586a310 100644 --- a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart +++ b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart @@ -18,7 +18,6 @@ import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dar import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart'; import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart'; -import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart'; import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart'; import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart'; @@ -40,6 +39,8 @@ import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heate import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_control_view.dart'; +import '../../one_g_glass_switch/view/one_gang_glass_switch_control_view.dart'; + mixin RouteControlsBasedCode { Widget routeControlsWidgets({required AllDevicesModel device}) { switch (device.productType) { @@ -106,7 +107,7 @@ mixin RouteControlsBasedCode { case 'SOS': return SosDeviceControlsView(device: device); - case 'NCPS': + case 'NCPS': return FlushMountedPresenceSensorControlView(device: device); default: return const SizedBox(); @@ -131,133 +132,76 @@ mixin RouteControlsBasedCode { switch (devices.first.productType) { case '1G': return WallLightBatchControlView( - deviceIds: devices - .where((e) => e.productType == '1G') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == '1G')).map((e) => e.uuid!).toList(), ); case '2G': return TwoGangBatchControlView( - deviceIds: devices - .where((e) => e.productType == '2G') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == '2G')).map((e) => e.uuid!).toList(), ); case '3G': return LivingRoomBatchControlsView( - deviceIds: devices - .where((e) => e.productType == '3G') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == '3G')).map((e) => e.uuid!).toList(), ); case '1GT': return OneGangGlassSwitchBatchControlView( - deviceIds: devices - .where((e) => e.productType == '1GT') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == '1GT')).map((e) => e.uuid!).toList(), ); case '2GT': return TwoGangGlassSwitchBatchControlView( - deviceIds: devices - .where((e) => e.productType == '2GT') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == '2GT')).map((e) => e.uuid!).toList(), ); case '3GT': return ThreeGangGlassSwitchBatchControlView( - deviceIds: devices - .where((e) => e.productType == '3GT') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == '3GT')).map((e) => e.uuid!).toList(), ); case 'GW': return GatewayBatchControlView( - gatewayIds: devices - .where((e) => e.productType == 'GW') - .map((e) => e.uuid!) - .toList(), + gatewayIds: devices.where((e) => (e.productType == 'GW')).map((e) => e.uuid!).toList(), ); case 'DL': return DoorLockBatchControlView( - devicesIds: devices - .where((e) => e.productType == 'DL') - .map((e) => e.uuid!) - .toList()); + devicesIds: devices.where((e) => (e.productType == 'DL')).map((e) => e.uuid!).toList()); case 'WPS': return WallSensorBatchControlView( - devicesIds: devices - .where((e) => e.productType == 'WPS') - .map((e) => e.uuid!) - .toList()); + devicesIds: devices.where((e) => (e.productType == 'WPS')).map((e) => e.uuid!).toList()); case 'CPS': return CeilingSensorBatchControlView( - devicesIds: devices - .where((e) => e.productType == 'CPS') - .map((e) => e.uuid!) - .toList(), + devicesIds: devices.where((e) => (e.productType == 'CPS')).map((e) => e.uuid!).toList(), ); case 'CUR': return CurtainBatchStatusView( - devicesIds: devices - .where((e) => e.productType == 'CUR') - .map((e) => e.uuid!) - .toList(), + devicesIds: devices.where((e) => (e.productType == 'CUR')).map((e) => e.uuid!).toList(), ); case 'AC': return AcDeviceBatchControlView( - devicesIds: devices - .where((e) => e.productType == 'AC') - .map((e) => e.uuid!) - .toList()); + devicesIds: devices.where((e) => (e.productType == 'AC')).map((e) => e.uuid!).toList()); case 'WH': return WaterHEaterBatchControlView( - deviceIds: devices - .where((e) => e.productType == 'WH') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == 'WH')).map((e) => e.uuid!).toList(), ); case 'DS': return MainDoorSensorBatchView( - devicesIds: devices - .where((e) => e.productType == 'DS') - .map((e) => e.uuid!) - .toList(), + devicesIds: devices.where((e) => (e.productType == 'DS')).map((e) => e.uuid!).toList(), ); case 'GD': return GarageDoorBatchControlView( - deviceIds: devices - .where((e) => e.productType == 'GD') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == 'GD')).map((e) => e.uuid!).toList(), ); case 'WL': return WaterLeakBatchControlView( - deviceIds: devices - .where((e) => e.productType == 'WL') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == 'WL')).map((e) => e.uuid!).toList(), ); case 'PC': return PowerClampBatchControlView( - deviceIds: devices - .where((e) => e.productType == 'PC') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == 'PC')).map((e) => e.uuid!).toList(), ); case 'SOS': return SOSBatchControlView( - deviceIds: devices - .where((e) => e.productType == 'SOS') - .map((e) => e.uuid!) - .toList(), + deviceIds: devices.where((e) => (e.productType == 'SOS')).map((e) => e.uuid!).toList(), ); case 'NCPS': return FlushMountedPresenceSensorBatchControlView( - devicesIds: devices - .where((e) => e.productType == 'NCPS') - .map((e) => e.uuid!) - .toList(), + devicesIds: devices.where((e) => (e.productType == 'NCPS')).map((e) => e.uuid!).toList(), ); default: return const SizedBox(); diff --git a/lib/pages/device_managment/all_devices/models/device_sub_space.dart b/lib/pages/device_managment/all_devices/models/device_sub_space.dart index bf94524b..96195f76 100644 --- a/lib/pages/device_managment/all_devices/models/device_sub_space.dart +++ b/lib/pages/device_managment/all_devices/models/device_sub_space.dart @@ -5,12 +5,7 @@ class DeviceSubSpace { String? subspaceName; bool? disabled; - DeviceSubSpace( - {this.id, - this.createdAt, - this.updatedAt, - this.subspaceName, - this.disabled}); + DeviceSubSpace({this.id, this.createdAt, this.updatedAt, this.subspaceName, this.disabled}); DeviceSubSpace.fromJson(Map json) { id = json['uuid']?.toString() ?? ''; diff --git a/lib/pages/device_managment/all_devices/models/devices_model.dart b/lib/pages/device_managment/all_devices/models/devices_model.dart index a14b14d3..808a683f 100644 --- a/lib/pages/device_managment/all_devices/models/devices_model.dart +++ b/lib/pages/device_managment/all_devices/models/devices_model.dart @@ -212,8 +212,8 @@ PC SOS */ - final type = devicesTypesMap[productType] ?? DeviceType.Other; - var tempIcon = ''; + DeviceType type = devicesTypesMap[productType] ?? DeviceType.Other; + String tempIcon = ''; if (type == DeviceType.LightBulb) { tempIcon = Assets.lightBulb; } else if (type == DeviceType.CeilingSensor || @@ -441,9 +441,13 @@ SOS VoltageCStatusFunction( deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), CurrentCStatusFunction( - deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), + deviceId: uuid ?? '', + deviceName: name ?? '', + type: 'IF'), PowerFactorCStatusFunction( - deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), + deviceId: uuid ?? '', + deviceName: name ?? '', + type: 'IF'), ]; default: @@ -561,23 +565,23 @@ SOS } Map devicesTypesMap = { - 'AC': DeviceType.AC, - 'GW': DeviceType.Gateway, - 'CPS': DeviceType.CeilingSensor, - 'DL': DeviceType.DoorLock, - 'WPS': DeviceType.WallSensor, - '3G': DeviceType.ThreeGang, - '2G': DeviceType.TwoGang, - '1G': DeviceType.OneGang, - 'CUR': DeviceType.Curtain, - 'WH': DeviceType.WH, - 'DS': DeviceType.DS, - '1GT': DeviceType.OneTouch, - '2GT': DeviceType.TowTouch, - '3GT': DeviceType.ThreeTouch, - 'GD': DeviceType.GarageDoor, - 'WL': DeviceType.WaterLeak, - 'NCPS': DeviceType.NCPS, - 'PC': DeviceType.PC, + "AC": DeviceType.AC, + "GW": DeviceType.Gateway, + "CPS": DeviceType.CeilingSensor, + "DL": DeviceType.DoorLock, + "WPS": DeviceType.WallSensor, + "3G": DeviceType.ThreeGang, + "2G": DeviceType.TwoGang, + "1G": DeviceType.OneGang, + "CUR": DeviceType.Curtain, + "WH": DeviceType.WH, + "DS": DeviceType.DS, + "1GT": DeviceType.OneTouch, + "2GT": DeviceType.TowTouch, + "3GT": DeviceType.ThreeTouch, + "GD": DeviceType.GarageDoor, + "WL": DeviceType.WaterLeak, + "NCPS": DeviceType.NCPS, + "PC": DeviceType.PC, }; } diff --git a/lib/pages/device_managment/all_devices/models/factory_reset_model.dart b/lib/pages/device_managment/all_devices/models/factory_reset_model.dart index decfa05f..1b5685a1 100644 --- a/lib/pages/device_managment/all_devices/models/factory_reset_model.dart +++ b/lib/pages/device_managment/all_devices/models/factory_reset_model.dart @@ -6,13 +6,13 @@ class FactoryResetModel { FactoryResetModel({ required this.devicesUuid, - this.operationType = 'RESET', + this.operationType = "RESET", }); factory FactoryResetModel.fromJson(Map json) { return FactoryResetModel( devicesUuid: List.from(json['devicesUuid']), - operationType: 'RESET', + operationType: "RESET", ); } @@ -58,3 +58,4 @@ class FactoryResetModel { @override int get hashCode => devicesUuid.hashCode; } + diff --git a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart index abd06cd0..f4baad0c 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart @@ -24,13 +24,13 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - var devicesToShow = []; - var selectedIndex = 0; - var onlineCount = 0; - var offlineCount = 0; - var lowBatteryCount = 0; - var isControlButtonEnabled = false; - var selectedDevices = []; + List devicesToShow = []; + int selectedIndex = 0; + int onlineCount = 0; + int offlineCount = 0; + int lowBatteryCount = 0; + bool isControlButtonEnabled = false; + List selectedDevices = []; if (state is DeviceManagementLoaded) { devicesToShow = state.devices; @@ -194,23 +194,18 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { device.name ?? '', device.productName ?? '', device.uuid ?? '', - if (device.spaces != null && - device.spaces!.isNotEmpty) - device.spaces![0].spaceName - else - '', + (device.spaces != null && + device.spaces!.isNotEmpty) + ? device.spaces![0].spaceName + : '', combinedSpaceNames, - if (device.batteryLevel != null) - '${device.batteryLevel}%' - else - '-', + device.batteryLevel != null + ? '${device.batteryLevel}%' + : '-', formatDateTime( DateTime.fromMillisecondsSinceEpoch( (device.createTime ?? 0) * 1000)), - if (device.online == true) - 'Online' - else - 'Offline', + device.online == true ? 'Online' : 'Offline', formatDateTime( DateTime.fromMillisecondsSinceEpoch( (device.updateTime ?? 0) * 1000)), @@ -248,7 +243,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { showGeneralDialog( context: context, barrierDismissible: true, - barrierLabel: 'Device Settings', + barrierLabel: "Device Settings", transitionDuration: const Duration(milliseconds: 300), pageBuilder: (context, anim1, anim2) { return Align( diff --git a/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart b/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart index 99378a86..6440d18f 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_search_filters.dart @@ -33,9 +33,9 @@ class _DeviceSearchFiltersState extends State spacing: 20, runSpacing: 10, children: [ - _buildSearchField('Space Name', _unitNameController, 200), + _buildSearchField("Space Name", _unitNameController, 200), _buildSearchField( - 'Device Name / Product Name', _productNameController, 300), + "Device Name / Product Name", _productNameController, 300), _buildSearchResetButtons(), ], ); diff --git a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart index 0d5e59b2..42387e57 100644 --- a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart +++ b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart @@ -37,8 +37,7 @@ class CeilingSensorBloc extends Bloc { ) async { emit(CeilingLoadingInitialState()); try { - final response = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final response = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); _listenToChanges(event.deviceId); @@ -55,12 +54,11 @@ class CeilingSensorBloc extends Bloc { stream.listen((DatabaseEvent event) { if (event.snapshot.value == null) return; - final usersMap = event.snapshot.value! as Map; + final usersMap = event.snapshot.value as Map; final statusList = []; usersMap['status'].forEach((element) { - statusList - .add(Status(code: element['code'], value: element['value'])); + statusList.add(Status(code: element['code'], value: element['value'])); }); deviceStatus = CeilingSensorModel.fromJson(statusList); @@ -180,8 +178,7 @@ class CeilingSensorBloc extends Bloc { ) async { emit(CeilingLoadingInitialState()); try { - final response = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final response = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); } catch (e) { diff --git a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart index e296e1b9..1dc7d8d7 100644 --- a/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart +++ b/lib/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart @@ -85,6 +85,8 @@ class CeilingFactoryResetEvent extends CeilingSensorEvent { List get props => [devicesId, factoryResetModel]; } + + class StatusUpdated extends CeilingSensorEvent { final CeilingSensorModel deviceStatus; const StatusUpdated(this.deviceStatus); diff --git a/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart b/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart index c05b4e09..08a65a11 100644 --- a/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart +++ b/lib/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart @@ -26,53 +26,48 @@ class CeilingSensorModel { }); factory CeilingSensorModel.fromJson(List jsonList) { - late var presenceState = 'none'; - late var sensitivity = 1; - late var checkingResult = ''; - var presenceRange = 1; - var sportsPara = 1; - var bodyMovement = 'none'; - var noBodyTime = 'none'; - var maxDis = 0; - var spaceType = SpaceTypes.none; + late String _presenceState = 'none'; + late int _sensitivity = 1; + late String _checkingResult = ''; + int _presenceRange = 1; + int _sportsPara = 1; + String _bodyMovement = 'none'; + String _noBodyTime = 'none'; + int _maxDis = 0; + SpaceTypes _spaceType = SpaceTypes.none; try { - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'presence_state': - presenceState = status.value ?? 'none'; + _presenceState = status.value ?? 'none'; break; case 'scene': - spaceType = getSpaceType(status.value ?? 'none'); + _spaceType = getSpaceType(status.value ?? 'none'); break; case 'sensitivity': - sensitivity = status.value is int - ? status.value - : int.tryParse(status.value ?? '1') ?? 1; + _sensitivity = + status.value is int ? status.value : int.tryParse(status.value ?? '1') ?? 1; break; case 'checking_result': - checkingResult = status.value ?? ''; + _checkingResult = status.value ?? ''; break; case 'presence_range': - presenceRange = status.value is int - ? status.value - : int.tryParse(status.value ?? '0') ?? 0; + _presenceRange = + status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0; break; case 'sports_para': - sportsPara = status.value is int - ? status.value - : int.tryParse(status.value ?? '0') ?? 0; + _sportsPara = + status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0; break; case 'body_movement': - bodyMovement = status.value ?? ''; + _bodyMovement = status.value ?? ''; break; case 'nobody_time': - noBodyTime = status.value ?? 'none'; + _noBodyTime = status.value ?? 'none'; break; case 'moving_max_dis': - maxDis = status.value is int - ? status.value - : int.tryParse(status.value ?? '0') ?? 0; + _maxDis = status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0; break; } } @@ -81,15 +76,15 @@ class CeilingSensorModel { } return CeilingSensorModel( - presenceState: presenceState, - sensitivity: sensitivity, - checkingResult: checkingResult, - presenceRange: presenceRange, - sportsPara: sportsPara, - bodyMovement: bodyMovement, - noBodyTime: noBodyTime, - maxDistance: maxDis, - spaceType: spaceType, + presenceState: _presenceState, + sensitivity: _sensitivity, + checkingResult: _checkingResult, + presenceRange: _presenceRange, + sportsPara: _sportsPara, + bodyMovement: _bodyMovement, + noBodyTime: _noBodyTime, + maxDistance: _maxDis, + spaceType: _spaceType, ); } diff --git a/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart b/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart index 3f57e7a1..9b5ab360 100644 --- a/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart +++ b/lib/pages/device_managment/ceiling_sensor/view/ceiling_sensor_batch_control.dart @@ -12,8 +12,7 @@ import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presen import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class CeilingSensorBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class CeilingSensorBatchControlView extends StatelessWidget with HelperResponsiveLayout { const CeilingSensorBatchControlView({super.key, required this.devicesIds}); final List devicesIds; @@ -29,12 +28,11 @@ class CeilingSensorBatchControlView extends StatelessWidget )..add(CeilingFetchDeviceStatusEvent(devicesIds)), child: BlocBuilder( builder: (context, state) { - if (state is CeilingLoadingInitialState || - state is CeilingReportsLoadingState) { + if (state is CeilingLoadingInitialState || state is CeilingReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is CeilingUpdateState) { - return _buildGridView(context, state.ceilingSensorModel, - isExtraLarge, isLarge, isMedium); + return _buildGridView( + context, state.ceilingSensorModel, isExtraLarge, isLarge, isMedium); } return const Center(child: Text('Error fetching status')); }, @@ -42,8 +40,8 @@ class CeilingSensorBatchControlView extends StatelessWidget ); } - Widget _buildGridView(BuildContext context, CeilingSensorModel model, - bool isExtraLarge, bool isLarge, bool isMedium) { + Widget _buildGridView(BuildContext context, CeilingSensorModel model, bool isExtraLarge, + bool isLarge, bool isMedium) { return GridView( padding: const EdgeInsets.symmetric(horizontal: 50), shrinkWrap: true, @@ -118,8 +116,7 @@ class CeilingSensorBatchControlView extends StatelessWidget context.read().add( CeilingFactoryResetEvent( devicesId: devicesIds.first, - factoryResetModel: - FactoryResetModel(devicesUuid: devicesIds), + factoryResetModel: FactoryResetModel(devicesUuid: devicesIds), ), ); }, diff --git a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart index f75ff8b4..749a7729 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_bloc.dart @@ -34,8 +34,7 @@ class CurtainBloc extends Bloc { ) async { emit(CurtainStatusLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(event.deviceId, emit); deviceStatus = _checkStatus(status.status[0].value); emit(CurtainStatusLoaded(deviceStatus)); @@ -55,7 +54,7 @@ class CurtainBloc extends Bloc { final statusList = []; if (data['status'] != null) { - for (final element in data['status']) { + for (var element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -122,8 +121,7 @@ class CurtainBloc extends Bloc { ) async { emit(CurtainStatusLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = _checkStatus(status.status[0].value); emit(CurtainStatusLoaded(deviceStatus)); } catch (e) { diff --git a/lib/pages/device_managment/curtain/bloc/curtain_event.dart b/lib/pages/device_managment/curtain/bloc/curtain_event.dart index d8c85ccd..dd6700f9 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_event.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_event.dart @@ -60,8 +60,7 @@ class CurtainFactoryReset extends CurtainEvent { @override List get props => [deviceId, factoryReset]; } - class StatusUpdated extends CurtainEvent { final bool deviceStatus; const StatusUpdated(this.deviceStatus); -} +} \ No newline at end of file diff --git a/lib/pages/device_managment/curtain/bloc/curtain_state.dart b/lib/pages/device_managment/curtain/bloc/curtain_state.dart index 72d974f1..dfe11c2a 100644 --- a/lib/pages/device_managment/curtain/bloc/curtain_state.dart +++ b/lib/pages/device_managment/curtain/bloc/curtain_state.dart @@ -1,6 +1,7 @@ + import 'package:equatable/equatable.dart'; -sealed class CurtainState extends Equatable { +sealed class CurtainState extends Equatable { const CurtainState(); @override diff --git a/lib/pages/device_managment/curtain/model/curtain_model.dart b/lib/pages/device_managment/curtain/model/curtain_model.dart index 0a400c38..908415d5 100644 --- a/lib/pages/device_managment/curtain/model/curtain_model.dart +++ b/lib/pages/device_managment/curtain/model/curtain_model.dart @@ -12,8 +12,8 @@ class CurtainModel { }); factory CurtainModel.fromJson(dynamic json) { - final statusList = json['status'] as List; - final status = statusList.map((i) => Status.fromJson(i)).toList(); + var statusList = json['status'] as List; + List status = statusList.map((i) => Status.fromJson(i)).toList(); return CurtainModel( productUuid: json['productUuid'], diff --git a/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart b/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart index ccb9613d..41dcaf9e 100644 --- a/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart +++ b/lib/pages/device_managment/curtain/view/curtain_batch_status_view.dart @@ -10,8 +10,7 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class CurtainBatchStatusView extends StatelessWidget - with HelperResponsiveLayout { +class CurtainBatchStatusView extends StatelessWidget with HelperResponsiveLayout { const CurtainBatchStatusView({super.key, required this.devicesIds}); final List devicesIds; @@ -19,8 +18,8 @@ class CurtainBatchStatusView extends StatelessWidget @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => CurtainBlocFactory.create(deviceId: devicesIds.first) - ..add(CurtainFetchBatchStatus(devicesIds)), + create: (context) => + CurtainBlocFactory.create(deviceId: devicesIds.first)..add(CurtainFetchBatchStatus(devicesIds)), child: BlocBuilder( builder: (context, state) { if (state is CurtainStatusLoading) { diff --git a/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart b/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart index 73e31f89..c996cf72 100644 --- a/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart +++ b/lib/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart @@ -2,13 +2,12 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; -import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart'; +import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; - part 'setting_bloc_event.dart'; class SettingDeviceBloc extends Bloc { @@ -38,7 +37,7 @@ class SettingDeviceBloc extends Bloc { String? _fullNameValidator(String? value) { if (value == null) return 'name is required'; - final withoutExtraSpaces = value.replaceAll(RegExp(r'\s+'), ' ').trim(); + final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { return 'name must be between 2 and 30 characters long'; } @@ -67,8 +66,8 @@ class SettingDeviceBloc extends Bloc { DeviceSettingInitialInfo event, Emitter emit) async { try { emit(DeviceSettingsLoading()); - final response = await DevicesManagementApi.getDeviceInfo(deviceId); - final deviceInfo = DeviceInfoModel.fromJson(response); + var response = await DevicesManagementApi.getDeviceInfo(deviceId); + DeviceInfoModel deviceInfo = DeviceInfoModel.fromJson(response); nameController.text = deviceInfo.name; emit(DeviceSettingsUpdate( deviceName: nameController.text, @@ -93,7 +92,9 @@ class SettingDeviceBloc extends Bloc { )); editName = event.value!; if (editName) { - Future.delayed(const Duration(milliseconds: 500), focusNode.requestFocus); + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); } else { add(const SettingBlocSaveName()); focusNode.unfocus(); @@ -105,7 +106,7 @@ class SettingDeviceBloc extends Bloc { )); } - Future _deleteDevice( + void _deleteDevice( SettingBlocDeleteDevice event, Emitter emit) async { try { emit(DeviceSettingsLoading()); @@ -122,7 +123,7 @@ class SettingDeviceBloc extends Bloc { } } - Future _onAssignDevice( + void _onAssignDevice( SettingBlocAssignRoom event, Emitter emit) async { try { emit(DeviceSettingsLoading()); @@ -142,7 +143,7 @@ class SettingDeviceBloc extends Bloc { } } - Future _fetchRooms( + void _fetchRooms( SettingBlocFetchRooms event, Emitter emit) async { try { emit(DeviceSettingsLoading()); diff --git a/lib/pages/device_managment/device_setting/device_settings_panel.dart b/lib/pages/device_managment/device_setting/device_settings_panel.dart index cea5bea6..48458b3b 100644 --- a/lib/pages/device_managment/device_setting/device_settings_panel.dart +++ b/lib/pages/device_managment/device_setting/device_settings_panel.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; -import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart'; -import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/device_icon_type_helper.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/device_management_content.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/remove_device_widget.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart'; +import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart'; import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -38,7 +38,7 @@ class DeviceSettingsPanel extends StatelessWidget { builder: (context) { return BlocBuilder( builder: (context, state) { - final bloc = context.read(); + final _bloc = context.read(); final iconPath = DeviceIconTypeHelper.getDeviceIconByTypeCode( device.productType); final deviceInfo = state is DeviceSettingsUpdate @@ -73,7 +73,7 @@ class DeviceSettingsPanel extends StatelessWidget { .copyWith( fontWeight: FontWeight.w700, color: ColorsManager.vividBlue - .withValues(alpha: 0.7), + .withOpacity(0.7), fontSize: 24), ), ], @@ -87,8 +87,8 @@ class DeviceSettingsPanel extends StatelessWidget { padding: const EdgeInsets.only(left: 15), child: CircleAvatar( radius: 38, - backgroundColor: ColorsManager.grayBorder - .withValues(alpha: 0.5), + backgroundColor: + ColorsManager.grayBorder.withOpacity(0.5), child: CircleAvatar( backgroundColor: ColorsManager.whiteColors, radius: 36, @@ -128,14 +128,14 @@ class DeviceSettingsPanel extends StatelessWidget { fontSize: 16, ), textAlign: TextAlign.start, - focusNode: bloc.focusNode, - controller: bloc.nameController, - enabled: bloc.editName, + focusNode: _bloc.focusNode, + controller: _bloc.nameController, + enabled: _bloc.editName, onFieldSubmitted: (value) { - bloc.add(const ChangeNameEvent( + _bloc.add(const ChangeNameEvent( value: false)); }, - decoration: const InputDecoration( + decoration: InputDecoration( isDense: true, contentPadding: EdgeInsets.zero, border: InputBorder.none, @@ -151,11 +151,11 @@ class DeviceSettingsPanel extends StatelessWidget { height: 25, child: Visibility( visible: - bloc.editName != true, + _bloc.editName != true, replacement: const SizedBox(), child: InkWell( onTap: () { - bloc.add( + _bloc.add( const ChangeNameEvent( value: true)); }, @@ -192,14 +192,14 @@ class DeviceSettingsPanel extends StatelessWidget { deviceInfo: deviceInfo, ), const SizedBox(height: 32), - RemoveDeviceWidget(bloc: bloc), + RemoveDeviceWidget(bloc: _bloc), ], ), ), if (state is DeviceSettingsLoading) Positioned.fill( - child: ColoredBox( - color: Colors.black.withValues(alpha: 0.1), + child: Container( + color: Colors.black.withOpacity(0.1), child: const Center( child: CircularProgressIndicator( color: ColorsManager.primaryColor, diff --git a/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart b/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart index f4ab1cd0..9d3f4036 100644 --- a/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart +++ b/lib/pages/device_managment/device_setting/settings_model/sub_space_model.dart @@ -20,9 +20,9 @@ class SubSpaceModel { } factory SubSpaceModel.fromJson(Map json) { - final devices = []; + List devices = []; if (json['devices'] != null) { - for (final device in json['devices']) { + for (var device in json['devices']) { devices.add(DeviceModel.fromJson(device)); } } diff --git a/lib/pages/device_managment/device_setting/sub_space_dialog.dart b/lib/pages/device_managment/device_setting/sub_space_dialog.dart index 2b909a85..28350d4d 100644 --- a/lib/pages/device_managment/device_setting/sub_space_dialog.dart +++ b/lib/pages/device_managment/device_setting/sub_space_dialog.dart @@ -12,11 +12,11 @@ class SubSpaceDialog extends StatefulWidget { final void Function(SubSpaceModel?) onConfirmed; const SubSpaceDialog({ - super.key, + Key? key, required this.subSpaces, this.selected, required this.onConfirmed, - }); + }) : super(key: key); @override State createState() => _SubSpaceDialogState(); @@ -63,7 +63,7 @@ class _SubSpaceDialogState extends State { _selectedId = value; }); }, - activeColor: const Color(0xFF2962FF), + activeColor: Color(0xFF2962FF), title: Text( space.name ?? 'Unnamed Sub-Space', style: context.textTheme.bodyMedium?.copyWith( @@ -75,7 +75,7 @@ class _SubSpaceDialogState extends State { controlAffinity: ListTileControlAffinity.trailing, contentPadding: const EdgeInsets.symmetric(horizontal: 24), ); - }), + }).toList(), const SizedBox(height: 12), const Divider(height: 1, thickness: 1), SubSpaceDialogButtons(selectedId: _selectedId, widget: widget), diff --git a/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart b/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart index a42f4352..f83ced1a 100644 --- a/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart +++ b/lib/pages/device_managment/door_lock/bloc/door_lock_bloc.dart @@ -22,15 +22,17 @@ class DoorLockBloc extends Bloc { on(_onStatusUpdated); } - void _listenToChanges(deviceId) { + _listenToChanges(deviceId) { try { - final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; stream.listen((DatabaseEvent event) { - final usersMap = event.snapshot.value! as Map; + Map usersMap = + event.snapshot.value as Map; - final statusList = []; + List statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); diff --git a/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart b/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart index 8bbb3c03..39c4ca16 100644 --- a/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart +++ b/lib/pages/device_managment/door_lock/bloc/door_lock_state.dart @@ -1,3 +1,4 @@ + import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/device_managment/door_lock/models/door_lock_status_model.dart'; diff --git a/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart b/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart index 9dca688b..cda512c5 100644 --- a/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart +++ b/lib/pages/device_managment/door_lock/models/door_lock_status_model.dart @@ -60,7 +60,7 @@ class DoorLockStatusModel { late String remoteNoDpKey; late bool normalOpenSwitch; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'unlock_fingerprint': unlockFingerprint = status.value ?? 0; diff --git a/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart b/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart index e2d85df9..b28737fc 100644 --- a/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart +++ b/lib/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart @@ -7,8 +7,7 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class DoorLockBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class DoorLockBatchControlView extends StatelessWidget with HelperResponsiveLayout { const DoorLockBatchControlView({super.key, required this.devicesIds}); final List devicesIds; diff --git a/lib/pages/device_managment/door_lock/widget/door_button.dart b/lib/pages/device_managment/door_lock/widget/door_button.dart index 6bf8acf6..e8e3066e 100644 --- a/lib/pages/device_managment/door_lock/widget/door_button.dart +++ b/lib/pages/device_managment/door_lock/widget/door_button.dart @@ -90,7 +90,7 @@ class _DoorLockButtonState extends State shape: BoxShape.circle, boxShadow: [ BoxShadow( - color: Colors.grey.withValues(alpha: 0.5), + color: Colors.grey.withOpacity(0.5), blurRadius: 18, blurStyle: BlurStyle.outer, ), diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart index f4b933ae..aea800dd 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart @@ -15,8 +15,8 @@ import 'package:syncrow_web/services/devices_mang_api.dart'; part 'flush_mounted_presence_sensor_event.dart'; part 'flush_mounted_presence_sensor_state.dart'; -class FlushMountedPresenceSensorBloc extends Bloc< - FlushMountedPresenceSensorEvent, FlushMountedPresenceSensorState> { +class FlushMountedPresenceSensorBloc + extends Bloc { final String deviceId; final ControlDeviceService controlDeviceService; final BatchControlDevicesService batchControlDevicesService; @@ -54,7 +54,7 @@ class FlushMountedPresenceSensorBloc extends Bloc< ); } - Future _onFlushMountedPresenceSensorFetchStatusEvent( + void _onFlushMountedPresenceSensorFetchStatusEvent( FlushMountedPresenceSensorFetchStatusEvent event, Emitter emit, ) async { @@ -76,8 +76,7 @@ class FlushMountedPresenceSensorBloc extends Bloc< ) async { emit(FlushMountedPresenceSensorLoadingInitialState()); try { - final response = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final response = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = FlushMountedPresenceSensorModel.fromJson(response.status); emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); } catch (e) { @@ -92,9 +91,9 @@ class FlushMountedPresenceSensorBloc extends Bloc< ); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value! as Map; + final eventsMap = event.snapshot.value as Map; - final statusList = []; + List statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), @@ -114,7 +113,7 @@ class FlushMountedPresenceSensorBloc extends Bloc< } } - Future _onFlushMountedPresenceSensorChangeValueEvent( + void _onFlushMountedPresenceSensorChangeValueEvent( FlushMountedPresenceSensorChangeValueEvent event, Emitter emit, ) async { @@ -197,8 +196,7 @@ class FlushMountedPresenceSensorBloc extends Bloc< deviceReport: value, code: event.code)); }); } catch (e) { - emit(FlushMountedPresenceSensorDeviceReportsFailedState( - error: e.toString())); + emit(FlushMountedPresenceSensorDeviceReportsFailedState(error: e.toString())); return; } } diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart index e7fe8156..08a01615 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart @@ -59,8 +59,7 @@ class FlushMountedPresenceSensorGetDeviceReportsEvent class FlushMountedPresenceSensorShowDescriptionEvent extends FlushMountedPresenceSensorEvent { final String description; - const FlushMountedPresenceSensorShowDescriptionEvent( - {required this.description}); + const FlushMountedPresenceSensorShowDescriptionEvent({required this.description}); } class FlushMountedPresenceSensorBackToGridViewEvent diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart index e88a9ad8..0fef07f2 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart @@ -13,8 +13,7 @@ class FlushMountedPresenceSensorInitialState class FlushMountedPresenceSensorLoadingInitialState extends FlushMountedPresenceSensorState {} -class FlushMountedPresenceSensorUpdateState - extends FlushMountedPresenceSensorState { +class FlushMountedPresenceSensorUpdateState extends FlushMountedPresenceSensorState { final FlushMountedPresenceSensorModel model; const FlushMountedPresenceSensorUpdateState({required this.model}); @@ -31,8 +30,7 @@ class FlushMountedPresenceSensorLoadingNewSate List get props => [model]; } -class FlushMountedPresenceSensorFailedState - extends FlushMountedPresenceSensorState { +class FlushMountedPresenceSensorFailedState extends FlushMountedPresenceSensorState { final String error; const FlushMountedPresenceSensorFailedState({required this.error}); @@ -60,8 +58,7 @@ class FlushMountedPresenceSensorDeviceReportsState class FlushMountedPresenceSensorDeviceReportsFailedState extends FlushMountedPresenceSensorState { - const FlushMountedPresenceSensorDeviceReportsFailedState( - {required this.error}); + const FlushMountedPresenceSensorDeviceReportsFailedState({required this.error}); final String error; @@ -71,8 +68,7 @@ class FlushMountedPresenceSensorDeviceReportsFailedState class FlushMountedPresenceSensorShowDescriptionState extends FlushMountedPresenceSensorState { - const FlushMountedPresenceSensorShowDescriptionState( - {required this.description}); + const FlushMountedPresenceSensorShowDescriptionState({required this.description}); final String description; @override diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart index e1458dc9..e842f36b 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/factories/flush_mounted_presence_sensor_bloc_factory.dart @@ -9,10 +9,8 @@ abstract final class FlushMountedPresenceSensorBlocFactory { }) { return FlushMountedPresenceSensorBloc( deviceId: deviceId, - controlDeviceService: - DeviceBlocDependenciesFactory.createControlDeviceService(), - batchControlDevicesService: - DeviceBlocDependenciesFactory.createBatchControlDevicesService(), + controlDeviceService: DeviceBlocDependenciesFactory.createControlDeviceService(), + batchControlDevicesService: DeviceBlocDependenciesFactory.createBatchControlDevicesService(), ); } } diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart index 106a9942..bf97005d 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart @@ -37,18 +37,18 @@ class FlushMountedPresenceSensorModel { int sensiReduce; factory FlushMountedPresenceSensorModel.fromJson(List jsonList) { - var presenceState = 'none'; - var sensitivity = 0; - var nearDetection = 0; - var farDetection = 0; - var checkingResult = 'none'; - var presenceDelay = 0; - var noneDelay = 0; - var occurDistReduce = 0; - var illuminance = 0; - var sensiReduce = 0; + String presenceState = 'none'; + int sensitivity = 0; + int nearDetection = 0; + int farDetection = 0; + String checkingResult = 'none'; + int presenceDelay = 0; + int noneDelay = 0; + int occurDistReduce = 0; + int illuminance = 0; + int sensiReduce = 0; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case codePresenceState: presenceState = status.value ?? 'presence'; @@ -97,3 +97,7 @@ class FlushMountedPresenceSensorModel { ); } } + + + + diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart index 589b6b0e..2860e5cc 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_batch_control_view.dart @@ -66,14 +66,13 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget minValue: 0, maxValue: 9, steps: 1, - action: (int value) => - context.read().add( - FlushMountedPresenceSensorBatchControlEvent( - deviceIds: devicesIds, - code: FlushMountedPresenceSensorModel.codeSensitivity, - value: value, - ), - ), + action: (int value) => context.read().add( + FlushMountedPresenceSensorBatchControlEvent( + deviceIds: devicesIds, + code: FlushMountedPresenceSensorModel.codeSensitivity, + value: value, + ), + ), ), PresenceUpdateData( value: (model.nearDetection / 100).clamp(0.0, double.infinity), @@ -115,14 +114,13 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => - context.read().add( - FlushMountedPresenceSensorBatchControlEvent( - deviceIds: devicesIds, - code: FlushMountedPresenceSensorModel.codeSensiReduce, - value: value, - ), - ), + action: (int value) => context.read().add( + FlushMountedPresenceSensorBatchControlEvent( + deviceIds: devicesIds, + code: FlushMountedPresenceSensorModel.codeSensiReduce, + value: value, + ), + ), ), PresenceUpdateData( value: model.occurDistReduce.toDouble(), @@ -130,17 +128,16 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => - context.read().add( - FlushMountedPresenceSensorBatchControlEvent( - deviceIds: devicesIds, - code: FlushMountedPresenceSensorModel.codeOccurDistReduce, - value: value, - ), - ), + action: (int value) => context.read().add( + FlushMountedPresenceSensorBatchControlEvent( + deviceIds: devicesIds, + code: FlushMountedPresenceSensorModel.codeOccurDistReduce, + value: value, + ), + ), ), PresenceUpdateData( - value: model.presenceDelay / 10, + value: (model.presenceDelay / 10).toDouble(), title: 'Target Confirm Time:', description: 's', minValue: 0.0, @@ -157,7 +154,7 @@ class FlushMountedPresenceSensorBatchControlView extends StatelessWidget ), ), PresenceUpdateData( - value: model.noneDelay / 10, + value: ((model.noneDelay / 10).toDouble()), description: 's', title: 'Disappe Delay:', minValue: 20, diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart index 098dbb61..08ad809d 100644 --- a/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/views/flush_mounted_presence_sensor_control_view.dart @@ -15,8 +15,7 @@ import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_la class FlushMountedPresenceSensorControlView extends StatelessWidget with HelperResponsiveLayout { - const FlushMountedPresenceSensorControlView( - {required this.device, super.key}); + const FlushMountedPresenceSensorControlView({required this.device, super.key}); final AllDevicesModel device; @@ -38,9 +37,9 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget return ReportsTable( report: state.deviceReport, thirdColumnTitle: - state.code == 'illuminance_value' ? 'Value' : 'Status', + state.code == 'illuminance_value' ? "Value" : 'Status', thirdColumnDescription: - state.code == 'illuminance_value' ? 'Lux' : null, + state.code == 'illuminance_value' ? "Lux" : null, onRowTap: (index) {}, onClose: () { context @@ -57,8 +56,7 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget .add(FlushMountedPresenceSensorBackToGridViewEvent()); }, ); - } else if (state - is FlushMountedPresenceSensorDeviceReportsFailedState) { + } else if (state is FlushMountedPresenceSensorDeviceReportsFailedState) { final model = context.read().deviceStatus; return _buildGridView(context, model); @@ -107,13 +105,12 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget minValue: 0, maxValue: 9, steps: 1, - action: (int value) => - context.read().add( - FlushMountedPresenceSensorChangeValueEvent( - code: FlushMountedPresenceSensorModel.codeSensitivity, - value: value, - ), - ), + action: (int value) => context.read().add( + FlushMountedPresenceSensorChangeValueEvent( + code: FlushMountedPresenceSensorModel.codeSensitivity, + value: value, + ), + ), ), PresenceUpdateData( value: (model.nearDetection / 100).clamp(0.0, double.infinity), @@ -153,13 +150,12 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => - context.read().add( - FlushMountedPresenceSensorChangeValueEvent( - code: FlushMountedPresenceSensorModel.codeSensiReduce, - value: value, - ), - ), + action: (int value) => context.read().add( + FlushMountedPresenceSensorChangeValueEvent( + code: FlushMountedPresenceSensorModel.codeSensiReduce, + value: value, + ), + ), ), PresenceUpdateData( value: model.occurDistReduce.toDouble(), @@ -167,16 +163,15 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget minValue: 0, maxValue: 3, steps: 1, - action: (int value) => - context.read().add( - FlushMountedPresenceSensorChangeValueEvent( - code: FlushMountedPresenceSensorModel.codeOccurDistReduce, - value: value, - ), - ), + action: (int value) => context.read().add( + FlushMountedPresenceSensorChangeValueEvent( + code: FlushMountedPresenceSensorModel.codeOccurDistReduce, + value: value, + ), + ), ), PresenceUpdateData( - value: model.presenceDelay / 10, + value: (model.presenceDelay / 10).toDouble(), valuesPercision: 1, title: 'Target Confirm Time:', description: 's', @@ -192,7 +187,7 @@ class FlushMountedPresenceSensorControlView extends StatelessWidget ), ), PresenceUpdateData( - value: model.noneDelay / 10, + value: (model.noneDelay / 10).toDouble(), description: 's', title: 'Disappe Delay:', minValue: 20, diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart index 48fd146b..28a7e33b 100644 --- a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart +++ b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart @@ -2,6 +2,7 @@ import 'dart:async'; 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_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_state.dart'; @@ -41,15 +42,17 @@ class GarageDoorBloc extends Bloc { on(_onEditSchedule); on(_onStatusUpdated); } - void _listenToChanges(deviceId) { + _listenToChanges(deviceId) { try { - final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; stream.listen((DatabaseEvent event) { - final usersMap = event.snapshot.value! as Map; + Map usersMap = + event.snapshot.value as Map; - final statusList = []; + List statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); @@ -69,11 +72,11 @@ class GarageDoorBloc extends Bloc { emit(GarageDoorLoadedState(status: deviceStatus)); } - Future _fetchGarageDoorStatus( + void _fetchGarageDoorStatus( GarageDoorInitialEvent event, Emitter emit) async { emit(GarageDoorLoadingState()); try { - final response = + var response = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status); _listenToChanges(deviceId); @@ -100,13 +103,13 @@ class GarageDoorBloc extends Bloc { Future _addSchedule( AddGarageDoorScheduleEvent event, Emitter emit) async { try { - final newSchedule = ScheduleEntry( + ScheduleEntry newSchedule = ScheduleEntry( category: event.category, time: formatTimeOfDayToISO(event.time), function: Status(code: 'doorcontact_state', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - final success = + bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId); if (success) { add(FetchGarageDoorSchedulesEvent( @@ -153,7 +156,7 @@ class GarageDoorBloc extends Bloc { } return schedule; }).toList(); - final success = await DevicesManagementApi().updateScheduleRecord( + bool success = await DevicesManagementApi().updateScheduleRecord( enable: event.enable, uuid: deviceStatus.uuid, scheduleId: event.scheduleId, @@ -172,7 +175,7 @@ class GarageDoorBloc extends Bloc { Future _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter emit) async { try { - final success = await DevicesManagementApi() + bool success = await DevicesManagementApi() .deleteScheduleRecord(deviceStatus.uuid, event.scheduleId); if (success) { final updatedSchedules = deviceStatus.schedules @@ -192,7 +195,7 @@ class GarageDoorBloc extends Bloc { Emitter emit) async { emit(ScheduleGarageLoadingState()); try { - final schedules = await DevicesManagementApi() + List schedules = await DevicesManagementApi() .getDeviceSchedules(deviceStatus.uuid, event.category); deviceStatus = deviceStatus.copyWith(schedules: schedules); emit( @@ -223,7 +226,7 @@ class GarageDoorBloc extends Bloc { UpdateSelectedDayEvent event, Emitter emit) async { final currentState = state; if (currentState is GarageDoorLoadedState) { - final updatedDays = List.from(currentState.selectedDays); + List updatedDays = List.from(currentState.selectedDays); updatedDays[event.dayIndex] = event.isSelected; emit(currentState.copyWith( selectedDays: updatedDays, selectedTime: currentState.selectedTime)); @@ -261,8 +264,9 @@ class GarageDoorBloc extends Bloc { .subtract(const Duration(days: 30)) .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final records = await DevicesManagementApi.getDeviceReportsByDate( - event.deviceId, 'switch_1', from.toString(), to.toString()); + final DeviceReport records = + await DevicesManagementApi.getDeviceReportsByDate( + event.deviceId, 'switch_1', from.toString(), to.toString()); emit(GarageDoorReportsState(deviceReport: records)); } catch (e) { emit(GarageDoorReportsFailedState(error: e.toString())); @@ -348,12 +352,12 @@ class GarageDoorBloc extends Bloc { } } - Future _increaseDelay( + void _increaseDelay( IncreaseGarageDoorDelayEvent event, Emitter emit) async { // if (deviceStatus.countdown1 != 0) { try { deviceStatus = deviceStatus.copyWith( - delay: deviceStatus.delay + const Duration(minutes: 10)); + delay: deviceStatus.delay + Duration(minutes: 10)); emit(GarageDoorLoadedState(status: deviceStatus)); add(GarageDoorControlEvent( deviceId: deviceId, @@ -365,13 +369,13 @@ class GarageDoorBloc extends Bloc { // } } - Future _decreaseDelay( + void _decreaseDelay( DecreaseGarageDoorDelayEvent event, Emitter emit) async { // if (deviceStatus.countdown1 != 0) { try { if (deviceStatus.delay.inMinutes > 10) { deviceStatus = deviceStatus.copyWith( - delay: deviceStatus.delay - const Duration(minutes: 10)); + delay: deviceStatus.delay - Duration(minutes: 10)); } emit(GarageDoorLoadedState(status: deviceStatus)); add(GarageDoorControlEvent( @@ -384,7 +388,7 @@ class GarageDoorBloc extends Bloc { //} } - Future _garageDoorControlEvent( + void _garageDoorControlEvent( GarageDoorControlEvent event, Emitter emit) async { final oldValue = event.code == 'countdown_1' ? deviceStatus.countdown1 @@ -485,14 +489,14 @@ class GarageDoorBloc extends Bloc { FutureOr _onEditSchedule( EditGarageDoorScheduleEvent event, Emitter emit) async { try { - final newSchedule = ScheduleEntry( + ScheduleEntry newSchedule = ScheduleEntry( scheduleId: event.scheduleId, category: event.category, time: formatTimeOfDayToISO(event.time), function: Status(code: 'doorcontact_state', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - final success = await DevicesManagementApi() + bool success = await DevicesManagementApi() .editScheduleRecord(deviceId, newSchedule); if (success) { add(FetchGarageDoorSchedulesEvent( diff --git a/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart b/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart index 4600a685..7b133d45 100644 --- a/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart +++ b/lib/pages/device_managment/garage_door/helper/garage_door_helper.dart @@ -18,7 +18,7 @@ class GarageDoorDialogHelper { final bloc = context.read(); if (schedule == null) { - bloc.add(const UpdateSelectedTimeEvent(null)); + bloc.add((const UpdateSelectedTimeEvent(null))); bloc.add(InitializeAddScheduleEvent( selectedTime: null, selectedDays: List.filled(7, false), @@ -77,10 +77,9 @@ class GarageDoorDialogHelper { backgroundColor: ColorsManager.boxColor, borderRadius: 15, onPressed: () async { - final time = await showTimePicker( + TimeOfDay? time = await showTimePicker( context: context, - initialTime: - state.selectedTime ?? TimeOfDay.now(), + initialTime: state.selectedTime ?? TimeOfDay.now(), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( @@ -100,9 +99,7 @@ class GarageDoorDialogHelper { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - state.selectedTime == null - ? 'Time' - : state.selectedTime!.format(context), + state.selectedTime == null ? 'Time' : state.selectedTime!.format(context), style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.grayColor, ), @@ -117,8 +114,7 @@ class GarageDoorDialogHelper { ), ), const SizedBox(height: 16), - _buildDayCheckboxes(context, state.selectedDays, - isEdit: isEdit), + _buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit), const SizedBox(height: 16), _buildFunctionSwitch(context, state.functionOn, isEdit), ], @@ -192,9 +188,9 @@ class GarageDoorDialogHelper { static List _convertDaysStringToBooleans(List selectedDays) { final daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - final daysBoolean = List.filled(7, false); + List daysBoolean = List.filled(7, false); - for (var i = 0; i < daysOfWeek.length; i++) { + for (int i = 0; i < daysOfWeek.length; i++) { if (selectedDays.contains(daysOfWeek[i])) { daysBoolean[i] = true; } @@ -203,9 +199,7 @@ class GarageDoorDialogHelper { return daysBoolean; } - static Widget _buildDayCheckboxes( - BuildContext context, List selectedDays, - {bool? isEdit}) { + static Widget _buildDayCheckboxes(BuildContext context, List selectedDays, {bool? isEdit}) { final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; return Row( @@ -215,9 +209,7 @@ class GarageDoorDialogHelper { Checkbox( value: selectedDays[index], onChanged: (bool? value) { - context - .read() - .add(UpdateSelectedDayEvent(index, value!)); + context.read().add(UpdateSelectedDayEvent(index, value!)); }, ), Text(dayLabels[index]), @@ -227,23 +219,19 @@ class GarageDoorDialogHelper { ); } - static Widget _buildFunctionSwitch( - BuildContext context, bool isOn, bool? isEdit) { + static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) { return Row( children: [ Text( 'Function:', - style: context.textTheme.bodySmall! - .copyWith(color: ColorsManager.grayColor), + style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor), ), const SizedBox(width: 10), Radio( value: true, groupValue: isOn, onChanged: (bool? value) { - context - .read() - .add(const UpdateFunctionOnEvent(functionOn: true)); + context.read().add(const UpdateFunctionOnEvent(functionOn: true)); }, ), const Text('On'), @@ -252,9 +240,7 @@ class GarageDoorDialogHelper { value: false, groupValue: isOn, onChanged: (bool? value) { - context - .read() - .add(const UpdateFunctionOnEvent(functionOn: false)); + context.read().add(const UpdateFunctionOnEvent(functionOn: false)); }, ), const Text('Off'), @@ -311,17 +297,13 @@ class GarageDoorDialogHelper { alertBody: TimeOutAlarmDialogBody(bloc), title: 'Time Out Alarm', onConfirm: () { - final updatedState = - context.read().state; - if (updatedState - is GarageDoorLoadedState) { + final updatedState = context.read().state; + if (updatedState is GarageDoorLoadedState) { context.read().add( GarageDoorControlEvent( - deviceId: - updatedState.status.uuid, + deviceId: updatedState.status.uuid, code: 'countdown_alarm', - value: updatedState - .status.countdownAlarm, + value: updatedState.status.countdownAlarm, ), ); Navigator.pop(context); @@ -329,11 +311,8 @@ class GarageDoorDialogHelper { }); }, child: ToggleWidget( - icon: '-1', - value: state.status.doorState1 == - 'close_time_alarm' - ? false - : true, + icon: "-1", + value: state.status.doorState1 == "close_time_alarm" ? false : true, code: 'door_state_1', deviceId: bloc.deviceId, label: 'Alarm when door is open', @@ -342,10 +321,9 @@ class GarageDoorDialogHelper { GarageDoorControlEvent( deviceId: bloc.deviceId, code: 'door_state_1', - value: state.status.doorState1 == - 'close_time_alarm' - ? 'unclosed_time' - : 'close_time_alarm', + value: state.status.doorState1 == "close_time_alarm" + ? "unclosed_time" + : "close_time_alarm", ), ); }), @@ -370,17 +348,13 @@ class GarageDoorDialogHelper { ), title: 'Opening and Closing Time', onConfirm: () { - final updatedState = - context.read().state; - if (updatedState - is GarageDoorLoadedState) { + final updatedState = context.read().state; + if (updatedState is GarageDoorLoadedState) { context.read().add( GarageDoorControlEvent( - deviceId: - updatedState.status.uuid, + deviceId: updatedState.status.uuid, code: 'tr_timecon', - value: updatedState - .status.trTimeCon, + value: updatedState.status.trTimeCon, ), ); Navigator.pop(context); diff --git a/lib/pages/device_managment/garage_door/models/garage_door_model.dart b/lib/pages/device_managment/garage_door/models/garage_door_model.dart index 4c991a9f..60d37d9f 100644 --- a/lib/pages/device_managment/garage_door/models/garage_door_model.dart +++ b/lib/pages/device_managment/garage_door/models/garage_door_model.dart @@ -39,9 +39,9 @@ class GarageDoorStatusModel { late String doorControl1; late bool voiceControl1; late String doorState1; - final schedules = []; // Initialize schedules + List schedules = []; // Initialize schedules - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; diff --git a/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart b/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart index d21db9db..9b3159bb 100644 --- a/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart +++ b/lib/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart @@ -11,11 +11,10 @@ import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class GarageDoorBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class GarageDoorBatchControlView extends StatelessWidget with HelperResponsiveLayout { final List deviceIds; - const GarageDoorBatchControlView({super.key, required this.deviceIds}); + const GarageDoorBatchControlView({Key? key, required this.deviceIds}) : super(key: key); @override Widget build(BuildContext context) { @@ -38,8 +37,7 @@ class GarageDoorBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, GarageDoorStatusModel status) { + Widget _buildStatusControls(BuildContext context, GarageDoorStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart b/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart index 403beb85..843bac9b 100644 --- a/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart +++ b/lib/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart'; import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart'; @@ -7,8 +8,7 @@ class OpeningAndClosingTimeDialogBody extends StatefulWidget { final ValueChanged onDurationChanged; final GarageDoorBloc bloc; - const OpeningAndClosingTimeDialogBody({ - super.key, + OpeningAndClosingTimeDialogBody({ required this.onDurationChanged, required this.bloc, }); diff --git a/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart b/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart index 238b7ad7..07cd9c7a 100644 --- a/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart +++ b/lib/pages/device_managment/garage_door/widgets/schedule__garage_table.dart @@ -26,8 +26,7 @@ class ScheduleGarageTableWidget extends StatelessWidget { Table( border: TableBorder.all( color: ColorsManager.graysColor, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(20), topRight: Radius.circular(20)), + borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)), ), children: [ TableRow( @@ -51,21 +50,17 @@ class ScheduleGarageTableWidget extends StatelessWidget { BlocBuilder( builder: (context, state) { if (state is ScheduleGarageLoadingState) { - return const SizedBox( - height: 200, - child: Center(child: CircularProgressIndicator())); + return const SizedBox(height: 200, child: Center(child: CircularProgressIndicator())); } - if (state is GarageDoorLoadedState && - state.status.schedules?.isEmpty == true) { + if (state is GarageDoorLoadedState && state.status.schedules?.isEmpty == true) { return _buildEmptyState(context); } else if (state is GarageDoorLoadedState) { return Container( height: 200, decoration: BoxDecoration( border: Border.all(color: ColorsManager.graysColor), - borderRadius: const BorderRadius.only( - bottomLeft: Radius.circular(20), - bottomRight: Radius.circular(20)), + borderRadius: + const BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), ), child: _buildTableBody(state, context)); } @@ -83,8 +78,7 @@ class ScheduleGarageTableWidget extends StatelessWidget { height: 200, decoration: BoxDecoration( border: Border.all(color: ColorsManager.graysColor), - borderRadius: const BorderRadius.only( - bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), + borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), ), child: Center( child: Column( @@ -118,8 +112,7 @@ class ScheduleGarageTableWidget extends StatelessWidget { children: [ if (state.status.schedules != null) for (int i = 0; i < state.status.schedules!.length; i++) - _buildScheduleRow( - state.status.schedules![i], i, context, state), + _buildScheduleRow(state.status.schedules![i], i, context, state), ], ), ), @@ -141,8 +134,7 @@ class ScheduleGarageTableWidget extends StatelessWidget { ); } - TableRow _buildScheduleRow(ScheduleModel schedule, int index, - BuildContext context, GarageDoorLoadedState state) { + TableRow _buildScheduleRow(ScheduleModel schedule, int index, BuildContext context, GarageDoorLoadedState state) { return TableRow( children: [ Center( @@ -160,8 +152,7 @@ class ScheduleGarageTableWidget extends StatelessWidget { width: 24, height: 24, child: schedule.enable - ? const Icon(Icons.radio_button_checked, - color: ColorsManager.blueColor) + ? const Icon(Icons.radio_button_checked, color: ColorsManager.blueColor) : const Icon( Icons.radio_button_unchecked, color: ColorsManager.grayColor, @@ -169,9 +160,7 @@ class ScheduleGarageTableWidget extends StatelessWidget { ), ), ), - Center( - child: Text(_getSelectedDays( - ScheduleModel.parseSelectedDays(schedule.days)))), + Center(child: Text(_getSelectedDays(ScheduleModel.parseSelectedDays(schedule.days)))), Center(child: Text(formatIsoStringToTime(schedule.time, context))), Center(child: Text(schedule.function.value ? 'On' : 'Off')), Center( @@ -181,24 +170,18 @@ class ScheduleGarageTableWidget extends StatelessWidget { TextButton( style: TextButton.styleFrom(padding: EdgeInsets.zero), onPressed: () { - GarageDoorDialogHelper.showAddGarageDoorScheduleDialog( - context, - schedule: schedule, - index: index, - isEdit: true); + GarageDoorDialogHelper.showAddGarageDoorScheduleDialog(context, + schedule: schedule, index: index, isEdit: true); }, child: Text( 'Edit', - style: context.textTheme.bodySmall! - .copyWith(color: ColorsManager.blueColor), + style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blueColor), ), ), TextButton( style: TextButton.styleFrom(padding: EdgeInsets.zero), onPressed: () { - context - .read() - .add(DeleteGarageDoorScheduleEvent( + context.read().add(DeleteGarageDoorScheduleEvent( index: index, scheduleId: schedule.scheduleId, deviceId: state.status.uuid, @@ -206,8 +189,7 @@ class ScheduleGarageTableWidget extends StatelessWidget { }, child: Text( 'Delete', - style: context.textTheme.bodySmall! - .copyWith(color: ColorsManager.blueColor), + style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blueColor), ), ), ], @@ -219,8 +201,8 @@ class ScheduleGarageTableWidget extends StatelessWidget { String _getSelectedDays(List selectedDays) { final days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - final selectedDaysStr = []; - for (var i = 0; i < selectedDays.length; i++) { + List selectedDaysStr = []; + for (int i = 0; i < selectedDays.length; i++) { if (selectedDays[i]) { selectedDaysStr.add(days[i]); } diff --git a/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart b/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart index 786b3fa6..e5819e89 100644 --- a/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart +++ b/lib/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart @@ -28,7 +28,7 @@ class ScheduleGarageManagementUI extends StatelessWidget { padding: 2, backgroundColor: ColorsManager.graysColor, borderRadius: 15, - onPressed: onAddSchedule, + onPressed: () => onAddSchedule(), child: Row( children: [ const Icon(Icons.add, color: ColorsManager.primaryColor), diff --git a/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart b/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart index 3f8939dd..7b6e4690 100644 --- a/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart +++ b/lib/pages/device_managment/garage_door/widgets/schedule_garage_mode_selector.dart @@ -35,8 +35,7 @@ class ScheduleGarageDoorModeSelector extends StatelessWidget { ); } - Widget _buildRadioTile(BuildContext context, String label, ScheduleModes mode, - GarageDoorLoadedState state) { + Widget _buildRadioTile(BuildContext context, String label, ScheduleModes mode, GarageDoorLoadedState state) { return Flexible( child: ListTile( contentPadding: EdgeInsets.zero, diff --git a/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart b/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart index f2805d39..491be37b 100644 --- a/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart +++ b/lib/pages/device_managment/garage_door/widgets/seconds_picker.dart @@ -4,8 +4,7 @@ class SecondsPicker extends StatefulWidget { final int initialSeconds; final ValueChanged onSecondsChanged; - const SecondsPicker({ - super.key, + SecondsPicker({ required this.initialSeconds, required this.onSecondsChanged, }); diff --git a/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart b/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart index 2eff275d..541ab9e4 100644 --- a/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart +++ b/lib/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart @@ -5,7 +5,7 @@ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart'; class TimeOutAlarmDialogBody extends StatefulWidget { - const TimeOutAlarmDialogBody(this.bloc, {super.key}); + TimeOutAlarmDialogBody(this.bloc); final GarageDoorBloc bloc; @override diff --git a/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart b/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart index 66c33fbe..e14672ae 100644 --- a/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart +++ b/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart @@ -16,12 +16,10 @@ class GateWayBloc extends Bloc { on(_onFactoryReset); } - FutureOr _getGatWayById( - GatWayById event, Emitter emit) async { + FutureOr _getGatWayById(GatWayById event, Emitter emit) async { emit(GatewayLoadingState()); try { - final devicesList = - await DevicesManagementApi.getDevicesByGatewayId(event.getWayId); + List devicesList = await DevicesManagementApi.getDevicesByGatewayId(event.getWayId); emit(UpdateGatewayState(list: devicesList)); } catch (e) { @@ -30,8 +28,7 @@ class GateWayBloc extends Bloc { } } - FutureOr _onFactoryReset( - GateWayFactoryReset event, Emitter emit) async { + FutureOr _onFactoryReset(GateWayFactoryReset event, Emitter emit) async { emit(GatewayLoadingState()); try { final response = await DevicesManagementApi().factoryReset( diff --git a/lib/pages/device_managment/gateway/view/gateway_batch_control.dart b/lib/pages/device_managment/gateway/view/gateway_batch_control.dart index a9fe13ba..f3a08a18 100644 --- a/lib/pages/device_managment/gateway/view/gateway_batch_control.dart +++ b/lib/pages/device_managment/gateway/view/gateway_batch_control.dart @@ -6,8 +6,7 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class GatewayBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class GatewayBatchControlView extends StatelessWidget with HelperResponsiveLayout { const GatewayBatchControlView({super.key, required this.gatewayIds}); final List gatewayIds; @@ -39,8 +38,7 @@ class GatewayBatchControlView extends StatelessWidget context.read().add( GateWayFactoryReset( deviceId: gatewayIds.first, - factoryReset: - FactoryResetModel(devicesUuid: gatewayIds), + factoryReset: FactoryResetModel(devicesUuid: gatewayIds), ), ); }, diff --git a/lib/pages/device_managment/gateway/view/gateway_view.dart b/lib/pages/device_managment/gateway/view/gateway_view.dart index 8f5d0674..d674e4d8 100644 --- a/lib/pages/device_managment/gateway/view/gateway_view.dart +++ b/lib/pages/device_managment/gateway/view/gateway_view.dart @@ -37,21 +37,21 @@ class GateWayControlsView extends StatelessWidget with HelperResponsiveLayout { mainAxisSize: MainAxisSize.min, children: [ Text( - 'Bluetooth Devices:', + "Bluetooth Devices:", style: context.textTheme.bodyMedium!.copyWith( color: ColorsManager.grayColor, ), ), const SizedBox(height: 12), Text( - 'No devices found', + "No devices found", style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.blackColor, ), ), const SizedBox(height: 30), Text( - 'ZigBee Devices:', + "ZigBee Devices:", style: context.textTheme.bodyMedium!.copyWith( color: ColorsManager.grayColor, ), diff --git a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart index 1a2d0ab1..493e3037 100644 --- a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart +++ b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart @@ -159,15 +159,17 @@ class MainDoorSensorBloc } } - void _listenToChanges(deviceId) { + _listenToChanges(deviceId) { try { - final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; stream.listen((DatabaseEvent event) { - final usersMap = event.snapshot.value! as Map; + Map usersMap = + event.snapshot.value as Map; - final statusList = []; + List statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); diff --git a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart index 8dcc221a..569cfa11 100644 --- a/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart +++ b/lib/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart @@ -1,7 +1,8 @@ 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/main_door_sensor/models/main_door_status_model.dart'; +import '../../all_devices/models/factory_reset_model.dart'; + class MainDoorSensorEvent extends Equatable { @override List get props => []; @@ -74,7 +75,7 @@ class MainDoorSensorFactoryReset extends MainDoorSensorEvent { class StatusUpdated extends MainDoorSensorEvent { final MainDoorSensorStatusModel deviceStatus; - StatusUpdated(this.deviceStatus); + StatusUpdated(this.deviceStatus); @override List get props => [deviceStatus]; } diff --git a/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart b/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart index 65518938..52dda7a3 100644 --- a/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart +++ b/lib/pages/device_managment/main_door_sensor/models/main_door_status_model.dart @@ -12,10 +12,10 @@ class MainDoorSensorStatusModel { }); factory MainDoorSensorStatusModel.fromJson(String id, List jsonList) { - late var doorContactState = false; - late var batteryPercentage = 0; + late bool doorContactState = false; + late int batteryPercentage = 0; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'doorcontact_state': doorContactState = status.value ?? false; diff --git a/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart b/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart index 723cb2f0..ecdb367a 100644 --- a/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart +++ b/lib/pages/device_managment/main_door_sensor/view/main_door_control_view.dart @@ -12,8 +12,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class MainDoorSensorControlView extends StatelessWidget - with HelperResponsiveLayout { +class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLayout { const MainDoorSensorControlView({super.key, required this.device}); final AllDevicesModel device; @@ -21,12 +20,10 @@ class MainDoorSensorControlView extends StatelessWidget @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => MainDoorSensorBloc() - ..add(MainDoorSensorFetchDeviceEvent(device.uuid!)), + create: (context) => MainDoorSensorBloc()..add(MainDoorSensorFetchDeviceEvent(device.uuid!)), child: BlocBuilder( builder: (context, state) { - if (state is MainDoorSensorLoadingState || - state is MainDoorSensorReportsLoadingState) { + if (state is MainDoorSensorLoadingState || state is MainDoorSensorReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is MainDoorSensorDeviceStatusLoaded) { return _buildStatusControls(context, state.status); @@ -35,15 +32,12 @@ class MainDoorSensorControlView extends StatelessWidget report: state.deviceReport, onRowTap: (index) {}, onClose: () { - context - .read() - .add(MainDoorSensorFetchDeviceEvent(device.uuid!)); + context.read().add(MainDoorSensorFetchDeviceEvent(device.uuid!)); }, hideValueShowDescription: true, mainDoorSensor: true, ); - } else if (state is MainDoorSensorFailedState || - state is MainDoorSensorBatchFailedState) { + } else if (state is MainDoorSensorFailedState || state is MainDoorSensorBatchFailedState) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); @@ -52,8 +46,7 @@ class MainDoorSensorControlView extends StatelessWidget )); } - Widget _buildStatusControls( - BuildContext context, MainDoorSensorStatusModel status) { + Widget _buildStatusControls(BuildContext context, MainDoorSensorStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -78,9 +71,7 @@ class MainDoorSensorControlView extends StatelessWidget icon: Assets.openCloseDoor, onTap: () {}, status: status.doorContactState, - textColor: status.doorContactState - ? ColorsManager.red - : ColorsManager.blackColor, + textColor: status.doorContactState ? ColorsManager.red : ColorsManager.blackColor, paddingAmount: 8, ), IconNameStatusContainer( @@ -88,9 +79,7 @@ class MainDoorSensorControlView extends StatelessWidget name: 'Open/Close\nRecord', icon: Assets.openCloseRecords, onTap: () { - final from = DateTime.now() - .subtract(const Duration(days: 30)) - .millisecondsSinceEpoch; + final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; context.read().add( MainDoorSensorReportsEvent( diff --git a/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart b/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart index e14321dd..bbebabaa 100644 --- a/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart +++ b/lib/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart @@ -27,8 +27,7 @@ class MainDoorSensorBatchView extends StatelessWidget { BlocProvider.of(innerContext).add( MainDoorSensorFactoryReset( deviceId: devicesIds.first, - factoryReset: - FactoryResetModel(devicesUuid: devicesIds), + factoryReset: FactoryResetModel(devicesUuid: devicesIds), ), ); }, diff --git a/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart b/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart index 8e9cc8cd..ac66b315 100644 --- a/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart +++ b/lib/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart @@ -53,7 +53,7 @@ class _NotificationDialogState extends State { ), ), child: IconButton( - padding: const EdgeInsets.all(1), + padding: EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, diff --git a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart index 8de84264..c1e976ab 100644 --- a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart @@ -39,11 +39,9 @@ class OneGangGlassSwitchBloc ) async { emit(OneGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(event.deviceId, emit); - deviceStatus = - OneGangGlassStatusModel.fromJson(event.deviceId, status.status); + deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(OneGangGlassSwitchError(e.toString())); @@ -64,7 +62,7 @@ class OneGangGlassSwitchBloc final statusList = []; if (data['status'] != null) { - for (final element in data['status']) { + for (var element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -74,8 +72,7 @@ class OneGangGlassSwitchBloc } } if (statusList.isNotEmpty) { - final newStatus = - OneGangGlassStatusModel.fromJson(deviceId, statusList); + final newStatus = OneGangGlassStatusModel.fromJson(deviceId, statusList); if (newStatus != deviceStatus) { deviceStatus = newStatus; if (!isClosed) { @@ -143,10 +140,9 @@ class OneGangGlassSwitchBloc ) async { emit(OneGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = OneGangGlassStatusModel.fromJson( - event.deviceIds.first, status.status); + final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = + OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(OneGangGlassSwitchError(e.toString())); diff --git a/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart b/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart index dd8a1140..39c96dd0 100644 --- a/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart +++ b/lib/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart @@ -15,7 +15,7 @@ class OneGangGlassStatusModel { late bool switch1; late int countDown; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; @@ -46,6 +46,5 @@ class OneGangGlassStatusModel { } @override - String toString() => - 'OneGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown: $countDown)'; + String toString() => 'OneGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown: $countDown)'; } diff --git a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart index 5f88768a..307e61da 100644 --- a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart +++ b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart @@ -8,19 +8,16 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class OneGangGlassSwitchBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class OneGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout { final List deviceIds; - const OneGangGlassSwitchBatchControlView( - {required this.deviceIds, super.key}); + const OneGangGlassSwitchBatchControlView({required this.deviceIds, super.key}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - OneGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(OneGangGlassSwitchFetchBatchStatusEvent(deviceIds)), + create: (context) => OneGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(OneGangGlassSwitchFetchBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is OneGangGlassSwitchLoading) { @@ -37,8 +34,7 @@ class OneGangGlassSwitchBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, OneGangGlassStatusModel status) { + Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart index 2c376ad6..997be513 100644 --- a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart @@ -7,8 +7,7 @@ import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class OneGangGlassSwitchControlView extends StatelessWidget - with HelperResponsiveLayout { +class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout { final String deviceId; const OneGangGlassSwitchControlView({required this.deviceId, super.key}); @@ -17,8 +16,7 @@ class OneGangGlassSwitchControlView extends StatelessWidget Widget build(BuildContext context) { return BlocProvider( create: (context) => - OneGangGlassSwitchBlocFactory.create(deviceId: deviceId) - ..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)), + OneGangGlassSwitchBlocFactory.create(deviceId: deviceId)..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is OneGangGlassSwitchLoading) { @@ -35,8 +33,7 @@ class OneGangGlassSwitchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, OneGangGlassStatusModel status) { + Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -59,7 +56,7 @@ class OneGangGlassSwitchControlView extends StatelessWidget value: status.switch1, code: 'switch_1', deviceId: deviceId, - label: 'Wall Light', + label: "Wall Light", onChange: (value) { context.read().add( OneGangGlassSwitchControl( diff --git a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart index cf22faba..59eccfe9 100644 --- a/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart +++ b/lib/pages/device_managment/one_gang_switch/bloc/wall_light_switch_bloc.dart @@ -10,8 +10,7 @@ import 'package:syncrow_web/services/batch_control_devices_service.dart'; import 'package:syncrow_web/services/control_device_service.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; -class WallLightSwitchBloc - extends Bloc { +class WallLightSwitchBloc extends Bloc { late WallLightStatusModel deviceStatus; final String deviceId; final ControlDeviceService controlDeviceService; @@ -36,11 +35,9 @@ class WallLightSwitchBloc ) async { emit(WallLightSwitchLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(event.deviceId, emit); - deviceStatus = - WallLightStatusModel.fromJson(event.deviceId, status.status); + deviceStatus = WallLightStatusModel.fromJson(event.deviceId, status.status); emit(WallLightSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(WallLightSwitchError(e.toString())); @@ -61,7 +58,7 @@ class WallLightSwitchBloc final statusList = []; if (data['status'] != null) { - for (final element in data['status']) { + for (var element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -139,8 +136,7 @@ class WallLightSwitchBloc ) async { emit(WallLightSwitchLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = WallLightStatusModel.fromJson(event.devicesIds.first, status.status); emit(WallLightSwitchStatusLoaded(deviceStatus)); diff --git a/lib/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart b/lib/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart index caf961f7..b479c71d 100644 --- a/lib/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart +++ b/lib/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart @@ -15,7 +15,7 @@ class WallLightStatusModel { late bool switch1; late int countDown; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; diff --git a/lib/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart b/lib/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart index e7a188c2..7fe57429 100644 --- a/lib/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart +++ b/lib/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart @@ -10,8 +10,7 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WallLightBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class WallLightBatchControlView extends StatelessWidget with HelperResponsiveLayout { const WallLightBatchControlView({super.key, required this.deviceIds}); final List deviceIds; @@ -19,17 +18,15 @@ class WallLightBatchControlView extends StatelessWidget @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - WallLightSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(WallLightSwitchFetchBatchEvent(deviceIds)), + create: (context) => WallLightSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(WallLightSwitchFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is WallLightSwitchLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is WallLightSwitchStatusLoaded) { return _buildStatusControls(context, state.status); - } else if (state is WallLightSwitchError || - state is WallLightSwitchControlError) { + } else if (state is WallLightSwitchError || state is WallLightSwitchControlError) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); @@ -39,8 +36,7 @@ class WallLightBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, WallLightStatusModel status) { + Widget _buildStatusControls(BuildContext context, WallLightStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -82,8 +78,7 @@ class WallLightBatchControlView extends StatelessWidget FactoryResetWidget( callFactoryReset: () { context.read().add(WallLightFactoryReset( - deviceId: status.uuid, - factoryReset: FactoryResetModel(devicesUuid: deviceIds))); + deviceId: status.uuid, factoryReset: FactoryResetModel(devicesUuid: deviceIds))); }, ), ], diff --git a/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart b/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart index 4cc0dbf3..24c5138f 100644 --- a/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart +++ b/lib/pages/device_managment/power_clamp/bloc/smart_power_bloc.dart @@ -215,46 +215,33 @@ class SmartPowerBloc extends Bloc { SmartPowerFetchDeviceEvent event, Emitter emit) async { emit(SmartPowerLoading()); try { - final status = + var status = await DevicesManagementApi().getPowerClampInfo(event.deviceId); - deviceStatus = - PowerClampModel.fromJson(status as Map? ?? {}); + deviceStatus = PowerClampModel.fromJson(status as Map? ??{}); final phaseADataPoints = deviceStatus.status.phaseA.dataPoints; final phaseBDataPoints = deviceStatus.status.phaseB.dataPoints; final phaseCDataPoints = deviceStatus.status.phaseC.dataPoints; phaseData = [ { 'name': 'Phase A', - 'voltage': - '${(phaseADataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', - 'current': - '${(phaseADataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', - 'activePower': - '${phaseADataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', - 'powerFactor': - '${phaseADataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', + 'voltage': '${(phaseADataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', + 'current': '${(phaseADataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', + 'activePower': '${phaseADataPoints.elementAtOrNull(2)?.value??'N/A'} W', + 'powerFactor': '${phaseADataPoints.elementAtOrNull(3)?.value??'N/A'}', }, { 'name': 'Phase B', - 'voltage': - '${(phaseBDataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', - 'current': - '${(phaseBDataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', - 'activePower': - '${phaseBDataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', - 'powerFactor': - '${phaseBDataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', + 'voltage': '${(phaseBDataPoints .elementAtOrNull(0)?.value as num? ?? 0) / 10} V', + 'current': '${(phaseBDataPoints .elementAtOrNull(1)?.value as num? ?? 0) / 10} A', + 'activePower': '${phaseBDataPoints.elementAtOrNull(2)?.value??'N/A'} W', + 'powerFactor': '${phaseBDataPoints.elementAtOrNull(3)?.value??'N/A'}', }, { 'name': 'Phase C', - 'voltage': - '${(phaseCDataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', - 'current': - '${(phaseCDataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', - 'activePower': - '${phaseCDataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', - 'powerFactor': - '${phaseCDataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', + 'voltage': '${(phaseCDataPoints.elementAtOrNull(0)?.value as num? ?? 0) / 10} V', + 'current': '${(phaseCDataPoints.elementAtOrNull(1)?.value as num? ?? 0) / 10} A', + 'activePower': '${phaseCDataPoints.elementAtOrNull(2)?.value ?? 'N/A'} W', + 'powerFactor': '${phaseCDataPoints.elementAtOrNull(3)?.value ?? 'N/A'}', }, ]; emit(GetDeviceStatus()); @@ -318,7 +305,8 @@ class SmartPowerBloc extends Bloc { try { final response = await DevicesManagementApi().getPowerStatus(event.devicesIds); - final deviceStatus = PowerClampBatchModel.fromJson(response); + PowerClampBatchModel deviceStatus = + PowerClampBatchModel.fromJson(response); emit(SmartPowerLoadBatchControll(deviceStatus)); } catch (e) { @@ -429,15 +417,15 @@ class SmartPowerBloc extends Bloc { } Future selectMonthAndYear(BuildContext context) async { - var selectedYear = DateTime.now().year; - var selectedMonth = DateTime.now().month; + int selectedYear = DateTime.now().year; + int selectedMonth = DateTime.now().month; - final yearController = + FixedExtentScrollController yearController = FixedExtentScrollController(initialItem: selectedYear - 1905); - final monthController = + FixedExtentScrollController monthController = FixedExtentScrollController(initialItem: selectedMonth - 1); - return showDialog( + return await showDialog( context: context, builder: (BuildContext context) { return Column( @@ -549,11 +537,11 @@ class SmartPowerBloc extends Bloc { } Future selectYear(BuildContext context) async { - var selectedYear = DateTime.now().year; - final yearController = + int selectedYear = DateTime.now().year; + FixedExtentScrollController yearController = FixedExtentScrollController(initialItem: selectedYear - 1905); - return showDialog( + return await showDialog( context: context, builder: (BuildContext context) { return Column( @@ -634,9 +622,9 @@ class SmartPowerBloc extends Bloc { Future dayMonthYearPicker({ required BuildContext context, }) async { - var selectedDate = DateTime.now(); + DateTime selectedDate = DateTime.now(); - return showDialog( + return await showDialog( context: context, builder: (BuildContext context) { return Column( @@ -698,7 +686,7 @@ class SmartPowerBloc extends Bloc { String formattedDate = DateFormat('yyyy/MM/dd').format(DateTime.now()); - Future checkDayMonthYearSelected( + void checkDayMonthYearSelected( SelectDateEvent event, Emitter emit) async { Future Function(BuildContext context)? dateSelector; String dateFormat; @@ -710,11 +698,15 @@ class SmartPowerBloc extends Bloc { dateFormat = 'yyyy/MM/dd'; break; case 1: - dateSelector = selectMonthAndYear; + dateSelector = (context) { + return selectMonthAndYear(context); + }; dateFormat = 'yyyy-MM'; break; case 2: - dateSelector = selectYear; + dateSelector = (context) { + return selectYear(context); + }; dateFormat = 'yyyy'; break; default: @@ -751,7 +743,7 @@ class SmartPowerBloc extends Bloc { .toList(); } else if (event.viewType == 'Month') { formattedDate = - '${event.selectedDate.year}-${getMonthShortName(event.selectedDate.month)}'; + "${event.selectedDate.year.toString()}-${getMonthShortName(event.selectedDate.month)}"; filteredRecords = record .where((record) => @@ -760,7 +752,7 @@ class SmartPowerBloc extends Bloc { .toList(); } else if (event.viewType == 'Day') { formattedDate = - '${event.selectedDate.year}-${getMonthShortName(event.selectedDate.month)}-${event.selectedDate.day}'; + "${event.selectedDate.year.toString()}-${getMonthShortName(event.selectedDate.month)}-${event.selectedDate.day}"; filteredRecords = record .where((record) => @@ -792,11 +784,11 @@ class SmartPowerBloc extends Bloc { String endChartDate = ''; - Future selectDateRange() async { - final startDate = dateTime!; - final endDate = DateTime(startDate.year, startDate.month + 1, 1) + void selectDateRange() async { + DateTime startDate = dateTime!; + DateTime endDate = DateTime(startDate.year, startDate.month + 1, 1) .subtract(const Duration(days: 1)); - final formattedEndDate = DateFormat('dd/MM/yyyy').format(endDate); + String formattedEndDate = DateFormat('dd/MM/yyyy').format(endDate); endChartDate = ' - $formattedEndDate'; } } diff --git a/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart b/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart index c6cca576..1985c67c 100644 --- a/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart +++ b/lib/pages/device_managment/power_clamp/bloc/smart_power_event.dart @@ -95,18 +95,16 @@ class FilterRecordsByDateEvent extends SmartPowerEvent { class FetchPowerClampBatchStatusEvent extends SmartPowerEvent { final List deviceIds; - FetchPowerClampBatchStatusEvent(this.deviceIds); + FetchPowerClampBatchStatusEvent(this.deviceIds); @override List get props => [deviceIds]; -} - -class PowerBatchControlEvent extends SmartPowerEvent { +}class PowerBatchControlEvent extends SmartPowerEvent { final List deviceIds; final String code; final dynamic value; - PowerBatchControlEvent({ + PowerBatchControlEvent({ required this.deviceIds, required this.code, required this.value, @@ -114,4 +112,4 @@ class PowerBatchControlEvent extends SmartPowerEvent { @override List get props => [deviceIds, code, value]; -} +} \ No newline at end of file diff --git a/lib/pages/device_managment/power_clamp/models/device_event.dart b/lib/pages/device_managment/power_clamp/models/device_event.dart index 8ef43961..09f7b46e 100644 --- a/lib/pages/device_managment/power_clamp/models/device_event.dart +++ b/lib/pages/device_managment/power_clamp/models/device_event.dart @@ -1,3 +1,4 @@ + class EventDevice { final String? code; final DateTime? eventTime; @@ -11,7 +12,7 @@ class EventDevice { EventDevice.fromJson(Map json) : code = json['code'] as String?, - eventTime = json['eventTime'], + eventTime = json['eventTime'] , value = json['value'] as String?; Map toJson() => { diff --git a/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart b/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart index 10ea3a11..1812d1c9 100644 --- a/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart +++ b/lib/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart @@ -19,10 +19,10 @@ class PowerClampBatchModel extends PowerClampModel1 { }); factory PowerClampBatchModel.fromJson(Map json) { - final String productUuid = json['productUuid'] ?? ''; - final String productType = json['productType'] ?? ''; + String productUuid = json['productUuid'] ?? ''; + String productType = json['productType'] ?? ''; - var statusList = []; + List statusList = []; if (json['status'] != null && json['status'] is List) { statusList = (json['status'] as List).map((e) => Status.fromJson(e)).toList(); diff --git a/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart b/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart index 424c940f..b6592f4d 100644 --- a/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart +++ b/lib/pages/device_managment/power_clamp/models/power_clamp_model.dart @@ -16,8 +16,7 @@ class PowerClampModel { return PowerClampModel( productUuid: json['productUuid'] as String? ?? '', productType: json['productType'] as String? ?? '', - status: - PowerStatus.fromJson(json['status'] as Map? ?? {}), + status: PowerStatus.fromJson(json['status'] as Map? ?? {}), ); } diff --git a/lib/pages/device_managment/power_clamp/view/phase_widget.dart b/lib/pages/device_managment/power_clamp/view/phase_widget.dart index ab70237e..223acd95 100644 --- a/lib/pages/device_managment/power_clamp/view/phase_widget.dart +++ b/lib/pages/device_managment/power_clamp/view/phase_widget.dart @@ -5,8 +5,7 @@ import 'package:syncrow_web/utils/constants/assets.dart'; class PhaseWidget extends StatefulWidget { final List> phaseData; - const PhaseWidget({ - super.key, + PhaseWidget({ required this.phaseData, }); @override @@ -20,7 +19,7 @@ class _PhaseWidgetState extends State { Widget build(BuildContext context) { return Column( children: [ - const SizedBox(height: 10), + SizedBox(height: 10), Row( children: List.generate(widget.phaseData.length, (index) { return InkWell( @@ -44,28 +43,27 @@ class _PhaseWidgetState extends State { ); }), ), - const SizedBox(height: 10), - if (_selectedPhaseIndex == 0) - phase( - totalActive: widget.phaseData[0]['activePower'] ?? '0', - totalCurrent: widget.phaseData[0]['current'] ?? '0', - totalFactor: widget.phaseData[0]['powerFactor'] ?? '0', - totalVoltage: widget.phaseData[0]['voltage'] ?? '0', - ) - else - _selectedPhaseIndex == 1 - ? phase( - totalActive: widget.phaseData[1]['activePower'] ?? '0', - totalCurrent: widget.phaseData[1]['current'] ?? '0', - totalFactor: widget.phaseData[1]['powerFactor'] ?? '0', - totalVoltage: widget.phaseData[1]['voltage'] ?? '0', - ) - : phase( - totalActive: widget.phaseData[2]['activePower'] ?? '0', - totalCurrent: widget.phaseData[2]['current'] ?? '0', - totalFactor: widget.phaseData[2]['powerFactor'] ?? '0', - totalVoltage: widget.phaseData[2]['voltage'] ?? '0', - ), + SizedBox(height: 10), + _selectedPhaseIndex == 0 + ? phase( + totalActive: widget.phaseData[0]['activePower'] ?? '0', + totalCurrent: widget.phaseData[0]['current'] ?? '0', + totalFactor: widget.phaseData[0]['powerFactor'] ?? '0', + totalVoltage: widget.phaseData[0]['voltage'] ?? '0', + ) + : _selectedPhaseIndex == 1 + ? phase( + totalActive: widget.phaseData[1]['activePower'] ?? '0', + totalCurrent: widget.phaseData[1]['current'] ?? '0', + totalFactor: widget.phaseData[1]['powerFactor'] ?? '0', + totalVoltage: widget.phaseData[1]['voltage'] ?? '0', + ) + : phase( + totalActive: widget.phaseData[2]['activePower'] ?? '0', + totalCurrent: widget.phaseData[2]['current'] ?? '0', + totalFactor: widget.phaseData[2]['powerFactor'] ?? '0', + totalVoltage: widget.phaseData[2]['voltage'] ?? '0', + ), ], ); } diff --git a/lib/pages/device_managment/power_clamp/view/power_chart.dart b/lib/pages/device_managment/power_clamp/view/power_chart.dart index bbdcd87d..7d6371f4 100644 --- a/lib/pages/device_managment/power_clamp/view/power_chart.dart +++ b/lib/pages/device_managment/power_clamp/view/power_chart.dart @@ -35,7 +35,7 @@ class _EnergyConsumptionPageState extends State { @override Widget build(BuildContext context) { - return ColoredBox( + return Container( color: ColorsManager.whiteColors, child: Column( children: [ @@ -146,7 +146,7 @@ class _EnergyConsumptionPageState extends State { showTitles: false, reservedSize: 70, getTitlesWidget: (value, meta) { - final index = value.toInt(); + int index = value.toInt(); if (index >= 0 && index < _chartData.length) { return Padding( padding: const EdgeInsets.all(8.0), @@ -169,14 +169,14 @@ class _EnergyConsumptionPageState extends State { verticalInterval: 1, getDrawingVerticalLine: (value) { return FlLine( - color: Colors.grey.withValues(alpha: 0.2), + color: Colors.grey.withOpacity(0.2), dashArray: [8, 8], strokeWidth: 1, ); }, getDrawingHorizontalLine: (value) { return FlLine( - color: Colors.grey.withValues(alpha: 0.2), + color: Colors.grey.withOpacity(0.2), dashArray: [5, 5], strokeWidth: 1, ); @@ -192,21 +192,19 @@ class _EnergyConsumptionPageState extends State { spots: _chartData .asMap() .entries - .map((entry) => FlSpot(entry.key.toDouble(), - entry.value.consumption)) + .map((entry) => FlSpot( + entry.key.toDouble(), entry.value.consumption)) .toList(), isCurved: true, - color: - ColorsManager.primaryColor.withValues(alpha: 0.6), + color: ColorsManager.primaryColor.withOpacity(0.6), show: true, shadow: const Shadow(color: Colors.black12), belowBarData: BarAreaData( show: true, gradient: LinearGradient( colors: [ - ColorsManager.primaryColor - .withValues(alpha: 0.5), - Colors.blue.withValues(alpha: 0.1), + ColorsManager.primaryColor.withOpacity(0.5), + Colors.blue.withOpacity(0.1), ], begin: Alignment.center, end: Alignment.bottomCenter, @@ -222,7 +220,7 @@ class _EnergyConsumptionPageState extends State { borderData: FlBorderData( show: false, border: Border.all( - color: const Color(0xff023DFE).withValues(alpha: 0.7), + color: const Color(0xff023DFE).withOpacity(0.7), width: 10, ), ), diff --git a/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart b/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart index 2032cd90..7f6a4b64 100644 --- a/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart +++ b/lib/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart @@ -9,17 +9,16 @@ import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_ // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class PowerClampBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class PowerClampBatchControlView extends StatelessWidget with HelperResponsiveLayout { final List deviceIds; - const PowerClampBatchControlView({super.key, required this.deviceIds}); + const PowerClampBatchControlView({Key? key, required this.deviceIds}) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => SmartPowerBloc(deviceId: deviceIds.first) - ..add(SmartPowerFetchBatchEvent(deviceIds)), + create: (context) => + SmartPowerBloc(deviceId: deviceIds.first)..add(SmartPowerFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is SmartPowerLoading) { @@ -36,8 +35,7 @@ class PowerClampBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, PowerClampBatchModel status) { + Widget _buildStatusControls(BuildContext context, PowerClampBatchModel status) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/pages/device_managment/power_clamp/view/power_info_card.dart b/lib/pages/device_managment/power_clamp/view/power_info_card.dart index b06bd1c3..601b6346 100644 --- a/lib/pages/device_managment/power_clamp/view/power_info_card.dart +++ b/lib/pages/device_managment/power_clamp/view/power_info_card.dart @@ -9,12 +9,12 @@ class PowerClampInfoCard extends StatelessWidget { final String unit; const PowerClampInfoCard({ - super.key, + Key? key, required this.iconPath, required this.title, required this.value, required this.unit, - }); + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart b/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart index 3f67a027..67313802 100644 --- a/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart +++ b/lib/pages/device_managment/power_clamp/view/smart_power_device_control.dart @@ -12,8 +12,7 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; //Smart Power Clamp -class SmartPowerDeviceControl extends StatelessWidget - with HelperResponsiveLayout { +class SmartPowerDeviceControl extends StatelessWidget with HelperResponsiveLayout { final String deviceId; const SmartPowerDeviceControl({super.key, required this.deviceId}); @@ -60,7 +59,7 @@ class SmartPowerDeviceControl extends StatelessWidget required SmartPowerBloc blocProvider, required int currentPage, }) { - final pageController = PageController(initialPage: currentPage); + PageController pageController = PageController(initialPage: currentPage); return Container( padding: const EdgeInsets.symmetric(horizontal: 50), child: DeviceControlsContainer( @@ -196,8 +195,8 @@ class SmartPowerDeviceControl extends StatelessWidget blocProvider.add(SelectDateEvent(context: context)); blocProvider.add(FilterRecordsByDateEvent( selectedDate: blocProvider.dateTime!, - viewType: blocProvider - .views[blocProvider.currentIndex])); + viewType: + blocProvider.views[blocProvider.currentIndex])); }, widget: blocProvider.dateSwitcher(), chartData: blocProvider.energyDataList.isNotEmpty diff --git a/lib/pages/device_managment/shared/device_batch_control_dialog.dart b/lib/pages/device_managment/shared/device_batch_control_dialog.dart index c99b0028..f2dc68f5 100644 --- a/lib/pages/device_managment/shared/device_batch_control_dialog.dart +++ b/lib/pages/device_managment/shared/device_batch_control_dialog.dart @@ -4,8 +4,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; -class DeviceBatchControlDialog extends StatelessWidget - with RouteControlsBasedCode { +class DeviceBatchControlDialog extends StatelessWidget with RouteControlsBasedCode { final List devices; const DeviceBatchControlDialog({super.key, required this.devices}); @@ -44,7 +43,7 @@ class DeviceBatchControlDialog extends StatelessWidget height: 8, ), Text( - 'Batch Control', + "Batch Control", style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.dialogBlueTitle, ), @@ -105,39 +104,39 @@ String getBatchDialogName(AllDevicesModel device) { */ switch (device.productType) { case '1G': - return 'Smart Light Switch'; + return "Smart Light Switch"; case '2G': - return 'Smart Light Switch'; + return "Smart Light Switch"; case '3G': - return 'Smart Light Switch'; + return "Smart Light Switch"; case 'GW': - return 'Gateway'; + return "Gateway"; case 'DL': - return 'Door Lock'; + return "Door Lock"; case 'WPS': - return 'White Presence Sensor'; + return "White Presence Sensor"; case 'CPS': - return 'Black Presence Sensor'; + return "Black Presence Sensor"; case 'CUR': - return 'Smart Curtains'; + return "Smart Curtains"; case 'WH': - return 'Smart Water Heater'; + return "Smart Water Heater"; case 'AC': - return 'Smart AC'; + return "Smart AC"; case 'DS': - return 'Door / Window Sensor'; + return "Door / Window Sensor"; case '1GT': - return 'Touch Switch'; + return "Touch Switch"; case '2GT': - return 'Touch Switch'; + return "Touch Switch"; case '3GT': - return 'Touch Switch'; + return "Touch Switch"; case 'GD': - return 'Garage Door Opener'; + return "Garage Door Opener"; case 'WL': - return 'Water Leak Sensor'; + return "Water Leak Sensor"; case 'SOS': - return 'SOS'; + return "SOS"; default: return device.categoryName ?? 'Device Control'; } diff --git a/lib/pages/device_managment/shared/device_control_dialog.dart b/lib/pages/device_managment/shared/device_control_dialog.dart index 0c9c4398..beb3b52c 100644 --- a/lib/pages/device_managment/shared/device_control_dialog.dart +++ b/lib/pages/device_managment/shared/device_control_dialog.dart @@ -50,7 +50,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { ), ), child: IconButton( - padding: const EdgeInsets.all(1), + padding: EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, @@ -107,7 +107,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { 'Installation Date and Time:', formatDateTime( DateTime.fromMillisecondsSinceEpoch( - (device.createTime ?? 0) * 1000, + ((device.createTime ?? 0) * 1000), ), ), ), @@ -115,7 +115,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { 'Battery Level:', device.batteryLevel != null ? '${device.batteryLevel ?? 0}%' - : '-', + : "-", statusColor: device.batteryLevel != null ? (device.batteryLevel! < 20 ? ColorsManager.red @@ -131,7 +131,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { 'Last Offline Date and Time:', formatDateTime( DateTime.fromMillisecondsSinceEpoch( - (device.updateTime ?? 0) * 1000, + ((device.updateTime ?? 0) * 1000), ), ), ), diff --git a/lib/pages/device_managment/shared/device_controls_container.dart b/lib/pages/device_managment/shared/device_controls_container.dart index 5ee8a978..888563da 100644 --- a/lib/pages/device_managment/shared/device_controls_container.dart +++ b/lib/pages/device_managment/shared/device_controls_container.dart @@ -18,9 +18,8 @@ class DeviceControlsContainer extends StatelessWidget { color: Colors.grey.shade100, borderRadius: BorderRadius.circular(20), ), - padding: EdgeInsets.symmetric( - vertical: padding ?? 10, - horizontal: padding ?? 16), //EdgeInsets.all(padding ?? 12), + padding: + EdgeInsets.symmetric(vertical: padding ?? 10, horizontal: padding ?? 16), //EdgeInsets.all(padding ?? 12), child: child, ), ); diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart index ba84bd87..aac34b77 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_display_data.dart @@ -4,10 +4,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; class PresenceDisplayValue extends StatelessWidget { const PresenceDisplayValue( - {super.key, - required this.value, - required this.postfix, - required this.description}); + {super.key, required this.value, required this.postfix, required this.description}); final String value; final String postfix; @@ -35,9 +32,7 @@ class PresenceDisplayValue extends StatelessWidget { child: Text( postfix, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, - fontSize: 16, - fontWeight: FontWeight.w700), + color: ColorsManager.blackColor, fontSize: 16, fontWeight: FontWeight.w700), ), ), ], @@ -45,9 +40,7 @@ class PresenceDisplayValue extends StatelessWidget { Text( description, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, - fontWeight: FontWeight.w400, - fontSize: 16), + color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 16), ), ], ), diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart index c33ac15c..e1ca0586 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_space_type.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart'; -import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart'; class PresenceSpaceType extends StatelessWidget { const PresenceSpaceType({ @@ -20,7 +20,7 @@ class PresenceSpaceType extends StatelessWidget { @override Widget build(BuildContext context) { - final spaceTypeIcons = { + final Map spaceTypeIcons = { SpaceTypes.none: Assets.office, SpaceTypes.parlour: Assets.parlour, SpaceTypes.area: Assets.dyi, diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart index b46bbcc5..d2d48b78 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart @@ -4,8 +4,7 @@ import 'package:syncrow_web/pages/device_managment/shared/device_controls_contai import 'package:syncrow_web/utils/color_manager.dart'; class PresenceStaticWidget extends StatelessWidget { - const PresenceStaticWidget( - {required this.icon, required this.description, super.key}); + const PresenceStaticWidget({required this.icon, required this.description, super.key}); final String icon; final String description; @@ -24,9 +23,7 @@ class PresenceStaticWidget extends StatelessWidget { Text( description, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, - fontWeight: FontWeight.w400, - fontSize: 16), + color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 16), ), ], ), diff --git a/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart b/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart index 4ec7737a..26e47c8b 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presence_status.dart @@ -25,9 +25,7 @@ class PresenceState extends StatelessWidget { Text( 'Status:', style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, - fontWeight: FontWeight.w400, - fontSize: 10), + color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 10), ), ], ), @@ -43,9 +41,7 @@ class PresenceState extends StatelessWidget { Text( value, style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: ColorsManager.blackColor, - fontWeight: FontWeight.w400, - fontSize: 16), + color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 16), ), ], ), diff --git a/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart b/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart index cda019ea..9cc23505 100644 --- a/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart +++ b/lib/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart @@ -48,7 +48,7 @@ class _PresenceUpdateDataState extends State { String _extractNumericValue(String value) { if (value == 'none') return '0'; - return value.replaceAll(RegExp('[a-zA-Z]'), '').trim(); + return value.replaceAll(RegExp(r'[a-zA-Z]'), '').trim(); } String _extractUnit(String value) { @@ -69,17 +69,17 @@ class _PresenceUpdateDataState extends State { } void _incrementValue() { - final currentIndex = nobodyTimeRange.indexOf(_currentValue); + int currentIndex = nobodyTimeRange.indexOf(_currentValue); if (currentIndex < nobodyTimeRange.length - 1) { - final newValue = nobodyTimeRange[currentIndex + 1]; + String newValue = nobodyTimeRange[currentIndex + 1]; _onValueChanged(newValue); } } void _decrementValue() { - final currentIndex = nobodyTimeRange.indexOf(_currentValue); + int currentIndex = nobodyTimeRange.indexOf(_currentValue); if (currentIndex > 0) { - final newValue = nobodyTimeRange[currentIndex - 1]; + String newValue = nobodyTimeRange[currentIndex - 1]; _onValueChanged(newValue); } } diff --git a/lib/pages/device_managment/shared/table/report_table.dart b/lib/pages/device_managment/shared/table/report_table.dart index 72a98f56..11385080 100644 --- a/lib/pages/device_managment/shared/table/report_table.dart +++ b/lib/pages/device_managment/shared/table/report_table.dart @@ -41,8 +41,7 @@ class ReportsTable extends StatelessWidget { height: 100, child: Text( 'No reports found', - style: context.textTheme.bodyLarge! - .copyWith(color: ColorsManager.grayColor), + style: context.textTheme.bodyLarge!.copyWith(color: ColorsManager.grayColor), ), ) : Stack( @@ -50,8 +49,7 @@ class ReportsTable extends StatelessWidget { Padding( padding: const EdgeInsets.all(20.0), child: Table( - border: - TableBorder.all(color: Colors.grey.shade300, width: 1), + border: TableBorder.all(color: Colors.grey.shade300, width: 1), columnWidths: const { 0: FlexColumnWidth(), 1: FlexColumnWidth(), @@ -68,36 +66,28 @@ class ReportsTable extends StatelessWidget { ), if (report.data != null) ...report.data!.asMap().entries.map((entry) { - final index = entry.key; - final data = entry.value; + int index = entry.key; + DeviceEvent data = entry.value; // Parse eventTime into Date and Time - final eventDateTime = - DateTime.fromMillisecondsSinceEpoch( - data.eventTime!); - final date = - DateFormat('dd/MM/yyyy').format(eventDateTime); - final time = DateFormat('HH:mm').format(eventDateTime); + DateTime eventDateTime = + DateTime.fromMillisecondsSinceEpoch(data.eventTime!); + String date = DateFormat('dd/MM/yyyy').format(eventDateTime); + String time = DateFormat('HH:mm').format(eventDateTime); String value; if (hideValueShowDescription == true) { - if (mainDoorSensor != null && - mainDoorSensor == true) { + if (mainDoorSensor != null && mainDoorSensor == true) { value = data.value == 'true' ? 'Open' : 'Close'; - } else if (garageDoorSensor != null && - garageDoorSensor == true) { + } else if (garageDoorSensor != null && garageDoorSensor == true) { value = data.value == 'true' ? 'Opened' : 'Closed'; } else if (waterLeak != null && waterLeak == true) { - value = data.value == 'normal' - ? 'Normal' - : 'Leak Detected'; + value = data.value == 'normal' ? 'Normal' : 'Leak Detected'; } else { - value = - '${data.value!} ${thirdColumnDescription ?? ''}'; + value = '${data.value!} ${thirdColumnDescription ?? ''}'; } } else { - value = - '${data.value!} ${thirdColumnDescription ?? ''}'; + value = '${data.value!} ${thirdColumnDescription ?? ''}'; } return TableRow( diff --git a/lib/pages/device_managment/shared/toggle_widget.dart b/lib/pages/device_managment/shared/toggle_widget.dart index 0e8cff37..4888572f 100644 --- a/lib/pages/device_managment/shared/toggle_widget.dart +++ b/lib/pages/device_managment/shared/toggle_widget.dart @@ -42,30 +42,29 @@ class ToggleWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (icon == '-1') - const SizedBox( - height: 60, - width: 60, - ) - else - ClipOval( - child: Container( - height: 60, - width: 60, - padding: const EdgeInsets.all(8), - color: ColorsManager.whiteColors, - child: SvgPicture.asset( - icon ?? Assets.lightPulp, - width: 35, - height: 35, - fit: BoxFit.contain, - ), - )), + icon == '-1' + ? const SizedBox( + height: 60, + width: 60, + ) + : ClipOval( + child: Container( + height: 60, + width: 60, + padding: const EdgeInsets.all(8), + color: ColorsManager.whiteColors, + child: SvgPicture.asset( + icon ?? Assets.lightPulp, + width: 35, + height: 35, + fit: BoxFit.contain, + ), + )), if (showToggle) Container( child: CupertinoSwitch( value: value, - activeTrackColor: ColorsManager.dialogBlueTitle, + activeColor: ColorsManager.dialogBlueTitle, onChanged: onChange, ), ), diff --git a/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart b/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart index 9334a039..14fdf61c 100644 --- a/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart +++ b/lib/pages/device_managment/sos/bloc/sos_device_bloc.dart @@ -22,8 +22,7 @@ class SosDeviceBloc extends Bloc { late SosStatusModel deviceStatus; - FutureOr _getDeviceStatus( - GetDeviceStatus event, Emitter emit) async { + FutureOr _getDeviceStatus(GetDeviceStatus event, Emitter emit) async { emit(SosDeviceLoadingState()); try { final status = await DevicesManagementApi().getDeviceStatus(event.uuid); @@ -34,8 +33,7 @@ class SosDeviceBloc extends Bloc { } } - FutureOr _getBatchStatus( - GetBatchStatus event, Emitter emit) async { + FutureOr _getBatchStatus(GetBatchStatus event, Emitter emit) async { emit(SosDeviceLoadingState()); try { final status = await DevicesManagementApi().getBatchStatus(event.uuids); @@ -46,31 +44,25 @@ class SosDeviceBloc extends Bloc { } } - FutureOr _getDeviceRecords( - GetDeviceRecords event, Emitter emit) async { + FutureOr _getDeviceRecords(GetDeviceRecords event, Emitter emit) async { emit(SosReportLoadingState()); try { - final from = DateTime.now() - .subtract(const Duration(days: 30)) - .millisecondsSinceEpoch; + final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final records = await DevicesManagementApi.getDeviceReportsByDate( - event.uuid, 'sos', from.toString(), to.toString()); + final DeviceReport records = + await DevicesManagementApi.getDeviceReportsByDate(event.uuid, 'sos', from.toString(), to.toString()); emit(SosReportLoadedState(records)); } catch (e) { emit(SosReportErrorState(e.toString())); } } - FutureOr _getDeviceAutomationRecords( - GetDeviceAutomationRecords event, Emitter emit) async { + FutureOr _getDeviceAutomationRecords(GetDeviceAutomationRecords event, Emitter emit) async { emit(SosAutomationReportLoadingState()); try { - final from = DateTime.now() - .subtract(const Duration(days: 30)) - .millisecondsSinceEpoch; + final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final records = await DevicesManagementApi.getDeviceReportsByDate( + final DeviceReport records = await DevicesManagementApi.getDeviceReportsByDate( event.uuid, 'sos_automation', from.toString(), to.toString()); emit(SosAutomationReportLoadedState(records)); } catch (e) { @@ -78,17 +70,14 @@ class SosDeviceBloc extends Bloc { } } - FutureOr _backToSosStatusView( - BackToSosStatusView event, Emitter emit) { + FutureOr _backToSosStatusView(BackToSosStatusView event, Emitter emit) { emit(SosDeviceLoadedState(deviceStatus)); } - FutureOr _sosFactoryReset( - SosFactoryReset event, Emitter emit) async { + FutureOr _sosFactoryReset(SosFactoryReset event, Emitter emit) async { emit(SosDeviceLoadingState()); try { - final response = await DevicesManagementApi() - .factoryReset(event.factoryReset, event.deviceId); + final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId); if (response) { emit(SosDeviceLoadedState(deviceStatus)); } else { diff --git a/lib/pages/device_managment/sos/models/sos_status_model.dart b/lib/pages/device_managment/sos/models/sos_status_model.dart index 4a9f2114..ac0de3b0 100644 --- a/lib/pages/device_managment/sos/models/sos_status_model.dart +++ b/lib/pages/device_managment/sos/models/sos_status_model.dart @@ -15,7 +15,7 @@ class SosStatusModel { late int batteryLevel; late String sosStatus; - for (final status in statuses) { + for (var status in statuses) { switch (status.code) { case 'battery_percentage': batteryLevel = status.value; diff --git a/lib/pages/device_managment/sos/view/sos_device_control_view.dart b/lib/pages/device_managment/sos/view/sos_device_control_view.dart index 631a7424..dde4512b 100644 --- a/lib/pages/device_managment/sos/view/sos_device_control_view.dart +++ b/lib/pages/device_managment/sos/view/sos_device_control_view.dart @@ -6,12 +6,13 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart'; import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart'; import 'package:syncrow_web/pages/device_managment/sos/bloc/sos_device_bloc.dart'; -import 'package:syncrow_web/pages/device_managment/sos/models/sos_status_model.dart'; import 'package:syncrow_web/pages/device_managment/sos/widgets/sos_notification_dialog.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; +import '../models/sos_status_model.dart'; + class SosDeviceControlsView extends StatelessWidget with HelperResponsiveLayout { const SosDeviceControlsView({ @@ -55,9 +56,9 @@ class SosDeviceControlsView extends StatelessWidget } else if (state is SosDeviceErrorState) { return const Center(child: Text('Error fetching status')); } else if (state is SosAutomationReportErrorState) { - return Center(child: Text('Error: ${state.message}')); + return Center(child: Text('Error: ${state.message.toString()}')); } else if (state is SosReportErrorState) { - return Center(child: Text('Error: ${state.message}')); + return Center(child: Text('Error: ${state.message.toString()}')); } return const Center(child: CircularProgressIndicator()); }, diff --git a/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart b/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart index bbdeaa3d..55428107 100644 --- a/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart +++ b/lib/pages/device_managment/sos/widgets/sos_notification_dialog.dart @@ -52,7 +52,7 @@ class _NotificationDialogState extends State { ), ), child: IconButton( - padding: const EdgeInsets.all(1), + padding: EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, diff --git a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart index 7ab5567d..766c3163 100644 --- a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart @@ -40,8 +40,7 @@ class ThreeGangGlassSwitchBloc ) async { emit(ThreeGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(event.deviceId, emit); deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status); @@ -65,7 +64,7 @@ class ThreeGangGlassSwitchBloc final statusList = []; if (data['status'] != null) { - for (final element in data['status']) { + for (var element in data['status']) { statusList.add( Status( code: element['code'].toString(), @@ -75,8 +74,7 @@ class ThreeGangGlassSwitchBloc } } if (statusList.isNotEmpty) { - final newStatus = - ThreeGangGlassStatusModel.fromJson(deviceId, statusList); + final newStatus = ThreeGangGlassStatusModel.fromJson(deviceId, statusList); if (newStatus != deviceStatus) { deviceStatus = newStatus; if (!isClosed) { @@ -144,10 +142,9 @@ class ThreeGangGlassSwitchBloc ) async { emit(ThreeGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = ThreeGangGlassStatusModel.fromJson( - event.deviceIds.first, status.status); + final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = + ThreeGangGlassStatusModel.fromJson(event.deviceIds.first, status.status); emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus)); } catch (e) { emit(ThreeGangGlassSwitchError(e.toString())); diff --git a/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart b/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart index e439a434..cec12b7f 100644 --- a/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart +++ b/lib/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart @@ -27,7 +27,7 @@ class ThreeGangGlassStatusModel { late bool switch3; late int countDown3; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; diff --git a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart index 22b5ff53..93fbe53e 100644 --- a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart +++ b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart @@ -9,19 +9,16 @@ import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/factorie import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class ThreeGangGlassSwitchBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout { final List deviceIds; - const ThreeGangGlassSwitchBatchControlView( - {required this.deviceIds, super.key}); + const ThreeGangGlassSwitchBatchControlView({required this.deviceIds, super.key}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(ThreeGangGlassSwitchFetchBatchStatusEvent(deviceIds)), + create: (context) => ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(ThreeGangGlassSwitchFetchBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is ThreeGangGlassSwitchLoading) { @@ -38,8 +35,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, ThreeGangGlassStatusModel status) { + Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -62,7 +58,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget value: status.switch1, code: 'switch_1', deviceId: deviceIds.first, - label: 'Wall Light', + label: "Wall Light", onChange: (value) { context.read().add( ThreeGangGlassSwitchBatchControl( @@ -77,7 +73,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget value: status.switch2, code: 'switch_2', deviceId: deviceIds.first, - label: 'Ceiling Light', + label: "Ceiling Light", onChange: (value) { context.read().add( ThreeGangGlassSwitchBatchControl( @@ -92,7 +88,7 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget value: status.switch3, code: 'switch_3', deviceId: deviceIds.first, - label: 'SpotLight', + label: "SpotLight", onChange: (value) { context.read().add( ThreeGangGlassSwitchBatchControl( diff --git a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart index 019f17f2..21a81df0 100644 --- a/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart @@ -3,12 +3,12 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/factories/three_gang_glass_switch_bloc_factory.dart'; -import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class ThreeGangGlassSwitchControlView extends StatelessWidget - with HelperResponsiveLayout { +import '../models/three_gang_glass_switch.dart'; + +class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout { final String deviceId; const ThreeGangGlassSwitchControlView({required this.deviceId, super.key}); @@ -17,8 +17,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget Widget build(BuildContext context) { return BlocProvider( create: (context) => - ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceId) - ..add(ThreeGangGlassSwitchFetchDeviceEvent(deviceId)), + ThreeGangGlassSwitchBlocFactory.create(deviceId: deviceId)..add(ThreeGangGlassSwitchFetchDeviceEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is ThreeGangGlassSwitchLoading) { @@ -35,8 +34,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, ThreeGangGlassStatusModel status) { + Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); @@ -59,7 +57,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget value: status.switch1, code: 'switch_1', deviceId: deviceId, - label: 'Wall Light', + label: "Wall Light", onChange: (value) { context.read().add( ThreeGangGlassSwitchControl( @@ -74,7 +72,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget value: status.switch2, code: 'switch_2', deviceId: deviceId, - label: 'Ceiling Light', + label: "Ceiling Light", onChange: (value) { context.read().add( ThreeGangGlassSwitchControl( @@ -89,7 +87,7 @@ class ThreeGangGlassSwitchControlView extends StatelessWidget value: status.switch3, code: 'switch_3', deviceId: deviceId, - label: 'SpotLight', + label: "SpotLight", onChange: (value) { context.read().add( ThreeGangGlassSwitchControl( diff --git a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart index be51b1d2..bec1314c 100644 --- a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart +++ b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart @@ -39,11 +39,9 @@ class LivingRoomBloc extends Bloc { ) async { emit(LivingRoomDeviceStatusLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); _listenToChanges(deviceId); - deviceStatus = - LivingRoomStatusModel.fromJson(event.deviceId, status.status); + deviceStatus = LivingRoomStatusModel.fromJson(event.deviceId, status.status); emit(LivingRoomDeviceStatusLoaded(deviceStatus)); } catch (e) { emit(LivingRoomDeviceManagementError(e.toString())); @@ -54,9 +52,9 @@ class LivingRoomBloc extends Bloc { try { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value! as Map; + final eventsMap = event.snapshot.value as Map; - final statusList = []; + List statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), @@ -124,8 +122,7 @@ class LivingRoomBloc extends Bloc { ) async { emit(LivingRoomDeviceStatusLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = LivingRoomStatusModel.fromJson(event.devicesIds.first, status.status); emit(LivingRoomDeviceStatusLoaded(deviceStatus)); diff --git a/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart b/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart index 60ea3d12..4bb5eada 100644 --- a/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart +++ b/lib/pages/device_managment/three_gang_switch/models/living_room_model.dart @@ -18,7 +18,7 @@ class LivingRoomStatusModel { late bool switch2; late bool switch3; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; // default to false if null diff --git a/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart b/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart index 77647078..0b1a2f06 100644 --- a/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart +++ b/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart @@ -2,15 +2,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; -import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/factories/living_room_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; +import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class LivingRoomBatchControlsView extends StatelessWidget - with HelperResponsiveLayout { +class LivingRoomBatchControlsView extends StatelessWidget with HelperResponsiveLayout { const LivingRoomBatchControlsView({super.key, required this.deviceIds}); final List deviceIds; @@ -19,16 +18,14 @@ class LivingRoomBatchControlsView extends StatelessWidget Widget build(BuildContext context) { return BlocProvider( create: (context) => - LivingRoomBlocFactory.create(deviceId: deviceIds.first) - ..add(LivingRoomFetchBatchEvent(deviceIds)), + LivingRoomBlocFactory.create(deviceId: deviceIds.first)..add(LivingRoomFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is LivingRoomDeviceStatusLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is LivingRoomDeviceStatusLoaded) { return _buildStatusControls(context, state.status); - } else if (state is LivingRoomDeviceManagementError || - state is LivingRoomControlError) { + } else if (state is LivingRoomDeviceManagementError || state is LivingRoomControlError) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); @@ -38,8 +35,7 @@ class LivingRoomBatchControlsView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, LivingRoomStatusModel status) { + Widget _buildStatusControls(BuildContext context, LivingRoomStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart b/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart index 7d0faf7f..731b354c 100644 --- a/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart +++ b/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/factories/living_room_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; +import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; class LivingRoomDeviceControlsView extends StatelessWidget diff --git a/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart b/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart index ed0896fa..629c131b 100644 --- a/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart +++ b/lib/pages/device_managment/three_gang_switch/widgets/cieling_light.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; @@ -6,11 +7,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class CeilingLight extends StatelessWidget { - const CeilingLight( - {super.key, - required this.value, - required this.code, - required this.deviceId}); + const CeilingLight({super.key, required this.value, required this.code, required this.deviceId}); final bool value; final String code; @@ -26,7 +23,7 @@ class CeilingLight extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.lightPulp, @@ -40,7 +37,7 @@ class CeilingLight extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeTrackColor: ColorsManager.dialogBlueTitle, + activeColor: ColorsManager.dialogBlueTitle, onChanged: (newValue) { context.read().add( LivingRoomControl( diff --git a/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart b/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart index ea635247..6ac71a38 100644 --- a/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart +++ b/lib/pages/device_managment/three_gang_switch/widgets/spot_light.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; @@ -6,11 +7,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class SpotLight extends StatelessWidget { - const SpotLight( - {super.key, - required this.value, - required this.code, - required this.deviceId}); + const SpotLight({super.key, required this.value, required this.code, required this.deviceId}); final bool value; final String code; @@ -26,7 +23,7 @@ class SpotLight extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.lightPulp, @@ -40,7 +37,7 @@ class SpotLight extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeTrackColor: ColorsManager.dialogBlueTitle, + activeColor: ColorsManager.dialogBlueTitle, onChanged: (newValue) { context.read().add( LivingRoomControl( diff --git a/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart b/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart index 8844cb1e..12c814ac 100644 --- a/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart +++ b/lib/pages/device_managment/three_gang_switch/widgets/wall_light.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; @@ -6,11 +7,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class WallLight extends StatelessWidget { - const WallLight( - {super.key, - required this.value, - required this.code, - required this.deviceId}); + const WallLight({super.key, required this.value, required this.code, required this.deviceId}); final bool value; final String code; @@ -26,7 +23,7 @@ class WallLight extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, child: SvgPicture.asset( Assets.lightPulp, @@ -40,7 +37,7 @@ class WallLight extends StatelessWidget { width: 35, child: CupertinoSwitch( value: value, - activeTrackColor: ColorsManager.dialogBlueTitle, + activeColor: ColorsManager.dialogBlueTitle, onChanged: (newValue) { context.read().add( LivingRoomControl( diff --git a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart index 2a71f477..8f82c198 100644 --- a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart @@ -42,10 +42,8 @@ class TwoGangGlassSwitchBloc ) async { emit(TwoGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = - TwoGangGlassStatusModel.fromJson(event.deviceId, status.status); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceId, status.status); _listenToChanges(event.deviceId); emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { @@ -60,12 +58,11 @@ class TwoGangGlassSwitchBloc ); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value! as Map; + final eventsMap = event.snapshot.value as Map; - final statusList = []; + List statusList = []; eventsMap['status'].forEach((element) { - statusList - .add(Status(code: element['code'], value: element['value'])); + statusList.add(Status(code: element['code'], value: element['value'])); }); deviceStatus = TwoGangGlassStatusModel.fromJson(deviceId, statusList); @@ -124,8 +121,7 @@ class TwoGangGlassSwitchBloc ) async { emit(TwoGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.deviceIds); + final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); deviceStatus = TwoGangGlassStatusModel.fromJson( event.deviceIds.first, status.status, diff --git a/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart b/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart index 1d407ab6..54d99d74 100644 --- a/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart +++ b/lib/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart @@ -21,7 +21,7 @@ class TwoGangGlassStatusModel { late bool switch2; late int countDown2; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': switch1 = status.value ?? false; diff --git a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart index a70f1dfe..9d120ad6 100644 --- a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart +++ b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart @@ -9,19 +9,16 @@ import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/factories/ import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class TwoGangGlassSwitchBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class TwoGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout { final List deviceIds; - const TwoGangGlassSwitchBatchControlView( - {required this.deviceIds, super.key}); + const TwoGangGlassSwitchBatchControlView({required this.deviceIds, super.key}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - TwoGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)), + create: (context) => TwoGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is TwoGangGlassSwitchLoading) { @@ -38,8 +35,7 @@ class TwoGangGlassSwitchBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, TwoGangGlassStatusModel status) { + Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart index 34e96c2b..575deeac 100644 --- a/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart @@ -16,9 +16,8 @@ class TwoGangGlassSwitchControlView extends StatelessWidget @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - TwoGangGlassSwitchBlocFactory.create(deviceId: deviceId) - ..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)), + create: (context) => TwoGangGlassSwitchBlocFactory.create(deviceId: deviceId) + ..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is TwoGangGlassSwitchLoading) { diff --git a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart index 1d959ffb..2e3a8633 100644 --- a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart +++ b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart @@ -37,8 +37,7 @@ class TwoGangSwitchBloc extends Bloc { ) async { emit(TwoGangSwitchLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = TwoGangStatusModel.fromJson(event.deviceId, status.status); _listenToChanges(event.deviceId); emit(TwoGangSwitchStatusLoaded(deviceStatus)); @@ -52,9 +51,9 @@ class TwoGangSwitchBloc extends Bloc { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value! as Map; + final eventsMap = event.snapshot.value as Map; - final statusList = []; + List statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), @@ -117,8 +116,7 @@ class TwoGangSwitchBloc extends Bloc { ) async { emit(TwoGangSwitchLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = TwoGangStatusModel.fromJson( event.devicesIds.first, status.status, diff --git a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart index f4596d8c..b9208211 100644 --- a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart +++ b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_state.dart @@ -22,7 +22,7 @@ class TwoGangSwitchStatusLoaded extends TwoGangSwitchState { class TwoGangSwitchError extends TwoGangSwitchState { final String message; - TwoGangSwitchError(this.message); + TwoGangSwitchError(this.message); @override List get props => [message]; diff --git a/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart b/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart index 78794d72..58094a71 100644 --- a/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart +++ b/lib/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart @@ -21,7 +21,7 @@ class TwoGangStatusModel { late int countDown; late int countDown2; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': switch1 = bool.tryParse(status.value.toString()) ?? false; diff --git a/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart b/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart index 1284a93b..e8346cb2 100644 --- a/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart +++ b/lib/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart @@ -10,8 +10,7 @@ import 'package:syncrow_web/pages/device_managment/two_gang_switch/factories/two import 'package:syncrow_web/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class TwoGangBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class TwoGangBatchControlView extends StatelessWidget with HelperResponsiveLayout { const TwoGangBatchControlView({super.key, required this.deviceIds}); final List deviceIds; @@ -19,17 +18,15 @@ class TwoGangBatchControlView extends StatelessWidget @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - TwoGangSwitchBlocFactory.create(deviceId: deviceIds.first) - ..add(TwoGangSwitchFetchBatchEvent(deviceIds)), + create: (context) => TwoGangSwitchBlocFactory.create(deviceId: deviceIds.first) + ..add(TwoGangSwitchFetchBatchEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is TwoGangSwitchLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is TwoGangSwitchStatusLoaded) { return _buildStatusControls(context, state.status); - } else if (state is TwoGangSwitchError || - state is TwoGangSwitchControlError) { + } else if (state is TwoGangSwitchError || state is TwoGangSwitchControlError) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); diff --git a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart index 4db3798e..630a132b 100644 --- a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart +++ b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart @@ -55,8 +55,7 @@ class WallSensorBloc extends Bloc { ) async { emit(WallSensorLoadingInitialState()); try { - final response = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final response = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = WallSensorModel.fromJson(response.status); emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); } catch (e) { @@ -69,9 +68,9 @@ class WallSensorBloc extends Bloc { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); ref.onValue.listen((event) { - final eventsMap = event.snapshot.value! as Map; + final eventsMap = event.snapshot.value as Map; - final statusList = []; + List statusList = []; eventsMap['status'].forEach((element) { statusList.add( Status(code: element['code'], value: element['value']), diff --git a/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart b/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart index d193df93..92b1842e 100644 --- a/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart +++ b/lib/pages/device_managment/wall_sensor/model/wall_sensor_model.dart @@ -23,46 +23,46 @@ class WallSensorModel { required this.noBodyTime}); factory WallSensorModel.fromJson(List jsonList) { - late String presenceState; - late int farDetection; - late int presenceTime; - late int motionSensitivity; - late int motionlessSensitivity; - late int currentDistance; - late int illuminance; - late bool indicator; - late int noBodyTime; + late String _presenceState; + late int _farDetection; + late int _presenceTime; + late int _motionSensitivity; + late int _motionlessSensitivity; + late int _currentDistance; + late int _illuminance; + late bool _indicator; + late int _noBodyTime; - for (var i = 0; i < jsonList.length; i++) { + for (int i = 0; i < jsonList.length; i++) { if (jsonList[i].code == 'presence_state') { - presenceState = jsonList[i].value ?? 'none'; + _presenceState = jsonList[i].value ?? 'none'; } else if (jsonList[i].code == 'far_detection') { - farDetection = jsonList[i].value ?? 0; + _farDetection = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'presence_time') { - presenceTime = jsonList[i].value ?? 0; + _presenceTime = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'motion_sensitivity_value') { - motionSensitivity = jsonList[i].value ?? 0; + _motionSensitivity = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'motionless_sensitivity') { - motionlessSensitivity = jsonList[i].value ?? 0; + _motionlessSensitivity = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'dis_current') { - currentDistance = jsonList[i].value ?? 0; + _currentDistance = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'illuminance_value') { - illuminance = jsonList[i].value ?? 0; + _illuminance = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'indicator') { - indicator = jsonList[i].value ?? false; + _indicator = jsonList[i].value ?? false; } else if (jsonList[i].code == 'no_one_time') { - noBodyTime = jsonList[i].value ?? 0; + _noBodyTime = jsonList[i].value ?? 0; } } return WallSensorModel( - presenceState: presenceState, - farDetection: farDetection, - presenceTime: presenceTime, - motionSensitivity: motionSensitivity, - motionlessSensitivity: motionlessSensitivity, - currentDistance: currentDistance, - illuminance: illuminance, - indicator: indicator, - noBodyTime: noBodyTime); + presenceState: _presenceState, + farDetection: _farDetection, + presenceTime: _presenceTime, + motionSensitivity: _motionSensitivity, + motionlessSensitivity: _motionlessSensitivity, + currentDistance: _currentDistance, + illuminance: _illuminance, + indicator: _indicator, + noBodyTime: _noBodyTime); } } diff --git a/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart b/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart index 6d15ba37..61108387 100644 --- a/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart +++ b/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart @@ -11,8 +11,7 @@ import 'package:syncrow_web/pages/device_managment/wall_sensor/factories/wall_se import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WallSensorBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class WallSensorBatchControlView extends StatelessWidget with HelperResponsiveLayout { const WallSensorBatchControlView({super.key, required this.devicesIds}); final List devicesIds; @@ -23,21 +22,17 @@ class WallSensorBatchControlView extends StatelessWidget final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => - WallSensorBlocFactory.create(deviceId: devicesIds.first) - ..add(WallSensorFetchBatchStatusEvent(devicesIds)), + create: (context) => WallSensorBlocFactory.create(deviceId: devicesIds.first) + ..add(WallSensorFetchBatchStatusEvent(devicesIds)), child: BlocBuilder( builder: (context, state) { - if (state is WallSensorLoadingInitialState || - state is DeviceReportsLoadingState) { + if (state is WallSensorLoadingInitialState || state is DeviceReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is WallSensorUpdateState) { - return _buildGridView(context, state.wallSensorModel, isExtraLarge, - isLarge, isMedium); + return _buildGridView(context, state.wallSensorModel, isExtraLarge, isLarge, isMedium); } else if (state is DeviceReportsFailedState) { final model = context.read().deviceStatus; - return _buildGridView( - context, model, isExtraLarge, isLarge, isMedium); + return _buildGridView(context, model, isExtraLarge, isLarge, isMedium); } return const Center(child: Text('Error fetching status')); }, @@ -45,8 +40,8 @@ class WallSensorBatchControlView extends StatelessWidget ); } - Widget _buildGridView(BuildContext context, WallSensorModel model, - bool isExtraLarge, bool isLarge, bool isMedium) { + Widget _buildGridView( + BuildContext context, WallSensorModel model, bool isExtraLarge, bool isLarge, bool isMedium) { return GridView( padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20), shrinkWrap: true, @@ -99,12 +94,11 @@ class WallSensorBatchControlView extends StatelessWidget maxValue: 10000, steps: 1, description: 'sec', - action: (int value) => - context.read().add(WallSensorBatchControlEvent( - deviceIds: devicesIds, - code: 'no_one_time', - value: value, - ))), + action: (int value) => context.read().add(WallSensorBatchControlEvent( + deviceIds: devicesIds, + code: 'no_one_time', + value: value, + ))), PresenceUpdateData( value: model.farDetection.toDouble(), title: 'Far Detection:', diff --git a/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart b/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart index b6279b07..def8ed93 100644 --- a/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart +++ b/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart @@ -1,22 +1,21 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_status.dart'; -import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart'; import 'package:syncrow_web/pages/device_managment/shared/table/description_view.dart'; import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_bloc.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_state.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_status.dart'; +import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/factories/wall_sensor_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_model.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WallSensorControlsView extends StatelessWidget - with HelperResponsiveLayout { +class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout { const WallSensorControlsView({super.key, required this.device}); final AllDevicesModel device; @@ -27,23 +26,19 @@ class WallSensorControlsView extends StatelessWidget final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => WallSensorBlocFactory.create(deviceId: device.uuid!) - ..add(WallSensorFetchStatusEvent()), + create: (context) => + WallSensorBlocFactory.create(deviceId: device.uuid!)..add(WallSensorFetchStatusEvent()), child: BlocBuilder( builder: (context, state) { - if (state is WallSensorLoadingInitialState || - state is DeviceReportsLoadingState) { + if (state is WallSensorLoadingInitialState || state is DeviceReportsLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is WallSensorUpdateState) { - return _buildGridView(context, state.wallSensorModel, isExtraLarge, - isLarge, isMedium); + return _buildGridView(context, state.wallSensorModel, isExtraLarge, isLarge, isMedium); } else if (state is DeviceReportsState) { return ReportsTable( report: state.deviceReport, - thirdColumnTitle: - state.code == 'illuminance_value' ? 'Value' : 'Status', - thirdColumnDescription: - state.code == 'illuminance_value' ? 'Lux' : null, + thirdColumnTitle: state.code == 'illuminance_value' ? "Value" : 'Status', + thirdColumnDescription: state.code == 'illuminance_value' ? "Lux" : null, onRowTap: (index) {}, onClose: () { context.read().add(BackToGridViewEvent()); @@ -58,8 +53,7 @@ class WallSensorControlsView extends StatelessWidget ); } else if (state is DeviceReportsFailedState) { final model = context.read().deviceStatus; - return _buildGridView( - context, model, isExtraLarge, isLarge, isMedium); + return _buildGridView(context, model, isExtraLarge, isLarge, isMedium); } return const Center(child: Text('Error fetching status')); }, @@ -67,8 +61,8 @@ class WallSensorControlsView extends StatelessWidget ); } - Widget _buildGridView(BuildContext context, WallSensorModel model, - bool isExtraLarge, bool isLarge, bool isMedium) { + Widget _buildGridView( + BuildContext context, WallSensorModel model, bool isExtraLarge, bool isLarge, bool isMedium) { return GridView( padding: const EdgeInsets.symmetric(horizontal: 50), shrinkWrap: true, @@ -137,11 +131,10 @@ class WallSensorControlsView extends StatelessWidget maxValue: 10000, steps: 1, description: 'sec', - action: (int value) => - context.read().add(WallSensorChangeValueEvent( - code: 'no_one_time', - value: value, - ))), + action: (int value) => context.read().add(WallSensorChangeValueEvent( + code: 'no_one_time', + value: value, + ))), PresenceUpdateData( value: model.farDetection.toDouble(), title: 'Far Detection:', @@ -158,8 +151,9 @@ class WallSensorControlsView extends StatelessWidget ), GestureDetector( onTap: () { - context.read().add(GetDeviceReportsEvent( - code: 'illuminance_value', deviceUuid: device.uuid!)); + context + .read() + .add(GetDeviceReportsEvent(code: 'illuminance_value', deviceUuid: device.uuid!)); }, child: const PresenceStaticWidget( icon: Assets.illuminanceRecordIcon, @@ -168,8 +162,9 @@ class WallSensorControlsView extends StatelessWidget ), GestureDetector( onTap: () { - context.read().add(GetDeviceReportsEvent( - code: 'presence_state', deviceUuid: device.uuid!)); + context + .read() + .add(GetDeviceReportsEvent(code: 'presence_state', deviceUuid: device.uuid!)); }, child: const PresenceStaticWidget( icon: Assets.presenceRecordIcon, diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart index 69b49e4c..560a61e1 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart @@ -123,13 +123,11 @@ class WaterHeaterBloc extends Bloc { countdownRemaining: countdownRemaining, )); - if (!currentState.isCountdownActive! && - countdownRemaining > Duration.zero) { + if (!currentState.isCountdownActive! && countdownRemaining > Duration.zero) { _startCountdownTimer(emit, countdownRemaining); } } else if (event.scheduleMode == ScheduleModes.inching) { - final inchingDuration = - Duration(hours: event.hours, minutes: event.minutes); + final inchingDuration = Duration(hours: event.hours, minutes: event.minutes); emit( currentState.copyWith( @@ -167,7 +165,7 @@ class WaterHeaterBloc extends Bloc { ); if (success) { - if (event.code == 'countdown_1') { + if (event.code == "countdown_1") { final countdownDuration = Duration(seconds: event.value); emit( @@ -192,7 +190,7 @@ class WaterHeaterBloc extends Bloc { ), ); } - } else if (event.code == 'switch_inching') { + } else if (event.code == "switch_inching") { final inchingDuration = Duration(seconds: event.value); emit( currentState.copyWith( @@ -238,8 +236,7 @@ class WaterHeaterBloc extends Bloc { try { final status = await DevicesManagementApi().deviceControl( event.deviceId, - Status( - code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), + Status(code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), ); if (!status) { emit(const WaterHeaterFailedState(error: 'Failed to stop schedule.')); @@ -257,10 +254,8 @@ class WaterHeaterBloc extends Bloc { emit(WaterHeaterLoadingState()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = - WaterHeaterStatusModel.fromJson(event.deviceId, status.status); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = WaterHeaterStatusModel.fromJson(event.deviceId, status.status); if (deviceStatus.scheduleMode == ScheduleModes.countdown) { final countdownRemaining = Duration( @@ -331,20 +326,21 @@ class WaterHeaterBloc extends Bloc { void _listenToChanges(deviceId) { try { - final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; stream.listen((DatabaseEvent event) { - final usersMap = event.snapshot.value! as Map; + Map usersMap = + event.snapshot.value as Map; - final statusList = []; + List statusList = []; usersMap['status'].forEach((element) { - statusList - .add(Status(code: element['code'], value: element['value'])); + statusList.add(Status(code: element['code'], value: element['value'])); }); - deviceStatus = WaterHeaterStatusModel.fromJson( - usersMap['productUuid'], statusList); + deviceStatus = + WaterHeaterStatusModel.fromJson(usersMap['productUuid'], statusList); if (!isClosed) { add(StatusUpdated(deviceStatus)); } @@ -479,14 +475,14 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - final newSchedule = ScheduleEntry( + ScheduleEntry newSchedule = ScheduleEntry( category: event.category, time: formatTimeOfDayToISO(event.time), function: Status(code: 'switch_1', value: event.functionOn), days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - final success = await DevicesManagementApi() + bool success = await DevicesManagementApi() .addScheduleRecord(newSchedule, currentState.status.uuid); if (success) { @@ -504,7 +500,7 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - final newSchedule = ScheduleEntry( + ScheduleEntry newSchedule = ScheduleEntry( scheduleId: event.scheduleId, category: event.category, time: formatTimeOfDayToISO(event.time), @@ -512,7 +508,7 @@ class WaterHeaterBloc extends Bloc { days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - final success = await DevicesManagementApi().editScheduleRecord( + bool success = await DevicesManagementApi().editScheduleRecord( currentState.status.uuid, newSchedule, ); @@ -542,7 +538,7 @@ class WaterHeaterBloc extends Bloc { return schedule; }).toList(); - final success = await DevicesManagementApi().updateScheduleRecord( + bool success = await DevicesManagementApi().updateScheduleRecord( enable: event.enable, uuid: currentState.status.uuid, scheduleId: event.scheduleId, @@ -563,7 +559,7 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - final success = await DevicesManagementApi() + bool success = await DevicesManagementApi() .deleteScheduleRecord(currentState.status.uuid, event.scheduleId); if (success) { @@ -588,8 +584,8 @@ class WaterHeaterBloc extends Bloc { final status = await DevicesManagementApi().getBatchStatus( event.devicesUuid, ); - deviceStatus = WaterHeaterStatusModel.fromJson( - event.devicesUuid.first, status.status); + deviceStatus = + WaterHeaterStatusModel.fromJson(event.devicesUuid.first, status.status); emit(WaterHeaterDeviceStatusLoaded(deviceStatus)); } catch (e) { @@ -597,8 +593,8 @@ class WaterHeaterBloc extends Bloc { } } - Future _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, - Emitter emit) async { + Future _batchControlWaterHeater( + ControlWaterHeaterBatchEvent event, Emitter emit) async { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; @@ -617,7 +613,7 @@ class WaterHeaterBloc extends Bloc { ); if (success) { - if (event.code == 'switch_1') { + if (event.code == "switch_1") { emit(currentState.copyWith( status: deviceStatus, )); diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart index 92c5c293..e4cc8474 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart @@ -54,6 +54,7 @@ final class WaterHeaterFetchStatusEvent extends WaterHeaterEvent { final class DecrementCountdownEvent extends WaterHeaterEvent {} + class StatusUpdated extends WaterHeaterEvent { final WaterHeaterStatusModel deviceStatus; const StatusUpdated(this.deviceStatus); @@ -61,6 +62,7 @@ class StatusUpdated extends WaterHeaterEvent { List get props => [deviceStatus]; } + final class AddScheduleEvent extends WaterHeaterEvent { final List selectedDays; final TimeOfDay time; diff --git a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart index 27df3a9e..9278e396 100644 --- a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart +++ b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart @@ -7,12 +7,11 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class ScheduleDialogHelper { - static void showAddScheduleDialog(BuildContext context, - {ScheduleModel? schedule, int? index, bool? isEdit}) { + static void showAddScheduleDialog(BuildContext context, {ScheduleModel? schedule, int? index, bool? isEdit}) { final bloc = context.read(); if (schedule == null) { - bloc.add(const UpdateSelectedTimeEvent(null)); + bloc.add((const UpdateSelectedTimeEvent(null))); bloc.add(InitializeAddScheduleEvent( selectedTime: null, selectedDays: List.filled(7, false), @@ -71,10 +70,9 @@ class ScheduleDialogHelper { backgroundColor: ColorsManager.boxColor, borderRadius: 15, onPressed: () async { - final time = await showTimePicker( + TimeOfDay? time = await showTimePicker( context: context, - initialTime: - state.selectedTime ?? TimeOfDay.now(), + initialTime: state.selectedTime ?? TimeOfDay.now(), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( @@ -94,9 +92,7 @@ class ScheduleDialogHelper { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - state.selectedTime == null - ? 'Time' - : state.selectedTime!.format(context), + state.selectedTime == null ? 'Time' : state.selectedTime!.format(context), style: context.textTheme.bodySmall!.copyWith( color: ColorsManager.grayColor, ), @@ -111,8 +107,7 @@ class ScheduleDialogHelper { ), ), const SizedBox(height: 16), - _buildDayCheckboxes(context, state.selectedDays, - isEdit: isEdit), + _buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit), const SizedBox(height: 16), _buildFunctionSwitch(context, state.functionOn, isEdit), ], @@ -186,9 +181,9 @@ class ScheduleDialogHelper { static List _convertDaysStringToBooleans(List selectedDays) { final daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - final daysBoolean = List.filled(7, false); + List daysBoolean = List.filled(7, false); - for (var i = 0; i < daysOfWeek.length; i++) { + for (int i = 0; i < daysOfWeek.length; i++) { if (selectedDays.contains(daysOfWeek[i])) { daysBoolean[i] = true; } @@ -197,9 +192,7 @@ class ScheduleDialogHelper { return daysBoolean; } - static Widget _buildDayCheckboxes( - BuildContext context, List selectedDays, - {bool? isEdit}) { + static Widget _buildDayCheckboxes(BuildContext context, List selectedDays, {bool? isEdit}) { final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; return Row( @@ -209,9 +202,7 @@ class ScheduleDialogHelper { Checkbox( value: selectedDays[index], onChanged: (bool? value) { - context - .read() - .add(UpdateSelectedDayEvent(index, value!)); + context.read().add(UpdateSelectedDayEvent(index, value!)); }, ), Text(dayLabels[index]), @@ -221,23 +212,19 @@ class ScheduleDialogHelper { ); } - static Widget _buildFunctionSwitch( - BuildContext context, bool isOn, bool? isEdit) { + static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) { return Row( children: [ Text( 'Function:', - style: context.textTheme.bodySmall! - .copyWith(color: ColorsManager.grayColor), + style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor), ), const SizedBox(width: 10), Radio( value: true, groupValue: isOn, onChanged: (bool? value) { - context - .read() - .add(const UpdateFunctionOnEvent(true)); + context.read().add(const UpdateFunctionOnEvent(true)); }, ), const Text('On'), @@ -246,9 +233,7 @@ class ScheduleDialogHelper { value: false, groupValue: isOn, onChanged: (bool? value) { - context - .read() - .add(const UpdateFunctionOnEvent(false)); + context.read().add(const UpdateFunctionOnEvent(false)); }, ), const Text('Off'), diff --git a/lib/pages/device_managment/water_heater/models/schedule_entry.dart b/lib/pages/device_managment/water_heater/models/schedule_entry.dart index 4a379009..a2a109af 100644 --- a/lib/pages/device_managment/water_heater/models/schedule_entry.dart +++ b/lib/pages/device_managment/water_heater/models/schedule_entry.dart @@ -58,8 +58,7 @@ class ScheduleEntry { String toJson() => json.encode(toMap()); - factory ScheduleEntry.fromJson(String source) => - ScheduleEntry.fromMap(json.decode(source)); + factory ScheduleEntry.fromJson(String source) => ScheduleEntry.fromMap(json.decode(source)); @override bool operator ==(Object other) { @@ -74,9 +73,6 @@ class ScheduleEntry { @override int get hashCode { - return category.hashCode ^ - time.hashCode ^ - function.hashCode ^ - days.hashCode; + return category.hashCode ^ time.hashCode ^ function.hashCode ^ days.hashCode; } } diff --git a/lib/pages/device_managment/water_heater/models/schedule_model.dart b/lib/pages/device_managment/water_heater/models/schedule_model.dart index b90cf921..3d05a3e0 100644 --- a/lib/pages/device_managment/water_heater/models/schedule_model.dart +++ b/lib/pages/device_managment/water_heater/models/schedule_model.dart @@ -1,8 +1,7 @@ import 'dart:convert'; - -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; +import 'package:flutter/foundation.dart'; class ScheduleModel { final String scheduleId; @@ -94,8 +93,8 @@ class ScheduleModel { static List convertSelectedDaysToStrings(List selectedDays) { const allDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - final result = []; - for (var i = 0; i < selectedDays.length; i++) { + List result = []; + for (int i = 0; i < selectedDays.length; i++) { if (selectedDays[i]) { result.add(allDays[i]); } diff --git a/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart b/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart index e4b48b5d..c535bda2 100644 --- a/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart +++ b/lib/pages/device_managment/water_heater/models/water_heater_status_model.dart @@ -16,7 +16,7 @@ class WaterHeaterStatusModel extends Equatable { final String cycleTiming; final List schedules; - const WaterHeaterStatusModel({ + const WaterHeaterStatusModel({ required this.uuid, required this.heaterSwitch, required this.countdownHours, @@ -30,13 +30,13 @@ class WaterHeaterStatusModel extends Equatable { }); factory WaterHeaterStatusModel.fromJson(String id, List jsonList) { - late var heaterSwitch = false; - late var countdownInSeconds = 0; - late var relayStatus = ''; - late var cycleTiming = ''; - late var scheduleMode = ScheduleModes.countdown; + late bool heaterSwitch = false; + late int countdownInSeconds = 0; + late String relayStatus = ''; + late String cycleTiming = ''; + late ScheduleModes scheduleMode = ScheduleModes.countdown; - for (final status in jsonList) { + for (var status in jsonList) { switch (status.code) { case 'switch_1': heaterSwitch = status.value ?? false; diff --git a/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart b/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart index 97ef6302..3c8a3858 100644 --- a/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart +++ b/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart @@ -37,8 +37,7 @@ class WaterHEaterBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, WaterHeaterStatusModel status) { + Widget _buildStatusControls(BuildContext context, WaterHeaterStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart index f654e62c..f1e56136 100644 --- a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart +++ b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart @@ -35,8 +35,7 @@ class WaterHeaterDeviceControlView extends StatelessWidget state is WaterHeaterBatchFailedState) { return const Center(child: Text('Error fetching status')); } else { - return const SizedBox( - height: 200, child: Center(child: SizedBox())); + return const SizedBox(height: 200, child: Center(child: SizedBox())); } }, )); diff --git a/lib/pages/device_managment/water_heater/widgets/count_down_button.dart b/lib/pages/device_managment/water_heater/widgets/count_down_button.dart index 4107b6ce..e60c7def 100644 --- a/lib/pages/device_managment/water_heater/widgets/count_down_button.dart +++ b/lib/pages/device_managment/water_heater/widgets/count_down_button.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class CountdownModeButtons extends StatelessWidget { diff --git a/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart b/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart index 5257dddc..8eec5cca 100644 --- a/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart +++ b/lib/pages/device_managment/water_heater/widgets/inching_mode_buttons.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class InchingModeButtons extends StatelessWidget { @@ -12,12 +12,12 @@ class InchingModeButtons extends StatelessWidget { final int minutes; const InchingModeButtons({ - super.key, + Key? key, required this.isActive, required this.deviceId, required this.hours, required this.minutes, - }); + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart b/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart index 0b2657c5..1710c439 100644 --- a/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart +++ b/lib/pages/device_managment/water_heater/widgets/schedule_managment_ui.dart @@ -28,7 +28,7 @@ class ScheduleManagementUI extends StatelessWidget { padding: 2, backgroundColor: ColorsManager.graysColor, borderRadius: 15, - onPressed: onAddSchedule, + onPressed: () => onAddSchedule(), child: Row( children: [ const Icon(Icons.add, color: ColorsManager.primaryColor), diff --git a/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart b/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart index fb73eaf4..bb9ddc8f 100644 --- a/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart +++ b/lib/pages/device_managment/water_heater/widgets/schedule_mode_selector.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; -import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; class ScheduleModeSelector extends StatelessWidget { final WaterHeaterDeviceStatusLoaded state; diff --git a/lib/pages/device_managment/water_heater/widgets/schedule_table.dart b/lib/pages/device_managment/water_heater/widgets/schedule_table.dart index 576ebc2b..18cbbe5a 100644 --- a/lib/pages/device_managment/water_heater/widgets/schedule_table.dart +++ b/lib/pages/device_managment/water_heater/widgets/schedule_table.dart @@ -2,13 +2,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; -import 'package:syncrow_web/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/format_date_time.dart'; +import '../helper/add_schedule_dialog_helper.dart'; + class ScheduleTableWidget extends StatelessWidget { final WaterHeaterDeviceStatusLoaded state; @@ -210,8 +211,8 @@ class ScheduleTableWidget extends StatelessWidget { String _getSelectedDays(List selectedDays) { final days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; - final selectedDaysStr = []; - for (var i = 0; i < selectedDays.length; i++) { + List selectedDaysStr = []; + for (int i = 0; i < selectedDays.length; i++) { if (selectedDays[i]) { selectedDaysStr.add(days[i]); } diff --git a/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart b/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart index ee1390a7..6d3ca9a6 100644 --- a/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart +++ b/lib/pages/device_managment/water_leak/bloc/water_leak_bloc.dart @@ -1,11 +1,13 @@ -import 'dart:async'; - 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_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_state.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart'; + +import 'dart:async'; + import 'package:syncrow_web/services/devices_mang_api.dart'; class WaterLeakBloc extends Bloc { @@ -37,15 +39,17 @@ class WaterLeakBloc extends Bloc { } } - void _listenToChanges() { + _listenToChanges() { try { - final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; stream.listen((DatabaseEvent event) { - final usersMap = event.snapshot.value! as Map; + Map usersMap = + event.snapshot.value as Map; - final statusList = []; + List statusList = []; usersMap['status'].forEach((element) { statusList .add(Status(code: element['code'], value: element['value'])); @@ -191,8 +195,9 @@ class WaterLeakBloc extends Bloc { .subtract(const Duration(days: 30)) .millisecondsSinceEpoch; final to = DateTime.now().millisecondsSinceEpoch; - final records = await DevicesManagementApi.getDeviceReportsByDate( - event.deviceId, event.code, from.toString(), to.toString()); + final DeviceReport records = + await DevicesManagementApi.getDeviceReportsByDate( + event.deviceId, event.code, from.toString(), to.toString()); emit(WaterLeakReportsLoadedState(records)); } catch (e) { emit(WaterLeakReportsFailedState(e.toString())); diff --git a/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart b/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart index 30b077bf..1eb795e5 100644 --- a/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart +++ b/lib/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart @@ -10,17 +10,16 @@ import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_st import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WaterLeakBatchControlView extends StatelessWidget - with HelperResponsiveLayout { +class WaterLeakBatchControlView extends StatelessWidget with HelperResponsiveLayout { final List deviceIds; - const WaterLeakBatchControlView({super.key, required this.deviceIds}); + const WaterLeakBatchControlView({Key? key, required this.deviceIds}) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => WaterLeakBloc(deviceIds.first) - ..add(FetchWaterLeakBatchStatusEvent(deviceIds)), + create: (context) => + WaterLeakBloc(deviceIds.first)..add(FetchWaterLeakBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is WaterLeakLoadingState) { @@ -37,8 +36,7 @@ class WaterLeakBatchControlView extends StatelessWidget ); } - Widget _buildStatusControls( - BuildContext context, WaterLeakStatusModel status) { + Widget _buildStatusControls(BuildContext context, WaterLeakStatusModel status) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart b/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart index 51fd5880..6b9dc564 100644 --- a/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart +++ b/lib/pages/device_managment/water_leak/view/water_leak_control_view.dart @@ -13,7 +13,7 @@ import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_la class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { final String deviceId; - const WaterLeakView({super.key, required this.deviceId}); + const WaterLeakView({Key? key, required this.deviceId}) : super(key: key); @override Widget build(BuildContext context) { @@ -21,8 +21,7 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => - WaterLeakBloc(deviceId)..add(FetchWaterLeakStatusEvent(deviceId)), + create: (context) => WaterLeakBloc(deviceId)..add(FetchWaterLeakStatusEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is WaterLeakLoadingState) { @@ -45,31 +44,21 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { children: [ IconNameStatusContainer( isFullIcon: false, - name: state.status.watersensorState == 'normal' - ? 'Normal' - : 'Leak Detection', - icon: state.status.watersensorState == 'normal' - ? Assets.waterLeakNormal - : Assets.waterLeakDetected, + name: state.status.watersensorState == 'normal' ? 'Normal' : 'Leak Detection', + icon: state.status.watersensorState == 'normal' ? Assets.waterLeakNormal : Assets.waterLeakDetected, onTap: () {}, status: state.status.watersensorState == 'normal', - textColor: state.status.watersensorState == 'normal' - ? ColorsManager.blackColor - : ColorsManager.red, + textColor: state.status.watersensorState == 'normal' ? ColorsManager.blackColor : ColorsManager.red, ), IconNameStatusContainer( isFullIcon: false, name: 'Records', icon: Assets.records, onTap: () { - context - .read() - .add(FetchWaterLeakReportsEvent( + context.read().add(FetchWaterLeakReportsEvent( deviceId: deviceId, code: 'watersensor_state', - from: DateTime.now() - .subtract(const Duration(days: 30)) - .millisecondsSinceEpoch, + from: DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch, to: DateTime.now().millisecondsSinceEpoch, )); }, @@ -109,9 +98,7 @@ class WaterLeakView extends StatelessWidget with HelperResponsiveLayout { waterLeak: true, onRowTap: (index) {}, onClose: () { - context - .read() - .add(FetchWaterLeakStatusEvent(deviceId)); + context.read().add(FetchWaterLeakStatusEvent(deviceId)); }, ); } else if (state is WaterLeakReportsFailedState) { diff --git a/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart b/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart index 924973c5..0e3e325f 100644 --- a/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart +++ b/lib/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart @@ -6,8 +6,7 @@ class WaterLeakNotificationDialog extends StatefulWidget { const WaterLeakNotificationDialog({super.key}); @override - State createState() => - _NotificationDialogState(); + State createState() => _NotificationDialogState(); } class _NotificationDialogState extends State { @@ -54,7 +53,7 @@ class _NotificationDialogState extends State { ), ), child: IconButton( - padding: const EdgeInsets.all(1), + padding: EdgeInsets.all(1), icon: const Icon( Icons.close, color: Colors.grey, diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index d422f318..ad6ed4d8 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -13,13 +13,14 @@ import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/services/home_api.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/routes_const.dart'; +import 'package:syncrow_web/utils/navigation_service.dart'; class HomeBloc extends Bloc { UserModel? user; String terms = ''; String policy = ''; - HomeBloc() : super(HomeInitial()) { + HomeBloc() : super((HomeInitial())) { // on(_createNode); on(_fetchUserInfo); on(_fetchTerms); @@ -29,12 +30,13 @@ class HomeBloc extends Bloc { Future _fetchUserInfo(FetchUserInfo event, Emitter emit) async { try { - final uuid = + var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); user = await HomeApi().fetchUserInfo(uuid); if (user != null && user!.project != null) { await ProjectManager.setProjectUUID(user!.project!.uuid); + } add(FetchTermEvent()); add(FetchPolicyEvent()); @@ -61,7 +63,7 @@ class HomeBloc extends Bloc { policy = await HomeApi().fetchPolicy(); emit(HomeInitial()); } catch (e) { - debugPrint('Error fetching policy: $e'); + debugPrint("Error fetching policy: $e"); return; } } @@ -70,7 +72,7 @@ class HomeBloc extends Bloc { ConfirmUserAgreementEvent event, Emitter emit) async { try { emit(LoadingHome()); - final uuid = + var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); policy = await HomeApi().confirmUserAgreements(uuid); emit(PolicyAgreement()); @@ -144,21 +146,21 @@ class HomeBloc extends Bloc { // icon: Assets.energyIcon, // active: false, // onPress: (context) {}, - // color: ColorsManager.slidingBlueColor.withValues(alpha:0.2), + // color: ColorsManager.slidingBlueColor.withOpacity(0.2), // ), // HomeItemModel( // title: 'Integrations', // icon: Assets.integrationsIcon, // active: false, // onPress: (context) {}, - // color: ColorsManager.slidingBlueColor.withValues(alpha:0.2), + // color: ColorsManager.slidingBlueColor.withOpacity(0.2), // ), // HomeItemModel( // title: 'Asset', // icon: Assets.assetIcon, // active: false, // onPress: (context) {}, - // color: ColorsManager.slidingBlueColor.withValues(alpha:0.2), + // color: ColorsManager.slidingBlueColor.withOpacity(0.2), // ), ]; } diff --git a/lib/pages/home/view/agreement_and_privacy_dialog.dart b/lib/pages/home/view/agreement_and_privacy_dialog.dart index 61e8a150..6b72c300 100644 --- a/lib/pages/home/view/agreement_and_privacy_dialog.dart +++ b/lib/pages/home/view/agreement_and_privacy_dialog.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:go_router/go_router.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/routes_const.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -87,7 +89,7 @@ class _AgreementAndPrivacyDialogState extends State { controller: _scrollController, padding: const EdgeInsets.all(25), child: Html( - data: '$_dialogContent $staticText', + data: "$_dialogContent $staticText", onLinkTap: (url, attributes, element) async { if (url != null) { final uri = Uri.parse(url); @@ -95,10 +97,10 @@ class _AgreementAndPrivacyDialogState extends State { } }, style: { - 'body': Style( + "body": Style( fontSize: FontSize(14), color: Colors.black87, - lineHeight: const LineHeight(1.5), + lineHeight: LineHeight(1.5), ), }, ), @@ -108,7 +110,7 @@ class _AgreementAndPrivacyDialogState extends State { } Widget _buildActionButton() { - final buttonText = _currentPage == 2 ? 'I Agree' : 'Next'; + final String buttonText = _currentPage == 2 ? "I Agree" : "Next"; return InkWell( onTap: _isAtEnd @@ -165,7 +167,7 @@ class _AgreementAndPrivacyDialogState extends State { AuthBloc.logout(context); context.go(RoutesConst.auth); }, - child: const Text('Cancel'), + child: const Text("Cancel"), ), _buildActionButton(), ], diff --git a/lib/pages/home/view/home_page.dart b/lib/pages/home/view/home_page.dart index 9652f0b6..9159011f 100644 --- a/lib/pages/home/view/home_page.dart +++ b/lib/pages/home/view/home_page.dart @@ -11,7 +11,7 @@ class HomePage extends StatelessWidget with HelperResponsiveLayout { final isSmallScreen = isSmallScreenSize(context); final isMediumScreen = isMediumScreenSize(context); return isSmallScreen || isMediumScreen - ? const HomeMobilePage() + ? HomeMobilePage() : const HomeWebPage(); } } diff --git a/lib/pages/home/view/home_page_mobile.dart b/lib/pages/home/view/home_page_mobile.dart index 2b1d502b..ad019ea8 100644 --- a/lib/pages/home/view/home_page_mobile.dart +++ b/lib/pages/home/view/home_page_mobile.dart @@ -4,15 +4,16 @@ import 'package:flutter_svg/svg.dart'; 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/view/home_card.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; class HomeMobilePage extends StatelessWidget { - const HomeMobilePage({super.key}); + HomeMobilePage({super.key}); @override Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; + Size size = MediaQuery.of(context).size; return PopScope( canPop: false, onPopInvoked: (didPop) => false, @@ -40,8 +41,7 @@ class HomeMobilePage extends StatelessWidget { SizedBox(height: size.height * 0.05), const Text( 'ACCESS YOUR APPS', - style: - TextStyle(fontSize: 20, fontWeight: FontWeight.w700), + style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700), ), const SizedBox(height: 30), Expanded( @@ -63,8 +63,8 @@ class HomeMobilePage extends StatelessWidget { index: index, active: true, color: homeBloc.homeItems[index].color, - name: homeBloc.homeItems[index].title!, - img: homeBloc.homeItems[index].icon!, + name: homeBloc.homeItems[index].title!, + img: homeBloc.homeItems[index].icon!, onTap: () => homeBloc.homeItems[index].onPress(context), ); diff --git a/lib/pages/home/view/home_page_web.dart b/lib/pages/home/view/home_page_web.dart index 5adb5a12..53a994f6 100644 --- a/lib/pages/home/view/home_page_web.dart +++ b/lib/pages/home/view/home_page_web.dart @@ -20,9 +20,11 @@ class _HomeWebPageState extends State { // Flag to track whether the dialog is already shown. bool _dialogShown = false; + + @override Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; + Size size = MediaQuery.of(context).size; final homeBloc = BlocProvider.of(context); return PopScope( diff --git a/lib/pages/home/view/tree_page.dart b/lib/pages/home/view/tree_page.dart index f8dc9c33..9458e361 100644 --- a/lib/pages/home/view/tree_page.dart +++ b/lib/pages/home/view/tree_page.dart @@ -144,7 +144,7 @@ // borderRadius: BorderRadius.circular(10.0), // boxShadow: [ // BoxShadow( -// color: Colors.grey.withValues(alpha:0.5), +// color: Colors.grey.withOpacity(0.5), // spreadRadius: 2, // blurRadius: 5, // offset: Offset(0, 3), // changes position of shadow diff --git a/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart b/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart index 15787fd7..4f4988b3 100644 --- a/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart +++ b/lib/pages/roles_and_permission/bloc/roles_permission_bloc.dart @@ -29,7 +29,7 @@ class RolesPermissionBloc bool tapSelect = true; - void changeTapSelected( + changeTapSelected( ChangeTapSelected event, Emitter emit) { try { emit(RolesLoadingState()); diff --git a/lib/pages/roles_and_permission/model/role_type_model.dart b/lib/pages/roles_and_permission/model/role_type_model.dart index 61a52f9d..16b24ec5 100644 --- a/lib/pages/roles_and_permission/model/role_type_model.dart +++ b/lib/pages/roles_and_permission/model/role_type_model.dart @@ -16,7 +16,7 @@ class RoleTypeModel { uuid: json['uuid'], createdAt: json['createdAt'], updatedAt: json['updatedAt'], - type: json['type'].toString().toLowerCase().replaceAll('_', ' '), + type: json['type'].toString().toLowerCase().replaceAll("_", " "), ); } } diff --git a/lib/pages/roles_and_permission/model/roles_user_model.dart b/lib/pages/roles_and_permission/model/roles_user_model.dart index 98049bcb..e502370a 100644 --- a/lib/pages/roles_and_permission/model/roles_user_model.dart +++ b/lib/pages/roles_and_permission/model/roles_user_model.dart @@ -36,14 +36,14 @@ class RolesUserModel { email: json['email'], firstName: json['firstName'], lastName: json['lastName'], - roleType: json['roleType'].toString().toLowerCase().replaceAll('_', ' '), + roleType: json['roleType'].toString().toLowerCase().replaceAll("_", " "), status: json['status'], isEnabled: json['isEnabled'], invitedBy: - json['invitedBy'].toString().toLowerCase().replaceAll('_', ' '), + json['invitedBy'].toString().toLowerCase().replaceAll("_", " "), phoneNumber: json['phoneNumber'], - jobTitle: json['jobTitle'] == null || json['jobTitle'] == ' ' - ? '_' + jobTitle: json['jobTitle'] == null || json['jobTitle'] == " " + ? "_" : json['jobTitle'], createdDate: json['createdDate'], createdTime: json['createdTime'], diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart index 00e8605d..54187152 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart @@ -1,3 +1,4 @@ +import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; @@ -10,6 +11,7 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialo import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/user_permission.dart'; @@ -64,7 +66,7 @@ class UsersBloc extends Bloc { void isCompleteSpacesFun( CheckSpacesStepStatus event, Emitter emit) { emit(UsersLoadingState()); - final spaceBloc = + var spaceBloc = NavigationService.navigatorKey.currentContext!.read(); isCompleteSpaces = spaceBloc.state.selectedCommunities.isNotEmpty; @@ -81,25 +83,26 @@ class UsersBloc extends Bloc { String communityUuid) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - return CommunitySpaceManagementApi() + return await CommunitySpaceManagementApi() .getSpaceHierarchy(communityUuid, projectUuid); } List updatedCommunities = []; List spacesNodes = []; List communityIds = []; - Future _onLoadCommunityAndSpaces( + _onLoadCommunityAndSpaces( LoadCommunityAndSpacesEvent event, Emitter emit) async { try { emit(UsersLoadingState()); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final communities = + List communities = await CommunitySpaceManagementApi().fetchCommunities(projectUuid); communityIds = communities.map((community) => community.uuid).toList(); updatedCommunities = await Future.wait( communities.map((community) async { - final spaces = await _fetchSpacesForCommunity(community.uuid); + List spaces = + await _fetchSpacesForCommunity(community.uuid); spacesNodes = _buildTreeNodes(spaces); return TreeNode( uuid: community.uuid, @@ -126,7 +129,7 @@ class UsersBloc extends Bloc { // Build tree nodes from your data model. List _buildTreeNodes(List spaces) { return spaces.map((space) { - final childNodes = + List childNodes = space.children.isNotEmpty ? _buildTreeNodes(space.children) : []; return TreeNode( uuid: space.uuid!, @@ -167,7 +170,7 @@ class UsersBloc extends Bloc { _clearHighlights(updatedCommunities); } else { // Start with a fresh clone of the original tree. - final freshClone = _cloneNodes(originalCommunities); + List freshClone = _cloneNodes(originalCommunities); _searchAndHighlightNodes(freshClone, event.searchTerm!); @@ -177,7 +180,7 @@ class UsersBloc extends Bloc { } void _clearHighlights(List nodes) { - for (final node in nodes) { + for (var node in nodes) { node.isHighlighted = false; if (node.children.isNotEmpty) { _clearHighlights(node.children); @@ -186,11 +189,11 @@ class UsersBloc extends Bloc { } bool _searchAndHighlightNodes(List nodes, String searchTerm) { - var anyMatch = false; - for (final node in nodes) { - final isMatch = + bool anyMatch = false; + for (var node in nodes) { + bool isMatch = node.title.toLowerCase().contains(searchTerm.toLowerCase()); - final childMatch = _searchAndHighlightNodes(node.children, searchTerm); + bool childMatch = _searchAndHighlightNodes(node.children, searchTerm); node.isHighlighted = isMatch || childMatch; anyMatch = anyMatch || node.isHighlighted; @@ -199,11 +202,11 @@ class UsersBloc extends Bloc { } List _filterNodes(List nodes, String searchTerm) { - final filteredNodes = []; - for (final node in nodes) { - final isMatch = + List filteredNodes = []; + for (var node in nodes) { + bool isMatch = node.title.toLowerCase().contains(searchTerm.toLowerCase()); - final filteredChildren = _filterNodes(node.children, searchTerm); + List filteredChildren = _filterNodes(node.children, searchTerm); if (isMatch || filteredChildren.isNotEmpty) { node.isHighlighted = isMatch; node.children = filteredChildren; @@ -286,8 +289,8 @@ class UsersBloc extends Bloc { List selectedIds = []; List getSelectedIds(List nodes) { - final selectedIds = []; - for (final node in nodes) { + List selectedIds = []; + for (var node in nodes) { if (node.isChecked) { selectedIds.add(node.uuid); } @@ -301,8 +304,7 @@ class UsersBloc extends Bloc { List roles = []; List permissions = []; - Future _getRolePermission( - RoleEvent event, Emitter emit) async { + _getRolePermission(RoleEvent event, Emitter emit) async { try { emit(UsersLoadingState()); roles = await UserPermissionApi().fetchRoles(); @@ -312,12 +314,11 @@ class UsersBloc extends Bloc { } } - Future _getPermissions( - PermissionEvent event, Emitter emit) async { + _getPermissions(PermissionEvent event, Emitter emit) async { try { emit(UsersLoadingState()); permissions = await UserPermissionApi().fetchPermission( - event.roleUuid == '' ? roles.first.uuid : event.roleUuid); + event.roleUuid == "" ? roles.first.uuid : event.roleUuid); roleSelected = event.roleUuid!; emit(RolePermissionInitial()); } catch (e) { @@ -326,19 +327,18 @@ class UsersBloc extends Bloc { } bool _searchRolePermission(List nodes, String searchTerm) { - var anyMatch = false; - for (final node in nodes) { - final isMatch = + bool anyMatch = false; + for (var node in nodes) { + bool isMatch = node.title.toLowerCase().contains(searchTerm.toLowerCase()); - final childMatch = _searchRolePermission(node.subOptions, searchTerm); + bool childMatch = _searchRolePermission(node.subOptions, searchTerm); node.isHighlighted = isMatch || childMatch; anyMatch = anyMatch || node.isHighlighted; } return anyMatch; } - Future _sendInvitUser( - SendInviteUsers event, Emitter emit) async { + void _sendInvitUser(SendInviteUsers event, Emitter emit) async { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -346,10 +346,10 @@ class UsersBloc extends Bloc { // List selectedIds = // getSelectedIds(updatedCommunities).where((id) => !communityIds.contains(id)).toList(); - final selectedSpacesId = getSelectedSpacesIds(); + List selectedSpacesId = getSelectedSpacesIds(); // List selectedIds = getSelectedIds(updatedCommunities); - final res = await UserPermissionApi().sendInviteUser( + bool res = await UserPermissionApi().sendInviteUser( email: emailController.text, firstName: firstNameController.text, jobTitle: jobTitleController.text, @@ -363,9 +363,9 @@ class UsersBloc extends Bloc { showCustomDialog( barrierDismissible: false, context: event.context, - message: 'The invite was sent successfully.', + message: "The invite was sent successfully.", iconPath: Assets.deviceNoteIcon, - title: 'Invite Success', + title: "Invite Success", dialogHeight: MediaQuery.of(event.context).size.height * 0.3, actions: [ TextButton( @@ -382,28 +382,27 @@ class UsersBloc extends Bloc { } emit(SaveState()); } catch (e) { - emit(ErrorState('Failed to send invite: $e')); + emit(ErrorState('Failed to send invite: ${e.toString()}')); } } List getSelectedSpacesIds() { - final selectedSpacesId = []; - final spaceBloc = + List selectedSpacesId = []; + var spaceBloc = NavigationService.navigatorKey.currentContext!.read(); - for (final community in spaceBloc.state.selectedCommunities) { + for (var community in spaceBloc.state.selectedCommunities) { selectedSpacesId .addAll(spaceBloc.state.selectedCommunityAndSpaces[community] ?? []); } return selectedSpacesId; } - Future _editInviteUser( - EditInviteUsers event, Emitter emit) async { + _editInviteUser(EditInviteUsers event, Emitter emit) async { try { emit(UsersLoadingState()); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final res = await UserPermissionApi().editInviteUser( + bool res = await UserPermissionApi().editInviteUser( userId: event.userId, firstName: firstNameController.text, jobTitle: jobTitleController.text, @@ -416,9 +415,9 @@ class UsersBloc extends Bloc { showCustomDialog( barrierDismissible: false, context: event.context, - message: 'The invite was sent successfully.', + message: "The invite was sent successfully.", iconPath: Assets.deviceNoteIcon, - title: 'Invite Success', + title: "Invite Success", dialogHeight: MediaQuery.of(event.context).size.height * 0.3, actions: [ TextButton( @@ -437,7 +436,7 @@ class UsersBloc extends Bloc { } emit(SaveState()); } catch (e) { - emit(ErrorState('Failed to send invite: $e')); + emit(ErrorState('Failed to send invite: ${e.toString()}')); } } @@ -456,7 +455,7 @@ class UsersBloc extends Bloc { Future checkEmail( CheckEmailEvent event, Emitter emit) async { emit(UsersLoadingState()); - final res = await UserPermissionApi().checkEmail( + String? res = await UserPermissionApi().checkEmail( emailController.text, ); checkEmailValid = res!; @@ -470,8 +469,8 @@ class UsersBloc extends Bloc { final emailRegex = RegExp( r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', ); - final isEmailValid = emailRegex.hasMatch(emailController.text); - final isEmailServerValid = checkEmailValid == 'Valid email'; + bool isEmailValid = emailRegex.hasMatch(emailController.text); + bool isEmailServerValid = checkEmailValid == 'Valid email'; isCompleteBasics = firstNameController.text.isNotEmpty && lastNameController.text.isNotEmpty && emailController.text.isNotEmpty && @@ -487,7 +486,7 @@ class UsersBloc extends Bloc { } void _clearHighlightsRolePermission(List nodes) { - for (final node in nodes) { + for (var node in nodes) { node.isHighlighted = false; if (node.subOptions.isNotEmpty) { _clearHighlightsRolePermission(node.subOptions); @@ -516,7 +515,7 @@ class UsersBloc extends Bloc { emit(UsersLoadingState()); try { - final spaceBloc = + var spaceBloc = NavigationService.navigatorKey.currentContext!.read(); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -534,9 +533,9 @@ class UsersBloc extends Bloc { res.roleType; res.spaces.map((space) { selectedIds.add(space.uuid); - final community = spaceBloc.state.communityList + CommunityModel community = spaceBloc.state.communityList .firstWhere((item) => item.uuid == space.communityUuid); - spaceBloc.add(OnSpaceSelected(community, space.uuid, const [])); + spaceBloc.add(OnSpaceSelected(community, space.uuid, [])); }).toList(); // if (updatedCommunities.isNotEmpty) { @@ -549,7 +548,7 @@ class UsersBloc extends Bloc { final roleId = roles .firstWhere((element) => element.type == - res.roleType.toLowerCase().replaceAll('_', ' ')) + res.roleType.toString().toLowerCase().replaceAll("_", " ")) .uuid; debugPrint('Role ID: $roleId'); roleSelected = roleId; @@ -605,14 +604,14 @@ class UsersBloc extends Bloc { } void _updateChildrenCheckStatus(TreeNode node, bool isChecked) { - for (final child in node.children) { + for (var child in node.children) { child.isChecked = isChecked; _updateChildrenCheckStatus(child, isChecked); } } void _updateParentCheckStatus(TreeNode node) { - final parent = _findParent(updatedCommunities, node); + TreeNode? parent = _findParent(updatedCommunities, node); if (parent != null) { parent.isChecked = _areAllChildrenChecked(parent); _updateParentCheckStatus(parent); @@ -627,7 +626,7 @@ class UsersBloc extends Bloc { } TreeNode? _findParent(List nodes, TreeNode target) { - for (final node in nodes) { + for (var node in nodes) { if (node.children.contains(target)) { return node; } diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart index b7dbebd6..2e82168c 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart @@ -48,7 +48,7 @@ class RoleEvent extends UsersEvent { class PermissionEvent extends UsersEvent { final String? roleUuid; - const PermissionEvent({this.roleUuid = ''}); + const PermissionEvent({this.roleUuid = ""}); @override List get props => [roleUuid]; } diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart index 2769fc09..4141ccdd 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/permission_option_model.dart @@ -17,7 +17,7 @@ class PermissionOption { return PermissionOption( id: json['id'] ?? '', title: json['title'] != null - ? json['title'].toString().toLowerCase().replaceAll('_', ' ') + ? json['title'].toString().toLowerCase().replaceAll("_", " ") : '', isChecked: json['isChecked'] ?? false, isHighlighted: json['isHighlighted'] ?? false, diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart index 6f715b5b..a5e622dc 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/model/tree_node_model.dart @@ -14,4 +14,4 @@ class TreeNode { this.isExpanded = false, this.children = const [], }); -} +} \ No newline at end of file diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart index 7d39858c..44ba81ff 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart @@ -29,13 +29,12 @@ class _AddNewUserDialogState extends State { child: BlocConsumer( listener: (context, state) {}, builder: (context, state) { - final blocRole = BlocProvider.of(context); + final _blocRole = BlocProvider.of(context); return Dialog( child: Container( decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(20))), + color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), width: 900, child: Column( children: [ @@ -44,7 +43,7 @@ class _AddNewUserDialogState extends State { padding: EdgeInsets.all(8.0), child: SizedBox( child: Text( - 'Add New User', + "Add New User", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w700, @@ -62,10 +61,9 @@ class _AddNewUserDialogState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildStep1Indicator(1, 'Basics', blocRole), - _buildStep2Indicator(2, 'Spaces', blocRole), - _buildStep3Indicator( - 3, 'Role & Permissions', blocRole), + _buildStep1Indicator(1, "Basics", _blocRole), + _buildStep2Indicator(2, "Spaces", _blocRole), + _buildStep3Indicator(3, "Role & Permissions", _blocRole), ], ), ), @@ -103,35 +101,31 @@ class _AddNewUserDialogState extends State { onTap: () { Navigator.of(context).pop(); }, - child: const Text('Cancel'), + child: const Text("Cancel"), ), InkWell( onTap: () { - blocRole.add(const CheckEmailEvent()); + _blocRole.add(const CheckEmailEvent()); setState(() { if (currentStep < 3) { currentStep++; if (currentStep == 2) { - blocRole.add(const CheckStepStatus( - isEditUser: false)); + _blocRole.add(const CheckStepStatus(isEditUser: false)); } else if (currentStep == 3) { - blocRole.add(const CheckSpacesStepStatus()); + _blocRole.add(const CheckSpacesStepStatus()); } } else { - blocRole - .add(SendInviteUsers(context: context)); + _blocRole.add(SendInviteUsers(context: context)); } }); }, child: Text( - currentStep < 3 ? 'Next' : 'Save', + currentStep < 3 ? "Next" : "Save", style: TextStyle( - color: (blocRole.isCompleteSpaces == false || - blocRole.isCompleteBasics == - false || - blocRole.isCompleteRolePermissions == - false) && + color: (_blocRole.isCompleteSpaces == false || + _blocRole.isCompleteBasics == false || + _blocRole.isCompleteRolePermissions == false) && currentStep == 3 ? ColorsManager.grayColor : ColorsManager.secondaryColor), @@ -202,12 +196,8 @@ class _AddNewUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step - ? ColorsManager.blackColor - : ColorsManager.greyColor, - fontWeight: currentStep == step - ? FontWeight.bold - : FontWeight.normal, + color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, + fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ), ), ], @@ -270,12 +260,8 @@ class _AddNewUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step - ? ColorsManager.blackColor - : ColorsManager.greyColor, - fontWeight: currentStep == step - ? FontWeight.bold - : FontWeight.normal, + color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, + fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ), ), ], @@ -305,7 +291,7 @@ class _AddNewUserDialogState extends State { currentStep = step; step3 = step; bloc.add(const CheckSpacesStepStatus()); - bloc.add(const CheckStepStatus(isEditUser: false)); + bloc.add(CheckStepStatus(isEditUser: false)); }); }, child: Column( @@ -332,12 +318,8 @@ class _AddNewUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step - ? ColorsManager.blackColor - : ColorsManager.greyColor, - fontWeight: currentStep == step - ? FontWeight.bold - : FontWeight.normal, + color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, + fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ), ), ], diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart index e5933995..fa04c051 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart @@ -15,12 +15,12 @@ class BasicsView extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { - final blocRole = BlocProvider.of(context); + final _blocRole = BlocProvider.of(context); if (state is BasicsStepInvalidState) { - blocRole.formKey.currentState?.validate(); + _blocRole.formKey.currentState?.validate(); } return Form( - key: blocRole.formKey, + key: _blocRole.formKey, child: ListView( shrinkWrap: true, children: [ @@ -57,7 +57,7 @@ class BasicsView extends StatelessWidget { child: Row( children: [ const Text( - ' * ', + " * ", style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -84,9 +84,9 @@ class BasicsView extends StatelessWidget { // _blocRole.add(const ValidateBasicsStep()); // }); // }, - controller: blocRole.firstNameController, + controller: _blocRole.firstNameController, decoration: inputTextFormDeco( - hintText: 'Enter first name', + hintText: "Enter first name", ).copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, @@ -117,7 +117,7 @@ class BasicsView extends StatelessWidget { child: Row( children: [ const Text( - ' * ', + " * ", style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -140,10 +140,10 @@ class BasicsView extends StatelessWidget { // _blocRole.add(ValidateBasicsStep()); // }); // }, - controller: blocRole.lastNameController, + controller: _blocRole.lastNameController, style: const TextStyle(color: Colors.black), decoration: - inputTextFormDeco(hintText: 'Enter last name') + inputTextFormDeco(hintText: "Enter last name") .copyWith( hintStyle: context.textTheme.bodyMedium ?.copyWith( @@ -172,7 +172,7 @@ class BasicsView extends StatelessWidget { child: Row( children: [ const Text( - ' * ', + " * ", style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -199,9 +199,9 @@ class BasicsView extends StatelessWidget { // _blocRole.add(ValidateBasicsStep()); // }); // }, - controller: blocRole.emailController, + controller: _blocRole.emailController, style: const TextStyle(color: ColorsManager.blackColor), - decoration: inputTextFormDeco(hintText: 'name@example.com') + decoration: inputTextFormDeco(hintText: "name@example.com") .copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, @@ -218,10 +218,9 @@ class BasicsView extends StatelessWidget { if (!emailRegex.hasMatch(value)) { return 'Enter a valid Email Address'; } - if (blocRole.checkEmailValid != 'Valid email') { - return blocRole.checkEmailValid; + if (_blocRole.checkEmailValid != "Valid email") { + return _blocRole.checkEmailValid; } - return null; // return null; }, ), @@ -255,7 +254,7 @@ class BasicsView extends StatelessWidget { const TextStyle(color: ColorsManager.blackColor), textInputAction: TextInputAction.done, decoration: inputTextFormDeco( - hintText: '05x xxx xxxx', + hintText: "05x xxx xxxx", ).copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, @@ -265,32 +264,32 @@ class BasicsView extends StatelessWidget { initialCountryCode: 'AE', countries: const [ Country( - name: 'United Arab Emirates', + name: "United Arab Emirates", nameTranslations: { - 'en': 'United Arab Emirates', - 'ar': 'الإمارات العربية المتحدة', + "en": "United Arab Emirates", + "ar": "الإمارات العربية المتحدة", }, - flag: '🇦🇪', - code: 'AE', - dialCode: '971', + flag: "🇦🇪", + code: "AE", + dialCode: "971", minLength: 9, maxLength: 9, ), Country( - name: 'Saudi Arabia', + name: "Saudi Arabia", nameTranslations: { - 'en': 'Saudi Arabia', - 'ar': 'السعودية', + "en": "Saudi Arabia", + "ar": "السعودية", }, - flag: '🇸🇦', - code: 'SA', - dialCode: '966', + flag: "🇸🇦", + code: "SA", + dialCode: "966", minLength: 9, maxLength: 9, ), ], style: const TextStyle(color: Colors.black), - controller: blocRole.phoneController, + controller: _blocRole.phoneController, ) ], ), @@ -315,11 +314,11 @@ class BasicsView extends StatelessWidget { Padding( padding: const EdgeInsets.all(8.0), child: TextFormField( - controller: blocRole.jobTitleController, + controller: _blocRole.jobTitleController, style: const TextStyle(color: ColorsManager.blackColor), decoration: inputTextFormDeco( - hintText: 'Job Title (Optional)') + hintText: "Job Title (Optional)") .copyWith( hintStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart index 789e88e2..cbe15ecd 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart'; @@ -18,7 +19,7 @@ class TreeView extends StatelessWidget { @override Widget build(BuildContext context) { - final blocRole = BlocProvider.of(context); + final _blocRole = BlocProvider.of(context); return BlocProvider( create: (_) => UsersBloc(), // ..add(const LoadCommunityAndSpacesEvent()), @@ -33,7 +34,7 @@ class TreeView extends StatelessWidget { return const Center(child: CircularProgressIndicator()); } return SingleChildScrollView( - child: _buildTree(blocRole.updatedCommunities, blocRole), + child: _buildTree(_blocRole.updatedCommunities, _blocRole), ); }, ), @@ -47,7 +48,7 @@ class TreeView extends StatelessWidget { }) { return Column( children: nodes.map((node) { - return ColoredBox( + return Container( color: node.isHighlighted ? Colors.blue.shade50 : Colors.transparent, child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart index fd6666c5..10e8c273 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/delete_user_dialog.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class DeleteUserDialog extends StatefulWidget { final Function()? onTapDelete; - const DeleteUserDialog({super.key, this.onTapDelete}); + DeleteUserDialog({super.key, this.onTapDelete}); @override _DeleteUserDialogState createState() => _DeleteUserDialogState(); @@ -34,7 +35,7 @@ class _DeleteUserDialogState extends State { padding: EdgeInsets.all(8.0), child: SizedBox( child: Text( - 'Delete User', + "Delete User", style: TextStyle( color: ColorsManager.red, fontSize: 18, @@ -53,7 +54,7 @@ class _DeleteUserDialogState extends State { child: Padding( padding: EdgeInsets.only(left: 25, right: 25, top: 10, bottom: 10), child: Text( - 'Are you sure you want to delete this user?', + "Are you sure you want to delete this user?", textAlign: TextAlign.center, ), )), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart index 50ae1d7c..071de067 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/edit_user_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart'; @@ -30,17 +31,15 @@ class _EditUserDialogState extends State { ..add(GetUserByIdEvent(uuid: widget.userId)), child: BlocConsumer(listener: (context, state) { if (state is SpacesLoadedState) { - BlocProvider.of(context) - .add(GetUserByIdEvent(uuid: widget.userId)); + BlocProvider.of(context).add(GetUserByIdEvent(uuid: widget.userId)); } }, builder: (context, state) { - final blocRole = BlocProvider.of(context); + final _blocRole = BlocProvider.of(context); return Dialog( child: Container( decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(20))), + color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), width: 900, child: Column( children: [ @@ -49,7 +48,7 @@ class _EditUserDialogState extends State { padding: EdgeInsets.all(8.0), child: SizedBox( child: Text( - 'Edit User', + "Edit User", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w700, @@ -67,10 +66,9 @@ class _EditUserDialogState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildStep1Indicator(1, 'Basics', blocRole), - _buildStep2Indicator(2, 'Spaces', blocRole), - _buildStep3Indicator( - 3, 'Role & Permissions', blocRole), + _buildStep1Indicator(1, "Basics", _blocRole), + _buildStep2Indicator(2, "Spaces", _blocRole), + _buildStep3Indicator(3, "Role & Permissions", _blocRole), ], ), ), @@ -108,7 +106,7 @@ class _EditUserDialogState extends State { onTap: () { Navigator.of(context).pop(); }, - child: const Text('Cancel'), + child: const Text("Cancel"), ), InkWell( onTap: () { @@ -118,24 +116,22 @@ class _EditUserDialogState extends State { if (currentStep < 3) { currentStep++; if (currentStep == 2) { - blocRole.add( - const CheckStepStatus(isEditUser: true)); + _blocRole.add(CheckStepStatus(isEditUser: true)); } else if (currentStep == 3) { - blocRole.add(const CheckSpacesStepStatus()); + _blocRole.add(const CheckSpacesStepStatus()); } } else { - blocRole.add(EditInviteUsers( - context: context, userId: widget.userId!)); + _blocRole + .add(EditInviteUsers(context: context, userId: widget.userId!)); } }); }, child: Text( - currentStep < 3 ? 'Next' : 'Save', + currentStep < 3 ? "Next" : "Save", style: TextStyle( - color: (blocRole.isCompleteSpaces == false || - blocRole.isCompleteBasics == false || - blocRole.isCompleteRolePermissions == - false) && + color: (_blocRole.isCompleteSpaces == false || + _blocRole.isCompleteBasics == false || + _blocRole.isCompleteRolePermissions == false) && currentStep == 3 ? ColorsManager.grayColor : ColorsManager.secondaryColor), @@ -176,7 +172,7 @@ class _EditUserDialogState extends State { bloc.add(const CheckSpacesStepStatus()); currentStep = step; Future.delayed(const Duration(milliseconds: 500), () { - bloc.add(const ValidateBasicsStep()); + bloc.add(ValidateBasicsStep()); }); }); @@ -208,12 +204,8 @@ class _EditUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step - ? ColorsManager.blackColor - : ColorsManager.greyColor, - fontWeight: currentStep == step - ? FontWeight.bold - : FontWeight.normal, + color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, + fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ), ), ], @@ -241,7 +233,7 @@ class _EditUserDialogState extends State { onTap: () { setState(() { currentStep = step; - bloc.add(const CheckStepStatus(isEditUser: true)); + bloc.add(CheckStepStatus(isEditUser: true)); if (step3 == 3) { bloc.add(const CheckRoleStepStatus()); } @@ -271,12 +263,8 @@ class _EditUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step - ? ColorsManager.blackColor - : ColorsManager.greyColor, - fontWeight: currentStep == step - ? FontWeight.bold - : FontWeight.normal, + color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, + fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ), ), ], @@ -306,7 +294,7 @@ class _EditUserDialogState extends State { currentStep = step; step3 = step; bloc.add(const CheckSpacesStepStatus()); - bloc.add(const CheckStepStatus(isEditUser: true)); + bloc.add(CheckStepStatus(isEditUser: true)); }); }, child: Column( @@ -333,12 +321,8 @@ class _EditUserDialogState extends State { label, style: TextStyle( fontSize: 16, - color: currentStep == step - ? ColorsManager.blackColor - : ColorsManager.greyColor, - fontWeight: currentStep == step - ? FontWeight.bold - : FontWeight.normal, + color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, + fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ), ), ], diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart index 76bacad9..aee84ed4 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/permission_management.dart @@ -7,7 +7,7 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; class PermissionManagement extends StatefulWidget { final UsersBloc? bloc; - const PermissionManagement({super.key, this.bloc}); + const PermissionManagement({Key? key, this.bloc}) : super(key: key); @override _PermissionManagementState createState() => _PermissionManagementState(); @@ -16,25 +16,25 @@ class PermissionManagement extends StatefulWidget { class _PermissionManagementState extends State { void toggleOptionById(String id) { setState(() { - for (final mainOption in widget.bloc!.permissions) { + for (var mainOption in widget.bloc!.permissions) { if (mainOption.id == id) { final isChecked = checkifOneOfthemChecked(mainOption) == CheckState.all; mainOption.isChecked = !isChecked; - for (final subOption in mainOption.subOptions) { + for (var subOption in mainOption.subOptions) { subOption.isChecked = !isChecked; - for (final child in subOption.subOptions) { + for (var child in subOption.subOptions) { child.isChecked = !isChecked; } } return; } - for (final subOption in mainOption.subOptions) { + for (var subOption in mainOption.subOptions) { if (subOption.id == id) { subOption.isChecked = !subOption.isChecked; - for (final child in subOption.subOptions) { + for (var child in subOption.subOptions) { child.isChecked = subOption.isChecked; } mainOption.isChecked = @@ -42,7 +42,7 @@ class _PermissionManagementState extends State { return; } - for (final child in subOption.subOptions) { + for (var child in subOption.subOptions) { if (child.id == id) { child.isChecked = !child.isChecked; subOption.isChecked = @@ -58,17 +58,17 @@ class _PermissionManagementState extends State { } CheckState checkifOneOfthemChecked(PermissionOption mainOption) { - var allSelected = true; - var someSelected = false; + bool allSelected = true; + bool someSelected = false; - for (final subOption in mainOption.subOptions) { + for (var subOption in mainOption.subOptions) { if (subOption.isChecked) { someSelected = true; } else { allSelected = false; } - for (final child in subOption.subOptions) { + for (var child in subOption.subOptions) { if (child.isChecked) { someSelected = true; } else { @@ -143,7 +143,7 @@ class _PermissionManagementState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ColoredBox( + Container( color: option.isHighlighted ? Colors.blue.shade50 : Colors.white, @@ -208,7 +208,7 @@ class _PermissionManagementState extends State { itemCount: subOption.subOptions.length, itemBuilder: (context, index) { final child = subOption.subOptions[index]; - return ColoredBox( + return Container( color: option.isHighlighted ? Colors.blue.shade50 : Colors.white, @@ -260,7 +260,7 @@ class _PermissionManagementState extends State { ) ], ); - }), + }).toList(), ], ); }, @@ -268,27 +268,28 @@ class _PermissionManagementState extends State { } } -// Container( -// height: 50, -// width: 120, -// child: CheckboxListTile( -// activeColor: ColorsManager.dialogBlueTitle, -// selectedTileColor: child.isHighlighted -// ? Colors.blue.shade50 -// : Colors.white, -// dense: true, -// controlAffinity: -// ListTileControlAffinity.leading, -// title: Text( -// child.title, -// style: context.textTheme.bodyMedium?.copyWith( -// fontWeight: FontWeight.w400, -// fontSize: 12, -// color: ColorsManager.lightGreyColor), -// ), -// value: child.isChecked, -// onChanged: (value) => -// toggleOptionById(child.id), -// enabled: false, -// ), -// ), + + // Container( + // height: 50, + // width: 120, + // child: CheckboxListTile( + // activeColor: ColorsManager.dialogBlueTitle, + // selectedTileColor: child.isHighlighted + // ? Colors.blue.shade50 + // : Colors.white, + // dense: true, + // controlAffinity: + // ListTileControlAffinity.leading, + // title: Text( + // child.title, + // style: context.textTheme.bodyMedium?.copyWith( + // fontWeight: FontWeight.w400, + // fontSize: 12, + // color: ColorsManager.lightGreyColor), + // ), + // value: child.isChecked, + // onChanged: (value) => + // toggleOptionById(child.id), + // enabled: false, + // ), + // ), \ No newline at end of file diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart index e79249d7..a7f6c2b5 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/popup_menu_filter.dart @@ -47,9 +47,9 @@ Future showPopUpFilterMenu({ width: 25, ), title: Text( - 'Sort A to Z', + "Sort A to Z", style: TextStyle( - color: isSelected == 'Asc' + color: isSelected == "Asc" ? ColorsManager.blackColor : ColorsManager.grayColor), ), @@ -72,16 +72,16 @@ Future showPopUpFilterMenu({ width: 25, ), title: Text( - 'Sort Z to A', + "Sort Z to A", style: TextStyle( - color: isSelected == 'Desc' + color: isSelected == "Desc" ? ColorsManager.blackColor : ColorsManager.grayColor), ), ), const Divider(), const Text( - 'Filter by ', + "Filter by ", style: TextStyle(fontWeight: FontWeight.bold), ), Container( @@ -113,8 +113,7 @@ Future showPopUpFilterMenu({ ), Text( item, - style: const TextStyle( - color: ColorsManager.grayColor), + style: TextStyle(color: ColorsManager.grayColor), ), ], ); @@ -137,12 +136,12 @@ Future showPopUpFilterMenu({ onTap: () { Navigator.of(context).pop(); // Close the menu }, - child: const Text('Cancel'), + child: const Text("Cancel"), ), GestureDetector( onTap: onOkPressed, child: const Text( - 'OK', + "OK", style: TextStyle( color: ColorsManager.spaceColor, ), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart index 80ea8677..3a5ac65c 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/role_dropdown.dart @@ -31,7 +31,7 @@ class _RoleDropdownState extends State { const Row( children: [ Text( - ' * ', + " * ", style: TextStyle( color: ColorsManager.red, fontWeight: FontWeight.w900, @@ -39,7 +39,7 @@ class _RoleDropdownState extends State { ), ), Text( - 'Role', + "Role", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 16, @@ -77,7 +77,7 @@ class _RoleDropdownState extends State { hint: const Padding( padding: EdgeInsets.only(left: 10), child: Text( - 'Please Select', + "Please Select", style: TextStyle( color: ColorsManager.textGray, ), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart index a5e140b4..f4b91747 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/roles_and_permission.dart @@ -16,11 +16,11 @@ class RolesAndPermission extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { - final blocRole = BlocProvider.of(context); - return ColoredBox( + final _blocRole = BlocProvider.of(context); + return Container( color: Colors.white, child: Form( - key: blocRole.formKey, + key: _blocRole.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -39,7 +39,7 @@ class RolesAndPermission extends StatelessWidget { width: 350, height: 100, child: RoleDropdown( - bloc: blocRole, + bloc: _blocRole, )), const SizedBox(height: 10), Expanded( @@ -69,10 +69,11 @@ class RolesAndPermission extends StatelessWidget { child: TextFormField( style: const TextStyle(color: Colors.black), - controller: blocRole.roleSearchController, + controller: + _blocRole.roleSearchController, onChanged: (value) { - blocRole.add(SearchPermission( - nodes: blocRole.permissions, + _blocRole.add(SearchPermission( + nodes: _blocRole.permissions, searchTerm: value)); }, decoration: textBoxDecoration(radios: 20)! @@ -106,10 +107,10 @@ class RolesAndPermission extends StatelessWidget { child: Container( color: ColorsManager.circleRolesBackground, padding: const EdgeInsets.all(8.0), - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, child: PermissionManagement( - bloc: blocRole, + bloc: _blocRole, )))) ], ), diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart index dfd59ae8..63f870e6 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/spaces_access_view.dart @@ -11,21 +11,19 @@ class SpacesAccessView extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder(builder: (context, state) { - final blocRole = BlocProvider.of(context); - return ColoredBox( + final _blocRole = BlocProvider.of(context); + return Container( color: Colors.white, child: Form( - key: blocRole.formKey, + key: _blocRole.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( 'Spaces access', - style: context.textTheme.bodyLarge?.copyWith( - fontWeight: FontWeight.w700, - fontSize: 20, - color: Colors.black), + style: context.textTheme.bodyLarge + ?.copyWith(fontWeight: FontWeight.w700, fontSize: 20, color: Colors.black), ), const SizedBox( height: 35, diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart index e032f6e4..e7eda606 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart @@ -6,6 +6,8 @@ import 'package:syncrow_web/pages/roles_and_permission/model/roles_user_model.da 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/services/user_permission.dart'; +import 'package:syncrow_web/utils/constants/strings_manager.dart'; +import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart'; class UserTableBloc extends Bloc { UserTableBloc() : super(TableInitial()) { @@ -58,20 +60,20 @@ class UserTableBloc extends Bloc { final dateB = _parseDateTime(b.createdDate); return dateB.compareTo(dateA); }); - for (final user in users) { + for (var user in users) { roleTypes.add(user.roleType.toString()); } - for (final user in users) { + for (var user in users) { jobTitle.add(user.jobTitle.toString()); } - for (final user in users) { - createdBy.add(user.invitedBy); + for (var user in users) { + createdBy.add(user.invitedBy.toString()); } initialUsers = List.from(users); roleTypes = roleTypes.toSet().toList(); jobTitle = jobTitle.toSet().toList(); createdBy = createdBy.toSet().toList(); - _handlePageChange(const ChangePage(1), emit); + _handlePageChange(ChangePage(1), emit); totalUsersCount = initialUsers; add(ChangePage(currentPage)); emit(UsersLoadedState(users: users)); @@ -84,7 +86,7 @@ class UserTableBloc extends Bloc { DeleteUserEvent event, Emitter emit) async { emit(UsersLoadingState()); try { - final res = await UserPermissionApi().deleteUserById(event.userId); + bool res = await UserPermissionApi().deleteUserById(event.userId); if (res == true) { Navigator.of(event.context).pop(true); } else { @@ -102,8 +104,8 @@ class UserTableBloc extends Bloc { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; emit(UsersLoadingState()); - final res = await UserPermissionApi().changeUserStatusById(event.userId, - event.newStatus == 'disabled' ? false : true, projectUuid); + bool res = await UserPermissionApi().changeUserStatusById(event.userId, + event.newStatus == "disabled" ? false : true, projectUuid); if (res == true) { add(const GetUsers()); } @@ -119,13 +121,13 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrder == 'Asc') { + if (currentSortOrder == "Asc") { emit(UsersLoadingState()); - currentSortOrder = ''; + currentSortOrder = ""; users = List.from(users); } else { emit(UsersLoadingState()); - currentSortOrder = 'Asc'; + currentSortOrder = "Asc"; users.sort((a, b) => a.firstName .toString() .toLowerCase() @@ -144,13 +146,13 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrder == 'Desc') { + if (currentSortOrder == "Desc") { emit(UsersLoadingState()); - currentSortOrder = ''; + currentSortOrder = ""; users = List.from(initialUsers); } else { emit(UsersLoadingState()); - currentSortOrder = 'Desc'; + currentSortOrder = "Desc"; users.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } currentSortJopTitle = ''; @@ -166,15 +168,15 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrderDate == 'NewestToOldest') { + if (currentSortOrderDate == "NewestToOldest") { emit(UsersLoadingState()); - currentSortOrder = ''; - currentSortOrderDate = ''; + currentSortOrder = ""; + currentSortOrderDate = ""; users = List.from(initialUsers); emit(UsersLoadedState(users: users)); } else { emit(UsersLoadingState()); - currentSortOrder = 'NewestToOldest'; + currentSortOrder = "NewestToOldest"; users.sort((a, b) { final dateA = _parseDateTime(a.createdDate); final dateB = _parseDateTime(b.createdDate); @@ -190,10 +192,10 @@ class UserTableBloc extends Bloc { selectedJobTitles.clear(); selectedCreatedBy.clear(); selectedStatuses.clear(); - if (currentSortOrderDate == 'OldestToNewest') { + if (currentSortOrderDate == "OldestToNewest") { emit(UsersLoadingState()); - currentSortOrder = ''; - currentSortOrderDate = ''; + currentSortOrder = ""; + currentSortOrderDate = ""; users = List.from(initialUsers); emit(UsersLoadedState(users: users)); } else { @@ -203,7 +205,7 @@ class UserTableBloc extends Bloc { final dateB = _parseDateTime(b.createdDate); return dateA.compareTo(dateB); }); - currentSortOrder = 'OldestToNewest'; + currentSortOrder = "OldestToNewest"; emit(UsersLoadedState(users: users)); } } @@ -226,7 +228,7 @@ class UserTableBloc extends Bloc { emit(TableSearch()); final query = event.query.toLowerCase(); final filteredUsers = initialUsers.where((user) { - final fullName = '${user.firstName} ${user.lastName}'.toLowerCase(); + final fullName = "${user.firstName} ${user.lastName}".toLowerCase(); final email = user.email.toLowerCase(); return fullName.contains(query) || email.contains(query); }).toList(); @@ -281,22 +283,22 @@ class UserTableBloc extends Bloc { return selectedRoles.contains(user.roleType); }).toList(); - if (event.sortOrder == 'Asc') { - currentSortOrder = 'Asc'; + if (event.sortOrder == "Asc") { + currentSortOrder = "Asc"; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == 'Desc') { - currentSortOrder = 'Desc'; + } else if (event.sortOrder == "Desc") { + currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } else {} - currentSortOrder = ''; + currentSortOrder = ""; currentSortCreatedDate = ''; currentSortStatus = ''; currentSortCreatedBy = ''; currentSortJopTitle = ''; - currentSortOrderDate = ''; + currentSortOrderDate = ""; totalUsersCount = filteredUsers; @@ -311,22 +313,22 @@ class UserTableBloc extends Bloc { if (selectedJobTitles.isEmpty) return true; return selectedJobTitles.contains(user.jobTitle); }).toList(); - if (event.sortOrder == 'Asc') { - currentSortOrder = 'Asc'; + if (event.sortOrder == "Asc") { + currentSortOrder = "Asc"; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == 'Desc') { - currentSortOrder = 'Desc'; + } else if (event.sortOrder == "Desc") { + currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } else {} - currentSortOrder = ''; + currentSortOrder = ""; currentSortCreatedDate = ''; currentSortStatus = ''; currentSortCreatedBy = ''; currentSortRole = ''; - currentSortOrderDate = ''; + currentSortOrderDate = ""; totalUsersCount = filteredUsers; @@ -342,21 +344,21 @@ class UserTableBloc extends Bloc { return selectedCreatedBy.contains(user.invitedBy); }).toList(); - if (event.sortOrder == 'Asc') { - currentSortOrder = 'Asc'; + if (event.sortOrder == "Asc") { + currentSortOrder = "Asc"; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == 'Desc') { - currentSortOrder = 'Desc'; + } else if (event.sortOrder == "Desc") { + currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); } else {} currentSortOrder = ''; currentSortRole = ''; currentSortCreatedDate = ''; currentSortStatus = ''; - currentSortOrderDate = ''; + currentSortOrderDate = ""; totalUsersCount = filteredUsers; @@ -384,14 +386,14 @@ class UserTableBloc extends Bloc { } }); }).toList(); - if (event.sortOrder == 'Asc') { - currentSortOrder = 'Asc'; + if (event.sortOrder == "Asc") { + currentSortOrder = "Asc"; filteredUsers.sort((a, b) => a.firstName .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - } else if (event.sortOrder == 'Desc') { - currentSortOrder = 'Desc'; + } else if (event.sortOrder == "Desc") { + currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); totalUsersCount = filteredUsers; } else {} @@ -399,7 +401,7 @@ class UserTableBloc extends Bloc { currentSortRole = ''; currentSortCreatedDate = ''; currentSortCreatedBy = ''; - currentSortOrderDate = ''; + currentSortOrderDate = ""; emit(UsersLoadedState(users: filteredUsers)); } diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart index aea65950..1d9567cf 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_event.dart @@ -64,7 +64,7 @@ class DateOldestToNewestEvent extends UserTableEvent { class SearchUsers extends UserTableEvent { final String query; - const SearchUsers(this.query); + SearchUsers(this.query); @override List get props => []; } @@ -72,7 +72,7 @@ class SearchUsers extends UserTableEvent { class ChangePage extends UserTableEvent { final int pageNumber; - const ChangePage(this.pageNumber); + ChangePage(this.pageNumber); @override List get props => [pageNumber]; @@ -93,7 +93,6 @@ class FilterUsersByRoleEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByRoleEvent({this.selectedRoles, this.sortOrder}); - @override List get props => [selectedRoles, sortOrder]; } @@ -102,7 +101,6 @@ class FilterUsersByJobEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByJobEvent({this.selectedJob, this.sortOrder}); - @override List get props => [selectedJob, sortOrder]; } @@ -112,7 +110,6 @@ class FilterUsersByCreatedEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByCreatedEvent({this.selectedCreatedBy, this.sortOrder}); - @override List get props => [selectedCreatedBy, sortOrder]; } @@ -121,7 +118,6 @@ class FilterUsersByDeActevateEvent extends UserTableEvent { final String? sortOrder; const FilterUsersByDeActevateEvent({this.selectedActivate, this.sortOrder}); - @override List get props => [selectedActivate, sortOrder]; } @@ -129,14 +125,14 @@ class FilterOptionsEvent extends UserTableEvent { final String query; final List fullOptions; - const FilterOptionsEvent({required this.query, required this.fullOptions}); + FilterOptionsEvent({required this.query, required this.fullOptions}); @override List get props => [query, fullOptions]; } class FilterClearEvent extends UserTableEvent { - const FilterClearEvent(); + FilterClearEvent(); @override List get props => []; } diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart index 9d71602b..ae99af3a 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart @@ -9,12 +9,10 @@ final class TableInitial extends UserTableState { @override List get props => []; } - final class TableSearch extends UserTableState { @override List get props => []; } - final class RolesLoadingState extends UserTableState { @override List get props => []; diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart b/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart index 198049f0..7b7da0bd 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/creation_date_filter.dart @@ -8,8 +8,9 @@ Future showDateFilterMenu({ Function()? zToaTap, String? isSelected, }) async { - final overlay = Overlay.of(context).context.findRenderObject()! as RenderBox; - final position = RelativeRect.fromRect( + final RenderBox overlay = + Overlay.of(context).context.findRenderObject() as RenderBox; + final RelativeRect position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width / 3, 240, @@ -38,9 +39,9 @@ Future showDateFilterMenu({ width: 25, ), title: Text( - 'Sort from newest to oldest', + "Sort from newest to oldest", style: TextStyle( - color: isSelected == 'NewestToOldest' + color: isSelected == "NewestToOldest" ? Colors.black : Colors.blueGrey), ), @@ -54,9 +55,9 @@ Future showDateFilterMenu({ width: 25, ), title: Text( - 'Sort from oldest to newest', + "Sort from oldest to newest", style: TextStyle( - color: isSelected == 'OldestToNewest' + color: isSelected == "OldestToNewest" ? Colors.black : Colors.blueGrey), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart b/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart index 166e1ca9..c8742ea5 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/de_activate_filter.dart @@ -8,8 +8,9 @@ Future showDeActivateFilterMenu({ Function()? zToaTap, String? isSelected, }) async { - final overlay = Overlay.of(context).context.findRenderObject()! as RenderBox; - final position = RelativeRect.fromRect( + final RenderBox overlay = + Overlay.of(context).context.findRenderObject() as RenderBox; + final RelativeRect position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width / 2, 240, @@ -38,9 +39,9 @@ Future showDeActivateFilterMenu({ width: 25, ), title: Text( - 'Sort A to Z', + "Sort A to Z", style: TextStyle( - color: isSelected == 'NewestToOldest' + color: isSelected == "NewestToOldest" ? Colors.black : Colors.blueGrey), ), @@ -54,9 +55,9 @@ Future showDeActivateFilterMenu({ width: 25, ), title: Text( - 'Sort Z to A', + "Sort Z to A", style: TextStyle( - color: isSelected == 'OldestToNewest' + color: isSelected == "OldestToNewest" ? Colors.black : Colors.blueGrey), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart b/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart index a047fe97..f551cf3c 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/name_filter.dart @@ -8,8 +8,9 @@ Future showNameMenu({ Function()? zToATap, String? isSelected, }) async { - final overlay = Overlay.of(context).context.findRenderObject()! as RenderBox; - final position = RelativeRect.fromRect( + final RenderBox overlay = + Overlay.of(context).context.findRenderObject() as RenderBox; + final RelativeRect position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width / 35, 240, @@ -38,9 +39,9 @@ Future showNameMenu({ width: 25, ), title: Text( - 'Sort A to Z', + "Sort A to Z", style: TextStyle( - color: isSelected == 'Asc' ? Colors.black : Colors.blueGrey), + color: isSelected == "Asc" ? Colors.black : Colors.blueGrey), ), ), ), @@ -52,9 +53,9 @@ Future showNameMenu({ width: 25, ), title: Text( - 'Sort Z to A', + "Sort Z to A", style: TextStyle( - color: isSelected == 'Desc' ? Colors.black : Colors.blueGrey), + color: isSelected == "Desc" ? Colors.black : Colors.blueGrey), ), ), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart b/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart index 624a57f7..9b10b5d4 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/user_table.dart @@ -17,7 +17,8 @@ class _HeaderColumn extends StatelessWidget { required this.showFilter, required this.onResize, this.onFilter, - }); + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -70,7 +71,8 @@ class _TableRow extends StatelessWidget { required this.cells, required this.columnWidths, required this.isLast, - }); + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -114,9 +116,9 @@ class DynamicTableScreen extends StatefulWidget { required this.titles, required this.rows, required this.onFilter, - super.key, + Key? key, required this.tableSize, - }); + }) : super(key: key); @override _DynamicTableScreenState createState() => _DynamicTableScreenState(); @@ -137,12 +139,12 @@ class _DynamicTableScreenState extends State { void _handleColumnResize(int index, double delta) { setState(() { - var newWidth = columnWidths[index] + delta; + double newWidth = columnWidths[index] + delta; newWidth = newWidth.clamp(_minColumnWidth, _maxColumnWidth); - final actualDelta = newWidth - columnWidths[index]; + double actualDelta = newWidth - columnWidths[index]; if (actualDelta == 0) return; - final nextIndex = (index + 1) % columnWidths.length; + int nextIndex = (index + 1) % columnWidths.length; columnWidths[index] = newWidth; columnWidths[nextIndex] = (columnWidths[nextIndex] - actualDelta) .clamp(_minColumnWidth, _maxColumnWidth); @@ -254,7 +256,7 @@ class _DynamicTableScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildHeader(), - SizedBox(height: widget.tableSize - 37, child: _buildBody()), + Container(height: widget.tableSize - 37, child: _buildBody()), ], ), ), diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart b/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart index d007baf2..735ce839 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart @@ -21,11 +21,11 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/style.dart'; class UsersPage extends StatelessWidget { - const UsersPage({super.key}); + UsersPage({super.key}); @override Widget build(BuildContext context) { - final searchController = TextEditingController(); + final TextEditingController searchController = TextEditingController(); Widget actionButton( {bool isActive = false, required String title, Function()? onTap}) { @@ -36,9 +36,9 @@ class UsersPage extends StatelessWidget { child: Text( title, style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: isActive == false && title != 'Delete' + color: isActive == false && title != "Delete" ? Colors.grey - : title == 'Delete' + : title == "Delete" ? ColorsManager.red : ColorsManager.spaceColor, fontWeight: FontWeight.w400, @@ -54,11 +54,11 @@ class UsersPage extends StatelessWidget { padding: const EdgeInsets.only(left: 5, right: 5, bottom: 5, top: 5), decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(20)), - color: status == 'invited' - ? ColorsManager.invitedOrange.withValues(alpha: 0.5) - : status == 'active' - ? ColorsManager.activeGreen.withValues(alpha: 0.5) - : ColorsManager.disabledPink.withValues(alpha: 0.5), + color: status == "invited" + ? ColorsManager.invitedOrange.withOpacity(0.5) + : status == "active" + ? ColorsManager.activeGreen.withOpacity(0.5) + : ColorsManager.disabledPink.withOpacity(0.5), ), child: Padding( padding: @@ -70,9 +70,9 @@ class UsersPage extends StatelessWidget { Text( status, style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: status == 'invited' + color: status == "invited" ? ColorsManager.invitedOrangeText - : status == 'active' + : status == "active" ? ColorsManager.activeGreenText : ColorsManager.disabledRedText, fontWeight: FontWeight.w400, @@ -96,9 +96,9 @@ class UsersPage extends StatelessWidget { padding: const EdgeInsets.only(left: 5, right: 5, bottom: 5, top: 5), child: SvgPicture.asset( - status == 'invited' + status == "invited" ? Assets.invitedIcon - : status == 'active' + : status == "active" ? Assets.activeUser : Assets.deActiveUser, height: 35, @@ -111,7 +111,7 @@ class UsersPage extends StatelessWidget { return BlocBuilder( builder: (context, state) { final screenSize = MediaQuery.of(context).size; - final blocRole = BlocProvider.of(context); + final _blocRole = BlocProvider.of(context); if (state is UsersLoadingState) { return const Center(child: CircularProgressIndicator()); } else if (state is UsersLoadedState) { @@ -134,10 +134,10 @@ class UsersPage extends StatelessWidget { controller: searchController, onChanged: (value) { final bloc = context.read(); - bloc.add(const FilterClearEvent()); + bloc.add(FilterClearEvent()); bloc.add(SearchUsers(value)); if (value == '') { - bloc.add(const ChangePage(1)); + bloc.add(ChangePage(1)); } }, style: const TextStyle(color: Colors.black), @@ -170,7 +170,7 @@ class UsersPage extends StatelessWidget { }, ).then((v) { if (v != null) { - blocRole.add(const GetUsers()); + _blocRole.add(const GetUsers()); } }); }, @@ -193,7 +193,7 @@ class UsersPage extends StatelessWidget { ], ), const SizedBox(height: 20), - SizedBox( + Container( height: screenSize.height * 0.65, child: DynamicTableScreen( tableSize: screenSize.height * 0.65, @@ -201,7 +201,7 @@ class UsersPage extends StatelessWidget { if (columnIndex == 0) { showNameMenu( context: context, - isSelected: blocRole.currentSortOrder, + isSelected: _blocRole.currentSortOrder, aToZTap: () { context .read() @@ -215,13 +215,13 @@ class UsersPage extends StatelessWidget { ); } if (columnIndex == 2) { - final checkboxStates = { - for (final item in blocRole.jobTitle) - item: blocRole.selectedJobTitles.contains(item), + final Map checkboxStates = { + for (var item in _blocRole.jobTitle) + item: _blocRole.selectedJobTitles.contains(item), }; - final overlay = Overlay.of(context) + final RenderBox overlay = Overlay.of(context) .context - .findRenderObject()! as RenderBox; + .findRenderObject() as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( @@ -230,40 +230,40 @@ class UsersPage extends StatelessWidget { overlay.size.width / 4, 0, ), - list: blocRole.jobTitle, + list: _blocRole.jobTitle, context: context, checkboxStates: checkboxStates, - isSelected: blocRole.currentSortJopTitle, + isSelected: _blocRole.currentSortJopTitle, onOkPressed: () { searchController.clear(); - blocRole.add(const FilterClearEvent()); + _blocRole.add(FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) .toList(); Navigator.of(context).pop(); - blocRole.add(FilterUsersByJobEvent( + _blocRole.add(FilterUsersByJobEvent( selectedJob: selectedItems, - sortOrder: blocRole.currentSortJopTitle, + sortOrder: _blocRole.currentSortJopTitle, )); }, onSortAtoZ: (v) { - blocRole.currentSortJopTitle = v; + _blocRole.currentSortJopTitle = v; }, onSortZtoA: (v) { - blocRole.currentSortJopTitle = v; + _blocRole.currentSortJopTitle = v; }, ); } if (columnIndex == 3) { - final checkboxStates = { - for (final item in blocRole.roleTypes) - item: blocRole.selectedRoles.contains(item), + final Map checkboxStates = { + for (var item in _blocRole.roleTypes) + item: _blocRole.selectedRoles.contains(item), }; - final overlay = Overlay.of(context) + final RenderBox overlay = Overlay.of(context) .context - .findRenderObject()! as RenderBox; + .findRenderObject() as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( overlay.size.width / 4, @@ -271,13 +271,13 @@ class UsersPage extends StatelessWidget { overlay.size.width / 4, 0, ), - list: blocRole.roleTypes, + list: _blocRole.roleTypes, context: context, checkboxStates: checkboxStates, - isSelected: blocRole.currentSortRole, + isSelected: _blocRole.currentSortRole, onOkPressed: () { searchController.clear(); - blocRole.add(const FilterClearEvent()); + _blocRole.add(FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) @@ -286,20 +286,20 @@ class UsersPage extends StatelessWidget { context.read().add( FilterUsersByRoleEvent( selectedRoles: selectedItems, - sortOrder: blocRole.currentSortRole)); + sortOrder: _blocRole.currentSortRole)); }, onSortAtoZ: (v) { - blocRole.currentSortRole = v; + _blocRole.currentSortRole = v; }, onSortZtoA: (v) { - blocRole.currentSortRole = v; + _blocRole.currentSortRole = v; }, ); } if (columnIndex == 4) { showDateFilterMenu( context: context, - isSelected: blocRole.currentSortOrder, + isSelected: _blocRole.currentSortOrder, aToZTap: () { context .read() @@ -313,13 +313,13 @@ class UsersPage extends StatelessWidget { ); } if (columnIndex == 6) { - final checkboxStates = { - for (final item in blocRole.createdBy) - item: blocRole.selectedCreatedBy.contains(item), + final Map checkboxStates = { + for (var item in _blocRole.createdBy) + item: _blocRole.selectedCreatedBy.contains(item), }; - final overlay = Overlay.of(context) + final RenderBox overlay = Overlay.of(context) .context - .findRenderObject()! as RenderBox; + .findRenderObject() as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( overlay.size.width / 1, @@ -327,39 +327,39 @@ class UsersPage extends StatelessWidget { overlay.size.width / 4, 0, ), - list: blocRole.createdBy, + list: _blocRole.createdBy, context: context, checkboxStates: checkboxStates, - isSelected: blocRole.currentSortCreatedBy, + isSelected: _blocRole.currentSortCreatedBy, onOkPressed: () { searchController.clear(); - blocRole.add(const FilterClearEvent()); + _blocRole.add(FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) .toList(); Navigator.of(context).pop(); - blocRole.add(FilterUsersByCreatedEvent( + _blocRole.add(FilterUsersByCreatedEvent( selectedCreatedBy: selectedItems, - sortOrder: blocRole.currentSortCreatedBy)); + sortOrder: _blocRole.currentSortCreatedBy)); }, onSortAtoZ: (v) { - blocRole.currentSortCreatedBy = v; + _blocRole.currentSortCreatedBy = v; }, onSortZtoA: (v) { - blocRole.currentSortCreatedBy = v; + _blocRole.currentSortCreatedBy = v; }, ); } if (columnIndex == 7) { - final checkboxStates = { - for (final item in blocRole.status) - item: blocRole.selectedStatuses.contains(item), + final Map checkboxStates = { + for (var item in _blocRole.status) + item: _blocRole.selectedStatuses.contains(item), }; - final overlay = Overlay.of(context) + final RenderBox overlay = Overlay.of(context) .context - .findRenderObject()! as RenderBox; + .findRenderObject() as RenderBox; showPopUpFilterMenu( position: RelativeRect.fromLTRB( overlay.size.width / 0, @@ -367,34 +367,34 @@ class UsersPage extends StatelessWidget { overlay.size.width / 5, 0, ), - list: blocRole.status, + list: _blocRole.status, context: context, checkboxStates: checkboxStates, - isSelected: blocRole.currentSortStatus, + isSelected: _blocRole.currentSortStatus, onOkPressed: () { searchController.clear(); - blocRole.add(const FilterClearEvent()); + _blocRole.add(FilterClearEvent()); final selectedItems = checkboxStates.entries .where((entry) => entry.value) .map((entry) => entry.key) .toList(); Navigator.of(context).pop(); - blocRole.add(FilterUsersByDeActevateEvent( + _blocRole.add(FilterUsersByDeActevateEvent( selectedActivate: selectedItems, - sortOrder: blocRole.currentSortStatus)); + sortOrder: _blocRole.currentSortStatus)); }, onSortAtoZ: (v) { - blocRole.currentSortStatus = v; + _blocRole.currentSortStatus = v; }, onSortZtoA: (v) { - blocRole.currentSortStatus = v; + _blocRole.currentSortStatus = v; }, ); } if (columnIndex == 8) { showDeActivateFilterMenu( context: context, - isSelected: blocRole.currentSortOrderDate, + isSelected: _blocRole.currentSortOrderDate, aToZTap: () { context .read() @@ -409,16 +409,16 @@ class UsersPage extends StatelessWidget { } }, titles: const [ - 'Full Name', - 'Email Address', - 'Job Title', - 'Role', - 'Creation Date', - 'Creation Time', - 'Created By', - 'Status', - 'De/Activate', - 'Action' + "Full Name", + "Email Address", + "Job Title", + "Role", + "Creation Date", + "Creation Time", + "Created By", + "Status", + "De/Activate", + "Action" ], rows: state.users.map((user) { return [ @@ -439,7 +439,7 @@ class UsersPage extends StatelessWidget { ? 'disabled' : user.status, userId: user.uuid, - onTap: user.status != 'invited' + onTap: user.status != "invited" ? () { context.read().add( ChangeUserStatus( @@ -452,36 +452,35 @@ class UsersPage extends StatelessWidget { ), Row( children: [ - if (user.isEnabled != false) - actionButton( - isActive: true, - title: 'Edit', - onTap: () { - context - .read() - .add(ClearCachedData()); - showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return EditUserDialog( - userId: user.uuid); + user.isEnabled != false + ? actionButton( + isActive: true, + title: "Edit", + onTap: () { + context + .read() + .add(ClearCachedData()); + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return EditUserDialog( + userId: user.uuid); + }, + ).then((v) { + if (v != null) { + if (v != null) { + _blocRole.add(const GetUsers()); + } + } + }); }, - ).then((v) { - if (v != null) { - if (v != null) { - blocRole.add(const GetUsers()); - } - } - }); - }, - ) - else - actionButton( - title: 'Edit', - ), + ) + : actionButton( + title: "Edit", + ), actionButton( - title: 'Delete', + title: "Delete", onTap: () { showDialog( context: context, @@ -490,7 +489,7 @@ class UsersPage extends StatelessWidget { return DeleteUserDialog( onTapDelete: () async { try { - blocRole.add(DeleteUserEvent( + _blocRole.add(DeleteUserEvent( user.uuid, context)); await Future.delayed( const Duration(seconds: 2)); @@ -502,7 +501,7 @@ class UsersPage extends StatelessWidget { }, ).then((v) { if (v != null) { - blocRole.add(const GetUsers()); + _blocRole.add(const GetUsers()); } }); }, @@ -530,10 +529,10 @@ class UsersPage extends StatelessWidget { const Icon(Icons.keyboard_double_arrow_right), firstPageIcon: const Icon(Icons.keyboard_double_arrow_left), - totalPages: (blocRole.totalUsersCount.length / - blocRole.itemsPerPage) + totalPages: (_blocRole.totalUsersCount.length / + _blocRole.itemsPerPage) .ceil(), - currentPage: blocRole.currentPage, + currentPage: _blocRole.currentPage, onPageChanged: (int pageNumber) { context .read() diff --git a/lib/pages/roles_and_permission/view/create_role_card.dart b/lib/pages/roles_and_permission/view/create_role_card.dart index 8b137891..e69de29b 100644 --- a/lib/pages/roles_and_permission/view/create_role_card.dart +++ b/lib/pages/roles_and_permission/view/create_role_card.dart @@ -1 +0,0 @@ - diff --git a/lib/pages/roles_and_permission/view/role_card.dart b/lib/pages/roles_and_permission/view/role_card.dart index 866b0345..b08b14ea 100644 --- a/lib/pages/roles_and_permission/view/role_card.dart +++ b/lib/pages/roles_and_permission/view/role_card.dart @@ -13,8 +13,7 @@ class RoleCard extends StatelessWidget { borderRadius: BorderRadius.circular(20), // Rounded corners boxShadow: [ BoxShadow( - color: - ColorsManager.blackColor.withValues(alpha: 0.2), // Shadow color + color: ColorsManager.blackColor.withOpacity(0.2), // Shadow color blurRadius: 20, // Spread of the shadow offset: const Offset(2, 2), // No directional bias spreadRadius: 1, // Ensures the shadow is more noticeable @@ -24,7 +23,7 @@ class RoleCard extends StatelessWidget { child: Container( decoration: BoxDecoration( color: ColorsManager.whiteColors, - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.circular(20), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, diff --git a/lib/pages/roles_and_permission/view/roles_and_permission_page.dart b/lib/pages/roles_and_permission/view/roles_and_permission_page.dart index b7a510d0..4ba83cc1 100644 --- a/lib/pages/roles_and_permission/view/roles_and_permission_page.dart +++ b/lib/pages/roles_and_permission/view/roles_and_permission_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/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_state.dart'; @@ -21,7 +22,7 @@ class RolesAndPermissionPage extends StatelessWidget { child: BlocConsumer( listener: (context, state) {}, builder: (context, state) { - final blocRole = BlocProvider.of(context); + final _blocRole = BlocProvider.of(context); return state is RolesLoadingState ? const Center(child: CircularProgressIndicator()) @@ -64,10 +65,10 @@ class RolesAndPermissionPage extends StatelessWidget { child: Text( 'Users', style: context.textTheme.titleMedium?.copyWith( - color: (blocRole.tapSelect == true) + color: (_blocRole.tapSelect == true) ? ColorsManager.whiteColors : ColorsManager.grayColor, - fontWeight: (blocRole.tapSelect == true) + fontWeight: (_blocRole.tapSelect == true) ? FontWeight.w700 : FontWeight.w400, ), @@ -77,7 +78,7 @@ class RolesAndPermissionPage extends StatelessWidget { ), scaffoldBody: BlocProvider( create: (context) => UserTableBloc()..add(const GetUsers()), - child: const UsersPage(), + child: UsersPage(), ) // _blocRole.tapSelect == false // ? UsersPage( diff --git a/lib/pages/roles_and_permission/view/roles_page.dart b/lib/pages/roles_and_permission/view/roles_page.dart index b8c977e3..9c8ef0cd 100644 --- a/lib/pages/roles_and_permission/view/roles_page.dart +++ b/lib/pages/roles_and_permission/view/roles_page.dart @@ -13,10 +13,10 @@ class RolesPage extends StatelessWidget { @override Widget build(BuildContext context) { - final searchController = TextEditingController(); - final screenWidth = MediaQuery.of(context).size.width; + final TextEditingController searchController = TextEditingController(); + double screenWidth = MediaQuery.of(context).size.width; - final crossAxisCount = (screenWidth ~/ 200).clamp(1, 6); + int crossAxisCount = (screenWidth ~/ 200).clamp(1, 6); return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -54,6 +54,9 @@ class RolesPage extends StatelessWidget { itemCount: blocRole.roleModel.length ?? 0, itemBuilder: (context, index) { final role = blocRole.roleModel[index]; + if (role == null) { + return const SizedBox.shrink(); + } return RoleCard( name: role.roleName ?? 'Unknown', ); diff --git a/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart b/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart index b5326a40..c664c2c4 100644 --- a/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart +++ b/lib/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart @@ -1,3 +1,4 @@ + import 'dart:convert'; class AutomationStatusUpdate { @@ -16,23 +17,23 @@ class AutomationStatusUpdate { factory AutomationStatusUpdate.fromJson(Map json) => AutomationStatusUpdate( - spaceUuid: json['spaceUuid'], - isEnable: json['isEnable'], + spaceUuid: json["spaceUuid"], + isEnable: json["isEnable"], ); Map toJson() => { - 'spaceUuid': spaceUuid, - 'isEnable': isEnable, + "spaceUuid": spaceUuid, + "isEnable": isEnable, }; factory AutomationStatusUpdate.fromMap(Map map) => AutomationStatusUpdate( - spaceUuid: map['spaceUuid'], - isEnable: map['isEnable'], + spaceUuid: map["spaceUuid"], + isEnable: map["isEnable"], ); Map toMap() => { - 'spaceUuid': spaceUuid, - 'isEnable': isEnable, + "spaceUuid": spaceUuid, + "isEnable": isEnable, }; } diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart index ab154342..b472d034 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart @@ -36,7 +36,7 @@ class CreateRoutineBloc extends Bloc { } } - void saveSpaceIdCommunityId( + saveSpaceIdCommunityId( SaveCommunityIdAndSpaceIdEvent event, Emitter emit) { emit(const SpaceWithDeviceLoadingState()); selectedSpaceId = event.spaceID!; @@ -44,8 +44,7 @@ class CreateRoutineBloc extends Bloc { emit(const SelectedState()); } - void resetSelected( - ResetSelectedEvent event, Emitter emit) { + resetSelected(ResetSelectedEvent event, Emitter emit) { emit(const SpaceWithDeviceLoadingState()); selectedSpaceId = ''; selectedCommunityId = ''; diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart index 4b39fe62..ba901497 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_event.dart @@ -42,9 +42,10 @@ class ResetSelectedEvent extends CreateRoutineEvent { List get props => []; } + class FetchCommunityEvent extends CreateRoutineEvent { const FetchCommunityEvent(); @override List get props => []; -} +} \ No newline at end of file diff --git a/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart b/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart index 208b5e02..5ebc20f7 100644 --- a/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart +++ b/lib/pages/routines/bloc/create_routine_bloc/create_routine_state.dart @@ -1,3 +1,4 @@ + import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; @@ -38,6 +39,7 @@ class SelectedState extends CreateRoutineState { const SelectedState(); } + class ResetSelectedState extends CreateRoutineState { const ResetSelectedState(); } @@ -48,4 +50,4 @@ class CommunityLoadedState extends CreateRoutineState { class CommunitiesLoadingState extends CreateRoutineState { const CommunitiesLoadingState(); -} +} \ No newline at end of file diff --git a/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart b/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart index af429f7d..fd56d232 100644 --- a/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart +++ b/lib/pages/routines/bloc/effective_period/effect_period_bloc.dart @@ -25,8 +25,7 @@ class EffectPeriodBloc extends Bloc { on(_setAllDays); } - void _initialEvent( - InitialEffectPeriodEvent event, Emitter emit) { + void _initialEvent(InitialEffectPeriodEvent event, Emitter emit) { add(SetCustomTime(event.effectiveTime.start, event.effectiveTime.end)); emit(state.copyWith( selectedDaysBinary: event.effectiveTime.loops, @@ -36,8 +35,8 @@ class EffectPeriodBloc extends Bloc { } void _onSetPeriod(SetPeriod event, Emitter emit) { - var startTime = ''; - var endTime = ''; + String startTime = ''; + String endTime = ''; switch (event.period) { case EnumEffectivePeriodOptions.allDay: @@ -61,9 +60,7 @@ class EffectPeriodBloc extends Bloc { } emit(state.copyWith( - selectedPeriod: event.period, - customStartTime: startTime, - customEndTime: endTime)); + selectedPeriod: event.period, customStartTime: startTime, customEndTime: endTime)); } void _onToggleDay(ToggleDay event, Emitter emit) { @@ -79,8 +76,8 @@ class EffectPeriodBloc extends Bloc { } void _onSetCustomTime(SetCustomTime event, Emitter emit) { - final startTime = event.startTime; - final endTime = event.endTime; + String startTime = event.startTime; + String endTime = event.endTime; EnumEffectivePeriodOptions period; // Determine the period based on start and end times @@ -94,14 +91,11 @@ class EffectPeriodBloc extends Bloc { period = EnumEffectivePeriodOptions.custom; } - emit(state.copyWith( - customStartTime: startTime, - customEndTime: endTime, - selectedPeriod: period)); + emit( + state.copyWith(customStartTime: startTime, customEndTime: endTime, selectedPeriod: period)); } - void _onResetEffectivePeriod( - ResetEffectivePeriod event, Emitter emit) { + void _onResetEffectivePeriod(ResetEffectivePeriod event, Emitter emit) { emit(state.copyWith( selectedPeriod: EnumEffectivePeriodOptions.allDay, customStartTime: '00:00', diff --git a/lib/pages/routines/bloc/effective_period/effect_period_state.dart b/lib/pages/routines/bloc/effective_period/effect_period_state.dart index 4ecb83b9..2f8b66c8 100644 --- a/lib/pages/routines/bloc/effective_period/effect_period_state.dart +++ b/lib/pages/routines/bloc/effective_period/effect_period_state.dart @@ -17,9 +17,9 @@ class EffectPeriodState extends Equatable { factory EffectPeriodState.initial() { return const EffectPeriodState( selectedPeriod: EnumEffectivePeriodOptions.allDay, - selectedDaysBinary: '1111111', // All days selected - customStartTime: '00:00', - customEndTime: '23:59', + selectedDaysBinary: "1111111", // All days selected + customStartTime: "00:00", + customEndTime: "23:59", ); } @@ -50,6 +50,5 @@ class EffectPeriodState extends Equatable { } @override - List get props => - [selectedPeriod, selectedDaysBinary, customStartTime, customEndTime]; + List get props => [selectedPeriod, selectedDaysBinary, customStartTime, customEndTime]; } diff --git a/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart b/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart index b58b953d..ca8aac06 100644 --- a/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart +++ b/lib/pages/routines/bloc/routine_bloc/routine_bloc.dart @@ -1,9 +1,11 @@ import 'dart:async'; +import 'package:bloc/bloc.dart'; +import 'package:dio/dio.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; @@ -73,7 +75,7 @@ class RoutineBloc extends Bloc { } } - void _resetErrorMessage( + _resetErrorMessage( ResetErrorMessage event, Emitter emit, ) { @@ -91,7 +93,7 @@ class RoutineBloc extends Bloc { final updatedIfItems = List>.from(state.ifItems); // Find the index of the item in teh current itemsList - final index = updatedIfItems.indexWhere( + int index = updatedIfItems.indexWhere( (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); // Replace the map if the index is valid if (index != -1) { @@ -114,7 +116,7 @@ class RoutineBloc extends Bloc { final currentItems = List>.from(state.thenItems); // Find the index of the item in teh current itemsList - final index = currentItems.indexWhere( + int index = currentItems.indexWhere( (map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); // Replace the map if the index is valid if (index != -1) { @@ -133,7 +135,7 @@ class RoutineBloc extends Bloc { // List selectedFunction = List.from(event.functions); - final currentSelectedFunctions = + Map> currentSelectedFunctions = Map>.from(state.selectedFunctions); // if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) { @@ -174,18 +176,18 @@ class RoutineBloc extends Bloc { Future _onLoadScenes( LoadScenes event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); - final scenes = []; + List scenes = []; try { - final context = NavigationService.navigatorKey.currentContext!; - final createRoutineBloc = context.read(); + BuildContext context = NavigationService.navigatorKey.currentContext!; + var createRoutineBloc = context.read(); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { - final spaceBloc = context.read(); - for (final communityId in spaceBloc.state.selectedCommunities) { - final spacesList = + var spaceBloc = context.read(); + for (var communityId in spaceBloc.state.selectedCommunities) { + List spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - for (final spaceId in spacesList) { + for (var spaceId in spacesList) { scenes.addAll( await SceneApi.getScenes(spaceId, communityId, projectUuid)); } @@ -214,19 +216,19 @@ class RoutineBloc extends Bloc { Future _onLoadAutomation( LoadAutomation event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); - final automations = []; + List automations = []; final projectId = await ProjectManager.getProjectUUID() ?? ''; - final context = NavigationService.navigatorKey.currentContext!; - final createRoutineBloc = context.read(); + BuildContext context = NavigationService.navigatorKey.currentContext!; + var createRoutineBloc = context.read(); try { if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { - final spaceBloc = context.read(); - for (final communityId in spaceBloc.state.selectedCommunities) { - final spacesList = + var spaceBloc = context.read(); + for (var communityId in spaceBloc.state.selectedCommunities) { + List spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - for (final spaceId in spacesList) { + for (var spaceId in spacesList) { automations.addAll( await SceneApi.getAutomation(spaceId, communityId, projectId)); } @@ -334,8 +336,8 @@ class RoutineBloc extends Bloc { }); }).toList(); - final context = NavigationService.navigatorKey.currentContext!; - final createRoutineBloc = context.read(); + BuildContext context = NavigationService.navigatorKey.currentContext!; + var createRoutineBloc = context.read(); final createSceneModel = CreateSceneModel( spaceUuid: createRoutineBloc.selectedSpaceId, @@ -359,7 +361,7 @@ class RoutineBloc extends Bloc { } } on APIException catch (e) { final errorData = e.message; - final errorMessage = errorData; + String errorMessage = errorData; emit(state.copyWith( isLoading: false, errorMessage: errorMessage, @@ -398,7 +400,7 @@ class RoutineBloc extends Bloc { return; } emit(state.copyWith(isLoading: true, errorMessage: null)); - var i = 0; + int i = 0; final conditions = state.ifItems.expand((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; return functions.map((function) { @@ -466,8 +468,8 @@ class RoutineBloc extends Bloc { ); }); }).toList(); - final context = NavigationService.navigatorKey.currentContext!; - final createRoutineBloc = context.read(); + BuildContext context = NavigationService.navigatorKey.currentContext!; + var createRoutineBloc = context.read(); final createAutomationModel = CreateAutomationModel( spaceUuid: createRoutineBloc.selectedSpaceId, @@ -497,7 +499,7 @@ class RoutineBloc extends Bloc { } } on APIException catch (e) { final errorData = e.message; - final errorMessage = errorData; + String errorMessage = errorData; emit(state.copyWith( isLoading: false, errorMessage: errorMessage, @@ -703,14 +705,14 @@ class RoutineBloc extends Bloc { final List> thenItems; final List> ifItems; - final updatedFunctions = + final Map> updatedFunctions = Map>.from(state.selectedFunctions); - final deviceCards = >{}; + final Map> deviceCards = {}; - for (final action in sceneDetails.actions) { + for (var action in sceneDetails.actions) { AllDevicesModel? matchingDevice; - for (final device in state.devices) { + for (var device in state.devices) { if (device.uuid == action.entityId) { matchingDevice = device; break; @@ -775,7 +777,7 @@ class RoutineBloc extends Bloc { action.actionExecutor != 'delay') { final functions = matchingDevice?.functions ?? []; final functionCode = action.executorProperty?.functionCode; - for (final function in functions) { + for (DeviceFunction function in functions) { if (function.code == functionCode) { updatedFunctions[uniqueCustomId]!.add( DeviceFunctionData( @@ -869,8 +871,8 @@ class RoutineBloc extends Bloc { final projectId = await ProjectManager.getProjectUUID() ?? ''; emit(state.copyWith(isLoading: true)); - final context = NavigationService.navigatorKey.currentContext!; - final spaceBloc = context.read(); + BuildContext context = NavigationService.navigatorKey.currentContext!; + var spaceBloc = context.read(); if (state.isTabToRun) { await SceneApi.deleteScene( unitUuid: spaceBloc.state.selectedSpaces[0], @@ -899,7 +901,7 @@ class RoutineBloc extends Bloc { emit(state.copyWith(isLoading: false, createRoutineView: false)); } on APIException catch (e) { final errorData = e.message; - final errorMessage = errorData; + String errorMessage = errorData; emit(state.copyWith( isLoading: false, errorMessage: errorMessage, @@ -927,17 +929,17 @@ class RoutineBloc extends Bloc { emit(state.copyWith(isLoading: true)); try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final devices = []; - final context = NavigationService.navigatorKey.currentContext!; - final createRoutineBloc = context.read(); - final spaceBloc = context.read(); + List devices = []; + BuildContext context = NavigationService.navigatorKey.currentContext!; + var createRoutineBloc = context.read(); + var spaceBloc = context.read(); if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { - for (final communityId in spaceBloc.state.selectedCommunities) { - final spacesList = + for (var communityId in spaceBloc.state.selectedCommunities) { + List spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - for (final spaceId in spacesList) { + for (var spaceId in spacesList) { devices.addAll(await DevicesManagementApi() .fetchDevices(communityId, spaceId, projectUuid)); } @@ -1069,7 +1071,7 @@ class RoutineBloc extends Bloc { return; } emit(state.copyWith(isLoading: true, errorMessage: null)); - var i = 0; + int i = 0; final conditions = state.ifItems.expand((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; return functions.map((function) { @@ -1140,8 +1142,8 @@ class RoutineBloc extends Bloc { }); }).toList(); - final context = NavigationService.navigatorKey.currentContext!; - final spaceBloc = context.read(); + BuildContext context = NavigationService.navigatorKey.currentContext!; + var spaceBloc = context.read(); final createAutomationModel = CreateAutomationModel( spaceUuid: spaceBloc.selectedSpaceId, @@ -1161,8 +1163,8 @@ class RoutineBloc extends Bloc { if (result['success']) { add(ResetRoutineState()); - add(const LoadAutomation()); - add(const LoadScenes()); + add(LoadAutomation()); + add(LoadScenes()); } else { emit(state.copyWith( isLoading: false, @@ -1195,14 +1197,14 @@ class RoutineBloc extends Bloc { final automationDetails = await SceneApi.getAutomationDetails(event.automationId, projectUuid); - final deviceIfCards = >{}; - final deviceThenCards = >{}; + final Map> deviceIfCards = {}; + final Map> deviceThenCards = {}; - final updatedFunctions = + final Map> updatedFunctions = Map>.from(state.selectedFunctions); - for (final condition in automationDetails.conditions ?? []) { - final matchingDevice = state.devices.firstWhere( + for (RoutineCondition condition in automationDetails.conditions ?? []) { + AllDevicesModel? matchingDevice = state.devices.firstWhere( (device) => device.uuid == condition.entityId, orElse: () => AllDevicesModel( uuid: condition.entityId, @@ -1239,7 +1241,7 @@ class RoutineBloc extends Bloc { } final functions = matchingDevice.functions; - for (final function in functions) { + for (var function in functions) { if (function.code == condition.expr.statusCode) { updatedFunctions[uniqueCustomId]!.add( DeviceFunctionData( @@ -1255,8 +1257,8 @@ class RoutineBloc extends Bloc { } // Process actions (thenItems) - for (final action in automationDetails.actions) { - final matchingDevice = state.devices.firstWhere( + for (var action in automationDetails.actions) { + AllDevicesModel? matchingDevice = state.devices.firstWhere( (device) => device.uuid == action.entityId, orElse: () => AllDevicesModel( uuid: action.entityId, @@ -1310,7 +1312,7 @@ class RoutineBloc extends Bloc { action.actionExecutor != 'delay') { final functions = matchingDevice.functions; final functionCode = action.executorProperty!.functionCode; - for (final function in functions) { + for (var function in functions) { if (function.code == functionCode) { updatedFunctions[uniqueCustomId]!.add( DeviceFunctionData( @@ -1401,7 +1403,7 @@ class RoutineBloc extends Bloc { } catch (e) { emit(state.copyWith( loadingSceneId: null, - errorMessage: 'Trigger error: $e', + errorMessage: 'Trigger error: ${e.toString()}', )); } } @@ -1446,7 +1448,7 @@ class RoutineBloc extends Bloc { ..remove(event.automationId); emit(state.copyWith( loadingAutomationIds: updatedLoadingIds, - errorMessage: 'Update error: $e', + errorMessage: 'Update error: ${e.toString()}', )); } } diff --git a/lib/pages/routines/bloc/routine_bloc/routine_event.dart b/lib/pages/routines/bloc/routine_bloc/routine_event.dart index dd7adf71..b532235d 100644 --- a/lib/pages/routines/bloc/routine_bloc/routine_event.dart +++ b/lib/pages/routines/bloc/routine_bloc/routine_event.dart @@ -86,8 +86,7 @@ class RemoveDragCard extends RoutineEvent { final int index; final bool isFromThen; final String key; - const RemoveDragCard( - {required this.index, required this.isFromThen, required this.key}); + const RemoveDragCard({required this.index, required this.isFromThen, required this.key}); @override List get props => [index, isFromThen, key]; } @@ -212,6 +211,9 @@ class ClearFunctions extends RoutineEvent {} class ResetErrorMessage extends RoutineEvent {} + + + class SceneTrigger extends RoutineEvent { final String? sceneId; final String? name; @@ -219,7 +221,7 @@ class SceneTrigger extends RoutineEvent { const SceneTrigger({this.sceneId, this.name}); @override - List get props => [sceneId!, name!]; + List get props => [sceneId!,name!]; } //updateAutomationStatus @@ -228,10 +230,7 @@ class UpdateAutomationStatus extends RoutineEvent { final AutomationStatusUpdate automationStatusUpdate; final String communityId; - const UpdateAutomationStatus( - {required this.automationStatusUpdate, - required this.automationId, - required this.communityId}); + const UpdateAutomationStatus({required this.automationStatusUpdate, required this.automationId, required this.communityId}); @override List get props => [automationStatusUpdate]; diff --git a/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart b/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart index b35e3b21..843b35df 100644 --- a/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart +++ b/lib/pages/routines/bloc/setting_bloc/setting_bloc.dart @@ -15,44 +15,37 @@ class SettingBloc extends Bloc { on(_selectIcon); } - Future _initialSetting( - InitialEvent event, Emitter emit) async { + void _initialSetting(InitialEvent event, Emitter emit) async { try { emit(const LoadingState()); selectedIcon = event.selectedIcon; emit(TabToRunSettingLoaded( - showInDevice: true, - selectedIcon: event.selectedIcon, - iconList: iconModelList)); + showInDevice: true, selectedIcon: event.selectedIcon, iconList: iconModelList)); } catch (e) { emit(const FailedState(error: 'Something went wrong')); } } - Future _fetchIcons(FetchIcons event, Emitter emit) async { + void _fetchIcons(FetchIcons event, Emitter emit) async { try { isExpanded = event.expanded; emit(const LoadingState()); if (isExpanded) { iconModelList = await SceneApi.getIcon(); emit(TabToRunSettingLoaded( - showInDevice: true, - selectedIcon: selectedIcon, - iconList: iconModelList)); + showInDevice: true, selectedIcon: selectedIcon, iconList: iconModelList)); } } catch (e) { emit(const FailedState(error: 'Something went wrong')); } } - Future _selectIcon(SelectIcon event, Emitter emit) async { + void _selectIcon(SelectIcon event, Emitter emit) async { try { emit(const LoadingState()); selectedIcon = event.iconId; emit(TabToRunSettingLoaded( - showInDevice: true, - selectedIcon: event.iconId, - iconList: iconModelList)); + showInDevice: true, selectedIcon: event.iconId, iconList: iconModelList)); } catch (e) { emit(const FailedState(error: 'Something went wrong')); } diff --git a/lib/pages/routines/create_new_routines/commu_dropdown.dart b/lib/pages/routines/create_new_routines/commu_dropdown.dart index a3424013..6fd562b0 100644 --- a/lib/pages/routines/create_new_routines/commu_dropdown.dart +++ b/lib/pages/routines/create_new_routines/commu_dropdown.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/dropdown_menu_content.dart'; -import 'package:syncrow_web/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.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/utils/color_manager.dart'; +import 'space_tree_dropdown_bloc.dart'; class SpaceTreeDropdown extends StatefulWidget { final String? selectedSpaceId; @@ -68,7 +68,7 @@ class _SpaceTreeDropdownState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text( - 'Community', + "Community", style: Theme.of(context).textTheme.bodyMedium!.copyWith( fontWeight: FontWeight.w400, fontSize: 13, diff --git a/lib/pages/routines/create_new_routines/create_new_routines.dart b/lib/pages/routines/create_new_routines/create_new_routines.dart index adaff718..fe207910 100644 --- a/lib/pages/routines/create_new_routines/create_new_routines.dart +++ b/lib/pages/routines/create_new_routines/create_new_routines.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_event.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_state.dart'; +import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/commu_dropdown.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/space_dropdown.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -27,11 +27,11 @@ class _CreateNewRoutinesDialogState extends State { CreateRoutineBloc()..add(const FetchCommunityEvent()), child: BlocBuilder( builder: (context, state) { - final bloc = BlocProvider.of(context); - final spaces = bloc.spacesOnlyWithDevices; + final _bloc = BlocProvider.of(context); + final spaces = _bloc.spacesOnlyWithDevices; final isLoadingCommunities = state is CommunitiesLoadingState; final isLoadingSpaces = state is SpaceWithDeviceLoadingState; - var spaceHint = 'Please Select'; + String spaceHint = 'Please Select'; if (_selectedCommunity != null) { if (isLoadingSpaces) { spaceHint = 'Loading spaces...'; @@ -77,9 +77,9 @@ class _CreateNewRoutinesDialogState extends State { SpaceTreeDropdown( selectedSpaceId: _selectedId, onChanged: (String? newValue) { - setState(() => _selectedId = newValue); + setState(() => _selectedId = newValue!); if (_selectedId != null) { - bloc.add(SpaceOnlyWithDevicesEvent( + _bloc.add(SpaceOnlyWithDevicesEvent( _selectedId!)); } }, diff --git a/lib/pages/routines/create_new_routines/dropdown_menu_content.dart b/lib/pages/routines/create_new_routines/dropdown_menu_content.dart index 1ae5be86..70c88087 100644 --- a/lib/pages/routines/create_new_routines/dropdown_menu_content.dart +++ b/lib/pages/routines/create_new_routines/dropdown_menu_content.dart @@ -1,3 +1,7 @@ + + + + import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; @@ -10,7 +14,6 @@ class DropdownMenuContent extends StatefulWidget { final VoidCallback onClose; const DropdownMenuContent({ - super.key, required this.selectedSpaceId, required this.onChanged, required this.onClose, @@ -42,7 +45,7 @@ class _DropdownMenuContentState extends State { final state = bloc.state; if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 30) { - if (!state.paginationIsLoading) { + if (state is SpaceTreeState && !state.paginationIsLoading) { bloc.add(PaginationEvent(state.paginationModel, state.communityList)); } } @@ -123,7 +126,7 @@ class _DropdownMenuContentState extends State { _searchController.text.isEmpty ? context .read() - .add(const SearchQueryEvent('')) + .add(SearchQueryEvent('')) : context.read().add( SearchQueryEvent(_searchController.text)); }); diff --git a/lib/pages/routines/create_new_routines/space_dropdown.dart b/lib/pages/routines/create_new_routines/space_dropdown.dart index 5af30f28..1d11b02d 100644 --- a/lib/pages/routines/create_new_routines/space_dropdown.dart +++ b/lib/pages/routines/create_new_routines/space_dropdown.dart @@ -10,12 +10,12 @@ class SpaceDropdown extends StatelessWidget { final String hintMessage; const SpaceDropdown({ - super.key, + Key? key, required this.spaces, required this.selectedValue, required this.onChanged, required this.hintMessage, - }); + }) : super(key: key); @override Widget build(BuildContext context) { @@ -25,7 +25,7 @@ class SpaceDropdown extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'Space', + "Space", style: Theme.of(context).textTheme.bodyMedium!.copyWith( fontWeight: FontWeight.w400, fontSize: 13, @@ -67,7 +67,7 @@ class SpaceDropdown extends StatelessWidget { ); }).toList(), onChanged: onChanged, - style: const TextStyle(color: Colors.black), + style: TextStyle(color: Colors.black), hint: Padding( padding: const EdgeInsets.only(left: 10), child: Text( diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart index da835e4b..be2a7e9b 100644 --- a/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_bloc.dart @@ -24,4 +24,4 @@ class SpaceTreeDropdownBloc ) { emit(SpaceTreeDropdownState(selectedSpaceId: event.initialId)); } -} +} \ No newline at end of file diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart index 69cf3d3f..dec701dc 100644 --- a/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_event.dart @@ -12,4 +12,4 @@ class SpaceTreeDropdownResetEvent extends SpaceTreeDropdownEvent { final String? initialId; SpaceTreeDropdownResetEvent(this.initialId); -} +} \ No newline at end of file diff --git a/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart b/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart index c815da17..dd22d095 100644 --- a/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart +++ b/lib/pages/routines/create_new_routines/space_tree_dropdown_state.dart @@ -4,4 +4,4 @@ class SpaceTreeDropdownState { final String? selectedSpaceId; SpaceTreeDropdownState({this.selectedSpaceId}); -} +} \ No newline at end of file diff --git a/lib/pages/routines/helper/save_routine_helper.dart b/lib/pages/routines/helper/save_routine_helper.dart index 2b506620..f8b52dab 100644 --- a/lib/pages/routines/helper/save_routine_helper.dart +++ b/lib/pages/routines/helper/save_routine_helper.dart @@ -17,10 +17,9 @@ class SaveRoutineHelper { builder: (context) { return BlocBuilder( builder: (context, state) { - final selectedConditionLabel = - state.selectedAutomationOperator == 'and' - ? 'All Conditions are met' - : 'Any Condition is met'; + final selectedConditionLabel = state.selectedAutomationOperator == 'and' + ? 'All Conditions are met' + : 'Any Condition is met'; return AlertDialog( contentPadding: EdgeInsets.zero, @@ -38,11 +37,10 @@ class SaveRoutineHelper { Text( 'Create a scene: ${state.routineName ?? ""}', textAlign: TextAlign.center, - style: - Theme.of(context).textTheme.headlineMedium!.copyWith( - color: ColorsManager.primaryColorWithOpacity, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context).textTheme.headlineMedium!.copyWith( + color: ColorsManager.primaryColorWithOpacity, + fontWeight: FontWeight.bold, + ), ), const SizedBox(height: 18), _buildDivider(), @@ -60,8 +58,7 @@ class SaveRoutineHelper { _buildIfConditions(state, context), Container( width: 1, - color: ColorsManager.greyColor - .withValues(alpha: 0.8), + color: ColorsManager.greyColor.withValues(alpha: 0.8), ), _buildThenActions(state, context), ], @@ -100,8 +97,7 @@ class SaveRoutineHelper { child: Row( spacing: 16, children: [ - Expanded( - child: Text('IF: $selectedConditionLabel', style: textStyle)), + Expanded(child: Text('IF: $selectedConditionLabel', style: textStyle)), const Expanded(child: Text('THEN:', style: textStyle)), ], ), @@ -113,7 +109,7 @@ class SaveRoutineHelper { spacing: 16, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - DialogFooterButton( + DialogFooterButton( text: 'Back', onTap: () => Navigator.pop(context), ), @@ -147,8 +143,7 @@ class SaveRoutineHelper { child: ListView( // shrinkWrap: true, children: state.thenItems.map((item) { - final functions = - state.selectedFunctions[item['uniqueCustomId']] ?? []; + final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; return functionRow(item, context, functions); }).toList(), ), @@ -208,20 +203,19 @@ class SaveRoutineHelper { ), ), child: Center( - child: - item['type'] == 'tap_to_run' || item['type'] == 'scene' - ? Image.memory( - base64Decode(item['icon']), - width: 12, - height: 22, - fit: BoxFit.scaleDown, - ) - : SvgPicture.asset( - item['imagePath'], - width: 12, - height: 12, - fit: BoxFit.scaleDown, - ), + child: item['type'] == 'tap_to_run' || item['type'] == 'scene' + ? Image.memory( + base64Decode(item['icon']), + width: 12, + height: 22, + fit: BoxFit.scaleDown, + ) + : SvgPicture.asset( + item['imagePath'], + width: 12, + height: 12, + fit: BoxFit.scaleDown, + ), ), ), Flexible( diff --git a/lib/pages/routines/models/ac/ac_function.dart b/lib/pages/routines/models/ac/ac_function.dart index e92b6dee..edc377dd 100644 --- a/lib/pages/routines/models/ac/ac_function.dart +++ b/lib/pages/routines/models/ac/ac_function.dart @@ -37,12 +37,12 @@ class SwitchFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), ACOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; @@ -62,17 +62,17 @@ class ModeFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsAcCooling, - description: 'Cooling', + description: "Cooling", value: TempModes.cold.name, ), ACOperationalValue( icon: Assets.assetsAcHeating, - description: 'Heating', + description: "Heating", value: TempModes.hot.name, ), ACOperationalValue( icon: Assets.assetsFanSpeed, - description: 'Ventilation', + description: "Ventilation", value: TempModes.wind.name, ), ]; @@ -90,23 +90,22 @@ class TempSetFunction extends ACFunction { min: 200, max: 300, step: 1, - unit: '°C', + unit: "°C", ); @override List getOperationalValues() { - final values = []; - for (var temp = min!.toInt(); temp <= max!; temp += step!.toInt()) { + List values = []; + for (int temp = min!.toInt(); temp <= max!; temp += step!.toInt()) { values.add(ACOperationalValue( icon: Assets.assetsTempreture, - description: '${temp / 10}°C', + description: "${temp / 10}°C", value: temp, )); } return values; } } - class LevelFunction extends ACFunction { LevelFunction( {required super.deviceId, required super.deviceName, required type}) @@ -121,22 +120,22 @@ class LevelFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsAcFanLow, - description: 'LOW', + description: "LOW", value: FanSpeeds.low.name, ), ACOperationalValue( icon: Assets.assetsAcFanMiddle, - description: 'MIDDLE', + description: "MIDDLE", value: FanSpeeds.middle.name, ), ACOperationalValue( icon: Assets.assetsAcFanHigh, - description: 'HIGH', + description: "HIGH", value: FanSpeeds.high.name, ), ACOperationalValue( icon: Assets.assetsAcFanAuto, - description: 'AUTO', + description: "AUTO", value: FanSpeeds.auto.name, ), ]; @@ -156,26 +155,22 @@ class ChildLockFunction extends ACFunction { List getOperationalValues() => [ ACOperationalValue( icon: Assets.assetsSceneChildLock, - description: 'Lock', + description: "Lock", value: true, ), ACOperationalValue( icon: Assets.assetsSceneChildUnlock, - description: 'Unlock', + description: "Unlock", value: false, ), ]; } class CurrentTempFunction extends ACFunction { - @override final double min; - @override final double max; - @override final double step; - @override - final String unit = '°C'; + final String unit = "°C"; CurrentTempFunction( {required super.deviceId, required super.deviceName, required type}) @@ -191,11 +186,11 @@ class CurrentTempFunction extends ACFunction { @override List getOperationalValues() { - final values = []; - for (var temp = min.toInt(); temp <= max; temp += step.toInt()) { + List values = []; + for (int temp = min.toInt(); temp <= max; temp += step.toInt()) { values.add(ACOperationalValue( icon: Assets.currentTemp, - description: '${temp / 10}°C', + description: "${temp / 10}°C", value: temp, )); } diff --git a/lib/pages/routines/models/ceiling_presence_sensor_functions.dart b/lib/pages/routines/models/ceiling_presence_sensor_functions.dart index f364abdb..122d8ea1 100644 --- a/lib/pages/routines/models/ceiling_presence_sensor_functions.dart +++ b/lib/pages/routines/models/ceiling_presence_sensor_functions.dart @@ -6,10 +6,12 @@ class CpsOperationalValue { final String description; final dynamic value; + CpsOperationalValue({ required this.icon, required this.description, required this.value, + }); } @@ -43,12 +45,12 @@ final class CpsRadarSwitchFunction extends CpsFunctions { List getOperationalValues() => [ CpsOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), CpsOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; @@ -69,12 +71,12 @@ final class CpsSpatialParameterSwitchFunction extends CpsFunctions { List getOperationalValues() => [ CpsOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), CpsOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; @@ -94,11 +96,8 @@ final class CpsSensitivityFunction extends CpsFunctions { icon: Assets.sensitivity, ); - @override final double min; - @override final double max; - @override final double step; static const _images = [ @@ -145,11 +144,8 @@ final class CpsMovingSpeedFunction extends CpsFunctions { icon: Assets.speedoMeter, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -179,11 +175,8 @@ final class CpsSpatialStaticValueFunction extends CpsFunctions { icon: Assets.spatialStaticValue, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -213,11 +206,8 @@ final class CpsSpatialMotionValueFunction extends CpsFunctions { icon: Assets.spatialMotionValue, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -247,11 +237,8 @@ final class CpsMaxDistanceOfDetectionFunction extends CpsFunctions { icon: Assets.currentDistanceIcon, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -260,7 +247,7 @@ final class CpsMaxDistanceOfDetectionFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.currentDistanceIcon, description: '${value.toStringAsFixed(1)} M', @@ -285,11 +272,8 @@ final class CpsMaxDistanceOfStaticDetectionFunction extends CpsFunctions { icon: Assets.currentDistanceIcon, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -298,7 +282,7 @@ final class CpsMaxDistanceOfStaticDetectionFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.currentDistanceIcon, description: '${value.toStringAsFixed(1)} M', @@ -323,11 +307,8 @@ final class CpsDetectionRangeFunction extends CpsFunctions { icon: Assets.farDetection, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -336,7 +317,7 @@ final class CpsDetectionRangeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.farDetection, description: '${value.toStringAsFixed(1)} M', @@ -361,11 +342,8 @@ final class CpsDistanceOfMovingObjectsFunction extends CpsFunctions { icon: Assets.currentDistanceIcon, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -374,7 +352,7 @@ final class CpsDistanceOfMovingObjectsFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.currentDistanceIcon, description: '${value.toStringAsFixed(1)} M', @@ -399,11 +377,8 @@ final class CpsPresenceJudgementThrsholdFunction extends CpsFunctions { icon: Assets.presenceJudgementThrshold, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -433,11 +408,8 @@ final class CpsMotionAmplitudeTriggerThresholdFunction extends CpsFunctions { icon: Assets.presenceJudgementThrshold, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -467,11 +439,8 @@ final class CpsPerpetualBoundaryFunction extends CpsFunctions { icon: Assets.boundary, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -480,7 +449,7 @@ final class CpsPerpetualBoundaryFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.boundary, description: '${value.toStringAsFixed(1)}M', @@ -505,11 +474,8 @@ final class CpsMotionTriggerBoundaryFunction extends CpsFunctions { icon: Assets.motionMeter, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -518,7 +484,7 @@ final class CpsMotionTriggerBoundaryFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(1)} M', @@ -543,11 +509,8 @@ final class CpsMotionTriggerTimeFunction extends CpsFunctions { icon: Assets.motionMeter, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -556,7 +519,7 @@ final class CpsMotionTriggerTimeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(3)} sec', @@ -581,11 +544,8 @@ final class CpsMotionToStaticTimeFunction extends CpsFunctions { icon: Assets.motionMeter, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -594,7 +554,7 @@ final class CpsMotionToStaticTimeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(0)} sec', @@ -619,11 +579,8 @@ final class CpsEnteringNoBodyStateTimeFunction extends CpsFunctions { icon: Assets.motionMeter, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -632,7 +589,7 @@ final class CpsEnteringNoBodyStateTimeFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.motionMeter, description: '${value.toStringAsFixed(0)} sec', @@ -912,11 +869,8 @@ final class CpsSportsParaFunction extends CpsFunctions { icon: Assets.sportsPara, ); - @override final double min; - @override final double max; - @override final double step; @override @@ -925,7 +879,7 @@ final class CpsSportsParaFunction extends CpsFunctions { return List.generate( count, (index) { - final value = min + (index * step); + final value = (min + (index * step)); return CpsOperationalValue( icon: Assets.motionMeter, description: value.toStringAsFixed(0), diff --git a/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart b/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart index 835d8886..81ee1096 100644 --- a/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart +++ b/lib/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart @@ -112,7 +112,7 @@ class CreateSceneAction { CreateSceneExecutorProperty? executorProperty, }) { return CreateSceneAction( - actionType: actionType ?? actionType, + actionType: actionType ?? this.actionType, entityId: entityId ?? this.entityId, actionExecutor: actionExecutor ?? this.actionExecutor, executorProperty: executorProperty ?? this.executorProperty, @@ -128,7 +128,7 @@ class CreateSceneAction { }; } else { return { - 'actionType': actionType, + "actionType": actionType, 'entityId': entityId, 'actionExecutor': actionExecutor, }; diff --git a/lib/pages/routines/models/delay/delay_fucntions.dart b/lib/pages/routines/models/delay/delay_fucntions.dart index 28c87a25..428825f4 100644 --- a/lib/pages/routines/models/delay/delay_fucntions.dart +++ b/lib/pages/routines/models/delay/delay_fucntions.dart @@ -14,7 +14,7 @@ class DelayFunction extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: 'Duration in seconds', + description: "Duration in seconds", value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/flush/flush_functions.dart b/lib/pages/routines/models/flush/flush_functions.dart index 6f4b01a6..a8f6ccd4 100644 --- a/lib/pages/routines/models/flush/flush_functions.dart +++ b/lib/pages/routines/models/flush/flush_functions.dart @@ -24,7 +24,8 @@ class FlushPresenceDelayFunction extends FlushFunctions { required super.deviceId, required super.deviceName, required super.type, - }) : super( + }) : + super( code: FlushMountedPresenceSensorModel.codePresenceState, operationName: 'Presence State', icon: Assets.presenceStateIcon, @@ -36,7 +37,7 @@ class FlushPresenceDelayFunction extends FlushFunctions { FlushOperationalValue( icon: Assets.nobodyTime, description: 'None', - value: 'none', + value: "none", ), FlushOperationalValue( icon: Assets.presenceStateIcon, @@ -48,11 +49,8 @@ class FlushPresenceDelayFunction extends FlushFunctions { } class FlushSensiReduceFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; FlushSensiReduceFunction({ @@ -81,11 +79,8 @@ class FlushSensiReduceFunction extends FlushFunctions { } class FlushNoneDelayFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final String unit; FlushNoneDelayFunction({ @@ -114,11 +109,8 @@ class FlushNoneDelayFunction extends FlushFunctions { } class FlushIlluminanceFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; FlushIlluminanceFunction({ @@ -136,11 +128,11 @@ class FlushIlluminanceFunction extends FlushFunctions { @override List getOperationalValues() { - final values = []; - for (var lux = min.toInt(); lux <= max; lux += step.toInt()) { + List values = []; + for (int lux = min.toInt(); lux <= max; lux += step.toInt()) { values.add(FlushOperationalValue( icon: Assets.IlluminanceIcon, - description: '$lux Lux', + description: "$lux Lux", value: lux, )); } @@ -149,11 +141,8 @@ class FlushIlluminanceFunction extends FlushFunctions { } class FlushOccurDistReduceFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; FlushOccurDistReduceFunction({ @@ -183,11 +172,8 @@ class FlushOccurDistReduceFunction extends FlushFunctions { // ==== then functions ==== class FlushSensitivityFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; FlushSensitivityFunction({ @@ -216,13 +202,9 @@ class FlushSensitivityFunction extends FlushFunctions { } class FlushNearDetectionFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; - @override final String unit; FlushNearDetectionFunction({ @@ -242,7 +224,7 @@ class FlushNearDetectionFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min; value <= max; value += step) { + for (var value = min.toDouble(); value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -254,13 +236,9 @@ class FlushNearDetectionFunction extends FlushFunctions { } class FlushMaxDetectDistFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; - @override final String unit; FlushMaxDetectDistFunction({ @@ -292,13 +270,9 @@ class FlushMaxDetectDistFunction extends FlushFunctions { } class FlushTargetConfirmTimeFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; - @override final String unit; FlushTargetConfirmTimeFunction({ @@ -318,7 +292,7 @@ class FlushTargetConfirmTimeFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min; value <= max; value += step) { + for (var value = min.toDouble(); value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -330,13 +304,9 @@ class FlushTargetConfirmTimeFunction extends FlushFunctions { } class FlushDisappeDelayFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; - @override final String unit; FlushDisappeDelayFunction({ @@ -356,7 +326,7 @@ class FlushDisappeDelayFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min; value <= max; value += step) { + for (var value = min.toDouble(); value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -368,13 +338,9 @@ class FlushDisappeDelayFunction extends FlushFunctions { } class FlushIndentLevelFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; - @override final String unit; FlushIndentLevelFunction({ @@ -394,7 +360,7 @@ class FlushIndentLevelFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min; value <= max; value += step) { + for (var value = min.toDouble(); value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', @@ -406,13 +372,9 @@ class FlushIndentLevelFunction extends FlushFunctions { } class FlushTriggerLevelFunction extends FlushFunctions { - @override final double min; - @override final double max; - @override final double step; - @override final String unit; FlushTriggerLevelFunction({ @@ -432,7 +394,7 @@ class FlushTriggerLevelFunction extends FlushFunctions { @override List getOperationalValues() { final values = []; - for (var value = min; value <= max; value += step) { + for (var value = min.toDouble(); value <= max; value += step) { values.add(FlushOperationalValue( icon: Assets.nobodyTime, description: '$value $unit', diff --git a/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart b/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart index 78d32069..9451f89f 100644 --- a/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart +++ b/lib/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart @@ -14,12 +14,12 @@ class OneGangSwitchFunction extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; @@ -37,7 +37,7 @@ class OneGangCountdownFunction extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: 'sec', + description: "sec", value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart b/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart index eee0019d..9bdd30b4 100644 --- a/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart +++ b/lib/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart @@ -3,11 +3,8 @@ import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operation import 'package:syncrow_web/utils/constants/assets.dart'; class ThreeGangSwitch1Function extends BaseSwitchFunction { - ThreeGangSwitch1Function({ - required super.deviceId, - required super.deviceName, - required String type, - }) : super( + ThreeGangSwitch1Function({required super.deviceId, required super.deviceName ,required type}) + : super( code: 'switch_1', operationName: 'Light 1 Switch', icon: Assets.assetsAcPower, @@ -17,23 +14,20 @@ class ThreeGangSwitch1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; } class ThreeGangCountdown1Function extends BaseSwitchFunction { - ThreeGangCountdown1Function({ - required super.deviceId, - required super.deviceName, - required String type, - }) : super( + ThreeGangCountdown1Function({required super.deviceId, required super.deviceName ,required type}) + : super( code: 'countdown_1', operationName: 'Light 1 Countdown', icon: Assets.assetsLightCountdown, @@ -43,7 +37,7 @@ class ThreeGangCountdown1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: 'sec', + description: "sec", value: 0.0, minValue: 0, maxValue: 43200, @@ -53,11 +47,8 @@ class ThreeGangCountdown1Function extends BaseSwitchFunction { } class ThreeGangSwitch2Function extends BaseSwitchFunction { - ThreeGangSwitch2Function({ - required super.deviceId, - required super.deviceName, - required String type, - }) : super( + ThreeGangSwitch2Function({required super.deviceId, required super.deviceName, required type}) + : super( code: 'switch_2', operationName: 'Light 2 Switch', icon: Assets.assetsAcPower, @@ -67,23 +58,20 @@ class ThreeGangSwitch2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; } class ThreeGangCountdown2Function extends BaseSwitchFunction { - ThreeGangCountdown2Function({ - required super.deviceId, - required super.deviceName, - required String type, - }) : super( + ThreeGangCountdown2Function({required super.deviceId, required super.deviceName ,required type}) + : super( code: 'countdown_2', operationName: 'Light 2 Countdown', icon: Assets.assetsLightCountdown, @@ -93,7 +81,7 @@ class ThreeGangCountdown2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: 'sec', + description: "sec", value: 0.0, minValue: 0, maxValue: 43200, @@ -103,11 +91,8 @@ class ThreeGangCountdown2Function extends BaseSwitchFunction { } class ThreeGangSwitch3Function extends BaseSwitchFunction { - ThreeGangSwitch3Function({ - required super.deviceId, - required super.deviceName, - required String type, - }) : super( + ThreeGangSwitch3Function({required super.deviceId, required super.deviceName ,required type}) + : super( code: 'switch_3', operationName: 'Light 3 Switch', icon: Assets.assetsAcPower, @@ -117,23 +102,20 @@ class ThreeGangSwitch3Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; } class ThreeGangCountdown3Function extends BaseSwitchFunction { - ThreeGangCountdown3Function({ - required super.deviceId, - required super.deviceName, - required String type, - }) : super( + ThreeGangCountdown3Function({required super.deviceId, required super.deviceName ,required type}) + : super( code: 'countdown_3', operationName: 'Light 3 Countdown', icon: Assets.assetsLightCountdown, @@ -143,7 +125,7 @@ class ThreeGangCountdown3Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: 'sec', + description: "sec", value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart b/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart index a5f78436..95de1122 100644 --- a/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart +++ b/lib/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart @@ -14,12 +14,12 @@ class TwoGangSwitch1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; @@ -37,20 +37,19 @@ class TwoGangSwitch2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), SwitchOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; } class TwoGangCountdown1Function extends BaseSwitchFunction { - TwoGangCountdown1Function( - {required super.deviceId, required super.deviceName}) + TwoGangCountdown1Function({required super.deviceId, required super.deviceName}) : super( code: 'countdown_1', operationName: 'Light 1 Countdown', @@ -61,7 +60,7 @@ class TwoGangCountdown1Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: 'sec', + description: "sec", value: 0.0, minValue: 0, maxValue: 43200, @@ -71,8 +70,7 @@ class TwoGangCountdown1Function extends BaseSwitchFunction { } class TwoGangCountdown2Function extends BaseSwitchFunction { - TwoGangCountdown2Function( - {required super.deviceId, required super.deviceName}) + TwoGangCountdown2Function({required super.deviceId, required super.deviceName}) : super( code: 'countdown_2', operationName: 'Light 2 Countdown', @@ -83,7 +81,7 @@ class TwoGangCountdown2Function extends BaseSwitchFunction { List getOperationalValues() => [ SwitchOperationalValue( icon: '', - description: 'sec', + description: "sec", value: 0.0, minValue: 0, maxValue: 43200, diff --git a/lib/pages/routines/models/gateway.dart b/lib/pages/routines/models/gateway.dart index 06dc6f52..b1a70d2e 100644 --- a/lib/pages/routines/models/gateway.dart +++ b/lib/pages/routines/models/gateway.dart @@ -13,8 +13,7 @@ class GatewayOperationalValue { }); } -abstract class GatewayFunctions - extends DeviceFunction { +abstract class GatewayFunctions extends DeviceFunction { final String type; GatewayFunctions({ @@ -44,12 +43,12 @@ final class GatewaySwitchAlarmSound extends GatewayFunctions { List getOperationalValues() => [ GatewayOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), GatewayOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; @@ -71,12 +70,12 @@ final class GatewayMasterState extends GatewayFunctions { return [ GatewayOperationalValue( icon: Assets.assetsAcPower, - description: 'Normal', + description: "Normal", value: 'normal', ), GatewayOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'Alarm', + description: "Alarm", value: 'alarm', ), ]; @@ -99,12 +98,12 @@ final class GatewayFactoryReset extends GatewayFunctions { return [ GatewayOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), GatewayOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; diff --git a/lib/pages/routines/models/pc/energy_clamp_functions.dart b/lib/pages/routines/models/pc/energy_clamp_functions.dart index 5945faa4..4bf3ddd8 100644 --- a/lib/pages/routines/models/pc/energy_clamp_functions.dart +++ b/lib/pages/routines/models/pc/energy_clamp_functions.dart @@ -35,7 +35,7 @@ class TotalEnergyConsumedStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: 'kWh', + unit: "kWh", ); @override @@ -54,7 +54,7 @@ class TotalActivePowerConsumedStatusFunction extends EnergyClampFunctions { min: -19800000, max: 19800000, step: 0.1, - unit: 'kW', + unit: "kW", ); @override @@ -101,7 +101,7 @@ class TotalCurrentStatusFunction extends EnergyClampFunctions { min: 0.000, max: 9000.000, step: 1, - unit: 'A', + unit: "A", ); @override @@ -120,7 +120,7 @@ class FrequencyStatusFunction extends EnergyClampFunctions { min: 0, max: 80, step: 1, - unit: 'Hz', + unit: "Hz", ); @override @@ -140,7 +140,7 @@ class EnergyConsumedAStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: 'kWh', + unit: "kWh", ); @override @@ -159,7 +159,7 @@ class ActivePowerAStatusFunction extends EnergyClampFunctions { min: 200, max: 300, step: 1, - unit: 'kW', + unit: "kW", ); @override @@ -178,7 +178,7 @@ class VoltageAStatusFunction extends EnergyClampFunctions { min: 0.0, max: 500, step: 1, - unit: 'V', + unit: "V", ); @override @@ -197,7 +197,7 @@ class PowerFactorAStatusFunction extends EnergyClampFunctions { min: 0.00, max: 1.00, step: 0.1, - unit: '', + unit: "", ); @override @@ -216,7 +216,7 @@ class CurrentAStatusFunction extends EnergyClampFunctions { min: 0.000, max: 3000.000, step: 1, - unit: 'A', + unit: "A", ); @override @@ -236,7 +236,7 @@ class EnergyConsumedBStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: 'kWh', + unit: "kWh", ); @override @@ -255,7 +255,7 @@ class ActivePowerBStatusFunction extends EnergyClampFunctions { min: -6600000, max: 6600000, step: 1, - unit: 'kW', + unit: "kW", ); @override @@ -274,7 +274,7 @@ class VoltageBStatusFunction extends EnergyClampFunctions { min: 0.0, max: 500, step: 1, - unit: 'V', + unit: "V", ); @override @@ -293,7 +293,7 @@ class CurrentBStatusFunction extends EnergyClampFunctions { min: 0.000, max: 3000.000, step: 1, - unit: 'A', + unit: "A", ); @override @@ -312,7 +312,7 @@ class PowerFactorBStatusFunction extends EnergyClampFunctions { min: 0.0, max: 1.0, step: 0.1, - unit: '', + unit: "", ); @override @@ -332,7 +332,7 @@ class EnergyConsumedCStatusFunction extends EnergyClampFunctions { min: 0.00, max: 20000000.00, step: 1, - unit: 'kWh', + unit: "kWh", ); @override @@ -351,7 +351,7 @@ class ActivePowerCStatusFunction extends EnergyClampFunctions { min: -6600000, max: 6600000, step: 1, - unit: 'kW', + unit: "kW", ); @override @@ -370,7 +370,7 @@ class VoltageCStatusFunction extends EnergyClampFunctions { min: 0.00, max: 500, step: 0.1, - unit: 'V', + unit: "V", ); @override @@ -389,7 +389,7 @@ class CurrentCStatusFunction extends EnergyClampFunctions { min: 0.000, max: 3000.000, step: 0.1, - unit: 'A', + unit: "A", ); @override @@ -408,7 +408,7 @@ class PowerFactorCStatusFunction extends EnergyClampFunctions { min: 0.00, max: 1.00, step: 0.1, - unit: '', + unit: "", ); @override diff --git a/lib/pages/routines/models/routine_details_model.dart b/lib/pages/routines/models/routine_details_model.dart index 364a5bec..c42b4d36 100644 --- a/lib/pages/routines/models/routine_details_model.dart +++ b/lib/pages/routines/models/routine_details_model.dart @@ -48,8 +48,7 @@ class RoutineDetailsModel { spaceUuid: spaceUuid, automationName: name, decisionExpr: decisionExpr, - effectiveTime: - effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''), + effectiveTime: effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''), conditions: conditions?.map((c) => c.toCondition()).toList() ?? [], actions: actions.map((a) => a.toAutomationAction()).toList(), ); @@ -64,8 +63,7 @@ class RoutineDetailsModel { if (iconId != null) 'iconUuid': iconId, if (showInDevice != null) 'showInDevice': showInDevice, if (effectiveTime != null) 'effectiveTime': effectiveTime!.toMap(), - if (conditions != null) - 'conditions': conditions!.map((x) => x.toMap()).toList(), + if (conditions != null) 'conditions': conditions!.map((x) => x.toMap()).toList(), if (type != null) 'type': type, if (sceneId != null) 'sceneId': sceneId, if (automationId != null) 'automationId': automationId, @@ -82,12 +80,10 @@ class RoutineDetailsModel { ), iconId: map['iconUuid'], showInDevice: map['showInDevice'], - effectiveTime: map['effectiveTime'] != null - ? EffectiveTime.fromMap(map['effectiveTime']) - : null, + effectiveTime: + map['effectiveTime'] != null ? EffectiveTime.fromMap(map['effectiveTime']) : null, conditions: map['conditions'] != null - ? List.from( - map['conditions'].map((x) => RoutineCondition.fromMap(x))) + ? List.from(map['conditions'].map((x) => RoutineCondition.fromMap(x))) : null, type: map['type'], sceneId: map['sceneId'], @@ -141,8 +137,7 @@ class RoutineAction { 'actionExecutor': actionExecutor, if (type != null) 'type': type, if (name != null) 'name': name, - if (executorProperty != null) - 'executorProperty': executorProperty!.toMap(), + if (executorProperty != null) 'executorProperty': executorProperty!.toMap(), }; } diff --git a/lib/pages/routines/models/routine_model.dart b/lib/pages/routines/models/routine_model.dart index d1d3cdcd..2f7c2a24 100644 --- a/lib/pages/routines/models/routine_model.dart +++ b/lib/pages/routines/models/routine_model.dart @@ -42,27 +42,27 @@ class ScenesModel { factory ScenesModel.fromJson(Map json, {bool? isAutomation}) { return ScenesModel( - id: json['id'] ?? json['uuid'] ?? '', - sceneTuyaId: json['sceneTuyaId'] as String?, - name: json['name'] ?? '', - status: json['status'] ?? '', - type: json['type'] ?? '', - spaceName: json['spaceName'] ?? '', - spaceId: json['spaceId'] ?? '', - communityId: json['communityId'] ?? '', + id: json["id"] ?? json["uuid"] ?? '', + sceneTuyaId: json["sceneTuyaId"] as String?, + name: json["name"] ?? '', + status: json["status"] ?? '', + type: json["type"] ?? '', + spaceName: json["spaceName"] ?? '', + spaceId: json["spaceId"] ?? '', + communityId: json["communityId"] ?? '', icon: - isAutomation == true ? Assets.automation : (json['icon'] as String?), + isAutomation == true ? Assets.automation : (json["icon"] as String?), ); } Map toJson() => { - 'id': id, - 'sceneTuyaId': sceneTuyaId ?? '', - 'name': name, - 'status': status, - 'type': type, - 'spaceName': spaceName, - 'spaceId': spaceId, - 'communityId': communityId, + "id": id, + "sceneTuyaId": sceneTuyaId ?? '', + "name": name, + "status": status, + "type": type, + "spaceName": spaceName, + "spaceId": spaceId, + "communityId": communityId, }; } diff --git a/lib/pages/routines/models/water_heater/water_heater_functions.dart b/lib/pages/routines/models/water_heater/water_heater_functions.dart index 6c76a41d..7ebea019 100644 --- a/lib/pages/routines/models/water_heater/water_heater_functions.dart +++ b/lib/pages/routines/models/water_heater/water_heater_functions.dart @@ -29,6 +29,7 @@ class WHRestartStatusFunction extends WaterHeaterFunctions { operationName: 'Restart Status', icon: Assets.refreshStatusIcon, ); + @override List getOperationalValues() { @@ -36,7 +37,7 @@ class WHRestartStatusFunction extends WaterHeaterFunctions { WaterHeaterOperationalValue( icon: Assets.assetsAcPowerOFF, description: 'Power OFF', - value: 'off', + value: "off", ), WaterHeaterOperationalValue( icon: Assets.assetsAcPower, @@ -45,7 +46,7 @@ class WHRestartStatusFunction extends WaterHeaterFunctions { ), WaterHeaterOperationalValue( icon: Assets.refreshStatusIcon, - description: 'Restart Memory', + description: "Restart Memory", value: 'memory', ), ]; @@ -104,7 +105,8 @@ class BacklightFunction extends WaterHeaterFunctions { required super.deviceId, required super.deviceName, required super.type, - }) : super( + }) : + super( code: 'switch_backlight', operationName: 'Backlight', icon: Assets.indicator, diff --git a/lib/pages/routines/models/wps/wps_functions.dart b/lib/pages/routines/models/wps/wps_functions.dart index 3eae35a8..101c5cf0 100644 --- a/lib/pages/routines/models/wps/wps_functions.dart +++ b/lib/pages/routines/models/wps/wps_functions.dart @@ -24,11 +24,11 @@ abstract class WpsFunctions extends DeviceFunction { // For far_detection (75-600cm in 75cm steps) class FarDetectionFunction extends WpsFunctions { - @override + final double min; - @override + @override final double max; - @override + @override final double step; @override final String unit; @@ -62,13 +62,9 @@ class FarDetectionFunction extends WpsFunctions { // For presence_time (0-65535 minutes) class PresenceTimeFunction extends WpsFunctions { - @override final double min; - @override final double max; - @override final double step; - @override final String unit; PresenceTimeFunction( @@ -98,11 +94,8 @@ class PresenceTimeFunction extends WpsFunctions { // For motion_sensitivity_value (1-5 levels) class MotionSensitivityFunction extends WpsFunctions { - @override final double min; - @override final double max; - @override final double step; MotionSensitivityFunction( @@ -131,11 +124,8 @@ class MotionSensitivityFunction extends WpsFunctions { } class MotionLessSensitivityFunction extends WpsFunctions { - @override final double min; - @override final double max; - @override final double step; MotionLessSensitivityFunction( @@ -177,23 +167,20 @@ class IndicatorFunction extends WpsFunctions { List getOperationalValues() => [ WpsOperationalValue( icon: Assets.assetsAcPower, - description: 'ON', + description: "ON", value: true, ), WpsOperationalValue( icon: Assets.assetsAcPowerOFF, - description: 'OFF', + description: "OFF", value: false, ), ]; } class NoOneTimeFunction extends WpsFunctions { - @override final double min; - @override final double max; - @override final String unit; NoOneTimeFunction( @@ -234,23 +221,20 @@ class PresenceStateFunction extends WpsFunctions { List getOperationalValues() => [ WpsOperationalValue( icon: Assets.assetsAcPower, - description: 'None', + description: "None", value: 'none', ), WpsOperationalValue( icon: Assets.presenceStateIcon, - description: 'Presence', + description: "Presence", value: 'presence', ), ]; } class CurrentDistanceFunction extends WpsFunctions { - @override final double min; - @override final double max; - @override final double step; CurrentDistanceFunction( @@ -267,11 +251,11 @@ class CurrentDistanceFunction extends WpsFunctions { @override List getOperationalValues() { - final values = []; - for (var cm = min.toInt(); cm <= max; cm += step.toInt()) { + List values = []; + for (int cm = min.toInt(); cm <= max; cm += step.toInt()) { values.add(WpsOperationalValue( icon: Assets.assetsTempreture, - description: '${cm}CM', + description: "${cm}CM", value: cm, )); } @@ -280,11 +264,8 @@ class CurrentDistanceFunction extends WpsFunctions { } class IlluminanceValueFunction extends WpsFunctions { - @override final double min; - @override final double max; - @override final double step; IlluminanceValueFunction({ @@ -302,11 +283,11 @@ class IlluminanceValueFunction extends WpsFunctions { @override List getOperationalValues() { - final values = []; - for (var lux = min.toInt(); lux <= max; lux += step.toInt()) { + List values = []; + for (int lux = min.toInt(); lux <= max; lux += step.toInt()) { values.add(WpsOperationalValue( icon: Assets.IlluminanceIcon, - description: '$lux Lux', + description: "$lux Lux", value: lux, )); } diff --git a/lib/pages/routines/view/effective_period_view.dart b/lib/pages/routines/view/effective_period_view.dart index 8369d790..b54e4075 100644 --- a/lib/pages/routines/view/effective_period_view.dart +++ b/lib/pages/routines/view/effective_period_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart'; import 'package:syncrow_web/pages/routines/widgets/period_option.dart'; import 'package:syncrow_web/pages/routines/widgets/repeat_days.dart'; -import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class EffectivePeriodView extends StatelessWidget { diff --git a/lib/pages/routines/view/routines_view.dart b/lib/pages/routines/view/routines_view.dart index 51176419..f46ef15f 100644 --- a/lib/pages/routines/view/routines_view.dart +++ b/lib/pages/routines/view/routines_view.dart @@ -19,7 +19,7 @@ class RoutinesView extends StatefulWidget { } class _RoutinesViewState extends State { - Future _handleRoutineCreation(BuildContext context) async { + void _handleRoutineCreation(BuildContext context) async { final result = await showDialog>( context: context, builder: (context) => const CreateNewRoutinesDialog(), @@ -69,7 +69,7 @@ class _RoutinesViewState extends State { spacing: 16, children: [ Text( - 'Create New Routines', + "Create New Routines", style: Theme.of(context).textTheme.titleLarge?.copyWith( color: ColorsManager.grayColor, diff --git a/lib/pages/routines/widgets/condition_toggle.dart b/lib/pages/routines/widgets/condition_toggle.dart index 8a26db83..541ad431 100644 --- a/lib/pages/routines/widgets/condition_toggle.dart +++ b/lib/pages/routines/widgets/condition_toggle.dart @@ -11,8 +11,8 @@ class ConditionToggle extends StatelessWidget { super.key, }); - static const _conditions = ['<', '==', '>']; - static const List _icons = [ + static const _conditions = ["<", "==", ">"]; + static const _icons = [ Icons.chevron_left, Icons.drag_handle, Icons.chevron_right @@ -20,13 +20,13 @@ class ConditionToggle extends StatelessWidget { @override Widget build(BuildContext context) { - final selectedIndex = _conditions.indexOf(currentCondition ?? '=='); + final selectedIndex = _conditions.indexOf(currentCondition ?? "=="); return Container( height: 30, width: MediaQuery.of(context).size.width * 0.1, decoration: BoxDecoration( - color: ColorsManager.softGray.withValues(alpha: 0.5), + color: ColorsManager.softGray.withOpacity(0.5), borderRadius: BorderRadius.circular(50), ), clipBehavior: Clip.antiAlias, diff --git a/lib/pages/routines/widgets/custom_routines_textbox.dart b/lib/pages/routines/widgets/custom_routines_textbox.dart index f7ceda8f..f0767df4 100644 --- a/lib/pages/routines/widgets/custom_routines_textbox.dart +++ b/lib/pages/routines/widgets/custom_routines_textbox.dart @@ -1,5 +1,4 @@ import 'dart:math'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:syncrow_web/pages/routines/widgets/condition_toggle.dart'; @@ -46,10 +45,10 @@ class _CustomRoutinesTextboxState extends State { String? errorMessage; int getDecimalPlaces(double step) { - final stepStr = step.toString(); + String stepStr = step.toString(); if (stepStr.contains('.')) { - final parts = stepStr.split('.'); - var decimalPart = parts[1]; + List parts = stepStr.split('.'); + String decimalPart = parts[1]; decimalPart = decimalPart.replaceAll(RegExp(r'0+$'), ''); return decimalPart.isEmpty ? 0 : decimalPart.length; } else { @@ -112,11 +111,13 @@ class _CustomRoutinesTextboxState extends State { } } + + void _validateInput(String value) { final doubleValue = double.tryParse(value); if (doubleValue == null) { setState(() { - errorMessage = 'Invalid number'; + errorMessage = "Invalid number"; hasError = true; }); return; @@ -127,23 +128,23 @@ class _CustomRoutinesTextboxState extends State { if (doubleValue < min) { setState(() { - errorMessage = 'Value must be at least $min'; + errorMessage = "Value must be at least $min"; hasError = true; }); } else if (doubleValue > max) { setState(() { - errorMessage = 'Value must be at most $max'; + errorMessage = "Value must be at most $max"; hasError = true; }); } else { - final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); - final factor = pow(10, decimalPlaces).toInt(); - final scaledStep = (widget.stepIncreaseAmount * factor).round(); - final scaledValue = (doubleValue * factor).round(); + int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); + int factor = pow(10, decimalPlaces).toInt(); + int scaledStep = (widget.stepIncreaseAmount * factor).round(); + int scaledValue = (doubleValue * factor).round(); if (scaledValue % scaledStep != 0) { setState(() { - errorMessage = 'must be a multiple of ${widget.stepIncreaseAmount}'; + errorMessage = "must be a multiple of ${widget.stepIncreaseAmount}"; hasError = true; }); } else { @@ -155,10 +156,11 @@ class _CustomRoutinesTextboxState extends State { } } + void _correctAndUpdateValue(String value) { final doubleValue = double.tryParse(value) ?? 0.0; - final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); - var rounded = (doubleValue / widget.stepIncreaseAmount).round() * + int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); + double rounded = (doubleValue / widget.stepIncreaseAmount).round() * widget.stepIncreaseAmount; rounded = rounded.clamp(widget.sliderRange.$1, widget.sliderRange.$2); rounded = double.parse(rounded.toStringAsFixed(decimalPlaces)); @@ -177,9 +179,9 @@ class _CustomRoutinesTextboxState extends State { @override Widget build(BuildContext context) { - final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); + int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount); - final formatters = []; + List formatters = []; if (decimalPlaces == 0) { formatters.add(FilteringTextInputFormatter.digitsOnly); } else { @@ -231,7 +233,7 @@ class _CustomRoutinesTextboxState extends State { color: ColorsManager.lightGrayBorderColor, width: 1), boxShadow: [ BoxShadow( - color: ColorsManager.blackColor.withValues(alpha: 0.05), + color: ColorsManager.blackColor.withOpacity(0.05), blurRadius: 8, offset: const Offset(0, 4), ), diff --git a/lib/pages/routines/widgets/delete_scene.dart b/lib/pages/routines/widgets/delete_scene.dart index 13121493..10eeb493 100644 --- a/lib/pages/routines/widgets/delete_scene.dart +++ b/lib/pages/routines/widgets/delete_scene.dart @@ -33,17 +33,13 @@ class DeleteSceneWidget extends StatelessWidget { alignment: AlignmentDirectional.center, child: Text( 'Cancel', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith( + style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: ColorsManager.textGray, ), ), ), ), - Container( - width: 1, height: 50, color: ColorsManager.greyColor), + Container(width: 1, height: 50, color: ColorsManager.greyColor), InkWell( onTap: () { context.read().add(const DeleteScene()); @@ -54,10 +50,7 @@ class DeleteSceneWidget extends StatelessWidget { alignment: AlignmentDirectional.center, child: Text( 'Confirm', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith( + style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: ColorsManager.primaryColorWithOpacity, ), ), diff --git a/lib/pages/routines/widgets/dragable_card.dart b/lib/pages/routines/widgets/dragable_card.dart index 69daa31c..9853df7c 100644 --- a/lib/pages/routines/widgets/dragable_card.dart +++ b/lib/pages/routines/widgets/dragable_card.dart @@ -33,18 +33,17 @@ class DraggableCard extends StatelessWidget { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - final deviceFunctions = - state.selectedFunctions[deviceData['uniqueCustomId']] ?? []; + final deviceFunctions = state.selectedFunctions[deviceData['uniqueCustomId']] ?? []; - final index = state.thenItems.indexWhere( - (item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); + int index = state.thenItems + .indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); if (index != -1) { return _buildCardContent(context, deviceFunctions, padding: padding); } - final ifIndex = state.ifItems.indexWhere( - (item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); + int ifIndex = state.ifItems + .indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); if (ifIndex != -1) { return _buildCardContent(context, deviceFunctions, padding: padding); @@ -54,8 +53,7 @@ class DraggableCard extends StatelessWidget { data: deviceData, feedback: Transform.rotate( angle: -0.1, - child: - _buildCardContent(context, deviceFunctions, padding: padding), + child: _buildCardContent(context, deviceFunctions, padding: padding), ), childWhenDragging: _buildGreyContainer(), child: _buildCardContent(context, deviceFunctions, padding: padding), @@ -64,8 +62,7 @@ class DraggableCard extends StatelessWidget { ); } - Widget _buildCardContent( - BuildContext context, List deviceFunctions, + Widget _buildCardContent(BuildContext context, List deviceFunctions, {EdgeInsetsGeometry? padding}) { return Stack( children: [ @@ -95,8 +92,7 @@ class DraggableCard extends StatelessWidget { ), ), padding: const EdgeInsets.all(8), - child: deviceData['type'] == 'tap_to_run' || - deviceData['type'] == 'scene' + child: deviceData['type'] == 'tap_to_run' || deviceData['type'] == 'scene' ? Image.memory( base64Decode(deviceData['icon']), ) @@ -122,15 +118,12 @@ class DraggableCard extends StatelessWidget { height: 4, ), Visibility( - visible: - deviceData['tag'] != null && deviceData['tag'] != '', + visible: deviceData['tag'] != null && deviceData['tag'] != '', child: Row( spacing: 2, children: [ SizedBox( - width: 8, - height: 8, - child: SvgPicture.asset(Assets.deviceTagIcon)), + width: 8, height: 8, child: SvgPicture.asset(Assets.deviceTagIcon)), Flexible( child: Text( deviceData['tag'] ?? '', @@ -148,23 +141,20 @@ class DraggableCard extends StatelessWidget { ), ), Visibility( - visible: deviceData['subSpace'] != null && - deviceData['subSpace'] != '', + visible: deviceData['subSpace'] != null && deviceData['subSpace'] != '', child: const SizedBox( height: 4, ), ), Visibility( - visible: deviceData['subSpace'] != null && - deviceData['subSpace'] != '', + visible: deviceData['subSpace'] != null && deviceData['subSpace'] != '', child: Row( spacing: 2, children: [ SizedBox( width: 8, height: 8, - child: - SvgPicture.asset(Assets.spaceLocationIcon)), + child: SvgPicture.asset(Assets.spaceLocationIcon)), Flexible( child: Text( deviceData['subSpace'] ?? '', @@ -232,8 +222,7 @@ class DraggableCard extends StatelessWidget { } String _formatFunctionValue(DeviceFunctionData function) { - if (function.functionCode == 'temp_set' || - function.functionCode == 'temp_current') { + if (function.functionCode == 'temp_set' || function.functionCode == 'temp_current') { return '${(function.value / 10).toStringAsFixed(0)}°C'; } else if (function.functionCode.contains('countdown')) { final seconds = function.value?.toInt() ?? 0; diff --git a/lib/pages/routines/widgets/function_slider.dart b/lib/pages/routines/widgets/function_slider.dart index 559d8b20..50167a7b 100644 --- a/lib/pages/routines/widgets/function_slider.dart +++ b/lib/pages/routines/widgets/function_slider.dart @@ -17,13 +17,12 @@ class FunctionSlider extends StatelessWidget { @override Widget build(BuildContext context) { final (min, max) = range; - final isValidRange = max > min; - final value = initialValue is int + final bool isValidRange = max > min; + final double value = initialValue is int ? (initialValue as int).toDouble() : (initialValue as double); - final divisions = - isValidRange ? ((max - min) / dividendOfRange).round() : null; + final int? divisions = isValidRange ? ((max - min) / dividendOfRange).round() : null; return Slider( value: value.clamp(min, max), diff --git a/lib/pages/routines/widgets/if_container.dart b/lib/pages/routines/widgets/if_container.dart index 9832f627..da77c7c2 100644 --- a/lib/pages/routines/widgets/if_container.dart +++ b/lib/pages/routines/widgets/if_container.dart @@ -62,7 +62,7 @@ class IfContainer extends StatelessWidget { context: context, data: state.ifItems[index], removeComparetors: false, - dialogType: 'IF'); + dialogType: "IF"); if (result != null) { context.read().add( diff --git a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart index d28f88f0..f9c20c54 100644 --- a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart +++ b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart @@ -16,9 +16,8 @@ class FetchRoutineScenesAutomation extends StatelessWidget Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - if (state.isLoading) { + if (state.isLoading) return const Center(child: CircularProgressIndicator()); - } return SingleChildScrollView( child: Padding( @@ -27,23 +26,23 @@ class FetchRoutineScenesAutomation extends StatelessWidget crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - _buildListTitle(context, 'Scenes (Tap to Run)'), + _buildListTitle(context, "Scenes (Tap to Run)"), const SizedBox(height: 10), Visibility( visible: state.scenes.isNotEmpty, - replacement: _buildEmptyState(context, 'No scenes found'), + replacement: _buildEmptyState(context, "No scenes found"), child: SizedBox( height: 200, child: _buildScenes(state), ), ), const SizedBox(height: 10), - _buildListTitle(context, 'Automations'), + _buildListTitle(context, "Automations"), const SizedBox(height: 3), Visibility( visible: state.automations.isNotEmpty, replacement: - _buildEmptyState(context, 'No automations found'), + _buildEmptyState(context, "No automations found"), child: SizedBox( height: 200, child: _buildAutomations(state), diff --git a/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart b/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart index 8c587aba..4fc4bd0f 100644 --- a/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart +++ b/lib/pages/routines/widgets/main_routine_view/routine_view_card.dart @@ -67,15 +67,15 @@ class _RoutineViewCardState extends State { @override Widget build(BuildContext context) { - final cardWidth = widget.isSmallScreenSize(context) + final double cardWidth = widget.isSmallScreenSize(context) ? 120 : widget.isMediumScreenSize(context) ? 135 : 150; - final cardHeight = widget.isSmallScreenSize(context) ? 190 : 200; + final double cardHeight = widget.isSmallScreenSize(context) ? 190 : 200; - final iconSize = widget.isSmallScreenSize(context) + final double iconSize = widget.isSmallScreenSize(context) ? 70 : widget.isMediumScreenSize(context) ? 80 @@ -99,42 +99,41 @@ class _RoutineViewCardState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - if (widget.cardType != '') - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - if (widget.isFromScenes ?? false) - InkWell( - onTap: _handleSceneTap, - child: Image.asset( - _showTemporaryCheck - ? Assets.scenesPlayIcon - : Assets.scenesPlayIconCheck, - fit: BoxFit.contain, - ), - ) - else if (widget.isLoading) - const SizedBox( - width: 49, - height: 20, - child: Center( - child: SizedBox( - width: 16, - height: 16, - child: CircularProgressIndicator(strokeWidth: 2), - ), - ), - ) - else - CupertinoSwitch( - activeTrackColor: ColorsManager.primaryColor, - value: widget.status == 'enable', - onChanged: widget.onChanged, - ) - ], - ) - else - const SizedBox(), + widget.cardType != '' + ? Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (widget.isFromScenes ?? false) + InkWell( + onTap: _handleSceneTap, + child: Image.asset( + _showTemporaryCheck + ? Assets.scenesPlayIcon + : Assets.scenesPlayIconCheck, + fit: BoxFit.contain, + ), + ) + else if (widget.isLoading) + const SizedBox( + width: 49, + height: 20, + child: Center( + child: SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(strokeWidth: 2), + ), + ), + ) + else + CupertinoSwitch( + activeTrackColor: ColorsManager.primaryColor, + value: widget.status == 'enable', + onChanged: widget.onChanged, + ) + ], + ) + : const SizedBox(), Column( children: [ Center( @@ -160,9 +159,8 @@ class _RoutineViewCardState extends State { height: iconSize, width: iconSize, fit: BoxFit.contain, - errorBuilder: - (context, error, stackTrace) => - Image.asset( + errorBuilder: (context, error, stackTrace) => + Image.asset( Assets.logo, height: iconSize, width: iconSize, @@ -205,8 +203,7 @@ class _RoutineViewCardState extends State { maxLines: 1, style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, - fontSize: - widget.isSmallScreenSize(context) ? 10 : 12, + fontSize: widget.isSmallScreenSize(context) ? 10 : 12, ), ), if (widget.spaceName != '') @@ -225,9 +222,8 @@ class _RoutineViewCardState extends State { maxLines: 1, style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.blackColor, - fontSize: widget.isSmallScreenSize(context) - ? 10 - : 12, + fontSize: + widget.isSmallScreenSize(context) ? 10 : 12, ), ), ], diff --git a/lib/pages/routines/widgets/period_option.dart b/lib/pages/routines/widgets/period_option.dart index 2e455008..09ec590e 100644 --- a/lib/pages/routines/widgets/period_option.dart +++ b/lib/pages/routines/widgets/period_option.dart @@ -21,12 +21,9 @@ class PeriodOptions extends StatelessWidget { builder: (context, state) { return Column( children: [ - _buildRadioOption( - context, EnumEffectivePeriodOptions.allDay, '24 Hours'), - _buildRadioOption(context, EnumEffectivePeriodOptions.daytime, - 'Sunrise to Sunset'), - _buildRadioOption( - context, EnumEffectivePeriodOptions.night, 'Sunset to Sunrise'), + _buildRadioOption(context, EnumEffectivePeriodOptions.allDay, '24 Hours'), + _buildRadioOption(context, EnumEffectivePeriodOptions.daytime, 'Sunrise to Sunset'), + _buildRadioOption(context, EnumEffectivePeriodOptions.night, 'Sunset to Sunrise'), ListTile( contentPadding: EdgeInsets.zero, onTap: () => showCustomTimePicker(context), @@ -37,8 +34,7 @@ class PeriodOptions extends StatelessWidget { fontWeight: FontWeight.w400, fontSize: 14), ), - subtitle: state.customStartTime != null && - state.customEndTime != null + subtitle: state.customStartTime != null && state.customEndTime != null ? Text( '${"${state.customStartTime}"} - ${"${state.customEndTime}"}', style: Theme.of(context).textTheme.bodyMedium!.copyWith( @@ -82,16 +78,12 @@ class PeriodOptions extends StatelessWidget { title: Text( EffectPeriodHelper.formatEnumValue(value), style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.blackColor, - fontWeight: FontWeight.w400, - fontSize: 12), + color: ColorsManager.blackColor, fontWeight: FontWeight.w400, fontSize: 12), ), subtitle: Text( subtitle, style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, - fontSize: 10), + color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, fontSize: 10), ), trailing: Radio( value: value, diff --git a/lib/pages/routines/widgets/repeat_days.dart b/lib/pages/routines/widgets/repeat_days.dart index ee2389be..4920408a 100644 --- a/lib/pages/routines/widgets/repeat_days.dart +++ b/lib/pages/routines/widgets/repeat_days.dart @@ -16,9 +16,7 @@ class RepeatDays extends StatelessWidget { children: [ Text('Repeat', style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, - fontSize: 14)), + color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, fontSize: 14)), const SizedBox(width: 8), BlocBuilder( builder: (context, state) { @@ -33,8 +31,7 @@ class RepeatDays extends StatelessWidget { final day = entry.key; final abbreviation = entry.value; final dayIndex = effectiveBloc.getDayIndex(day); - final isSelected = - state.selectedDaysBinary[dayIndex] == '1'; + final isSelected = state.selectedDaysBinary[dayIndex] == '1'; return Padding( padding: const EdgeInsets.symmetric(horizontal: 3.0), child: GestureDetector( @@ -45,9 +42,7 @@ class RepeatDays extends StatelessWidget { decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( - color: isSelected - ? Colors.grey - : Colors.grey.shade300, + color: isSelected ? Colors.grey : Colors.grey.shade300, width: 1, ), ), @@ -58,9 +53,7 @@ class RepeatDays extends StatelessWidget { abbreviation, style: TextStyle( fontSize: 16, - color: isSelected - ? Colors.grey - : Colors.grey.shade300, + color: isSelected ? Colors.grey : Colors.grey.shade300, ), ), ), diff --git a/lib/pages/routines/widgets/routine_devices.dart b/lib/pages/routines/widgets/routine_devices.dart index 5b054908..f0b77467 100644 --- a/lib/pages/routines/widgets/routine_devices.dart +++ b/lib/pages/routines/widgets/routine_devices.dart @@ -74,15 +74,15 @@ class _RoutineDevicesState extends State { .toLowerCase() .contains(state.searchText!.toLowerCase()) ? DraggableCard( - imagePath: deviceData['imagePath']! as String, - title: deviceData['title']! as String, + imagePath: deviceData['imagePath'] as String, + title: deviceData['title'] as String, deviceData: deviceData, ) : const SizedBox.shrink(); } else { return DraggableCard( - imagePath: deviceData['imagePath']! as String, - title: deviceData['title']! as String, + imagePath: deviceData['imagePath'] as String, + title: deviceData['title'] as String, deviceData: deviceData, ); } diff --git a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart index 220bcde0..cbf13178 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ac_dialog.dart @@ -24,7 +24,8 @@ class ACHelper { required bool? removeComparetors, required String dialogType, }) async { - final acFunctions = functions.whereType().where((function) { + List acFunctions = + functions.whereType().where((function) { if (dialogType == 'THEN') { return function.type == 'THEN' || function.type == 'BOTH'; } @@ -370,7 +371,7 @@ class ACHelper { // return Container( // padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), // decoration: BoxDecoration( - // color: ColorsManager.primaryColorWithOpacity.withValues(alpha:0.1), + // color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), // borderRadius: BorderRadius.circular(10), // ), // child: Text( diff --git a/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart index 0ef19067..3c1eb1c2 100644 --- a/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/automation_dialog.dart @@ -3,8 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routines/models/device_functions.dart'; -import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; +import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; class AutomationDialog extends StatefulWidget { @@ -31,11 +31,9 @@ class _AutomationDialogState extends State { @override void initState() { super.initState(); - final functions = context - .read() - .state - .selectedFunctions[widget.uniqueCustomId]; - for (final data in functions ?? []) { + List? functions = + context.read().state.selectedFunctions[widget.uniqueCustomId]; + for (DeviceFunctionData data in functions ?? []) { if (data.entityId == widget.automationId) { selectedAutomationActionExecutor = data.value; } @@ -67,8 +65,7 @@ class _AutomationDialogState extends State { }), ), ListTile( - leading: - SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24), + leading: SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24), title: const Text('Disable'), trailing: Radio( value: 'rule_disable', diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart index 5bcc558d..504017a2 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart @@ -45,8 +45,7 @@ class CpsDialogValueSelector extends StatelessWidget { operationName: operationName, value: operation.value, condition: selectedFunctionData?.condition, - valueDescription: - selectedFunctionData?.valueDescription, + valueDescription: selectedFunctionData?.valueDescription, ), ), ); diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart index 0ce2fd04..d11871a7 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart @@ -57,7 +57,7 @@ class CpsFunctionsList extends StatelessWidget { 'moving_max_dis', 'moving_range', 'presence_range', - if (dialogType == 'IF') 'sensitivity', + if (dialogType == "IF") 'sensitivity', ], ); }); diff --git a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart index 4fa2e66c..fd637c28 100644 --- a/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart +++ b/lib/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart @@ -1,6 +1,5 @@ abstract final class CpsSliderHelpers { - static (double min, double max, double step) mappedRange( - String functionCode) { + static (double min, double max, double step) mappedRange(String functionCode) { final (defaultMin, defaultMax) = sliderRange(functionCode); final defaultDivdidend = dividendOfRange(functionCode); return switch (functionCode) { @@ -63,10 +62,7 @@ abstract final class CpsSliderHelpers { 'perceptual_boundary' || 'moving_boundary' => 'M', - 'moving_rigger_time' || - 'moving_static_time' || - 'none_body_time' => - 'sec', + 'moving_rigger_time' || 'moving_static_time' || 'none_body_time' => 'sec', _ => '', }; diff --git a/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart index b81c6a80..4580f6e1 100644 --- a/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/delay_dialog.dart @@ -9,14 +9,14 @@ import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; class DelayHelper { static Future?> showDelayPickerDialog( BuildContext context, Map data) async { - var hours = 0; - var minutes = 0; + int hours = 0; + int minutes = 0; return showDialog?>( context: context, builder: (BuildContext context) { final routineBloc = context.read(); - var totalSec = 0; + int totalSec = 0; final selectedFunctionData = routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? []; @@ -43,8 +43,7 @@ class DelayHelper { Expanded( child: CupertinoTimerPicker( mode: CupertinoTimerPickerMode.hm, - initialTimerDuration: - Duration(hours: hours, minutes: minutes), + initialTimerDuration: Duration(hours: hours, minutes: minutes), onTimerDurationChanged: (Duration newDuration) { hours = newDuration.inHours; minutes = newDuration.inMinutes % 60; @@ -56,7 +55,7 @@ class DelayHelper { Navigator.of(context).pop(); }, onConfirm: () { - final totalSeconds = (hours * 3600) + (minutes * 60); + int totalSeconds = (hours * 3600) + (minutes * 60); context.read().add(AddFunctionToRoutine( [ DeviceFunctionData( diff --git a/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart index 3a493abd..40036d32 100644 --- a/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/discard_dialog.dart @@ -38,10 +38,10 @@ class DiscardDialog { color: ColorsManager.red, fontWeight: FontWeight.bold, ), - onDismissText: 'Don’t Close', - onConfirmText: 'Close', + onDismissText: "Don’t Close", + onConfirmText: "Close", onDismissColor: ColorsManager.grayColor, - onConfirmColor: ColorsManager.red.withValues(alpha: 0.8), + onConfirmColor: ColorsManager.red.withOpacity(0.8), onDismiss: () { Navigator.pop(context); }, diff --git a/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart index 5543ec96..5fc31a96 100644 --- a/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart @@ -8,14 +8,13 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:time_picker_spinner/time_picker_spinner.dart'; class EffectPeriodHelper { - static Future?> showCustomTimePicker( - BuildContext context) async { - var selectedStartTime = '00:00'; - var selectedEndTime = '23:59'; - final pageController = PageController(initialPage: 0); + static Future?> showCustomTimePicker(BuildContext context) async { + String selectedStartTime = "00:00"; + String selectedEndTime = "23:59"; + PageController pageController = PageController(initialPage: 0); - final startDateTime = DateTime(2022, 1, 1, 0, 0); - final endDateTime = DateTime(2022, 1, 1, 23, 59); + DateTime startDateTime = DateTime(2022, 1, 1, 0, 0); + DateTime endDateTime = DateTime(2022, 1, 1, 23, 59); context.customAlertDialog( alertBody: SizedBox( @@ -47,7 +46,7 @@ class EffectPeriodHelper { ], ), ), - title: 'Custom', + title: "Custom", onConfirm: () { context.read().add( SetCustomTime(selectedStartTime, selectedEndTime), @@ -89,7 +88,7 @@ class EffectPeriodHelper { ), TextButton( onPressed: () {}, - child: Text(isStartTime ? 'Start' : 'End', + child: Text(isStartTime ? "Start" : "End", style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, @@ -136,17 +135,17 @@ class EffectPeriodHelper { static String formatEnumValue(EnumEffectivePeriodOptions value) { switch (value) { case EnumEffectivePeriodOptions.allDay: - return 'All Day'; + return "All Day"; case EnumEffectivePeriodOptions.daytime: - return 'Daytime'; + return "Daytime"; case EnumEffectivePeriodOptions.night: - return 'Night'; + return "Night"; case EnumEffectivePeriodOptions.custom: - return 'Custom'; + return "Custom"; case EnumEffectivePeriodOptions.none: - return 'None'; + return "None"; default: - return ''; + return ""; } } } diff --git a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart index b4fa1080..7ca89edb 100644 --- a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart +++ b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart @@ -7,6 +7,7 @@ import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/models/flush/flush_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/custom_routines_textbox.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart'; +import 'package:syncrow_web/pages/routines/widgets/slider_value_selector.dart'; class FlushValueSelectorWidget extends StatelessWidget { final String selectedFunction; @@ -61,7 +62,7 @@ class FlushValueSelectorWidget extends StatelessWidget { selectedFunction == FlushMountedPresenceSensorModel.codeFarDetection; final isDistanceDetection = isNearDetection || isFarDetection; - var initialValue = (functionData.value as num?)?.toDouble() ?? 0.0; + double initialValue = (functionData.value as num?)?.toDouble() ?? 0.0; if (isDistanceDetection) { initialValue = initialValue / 100; @@ -156,7 +157,7 @@ class FlushValueSelectorWidget extends StatelessWidget { String get getDisplayText { final num? value = functionData.value; - var displayValue = value?.toDouble() ?? 0.0; + double displayValue = value?.toDouble() ?? 0.0; if (functionData.functionCode == FlushMountedPresenceSensorModel.codeNearDetection || diff --git a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart index 4e296e65..56f74054 100644 --- a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart +++ b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/time_wheel.dart @@ -49,6 +49,8 @@ class _TimeWheelPickerState extends State { } } + + @override void dispose() { _hoursController.dispose(); @@ -101,7 +103,7 @@ class _TimeWheelPickerState extends State { } void _handleTimeChange(int hours, int minutes, int seconds) { - var total = hours * 3600 + minutes * 60 + seconds; + int total = hours * 3600 + minutes * 60 + seconds; if (total > 10000) { hours = 2; minutes = 46; diff --git a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart index 1d22f1a1..392c3012 100644 --- a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart +++ b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart @@ -45,8 +45,7 @@ class GatewayDialogValueSelector extends StatelessWidget { operationName: operationName, value: operation.value, condition: selectedFunctionData?.condition, - valueDescription: - selectedFunctionData?.valueDescription, + valueDescription: selectedFunctionData?.valueDescription, ), ), ); diff --git a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart index e2b103c5..641fd234 100644 --- a/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart @@ -25,7 +25,8 @@ class OneGangSwitchHelper { required String uniqueCustomId, required bool removeComparetors, }) async { - final oneGangFunctions = functions.whereType().toList(); + List oneGangFunctions = + functions.whereType().toList(); return showDialog?>( context: context, @@ -245,9 +246,9 @@ class OneGangSwitchHelper { withSpecialChar: false, currentCondition: selectedFunctionData?.condition, dialogType: dialogType, - sliderRange: (0, 43200), + sliderRange: (0, 43200), displayedValue: (initialValue ?? 0).toString(), - initialValue: (initialValue ?? 0).toString(), + initialValue: (initialValue ?? 0).toString(), onConditionChanged: (condition) { context.read().add( AddFunction( diff --git a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart index e6f832c8..2b8ba68f 100644 --- a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/enargy_operational_values_list.dart @@ -81,4 +81,6 @@ class EnergyOperationalValuesList extends StatelessWidget { ), ); } + + } diff --git a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart index 3695d075..696251a1 100644 --- a/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart +++ b/lib/pages/routines/widgets/routine_dialogs/power_clamp_enargy/energy_value_selector_widget.dart @@ -27,11 +27,13 @@ class EnergyValueSelectorWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final selectedFn = functions.firstWhere((f) => f.code == selectedFunction); + final selectedFn = + functions.firstWhere((f) => f.code == selectedFunction); final values = selectedFn.getOperationalValues(); - final step = selectedFn.step ?? 1.0; - final unit = selectedFn.unit ?? ''; - final sliderRange = (selectedFn.min ?? 0.0, selectedFn.max ?? 100.0); + final step = selectedFn.step ?? 1.0; + final _unit = selectedFn.unit ?? ''; + final (double, double) sliderRange = + (selectedFn.min ?? 0.0, selectedFn.max ?? 100.0); if (_isSliderFunction(selectedFunction)) { return CustomRoutinesTextbox( @@ -63,7 +65,7 @@ class EnergyValueSelectorWidget extends StatelessWidget { ), ), ), - unit: unit, + unit: _unit, dividendOfRange: 1, stepIncreaseAmount: step, ); diff --git a/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart index 2d02304a..b8449838 100644 --- a/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/setting_dialog.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_bloc.dart'; @@ -14,6 +13,7 @@ import 'package:syncrow_web/pages/routines/view/effective_period_view.dart'; import 'package:syncrow_web/pages/routines/widgets/delete_scene.dart'; import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:flutter/cupertino.dart'; class SettingHelper { static Future showSettingDialog({ @@ -30,16 +30,14 @@ class SettingHelper { providers: [ if (effectiveTime != null) BlocProvider( - create: (_) => EffectPeriodBloc() - ..add(InitialEffectPeriodEvent(effectiveTime)), + create: (_) => EffectPeriodBloc()..add(InitialEffectPeriodEvent(effectiveTime)), ), if (effectiveTime == null) BlocProvider( create: (_) => EffectPeriodBloc(), ), BlocProvider( - create: (_) => SettingBloc() - ..add(InitialEvent(selectedIcon: iconId ?? ''))), + create: (_) => SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? ''))), ], child: AlertDialog( contentPadding: EdgeInsets.zero, @@ -47,18 +45,15 @@ class SettingHelper { builder: (context, effectPeriodState) { return BlocBuilder( builder: (context, settingState) { - var selectedIcon = ''; - var list = []; + String selectedIcon = ''; + List list = []; if (settingState is TabToRunSettingLoaded) { selectedIcon = settingState.selectedIcon; list = settingState.iconList; } return Container( width: context.read().isExpanded ? 800 : 400, - height: - context.read().isExpanded && isAutomation - ? 500 - : 350, + height: context.read().isExpanded && isAutomation ? 500 : 350, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), @@ -81,18 +76,14 @@ class SettingHelper { children: [ Container( padding: const EdgeInsets.only( - top: 10, - left: 10, - right: 10, - bottom: 10), + top: 10, left: 10, right: 10, bottom: 10), child: Column( children: [ InkWell( onTap: () {}, child: Row( mainAxisAlignment: - MainAxisAlignment - .spaceBetween, + MainAxisAlignment.spaceBetween, children: [ Text( 'Validity', @@ -100,18 +91,14 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager - .textPrimaryColor, - fontWeight: - FontWeight - .w400, + color: + ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, fontSize: 14), ), const Icon( - Icons - .arrow_forward_ios_outlined, - color: ColorsManager - .textGray, + Icons.arrow_forward_ios_outlined, + color: ColorsManager.textGray, size: 15, ) ], @@ -121,27 +108,22 @@ class SettingHelper { height: 5, ), const Divider( - color: - ColorsManager.graysColor, + color: ColorsManager.graysColor, ), const SizedBox( height: 5, ), InkWell( onTap: () { - BlocProvider.of< - SettingBloc>( - context) - .add(FetchIcons( + BlocProvider.of(context).add( + FetchIcons( expanded: !context - .read< - SettingBloc>() + .read() .isExpanded)); }, child: Row( mainAxisAlignment: - MainAxisAlignment - .spaceBetween, + MainAxisAlignment.spaceBetween, children: [ Text( 'Effective Period', @@ -149,18 +131,14 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager - .textPrimaryColor, - fontWeight: - FontWeight - .w400, + color: + ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, fontSize: 14), ), const Icon( - Icons - .arrow_forward_ios_outlined, - color: ColorsManager - .textGray, + Icons.arrow_forward_ios_outlined, + color: ColorsManager.textGray, size: 15, ) ], @@ -170,16 +148,13 @@ class SettingHelper { height: 5, ), const Divider( - color: - ColorsManager.graysColor, + color: ColorsManager.graysColor, ), const SizedBox( height: 5, ), Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Executed by', @@ -187,11 +162,8 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager - .textPrimaryColor, - fontWeight: - FontWeight - .w400, + color: ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, fontSize: 14), ), Text('Cloud', @@ -199,19 +171,12 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: - ColorsManager - .textGray, - fontWeight: - FontWeight - .w400, + color: ColorsManager.textGray, + fontWeight: FontWeight.w400, fontSize: 14)), ], ), - if (context - .read() - .state - .isUpdate ?? + if (context.read().state.isUpdate ?? false) const DeleteSceneWidget() ], @@ -223,27 +188,20 @@ class SettingHelper { children: [ Container( padding: const EdgeInsets.only( - top: 10, - left: 10, - right: 10, - bottom: 10), + top: 10, left: 10, right: 10, bottom: 10), child: Column( children: [ InkWell( onTap: () { - BlocProvider.of< - SettingBloc>( - context) - .add(FetchIcons( + BlocProvider.of(context).add( + FetchIcons( expanded: !context - .read< - SettingBloc>() + .read() .isExpanded)); }, child: Row( mainAxisAlignment: - MainAxisAlignment - .spaceBetween, + MainAxisAlignment.spaceBetween, children: [ Text( 'Icons', @@ -251,18 +209,14 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager - .textPrimaryColor, - fontWeight: - FontWeight - .w400, + color: + ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, fontSize: 14), ), const Icon( - Icons - .arrow_forward_ios_outlined, - color: ColorsManager - .textGray, + Icons.arrow_forward_ios_outlined, + color: ColorsManager.textGray, size: 15, ) ], @@ -272,16 +226,13 @@ class SettingHelper { height: 5, ), const Divider( - color: - ColorsManager.graysColor, + color: ColorsManager.graysColor, ), const SizedBox( height: 5, ), Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Show on devices page', @@ -289,30 +240,23 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager - .textPrimaryColor, - fontWeight: - FontWeight - .w400, + color: ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, fontSize: 14), ), Row( - mainAxisAlignment: - MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, children: [ Container( height: 30, width: 1, - color: ColorsManager - .graysColor, + color: ColorsManager.graysColor, ), Transform.scale( scale: .8, - child: - CupertinoSwitch( + child: CupertinoSwitch( value: true, - onChanged: - (value) {}, + onChanged: (value) {}, applyTheme: true, ), ), @@ -324,16 +268,13 @@ class SettingHelper { height: 5, ), const Divider( - color: - ColorsManager.graysColor, + color: ColorsManager.graysColor, ), const SizedBox( height: 5, ), Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Executed by', @@ -341,11 +282,8 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: ColorsManager - .textPrimaryColor, - fontWeight: - FontWeight - .w400, + color: ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, fontSize: 14), ), Text('Cloud', @@ -353,19 +291,12 @@ class SettingHelper { .textTheme .bodyMedium! .copyWith( - color: - ColorsManager - .textGray, - fontWeight: - FontWeight - .w400, + color: ColorsManager.textGray, + fontWeight: FontWeight.w400, fontSize: 14)), ], ), - if (context - .read() - .state - .isUpdate ?? + if (context.read().state.isUpdate ?? false) const DeleteSceneWidget() ], @@ -373,14 +304,12 @@ class SettingHelper { ], ), ), - if (context.read().isExpanded && - !isAutomation) + if (context.read().isExpanded && !isAutomation) SizedBox( width: 400, height: 150, child: settingState is LoadingState - ? const Center( - child: CircularProgressIndicator()) + ? const Center(child: CircularProgressIndicator()) : GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( @@ -397,8 +326,7 @@ class SettingHelper { height: 35, child: InkWell( onTap: () { - BlocProvider.of( - context) + BlocProvider.of(context) .add(SelectIcon( iconId: iconModel.uuid, )); @@ -407,17 +335,13 @@ class SettingHelper { child: SizedBox( child: ClipOval( child: Container( - padding: - const EdgeInsets.all( - 1), + padding: const EdgeInsets.all(1), decoration: BoxDecoration( border: Border.all( - color: selectedIcon == - iconModel.uuid + color: selectedIcon == iconModel.uuid ? ColorsManager .primaryColorWithOpacity - : Colors - .transparent, + : Colors.transparent, width: 2, ), shape: BoxShape.circle, @@ -432,12 +356,8 @@ class SettingHelper { ); }, )), - if (context.read().isExpanded && - isAutomation) - const SizedBox( - height: 350, - width: 400, - child: EffectivePeriodView()) + if (context.read().isExpanded && isAutomation) + const SizedBox(height: 350, width: 400, child: EffectivePeriodView()) ], ), Container( @@ -461,33 +381,23 @@ class SettingHelper { alignment: AlignmentDirectional.center, child: Text( 'Cancel', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith( + style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: ColorsManager.textGray, ), ), ), ), ), - Container( - width: 1, - height: 50, - color: ColorsManager.greyColor), + Container(width: 1, height: 50, color: ColorsManager.greyColor), Expanded( child: InkWell( onTap: () { if (isAutomation) { BlocProvider.of(context).add( - EffectiveTimePeriodEvent( - EffectiveTime( - start: effectPeriodState - .customStartTime!, - end: effectPeriodState - .customEndTime!, - loops: effectPeriodState - .selectedDaysBinary))); + EffectiveTimePeriodEvent(EffectiveTime( + start: effectPeriodState.customStartTime!, + end: effectPeriodState.customEndTime!, + loops: effectPeriodState.selectedDaysBinary))); Navigator.of(context).pop(); } else { Navigator.of(context).pop(selectedIcon); @@ -497,12 +407,8 @@ class SettingHelper { alignment: AlignmentDirectional.center, child: Text( 'Confirm', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith( - color: ColorsManager - .primaryColorWithOpacity, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: ColorsManager.primaryColorWithOpacity, ), ), ), diff --git a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart index 8416837a..5e50c11d 100644 --- a/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart @@ -24,7 +24,8 @@ class ThreeGangSwitchHelper { required String dialogType, required bool removeComparetors, }) async { - final switchFunctions = functions.whereType().toList(); + List switchFunctions = + functions.whereType().toList(); return showDialog?>( context: context, diff --git a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart index 1ed89cd4..6b3dc813 100644 --- a/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart +++ b/lib/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart @@ -25,7 +25,8 @@ class TwoGangSwitchHelper { required bool removeComparetors, required String dialogType, }) async { - final switchFunctions = functions.whereType().toList(); + List switchFunctions = + functions.whereType().toList(); return showDialog?>( context: context, @@ -236,7 +237,7 @@ class TwoGangSwitchHelper { DeviceFunctionData? selectedFunctionData, // Function(String) onConditionChanged, ) { - final conditions = ['<', '==', '>']; + final conditions = ["<", "==", ">"]; return ToggleButtons( onPressed: (int index) { @@ -263,8 +264,8 @@ class TwoGangSwitchHelper { minWidth: 40.0, ), isSelected: - conditions.map((c) => c == (currentCondition ?? '==')).toList(), - children: conditions.map(Text.new).toList(), + conditions.map((c) => c == (currentCondition ?? "==")).toList(), + children: conditions.map((c) => Text(c)).toList(), ); } @@ -279,7 +280,7 @@ class TwoGangSwitchHelper { return Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: BoxDecoration( - color: ColorsManager.primaryColorWithOpacity.withValues(alpha: 0.1), + color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), borderRadius: BorderRadius.circular(10), ), child: Text( diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart index 4e296e65..56f74054 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart @@ -49,6 +49,8 @@ class _TimeWheelPickerState extends State { } } + + @override void dispose() { _hoursController.dispose(); @@ -101,7 +103,7 @@ class _TimeWheelPickerState extends State { } void _handleTimeChange(int hours, int minutes, int seconds) { - var total = hours * 3600 + minutes * 60 + seconds; + int total = hours * 3600 + minutes * 60 + seconds; if (total > 10000) { hours = 2; minutes = 46; diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart index 497ee3db..4d04102d 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart @@ -63,8 +63,7 @@ class _WallPresenceSensorState extends State { @override void initState() { super.initState(); - _wpsFunctions = - widget.functions.whereType().where((function) { + _wpsFunctions = widget.functions.whereType().where((function) { if (widget.dialogType == 'THEN') { return function.type == 'THEN' || function.type == 'BOTH'; } diff --git a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart index 6dacb85e..6c149cd3 100644 --- a/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/wall_sensor/wps_operational_values_list.dart @@ -30,8 +30,7 @@ class WpsOperationalValuesList extends StatelessWidget { : ListView.builder( padding: const EdgeInsets.all(20), itemCount: values.length, - itemBuilder: (context, index) => - _buildValueItem(context, values[index]), + itemBuilder: (context, index) => _buildValueItem(context, values[index]), ); } @@ -62,8 +61,7 @@ class WpsOperationalValuesList extends StatelessWidget { Widget _buildValueIcon(context, WpsOperationalValue value) { return Column( children: [ - if (_shouldShowTextDescription) - Text(value.description.replaceAll('cm', '')), + if (_shouldShowTextDescription) Text(value.description.replaceAll("cm", '')), SvgPicture.asset(value.icon, width: 25, height: 25), ], ); diff --git a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart index 25839c68..4042df36 100644 --- a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart @@ -61,4 +61,5 @@ class WaterHeaterOperationalValuesList extends StatelessWidget { groupValue: selectedValue, onChanged: (_) => onSelect(value)); } + } diff --git a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart index 9647408c..a09bbba7 100644 --- a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart +++ b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart @@ -12,7 +12,7 @@ class WaterHeaterValueSelectorWidget extends StatelessWidget { final DeviceFunctionData functionData; final List whFunctions; final AllDevicesModel? device; - final String dialogType; + final String dialogType; const WaterHeaterValueSelectorWidget({ required this.selectedFunction, @@ -39,13 +39,14 @@ class WaterHeaterValueSelectorWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ _buildCountDownSlider( - context, - functionData.value, - device, - selectedFn.operationName, - functionData, - selectedFunction, - dialogType), + context, + functionData.value, + device, + selectedFn.operationName, + functionData, + selectedFunction, + dialogType + ), const SizedBox(height: 10), ], ); diff --git a/lib/pages/routines/widgets/routine_search_and_buttons.dart b/lib/pages/routines/widgets/routine_search_and_buttons.dart index e261b3b1..efeedf9d 100644 --- a/lib/pages/routines/widgets/routine_search_and_buttons.dart +++ b/lib/pages/routines/widgets/routine_search_and_buttons.dart @@ -15,8 +15,7 @@ class RoutineSearchAndButtons extends StatefulWidget { }); @override - State createState() => - _RoutineSearchAndButtonsState(); + State createState() => _RoutineSearchAndButtonsState(); } class _RoutineSearchAndButtonsState extends State { @@ -62,9 +61,8 @@ class _RoutineSearchAndButtonsState extends State { children: [ ConstrainedBox( constraints: BoxConstraints( - maxWidth: constraints.maxWidth > 700 - ? 450 - : constraints.maxWidth - 32), + maxWidth: + constraints.maxWidth > 700 ? 450 : constraints.maxWidth - 32), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -73,13 +71,10 @@ class _RoutineSearchAndButtonsState extends State { children: [ Text('* ', style: context.textTheme.bodyMedium! - .copyWith( - color: ColorsManager.red, - fontSize: 13)), + .copyWith(color: ColorsManager.red, fontSize: 13)), Text( 'Routine Name', - style: context.textTheme.bodyMedium! - .copyWith( + style: context.textTheme.bodyMedium!.copyWith( fontSize: 13, fontWeight: FontWeight.w600, color: ColorsManager.blackColor, @@ -93,23 +88,20 @@ class _RoutineSearchAndButtonsState extends State { decoration: containerWhiteDecoration, child: TextFormField( style: context.textTheme.bodyMedium! - .copyWith( - color: ColorsManager.blackColor), + .copyWith(color: ColorsManager.blackColor), controller: _nameController, decoration: InputDecoration( hintText: 'Please enter the name', hintStyle: context.textTheme.bodyMedium! - .copyWith( - fontSize: 12, - color: ColorsManager.grayColor), + .copyWith(fontSize: 12, color: ColorsManager.grayColor), contentPadding: - const EdgeInsets.symmetric( - horizontal: 12, vertical: 10), + const EdgeInsets.symmetric(horizontal: 12, vertical: 10), border: InputBorder.none, ), onTapOutside: (_) { - context.read().add( - SetRoutineName(_nameController.text)); + context + .read() + .add(SetRoutineName(_nameController.text)); }, validator: (value) { if (value == null || value.isEmpty) { @@ -122,44 +114,41 @@ class _RoutineSearchAndButtonsState extends State { ], ), ), - if (constraints.maxWidth <= 1000) - const SizedBox() - else - SizedBox( - height: 40, - width: 200, - child: Center( - child: DefaultButton( - onPressed: state.isAutomation || - state.isTabToRun - ? () async { - final result = await SettingHelper - .showSettingDialog( - context: context, - iconId: state.selectedIcon ?? '', - ); - if (result != null) { - context - .read() - .add(AddSelectedIcon(result)); - } - } - : null, - borderRadius: 15, - elevation: 0, - borderColor: ColorsManager.greyColor, - backgroundColor: ColorsManager.boxColor, - child: const Text( - 'Settings', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, - color: ColorsManager.primaryColor, + (constraints.maxWidth <= 1000) + ? const SizedBox() + : SizedBox( + height: 40, + width: 200, + child: Center( + child: DefaultButton( + onPressed: state.isAutomation || state.isTabToRun + ? () async { + final result = await SettingHelper.showSettingDialog( + context: context, + iconId: state.selectedIcon ?? '', + ); + if (result != null) { + context + .read() + .add(AddSelectedIcon(result)); + } + } + : null, + borderRadius: 15, + elevation: 0, + borderColor: ColorsManager.greyColor, + backgroundColor: ColorsManager.boxColor, + child: const Text( + 'Settings', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + color: ColorsManager.primaryColor, + ), + ), ), ), ), - ), - ), ], ), ), @@ -197,12 +186,10 @@ class _RoutineSearchAndButtonsState extends State { child: Center( child: DefaultButton( onPressed: () async { - if (state.routineName == null || - state.routineName!.isEmpty) { + if (state.routineName == null || state.routineName!.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text( - 'Please enter the routine name'), + content: const Text('Please enter the routine name'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -216,12 +203,10 @@ class _RoutineSearchAndButtonsState extends State { return; } - if (state.ifItems.isEmpty || - state.thenItems.isEmpty) { + if (state.ifItems.isEmpty || state.thenItems.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text( - 'Please add if and then condition'), + content: const Text('Please add if and then condition'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -236,10 +221,8 @@ class _RoutineSearchAndButtonsState extends State { } // final result = // await - BlocProvider.of(context) - .add(ResetErrorMessage()); - SaveRoutineHelper.showSaveRoutineDialog( - context); + BlocProvider.of(context).add(ResetErrorMessage()); + SaveRoutineHelper.showSaveRoutineDialog(context); // if (result != null && result) { // BlocProvider.of(context).add( // const CreateNewRoutineViewEvent(createRoutineView: false), @@ -278,14 +261,10 @@ class _RoutineSearchAndButtonsState extends State { child: DefaultButton( onPressed: state.isAutomation || state.isTabToRun ? () async { - final result = - await SettingHelper.showSettingDialog( - context: context, - iconId: state.selectedIcon ?? ''); + final result = await SettingHelper.showSettingDialog( + context: context, iconId: state.selectedIcon ?? ''); if (result != null) { - context - .read() - .add(AddSelectedIcon(result)); + context.read().add(AddSelectedIcon(result)); } } : null, @@ -335,12 +314,10 @@ class _RoutineSearchAndButtonsState extends State { child: Center( child: DefaultButton( onPressed: () async { - if (state.routineName == null || - state.routineName!.isEmpty) { + if (state.routineName == null || state.routineName!.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text( - 'Please enter the routine name'), + content: const Text('Please enter the routine name'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -354,12 +331,10 @@ class _RoutineSearchAndButtonsState extends State { return; } - if (state.ifItems.isEmpty || - state.thenItems.isEmpty) { + if (state.ifItems.isEmpty || state.thenItems.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: const Text( - 'Please add if and then condition'), + content: const Text('Please add if and then condition'), duration: const Duration(seconds: 2), backgroundColor: ColorsManager.red, action: SnackBarAction( @@ -374,8 +349,7 @@ class _RoutineSearchAndButtonsState extends State { } // final result = // await - BlocProvider.of(context) - .add(ResetErrorMessage()); + BlocProvider.of(context).add(ResetErrorMessage()); SaveRoutineHelper.showSaveRoutineDialog(context); // if (result != null && result) { // BlocProvider.of(context).add( diff --git a/lib/pages/routines/widgets/scenes_and_automations.dart b/lib/pages/routines/widgets/scenes_and_automations.dart index 785686b6..14cb8d61 100644 --- a/lib/pages/routines/widgets/scenes_and_automations.dart +++ b/lib/pages/routines/widgets/scenes_and_automations.dart @@ -27,16 +27,14 @@ class _ScenesAndAutomationsState extends State { return BlocBuilder( builder: (context, state) { if (!state.isLoading) { - final scenes = [...state.scenes, ...state.automations]; + var scenes = [...state.scenes, ...state.automations]; return Wrap( spacing: 10, runSpacing: 10, children: scenes.asMap().entries.map((entry) { final scene = entry.value; if (state.searchText != null && state.searchText!.isNotEmpty) { - return scene.name - .toLowerCase() - .contains(state.searchText!.toLowerCase()) + return scene.name.toLowerCase().contains(state.searchText!.toLowerCase()) ? DraggableCard( imagePath: scene.icon ?? Assets.loginLogo, title: scene.name, diff --git a/lib/pages/routines/widgets/search_bar_condition_title.dart b/lib/pages/routines/widgets/search_bar_condition_title.dart index 9d2320bd..9ffcbf63 100644 --- a/lib/pages/routines/widgets/search_bar_condition_title.dart +++ b/lib/pages/routines/widgets/search_bar_condition_title.dart @@ -6,8 +6,7 @@ import 'package:syncrow_web/pages/routines/widgets/routines_title_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class ConditionTitleAndSearchBar extends StatelessWidget - with HelperResponsiveLayout { +class ConditionTitleAndSearchBar extends StatelessWidget with HelperResponsiveLayout { const ConditionTitleAndSearchBar({ super.key, }); diff --git a/lib/pages/routines/widgets/then_container.dart b/lib/pages/routines/widgets/then_container.dart index e32a2e67..d9eee4c4 100644 --- a/lib/pages/routines/widgets/then_container.dart +++ b/lib/pages/routines/widgets/then_container.dart @@ -30,118 +30,123 @@ class ThenContainer extends StatelessWidget { style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 16), - if (state.isLoading && state.isUpdate == true) - const Center( - child: CircularProgressIndicator(), - ) - else - Wrap( - spacing: 8, - runSpacing: 8, - children: List.generate( - state.thenItems.length, - (index) => GestureDetector( - onTap: () async { - if (state.thenItems[index]['deviceId'] == - 'delay') { - final result = await DelayHelper - .showDelayPickerDialog(context, - state.thenItems[index]); + state.isLoading && state.isUpdate == true + ? const Center( + child: CircularProgressIndicator(), + ) + : Wrap( + spacing: 8, + runSpacing: 8, + children: List.generate( + state.thenItems.length, + (index) => GestureDetector( + onTap: () async { + if (state.thenItems[index] + ['deviceId'] == + 'delay') { + final result = await DelayHelper + .showDelayPickerDialog(context, + state.thenItems[index]); + + if (result != null) { + context + .read() + .add(AddToThenContainer({ + ...state.thenItems[index], + 'imagePath': Assets.delay, + 'title': 'Delay', + })); + } + return; + } + + if (state.thenItems[index]['type'] == + 'automation') { + final result = await showDialog( + context: context, + builder: (BuildContext context) => + AutomationDialog( + automationName: + state.thenItems[index] + ['name'] ?? + 'Automation', + automationId: + state.thenItems[index] + ['deviceId'] ?? + '', + uniqueCustomId: + state.thenItems[index] + ['uniqueCustomId'], + ), + ); + + if (result != null) { + context + .read() + .add(AddToThenContainer({ + ...state.thenItems[index], + 'imagePath': + Assets.automation, + 'title': + state.thenItems[index] + ['name'] ?? + state.thenItems[index] + ['title'], + })); + } + return; + } + + final result = await DeviceDialogHelper + .showDeviceDialog( + context: context, + data: state.thenItems[index], + removeComparetors: true, + dialogType: "THEN"); if (result != null) { - context - .read() - .add(AddToThenContainer({ - ...state.thenItems[index], - 'imagePath': Assets.delay, - 'title': 'Delay', - })); + context.read().add( + AddToThenContainer( + state.thenItems[index])); + } else if (![ + 'AC', + '1G', + '2G', + '3G', + 'WPS', + 'CPS', + "GW", + "NCPS", + 'WH', + ].contains(state.thenItems[index] + ['productType'])) { + context.read().add( + AddToThenContainer( + state.thenItems[index])); } - return; - } - - if (state.thenItems[index]['type'] == - 'automation') { - final result = await showDialog( - context: context, - builder: (BuildContext context) => - AutomationDialog( - automationName: state - .thenItems[index]['name'] ?? - 'Automation', - automationId: state.thenItems[index] - ['deviceId'] ?? - '', - uniqueCustomId: - state.thenItems[index] - ['uniqueCustomId'], - ), - ); - - if (result != null) { - context - .read() - .add(AddToThenContainer({ - ...state.thenItems[index], - 'imagePath': Assets.automation, - 'title': state.thenItems[index] - ['name'] ?? - state.thenItems[index] - ['title'], - })); - } - return; - } - - final result = await DeviceDialogHelper - .showDeviceDialog( - context: context, - data: state.thenItems[index], - removeComparetors: true, - dialogType: 'THEN'); - - if (result != null) { - context.read().add( - AddToThenContainer( - state.thenItems[index])); - } else if (![ - 'AC', - '1G', - '2G', - '3G', - 'WPS', - 'CPS', - 'GW', - 'NCPS', - 'WH', - ].contains(state.thenItems[index] - ['productType'])) { - context.read().add( - AddToThenContainer( - state.thenItems[index])); - } - }, - child: DraggableCard( - imagePath: state.thenItems[index] - ['imagePath'] ?? - '', - title: - state.thenItems[index]['title'] ?? '', - deviceData: state.thenItems[index], - padding: const EdgeInsets.symmetric( - horizontal: 4, vertical: 8), - isFromThen: true, - isFromIf: false, - onRemove: () { - context.read().add( - RemoveDragCard( - index: index, - isFromThen: true, - key: state.thenItems[index] - ['uniqueCustomId'])); }, - ), - ))), + child: DraggableCard( + imagePath: state.thenItems[index] + ['imagePath'] ?? + '', + title: state.thenItems[index] + ['title'] ?? + '', + deviceData: state.thenItems[index], + padding: const EdgeInsets.symmetric( + horizontal: 4, vertical: 8), + isFromThen: true, + isFromIf: false, + onRemove: () { + context.read().add( + RemoveDragCard( + index: index, + isFromThen: true, + key: state.thenItems[index] + ['uniqueCustomId'])); + }, + ), + ))), ], ), ), @@ -163,7 +168,7 @@ class ThenContainer extends StatelessWidget { } if (mutableData['type'] == 'automation') { - final index = state.thenItems.indexWhere( + int index = state.thenItems.indexWhere( (item) => item['deviceId'] == mutableData['deviceId']); if (index != -1) { return; @@ -189,7 +194,7 @@ class ThenContainer extends StatelessWidget { } if (mutableData['type'] == 'tap_to_run' && state.isAutomation) { - final index = state.thenItems.indexWhere( + int index = state.thenItems.indexWhere( (item) => item['deviceId'] == mutableData['deviceId']); if (index != -1) { return; @@ -225,7 +230,7 @@ class ThenContainer extends StatelessWidget { context: context, data: mutableData, removeComparetors: true, - dialogType: 'THEN'); + dialogType: "THEN"); if (result != null) { context.read().add(AddToThenContainer(mutableData)); } else if (![ @@ -236,8 +241,8 @@ class ThenContainer extends StatelessWidget { 'WPS', 'GW', 'CPS', - 'NCPS', - 'WH', + "NCPS", + "WH", 'PC', ].contains(mutableData['productType'])) { context.read().add(AddToThenContainer(mutableData)); diff --git a/lib/pages/routines/widgets/value_display.dart b/lib/pages/routines/widgets/value_display.dart index b03720cf..6a8bd949 100644 --- a/lib/pages/routines/widgets/value_display.dart +++ b/lib/pages/routines/widgets/value_display.dart @@ -19,7 +19,7 @@ class ValueDisplay extends StatelessWidget { return Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: BoxDecoration( - color: ColorsManager.primaryColorWithOpacity.withValues(alpha: 0.1), + color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), borderRadius: BorderRadius.circular(10), ), child: Text( diff --git a/lib/pages/space_tree/bloc/space_tree_bloc.dart b/lib/pages/space_tree/bloc/space_tree_bloc.dart index cd374eb5..e8c2e015 100644 --- a/lib/pages/space_tree/bloc/space_tree_bloc.dart +++ b/lib/pages/space_tree/bloc/space_tree_bloc.dart @@ -30,7 +30,7 @@ class SpaceTreeBloc extends Bloc { } Timer _timer = Timer(const Duration(microseconds: 0), () {}); - Future _onCommunityUpdate( + void _onCommunityUpdate( OnCommunityUpdated event, Emitter emit, ) async { @@ -54,13 +54,12 @@ class SpaceTreeBloc extends Bloc { } } - Future _fetchSpaces( - InitialEvent event, Emitter emit) async { + _fetchSpaces(InitialEvent event, Emitter emit) async { emit(SpaceTreeLoadingState()); try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final paginationModel = await CommunitySpaceManagementApi() + PaginationModel paginationModel = await CommunitySpaceManagementApi() .fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1); // List updatedCommunities = await Future.wait( @@ -90,11 +89,10 @@ class SpaceTreeBloc extends Bloc { } } - Future _fetchPaginationSpaces( - PaginationEvent event, Emitter emit) async { + _fetchPaginationSpaces(PaginationEvent event, Emitter emit) async { emit(state.copyWith(paginationIsLoading: true)); - var paginationModel = event.paginationModel; - final communities = List.from(event.communities); + PaginationModel paginationModel = event.paginationModel; + List communities = List.from(event.communities); try { if (paginationModel.hasNext && state.searchQuery.isEmpty) { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -116,7 +114,7 @@ class SpaceTreeBloc extends Bloc { paginationIsLoading: false)); } - Future _onCommunityAdded( + void _onCommunityAdded( OnCommunityAdded event, Emitter emit) async { final updatedCommunities = List.from(state.communityList); updatedCommunities.add(event.newCommunity); @@ -124,11 +122,11 @@ class SpaceTreeBloc extends Bloc { emit(state.copyWith(communitiesList: updatedCommunities)); } - Future _onCommunityExpanded( + _onCommunityExpanded( OnCommunityExpanded event, Emitter emit) async { try { - final updatedExpandedCommunityList = - List.from(state.expandedCommunities); + List updatedExpandedCommunityList = + List.from(state.expandedCommunities); if (updatedExpandedCommunityList.contains(event.communityId)) { updatedExpandedCommunityList.remove(event.communityId); @@ -144,10 +142,9 @@ class SpaceTreeBloc extends Bloc { } } - Future _onSpaceExpanded( - OnSpaceExpanded event, Emitter emit) async { + _onSpaceExpanded(OnSpaceExpanded event, Emitter emit) async { try { - final updatedExpandedSpacesList = List.from(state.expandedSpaces); + List updatedExpandedSpacesList = List.from(state.expandedSpaces); if (updatedExpandedSpacesList.contains(event.spaceId)) { updatedExpandedSpacesList.remove(event.spaceId); @@ -161,21 +158,20 @@ class SpaceTreeBloc extends Bloc { } } - Future _onCommunitySelected( + _onCommunitySelected( OnCommunitySelected event, Emitter emit) async { try { - final updatedSelectedCommunities = - List.from(state.selectedCommunities.toSet().toList()); - final updatedSelectedSpaces = - List.from(state.selectedSpaces.toSet().toList()); - final updatedSoldChecks = - List.from(state.soldCheck.toSet().toList()); - final communityAndSpaces = - Map>.from(state.selectedCommunityAndSpaces); - final selectedSpacesInCommunity = + List updatedSelectedCommunities = + List.from(state.selectedCommunities.toSet().toList()); + List updatedSelectedSpaces = + List.from(state.selectedSpaces.toSet().toList()); + List updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); + Map> communityAndSpaces = + Map.from(state.selectedCommunityAndSpaces); + List selectedSpacesInCommunity = communityAndSpaces[event.communityId] ?? []; - final childrenIds = _getAllChildIds(event.children); + List childrenIds = _getAllChildIds(event.children); if (!updatedSelectedCommunities.contains(event.communityId)) { // Select the community and all its children @@ -202,25 +198,23 @@ class SpaceTreeBloc extends Bloc { } } - Future _onSpaceSelected( - OnSpaceSelected event, Emitter emit) async { + _onSpaceSelected(OnSpaceSelected event, Emitter emit) async { try { - final updatedSelectedCommunities = - List.from(state.selectedCommunities.toSet().toList()); - final updatedSelectedSpaces = - List.from(state.selectedSpaces.toSet().toList()); - final updatedSoldChecks = - List.from(state.soldCheck.toSet().toList()); - final communityAndSpaces = - Map>.from(state.selectedCommunityAndSpaces); + List updatedSelectedCommunities = + List.from(state.selectedCommunities.toSet().toList()); + List updatedSelectedSpaces = + List.from(state.selectedSpaces.toSet().toList()); + List updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); + Map> communityAndSpaces = + Map.from(state.selectedCommunityAndSpaces); - final selectedSpacesInCommunity = + List selectedSpacesInCommunity = communityAndSpaces[event.communityModel.uuid] ?? []; - final childrenIds = _getAllChildIds(event.children); - var isChildSelected = false; + List childrenIds = _getAllChildIds(event.children); + bool isChildSelected = false; - for (final id in childrenIds) { + for (String id in childrenIds) { if (updatedSelectedSpaces.contains(id)) { isChildSelected = true; } @@ -238,9 +232,9 @@ class SpaceTreeBloc extends Bloc { selectedSpacesInCommunity.addAll(childrenIds); } - final spaces = + List spaces = _getThePathToChild(event.communityModel.uuid, event.spaceId); - for (final space in spaces) { + for (String space in spaces) { if (!updatedSelectedSpaces.contains(space) && !updatedSoldChecks.contains(space)) { updatedSoldChecks.add(space); @@ -264,7 +258,7 @@ class SpaceTreeBloc extends Bloc { } updatedSoldChecks.remove(event.spaceId); - final parents = + List parents = _getThePathToChild(event.communityModel.uuid, event.spaceId) .toSet() .toList(); @@ -274,7 +268,7 @@ class SpaceTreeBloc extends Bloc { updatedSelectedCommunities.remove(event.communityModel.uuid); } else { // Check if any parent has selected children - for (final space in parents) { + for (String space in parents) { if (!_noChildrenSelected( event.communityModel, space, updatedSelectedSpaces, parents)) { updatedSoldChecks.remove(space); @@ -301,17 +295,17 @@ class SpaceTreeBloc extends Bloc { } } - bool _noChildrenSelected(CommunityModel community, String spaceId, + _noChildrenSelected(CommunityModel community, String spaceId, List selectedSpaces, List parents) { if (selectedSpaces.contains(spaceId)) { return true; } - final children = _getAllChildSpaces(community.spaces); - for (final child in children) { + List children = _getAllChildSpaces(community.spaces); + for (var child in children) { if (spaceId == child.uuid) { - final ids = _getAllChildIds(child.children); - for (final id in ids) { + List ids = _getAllChildIds(child.children); + for (var id in ids) { if (selectedSpaces.contains(id)) { return true; } @@ -322,15 +316,14 @@ class SpaceTreeBloc extends Bloc { return false; } - Future _onSearch( - SearchQueryEvent event, Emitter emit) async { + _onSearch(SearchQueryEvent event, Emitter emit) async { try { const duration = Duration(seconds: 1); if (_timer.isActive) { _timer.cancel(); // clear timer } - _timer = Timer( - duration, () async => add(DebouncedSearchEvent(event.searchQuery))); + _timer = + Timer(duration, () async => add(DebouncedSearchEvent(event.searchQuery))); // List communities = List.from(state.communityList); // List filteredCommunity = []; @@ -354,12 +347,12 @@ class SpaceTreeBloc extends Bloc { } } - Future _onDebouncedSearch( + _onDebouncedSearch( DebouncedSearchEvent event, Emitter emit) async { emit(state.copyWith( isSearching: true, )); - var paginationModel = const PaginationModel.emptyConstructor(); + PaginationModel paginationModel = const PaginationModel.emptyConstructor(); try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -374,8 +367,7 @@ class SpaceTreeBloc extends Bloc { searchQuery: event.searchQuery)); } - Future _clearAllData( - ClearAllData event, Emitter emit) async { + _clearAllData(ClearAllData event, Emitter emit) async { try { emit(state.copyWith( communitiesList: [], @@ -393,8 +385,7 @@ class SpaceTreeBloc extends Bloc { } } - Future _clearCachedData( - ClearCachedData event, Emitter emit) async { + _clearCachedData(ClearCachedData event, Emitter emit) async { try { emit(state.copyWith( communitiesList: state.communityList, @@ -422,8 +413,8 @@ class SpaceTreeBloc extends Bloc { // } List _getAllChildIds(List spaces) { - final ids = []; - for (final child in spaces) { + List ids = []; + for (var child in spaces) { ids.add(child.uuid!); ids.addAll(_getAllChildIds(child.children)); } @@ -431,8 +422,8 @@ class SpaceTreeBloc extends Bloc { } List _getAllChildSpaces(List spaces) { - final children = []; - for (final child in spaces) { + List children = []; + for (var child in spaces) { children.add(child); children.addAll(_getAllChildSpaces(child.children)); } @@ -441,9 +432,9 @@ class SpaceTreeBloc extends Bloc { bool _anySpacesSelectedInCommunity(CommunityModel community, List selectedSpaces, List partialCheckedList) { - var result = false; - final ids = _getAllChildIds(community.spaces); - for (final id in ids) { + bool result = false; + List ids = _getAllChildIds(community.spaces); + for (var id in ids) { result = selectedSpaces.contains(id) || partialCheckedList.contains(id); if (result) { return result; @@ -453,11 +444,11 @@ class SpaceTreeBloc extends Bloc { } List _getThePathToChild(String communityId, String selectedSpaceId) { - var ids = []; - for (final community in state.communityList) { + List ids = []; + for (var community in state.communityList) { if (community.uuid == communityId) { - for (final space in community.spaces) { - final list = []; + for (var space in community.spaces) { + List list = []; list.add(space.uuid!); ids = _getAllParentsIds(space, selectedSpaceId, List.from(list)); if (ids.isNotEmpty) { @@ -471,7 +462,7 @@ class SpaceTreeBloc extends Bloc { List _getAllParentsIds( SpaceModel child, String spaceId, List listIds) { - final ids = listIds; + List ids = listIds; ids.add(child.uuid ?? ''); @@ -480,8 +471,8 @@ class SpaceTreeBloc extends Bloc { } if (child.children.isNotEmpty) { - for (final space in child.children) { - final result = _getAllParentsIds(space, spaceId, List.from(ids)); + for (var space in child.children) { + var result = _getAllParentsIds(space, spaceId, List.from(ids)); if (result.isNotEmpty) { return result; } @@ -492,7 +483,7 @@ class SpaceTreeBloc extends Bloc { return []; } - Future _onSpaceTreeClearSelectionEvent( + void _onSpaceTreeClearSelectionEvent( SpaceTreeClearSelectionEvent event, Emitter emit, ) async { @@ -505,7 +496,7 @@ class SpaceTreeBloc extends Bloc { ); } - Future _onAnalyticsClearAllSpaceTreeSelectionsEvent( + void _onAnalyticsClearAllSpaceTreeSelectionsEvent( AnalyticsClearAllSpaceTreeSelectionsEvent event, Emitter emit, ) async { diff --git a/lib/pages/space_tree/bloc/space_tree_state.dart b/lib/pages/space_tree/bloc/space_tree_state.dart index 175a9da6..595380fd 100644 --- a/lib/pages/space_tree/bloc/space_tree_state.dart +++ b/lib/pages/space_tree/bloc/space_tree_state.dart @@ -44,16 +44,15 @@ class SpaceTreeState extends Equatable { PaginationModel? paginationModel, bool? paginationIsLoading}) { return SpaceTreeState( - communityList: communitiesList ?? communityList, + communityList: communitiesList ?? this.communityList, filteredCommunity: filteredCommunity ?? this.filteredCommunity, expandedSpaces: expandedSpaces ?? this.expandedSpaces, - expandedCommunities: expandedCommunity ?? expandedCommunities, + expandedCommunities: expandedCommunity ?? this.expandedCommunities, selectedCommunities: selectedCommunities ?? this.selectedCommunities, selectedSpaces: selectedSpaces ?? this.selectedSpaces, soldCheck: soldCheck ?? this.soldCheck, isSearching: isSearching ?? this.isSearching, - selectedCommunityAndSpaces: - selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces, + selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces, searchQuery: searchQuery ?? this.searchQuery, paginationModel: paginationModel ?? this.paginationModel, paginationIsLoading: paginationIsLoading ?? this.paginationIsLoading); diff --git a/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart b/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart index 624045e9..e84851c5 100644 --- a/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart +++ b/lib/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart @@ -1,7 +1,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_state.dart'; -import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart'; class AddDeviceTypeBloc extends Bloc { AddDeviceTypeBloc() : super(AddDeviceInitial()) { diff --git a/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart b/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart index 51b1ea34..254b78fd 100644 --- a/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart +++ b/lib/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart @@ -16,7 +16,7 @@ class UpdateProductCountEvent extends AddDeviceTypeEvent { final String productName; final ProductModel product; - const UpdateProductCountEvent( + UpdateProductCountEvent( {required this.productId, required this.count, required this.productName, @@ -26,6 +26,7 @@ class UpdateProductCountEvent extends AddDeviceTypeEvent { List get props => [productId, count]; } + class InitializeDevice extends AddDeviceTypeEvent { final List initialTags; final List addedProducts; diff --git a/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart b/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart index e95bc74d..ede6afb9 100644 --- a/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart +++ b/lib/pages/spaces_management/add_device_type/views/add_device_type_widget.dart @@ -6,10 +6,10 @@ import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_dev import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_state.dart'; import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/add_device_type/widgets/scrollable_grid_view_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -24,7 +24,8 @@ class AddDeviceTypeWidget extends StatelessWidget { final String spaceName; final bool isCreate; final Function(List, List?)? onSave; - final List projectTags; + final List projectTags; + const AddDeviceTypeWidget( {super.key, diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 4bda7999..a4d6628e 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -1,19 +1,20 @@ import 'dart:async'; - import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_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/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/space_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/tag_body_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; @@ -56,10 +57,10 @@ class SpaceManagementBloc UpdateSpaceModelCache event, Emitter emit) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final allSpaceModels = []; + List allSpaceModels = []; - var hasNext = true; - var page = 1; + bool hasNext = true; + int page = 1; while (hasNext) { final spaceModels = await _spaceModelApi.listSpaceModels( @@ -84,7 +85,7 @@ class SpaceManagementBloc allTags: _cachedTags ?? [])); } - Future _deleteSpaceModelFromCache(DeleteSpaceModelFromCache event, + void _deleteSpaceModelFromCache(DeleteSpaceModelFromCache event, Emitter emit) async { if (_cachedSpaceModels != null) { _cachedSpaceModels = _cachedSpaceModels! @@ -120,10 +121,10 @@ class SpaceManagementBloc final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final allSpaceModels = []; + List allSpaceModels = []; - var hasNext = true; - var page = 1; + bool hasNext = true; + int page = 1; while (hasNext) { final spaceModels = await _spaceModelApi.listSpaceModels( @@ -158,7 +159,7 @@ class SpaceManagementBloc } } - Future _onUpdateCommunity( + void _onUpdateCommunity( UpdateCommunityEvent event, Emitter emit, ) async { @@ -174,7 +175,7 @@ class SpaceManagementBloc if (previousState is SpaceManagementLoaded) { final updatedCommunities = List.from(previousState.communities); - for (final community in updatedCommunities) { + for (var community in updatedCommunities) { if (community.uuid == event.communityUuid) { community.name = event.name; _spaceTreeBloc.add(OnCommunityAdded(community)); @@ -183,7 +184,7 @@ class SpaceManagementBloc } } - final prevSpaceModels = await fetchSpaceModels(); + var prevSpaceModels = await fetchSpaceModels(); emit(SpaceManagementLoaded( communities: updatedCommunities, @@ -200,14 +201,14 @@ class SpaceManagementBloc } } - Future _onloadProducts() async { + void _onloadProducts() async { if (_cachedProducts == null) { final products = await _productApi.fetchProducts(); _cachedProducts = products; } } - Future _onFetchProducts( + void _onFetchProducts( FetchProductsEvent event, Emitter emit, ) async { @@ -222,7 +223,7 @@ class SpaceManagementBloc String communityUuid) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - return _api.getSpaceHierarchy(communityUuid, projectUuid); + return await _api.getSpaceHierarchy(communityUuid, projectUuid); } Future _onNewCommunity( @@ -237,7 +238,7 @@ class SpaceManagementBloc return; } - final prevSpaceModels = await fetchSpaceModels(); + var prevSpaceModels = await fetchSpaceModels(); emit(BlankState( communities: event.communities, @@ -254,15 +255,15 @@ class SpaceManagementBloc try { final previousState = state; final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final spaceBloc = event.context.read(); - final spaceTreeState = event.context.read().state; + var spaceBloc = event.context.read(); + var spaceTreeState = event.context.read().state; - final communities = + List communities = await _waitForCommunityList(spaceBloc, spaceTreeState); await fetchSpaceModels(); // await fetchTags(); - final prevSpaceModels = await fetchSpaceModels(); + var prevSpaceModels = await fetchSpaceModels(); if (previousState is SpaceManagementLoaded || previousState is BlankState) { @@ -286,17 +287,18 @@ class SpaceManagementBloc } } - Future _onLoadCommunityAndSpaces( + void _onLoadCommunityAndSpaces( LoadCommunityAndSpacesEvent event, Emitter emit, ) async { - final spaceTreeState = event.context.read().state; - final spaceBloc = event.context.read(); + var spaceTreeState = event.context.read().state; + var spaceBloc = event.context.read(); _onloadProducts(); await fetchTags(); // Wait until `communityList` is loaded - final communities = await _waitForCommunityList(spaceBloc, spaceTreeState); + List communities = + await _waitForCommunityList(spaceBloc, spaceTreeState); // Fetch space models after communities are available final prevSpaceModels = await fetchSpaceModels(); @@ -342,7 +344,7 @@ class SpaceManagementBloc } } - Future _onCommunityDelete( + void _onCommunityDelete( DeleteCommunityEvent event, Emitter emit, ) async { @@ -363,7 +365,7 @@ class SpaceManagementBloc } } - Future _onCreateCommunity( + void _onCreateCommunity( CreateCommunityEvent event, Emitter emit, ) async { @@ -373,9 +375,9 @@ class SpaceManagementBloc try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; await fetchTags(); - final newCommunity = await _api.createCommunity( + CommunityModel? newCommunity = await _api.createCommunity( event.name, event.description, projectUuid); - final prevSpaceModels = await fetchSpaceModels(); + var prevSpaceModels = await fetchSpaceModels(); if (newCommunity != null) { if (previousState is SpaceManagementLoaded || @@ -403,7 +405,7 @@ class SpaceManagementBloc } } - Future _onSelectCommunity( + void _onSelectCommunity( SelectCommunityEvent event, Emitter emit, ) async { @@ -429,7 +431,7 @@ class SpaceManagementBloc ); } - Future _handleCommunitySpaceStateUpdate({ + void _handleCommunitySpaceStateUpdate({ required Emitter emit, CommunityModel? selectedCommunity, SpaceModel? selectedSpace, @@ -462,7 +464,7 @@ class SpaceManagementBloc } } - Future _onSaveSpaces( + void _onSaveSpaces( SaveSpacesEvent event, Emitter emit, ) async { @@ -492,9 +494,9 @@ class SpaceManagementBloc event.spaces.removeWhere( (space) => space.status == SpaceStatus.deleted, ); - for (final space in event.spaces) { - space.status = SpaceStatus.unchanged; - } + event.spaces.forEach( + (space) => space.status = SpaceStatus.unchanged, + ); } } catch (e) { // emit(SpaceManagementError('Error saving spaces: $e')); @@ -513,7 +515,7 @@ class SpaceManagementBloc Emitter emit, ) async { try { - final prevSpaceModels = await fetchSpaceModels(); + var prevSpaceModels = await fetchSpaceModels(); await fetchTags(); @@ -521,7 +523,7 @@ class SpaceManagementBloc ? spaceTreeState.filteredCommunity : spaceTreeState.communityList; - for (final community in communities) { + for (var community in communities) { if (community.uuid == communityUuid) { community.spaces = allSpaces; _spaceTreeBloc.add(InitialEvent()); @@ -538,7 +540,7 @@ class SpaceManagementBloc } } emit(previousState); - } catch (e) { + } catch (e, stackTrace) { emit(previousState); // rethrow; } @@ -575,36 +577,36 @@ class SpaceManagementBloc space.status == SpaceStatus.deleted && (space.parent == null || space.parent?.status != SpaceStatus.deleted)); - for (final parent in parentsToDelete) { + for (var parent in parentsToDelete) { try { if (parent.uuid != null) { await _api.deleteSpace(communityUuid, parent.uuid!, projectUuid); } } catch (e) {} } - orderedSpaces.removeWhere(parentsToDelete.contains); + orderedSpaces.removeWhere((space) => parentsToDelete.contains(space)); - for (final space in orderedSpaces) { + for (var space in orderedSpaces) { try { if (space.uuid != null && space.uuid!.isNotEmpty) { - var tagUpdates = []; + List tagUpdates = []; - final matchedSpaces = + List matchedSpaces = findMatchingSpaces(selectedCommunity.spaces, space.uuid!); if (matchedSpaces.isEmpty) continue; final prevSpace = matchedSpaces.elementAtOrNull(0); - final subspaceUpdates = []; - final prevSubspaces = prevSpace?.subspaces; - final newSubspaces = space.subspaces; + final List subspaceUpdates = []; + final List? prevSubspaces = prevSpace?.subspaces; + final List? newSubspaces = space.subspaces; tagUpdates = processTagUpdates(prevSpace?.tags, space.tags); if (prevSubspaces != null || newSubspaces != null) { if (prevSubspaces != null && newSubspaces != null) { - for (final prevSubspace in prevSubspaces) { + for (var prevSubspace in prevSubspaces) { final existsInNew = newSubspaces .any((subspace) => subspace.uuid == prevSubspace.uuid); if (!existsInNew) { @@ -614,7 +616,7 @@ class SpaceManagementBloc } } } else if (prevSubspaces != null && newSubspaces == null) { - for (final prevSubspace in prevSubspaces) { + for (var prevSubspace in prevSubspaces) { subspaceUpdates.add(UpdateSubspaceTemplateModel( action: custom_action.Action.delete, uuid: prevSubspace.uuid)); @@ -622,13 +624,13 @@ class SpaceManagementBloc } if (newSubspaces != null) { - for (final newSubspace in newSubspaces) { + for (var newSubspace in newSubspaces) { // Tag without UUID - if (newSubspace.uuid == null || newSubspace.uuid!.isEmpty) { - final tagUpdates = []; + if ((newSubspace.uuid == null || newSubspace.uuid!.isEmpty)) { + final List tagUpdates = []; if (newSubspace.tags != null) { - for (final tag in newSubspace.tags!) { + for (var tag in newSubspace.tags!) { tagUpdates.add(TagModelUpdate( action: custom_action.Action.add, newTagUuid: tag.uuid == '' ? null : tag.uuid, @@ -646,14 +648,14 @@ class SpaceManagementBloc if (prevSubspaces != null && newSubspaces != null) { final newSubspaceMap = { - for (final subspace in newSubspaces) subspace.uuid: subspace + for (var subspace in newSubspaces) subspace.uuid: subspace }; - for (final prevSubspace in prevSubspaces) { + for (var prevSubspace in prevSubspaces) { final newSubspace = newSubspaceMap[prevSubspace.uuid]; if (newSubspace != null) { - final tagSubspaceUpdates = + final List tagSubspaceUpdates = processTagUpdates(prevSubspace.tags, newSubspace.tags); subspaceUpdates.add(UpdateSubspaceTemplateModel( action: custom_action.Action.update, @@ -667,7 +669,7 @@ class SpaceManagementBloc final response = await _api.updateSpace( communityId: communityUuid, - spaceId: space.uuid, + spaceId: space.uuid!, name: space.name, parentId: space.parent?.uuid, isPrivate: space.isPrivate, @@ -681,7 +683,7 @@ class SpaceManagementBloc projectId: projectUuid); } else { // Call create if the space does not have a UUID - var tagBodyModels = space.tags != null + List tagBodyModels = space.tags != null ? space.tags!.map((tag) => tag.toCreateTagBodyModel()).toList() : []; @@ -729,17 +731,17 @@ class SpaceManagementBloc void visit(SpaceModel space) { if (!result.contains(space)) { result.add(space); - for (final child in spaces.where((s) => s.parent == space)) { + for (var child in spaces.where((s) => s.parent == space)) { visit(child); } } } - for (final space in topLevelSpaces) { + for (var space in topLevelSpaces) { visit(space); } - for (final space in spaces) { + for (var space in spaces) { if (!result.contains(space)) { result.add(space); } @@ -747,7 +749,7 @@ class SpaceManagementBloc return result.toList(); // Convert back to a list } - Future _onLoadSpaceModel( + void _onLoadSpaceModel( SpaceModelLoadEvent event, Emitter emit) async { emit(SpaceManagementLoading()); @@ -758,9 +760,9 @@ class SpaceManagementBloc ? spaceTreeState.filteredCommunity : spaceTreeState.communityList; - final communities = filteredCommunities; + List communities = filteredCommunities; - final prevSpaceModels = await fetchSpaceModels(); + var prevSpaceModels = await fetchSpaceModels(); emit(SpaceModelLoaded( communities: communities, @@ -776,11 +778,11 @@ class SpaceManagementBloc List? prevTags, List? newTags, ) { - final tagUpdates = []; + final List tagUpdates = []; final processedTags = {}; if (prevTags == null && newTags != null) { - for (final newTag in newTags) { + for (var newTag in newTags) { tagUpdates.add(TagModelUpdate( action: custom_action.Action.add, tag: newTag.tag, @@ -794,7 +796,7 @@ class SpaceManagementBloc if (newTags != null || prevTags != null) { // Case 1: Tags deleted if (prevTags != null && newTags != null) { - for (final prevTag in prevTags) { + for (var prevTag in prevTags) { final existsInNew = newTags.any((newTag) => newTag.uuid == prevTag.uuid); if (!existsInNew) { @@ -803,7 +805,7 @@ class SpaceManagementBloc } } } else if (prevTags != null && newTags == null) { - for (final prevTag in prevTags) { + for (var prevTag in prevTags) { tagUpdates.add(TagModelUpdate( action: custom_action.Action.delete, uuid: prevTag.uuid)); } @@ -813,7 +815,7 @@ class SpaceManagementBloc if (newTags != null) { final prevTagUuids = prevTags?.map((t) => t.uuid).toSet() ?? {}; - for (final newTag in newTags) { + for (var newTag in newTags) { // Tag without UUID if ((newTag.uuid == null || !prevTagUuids.contains(newTag.uuid)) && !processedTags.contains(newTag.tag)) { @@ -829,9 +831,9 @@ class SpaceManagementBloc // Case 3: Tags updated if (prevTags != null && newTags != null) { - final newTagMap = {for (final tag in newTags) tag.uuid: tag}; + final newTagMap = {for (var tag in newTags) tag.uuid: tag}; - for (final prevTag in prevTags) { + for (var prevTag in prevTags) { final newTag = newTagMap[prevTag.uuid]; if (newTag != null) { tagUpdates.add(TagModelUpdate( @@ -850,9 +852,9 @@ class SpaceManagementBloc List findMatchingSpaces( List spaces, String targetUuid) { - final matched = []; + List matched = []; - for (final space in spaces) { + for (var space in spaces) { if (space.uuid == targetUuid) { matched.add(space); } diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart index b6c90304..8a9db432 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart @@ -166,10 +166,10 @@ class SpaceModelLoadEvent extends SpaceManagementEvent { class UpdateSpaceModelCache extends SpaceManagementEvent { final SpaceTemplateModel updatedModel; - const UpdateSpaceModelCache(this.updatedModel); + UpdateSpaceModelCache(this.updatedModel); } class DeleteSpaceModelFromCache extends SpaceManagementEvent { final String deletedUuid; - const DeleteSpaceModelFromCache(this.deletedUuid); + DeleteSpaceModelFromCache(this.deletedUuid); } diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart index 361be6c9..3efa7c00 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart @@ -40,10 +40,7 @@ class BlankState extends SpaceManagementState { final List allTags; BlankState( - {required this.communities, - required this.products, - this.spaceModels, - required this.allTags}); + {required this.communities, required this.products, this.spaceModels, required this.allTags}); } class SpaceCreationSuccess extends SpaceManagementState { diff --git a/lib/pages/spaces_management/all_spaces/model/base_tag.dart b/lib/pages/spaces_management/all_spaces/model/base_tag.dart index 44babc9e..57f223f4 100644 --- a/lib/pages/spaces_management/all_spaces/model/base_tag.dart +++ b/lib/pages/spaces_management/all_spaces/model/base_tag.dart @@ -16,7 +16,7 @@ abstract class BaseTag { this.location, }) : internalId = internalId ?? const Uuid().v4(); - Map toJson(); + Map toJson(); BaseTag copyWith({ String? tag, ProductModel? product, diff --git a/lib/pages/spaces_management/all_spaces/model/community_model.dart b/lib/pages/spaces_management/all_spaces/model/community_model.dart index 23388375..d1e27095 100644 --- a/lib/pages/spaces_management/all_spaces/model/community_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/community_model.dart @@ -27,12 +27,9 @@ class CommunityModel { updatedAt: DateTime.parse(json['updatedAt'] ?? ''), name: json['name'] ?? '', description: json['description'] ?? '', - region: - json['region'] != null ? RegionModel.fromJson(json['region']) : null, + region: json['region'] != null ? RegionModel.fromJson(json['region']) : null, spaces: json['spaces'] != null - ? (json['spaces'] as List) - .map((space) => SpaceModel.fromJson(space)) - .toList() + ? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList() : [], ); } @@ -45,9 +42,7 @@ class CommunityModel { 'name': name, 'description': description, 'region': region?.toJson(), - 'spaces': spaces - .map((space) => space.toMap()) - .toList(), // Convert spaces to Map + 'spaces': spaces.map((space) => space.toMap()).toList(), // Convert spaces to Map }; } } diff --git a/lib/pages/spaces_management/all_spaces/model/product_model.dart b/lib/pages/spaces_management/all_spaces/model/product_model.dart index 9ed528ed..8f905032 100644 --- a/lib/pages/spaces_management/all_spaces/model/product_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/product_model.dart @@ -1,6 +1,7 @@ -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; +import 'selected_product_model.dart'; + class ProductModel { final String uuid; final String catName; diff --git a/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart b/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart index 17fd429c..91314e42 100644 --- a/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart @@ -6,11 +6,7 @@ class SelectedProduct { final String productName; final ProductModel? product; - SelectedProduct( - {required this.productId, - required this.count, - required this.productName, - this.product}); + SelectedProduct({required this.productId, required this.count, required this.productName, this.product}); Map toJson() { return { @@ -20,7 +16,7 @@ class SelectedProduct { }; } - @override + @override String toString() { return 'SelectedProduct(productId: $productId, count: $count)'; } diff --git a/lib/pages/spaces_management/all_spaces/model/space_model.dart b/lib/pages/spaces_management/all_spaces/model/space_model.dart index 50cdb36c..f9c59d24 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_model.dart @@ -56,7 +56,7 @@ class SpaceModel { {String? parentInternalId}) { final String internalId = json['internalId'] ?? const Uuid().v4(); - final children = json['children'] != null + final List children = json['children'] != null ? (json['children'] as List).map((childJson) { return SpaceModel.fromJson( childJson, @@ -73,8 +73,8 @@ class SpaceModel { isPrivate: json['isPrivate'] ?? false, invitationCode: json['invitationCode'], subspaces: (json['subspaces'] as List?) - ?.whereType>() // Validate type - .map(SubspaceModel.fromJson) + ?.where((e) => e is Map) // Validate type + .map((e) => SubspaceModel.fromJson(e as Map)) .toList() ?? [], parent: parentInternalId != null @@ -102,8 +102,8 @@ class SpaceModel { ? SpaceTemplateModel.fromJson(json['spaceModel']) : null, tags: (json['productAllocations'] as List?) - ?.whereType>() // Validate type - .map(Tag.fromJson) + ?.where((item) => item is Map) // Validate type + .map((item) => Tag.fromJson(item as Map)) .toList() ?? [], ); @@ -150,7 +150,7 @@ class SpaceModel { extension SpaceExtensions on SpaceModel { List listAllTagValues() { - final tagValues = []; + final List tagValues = []; if (tags != null) { tagValues.addAll( @@ -174,10 +174,10 @@ extension SpaceExtensions on SpaceModel { bool isNoChangesSubmited(String name, icon, SpaceTemplateModel? spaceModel, List? subspaces, List? tags) { - return name == this.name && + return (name == this.name && icon == this.icon && spaceModel == this.spaceModel && subspaces == this.subspaces && - tags == this.tags; + tags == this.tags); } } diff --git a/lib/pages/spaces_management/all_spaces/model/space_response_model.dart b/lib/pages/spaces_management/all_spaces/model/space_response_model.dart index d698b48b..34df3d30 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_response_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_response_model.dart @@ -1,4 +1,5 @@ -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; + +import 'space_model.dart'; class SpacesResponse { final List data; diff --git a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart index 9c1defa8..fd3e780e 100644 --- a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart @@ -1,8 +1,9 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart'; import 'package:uuid/uuid.dart'; +import 'tag.dart'; + class SubspaceModel { final String? uuid; String subspaceName; diff --git a/lib/pages/spaces_management/all_spaces/model/tag.dart b/lib/pages/spaces_management/all_spaces/model/tag.dart index f17c3d86..a7ec1e15 100644 --- a/lib/pages/spaces_management/all_spaces/model/tag.dart +++ b/lib/pages/spaces_management/all_spaces/model/tag.dart @@ -6,12 +6,18 @@ import 'package:uuid/uuid.dart'; class Tag extends BaseTag { Tag({ - super.uuid, - required super.tag, - super.product, - super.internalId, - super.location, - }); + String? uuid, + required String? tag, + ProductModel? product, + String? internalId, + String? location, + }) : super( + uuid: uuid, + tag: tag, + product: product, + internalId: internalId, + location: location, + ); factory Tag.fromJson(Map json) { final String internalId = json['internalId'] ?? const Uuid().v4(); @@ -44,7 +50,6 @@ class Tag extends BaseTag { ); } - @override Map toJson() { return { if (uuid != null) 'uuid': uuid, diff --git a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart index 9094ebc0..291e6235 100644 --- a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_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_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/structure_selector/view/center_body_widget.dart'; import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; @@ -47,7 +47,7 @@ class SpaceManagementPageState extends State { style: ResponsiveTextTheme.of(context).deviceManagementTitle, ), enableMenuSidebar: false, - centerBody: const CenterBodyWidget(), + centerBody: CenterBodyWidget(), rightBody: const NavigateHomeGridView(), scaffoldBody: BlocBuilder( builder: (context, state) { diff --git a/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart index 71bda2ca..0e9f4bd1 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart @@ -32,9 +32,8 @@ class _AddDeviceWidgetState extends State { void initState() { super.initState(); _scrollController = ScrollController(); - productCounts = widget.initialSelectedProducts != null - ? List.from(widget.initialSelectedProducts!) - : []; + productCounts = + widget.initialSelectedProducts != null ? List.from(widget.initialSelectedProducts!) : []; } @override @@ -97,12 +96,10 @@ class _AddDeviceWidgetState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - _buildActionButton( - 'Cancel', ColorsManager.boxColor, ColorsManager.blackColor, () { + _buildActionButton('Cancel', ColorsManager.boxColor, ColorsManager.blackColor, () { Navigator.of(context).pop(); }), - _buildActionButton('Continue', ColorsManager.secondaryColor, - ColorsManager.whiteColors, () { + _buildActionButton('Continue', ColorsManager.secondaryColor, ColorsManager.whiteColors, () { Navigator.of(context).pop(); if (widget.onProductsSelected != null) { widget.onProductsSelected!(productCounts); @@ -117,11 +114,7 @@ class _AddDeviceWidgetState extends State { Widget _buildDeviceTypeTile(ProductModel product, Size size) { final selectedProduct = productCounts.firstWhere( (p) => p.productId == product.uuid, - orElse: () => SelectedProduct( - productId: product.uuid, - count: 0, - productName: product.catName, - product: product), + orElse: () => SelectedProduct(productId: product.uuid, count: 0, productName: product.catName, product: product), ); return SizedBox( @@ -150,17 +143,13 @@ class _AddDeviceWidgetState extends State { setState(() { if (newCount > 0) { if (!productCounts.contains(selectedProduct)) { - productCounts.add(SelectedProduct( - productId: product.uuid, - count: newCount, - productName: product.catName, - product: product)); + productCounts + .add(SelectedProduct(productId: product.uuid, count: newCount, productName: product.catName, product: product)); } else { selectedProduct.count = newCount; } } else { - productCounts - .removeWhere((p) => p.productId == product.uuid); + productCounts.removeWhere((p) => p.productId == product.uuid); } if (widget.onProductsSelected != null) { @@ -203,8 +192,7 @@ class _AddDeviceWidgetState extends State { height: size.width > 800 ? 35 : 25, child: Text( product.name ?? '', - style: context.textTheme.bodySmall - ?.copyWith(color: ColorsManager.blackColor), + style: context.textTheme.bodySmall?.copyWith(color: ColorsManager.blackColor), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, diff --git a/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart index 18dec3a1..66f1a026 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart @@ -9,7 +9,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; class BlankCommunityWidget extends StatefulWidget { final List communities; - const BlankCommunityWidget({super.key, required this.communities}); + BlankCommunityWidget({required this.communities}); @override _BlankCommunityWidgetState createState() => _BlankCommunityWidgetState(); @@ -19,7 +19,7 @@ class _BlankCommunityWidgetState extends State { @override Widget build(BuildContext context) { return Expanded( - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, // Parent container with white background child: GridView.builder( diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart index 49a19681..f5188c1e 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_action_button.dart @@ -36,7 +36,7 @@ class CommunityStructureHeaderActionButtons extends StatelessWidget { children: [ if (isSave) CommunityStructureHeaderButton( - label: 'Save', + label: "Save", icon: const Icon(Icons.save, size: 18, color: ColorsManager.spaceColor), onPressed: onSave, @@ -44,19 +44,19 @@ class CommunityStructureHeaderActionButtons extends StatelessWidget { ), if (canShowActions) ...[ CommunityStructureHeaderButton( - label: 'Edit', + label: "Edit", svgAsset: Assets.editSpace, onPressed: onEdit, theme: theme, ), CommunityStructureHeaderButton( - label: 'Duplicate', + label: "Duplicate", svgAsset: Assets.duplicate, onPressed: onDuplicate, theme: theme, ), CommunityStructureHeaderButton( - label: 'Delete', + label: "Delete", svgAsset: Assets.spaceDelete, onPressed: onDelete, theme: theme, diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart index 9a45d76a..6bc35cca 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart @@ -14,7 +14,7 @@ class CommunityStructureHeader extends StatefulWidget { final TextEditingController nameController; final VoidCallback onSave; final VoidCallback onDelete; - final VoidCallback onEdit; + final VoidCallback onEdit; final VoidCallback onDuplicate; final VoidCallback onEditName; diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index 1e882d8a..4f68fb7e 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -3,23 +3,24 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; + // Syncrow project imports import 'package:syncrow_web/pages/common/buttons/add_space_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/spaces_management/all_spaces/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_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/selected_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/community_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_card_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_container_widget.dart'; @@ -40,8 +41,7 @@ class CommunityStructureArea extends StatefulWidget { final List projectTags; CommunityStructureArea( - {super.key, - this.selectedCommunity, + {this.selectedCommunity, this.selectedSpace, required this.communities, this.products, @@ -120,7 +120,7 @@ class _CommunityStructureAreaState extends State { ); } - final screenSize = MediaQuery.of(context).size; + Size screenSize = MediaQuery.of(context).size; return Expanded( child: GestureDetector( onTap: () { @@ -173,16 +173,16 @@ class _CommunityStructureAreaState extends State { children: [ InteractiveViewer( transformationController: _transformationController, - boundaryMargin: const EdgeInsets.all(500), + boundaryMargin: EdgeInsets.all(500), minScale: 0.5, maxScale: 3.0, constrained: false, - child: SizedBox( + child: Container( width: canvasWidth, height: canvasHeight, child: Stack( children: [ - for (final connection in connections) + for (var connection in connections) Opacity( opacity: ConnectionHelper.isHighlightedConnection( connection, widget.selectedSpace) @@ -191,7 +191,7 @@ class _CommunityStructureAreaState extends State { child: CustomPaint( painter: CurvedLinePainter([connection])), ), - for (final entry in spaces.asMap().entries) + for (var entry in spaces.asMap().entries) if (entry.value.status != SpaceStatus.deleted && entry.value.status != SpaceStatus.parentDeleted) Positioned( @@ -214,7 +214,7 @@ class _CommunityStructureAreaState extends State { _updateNodePosition(entry.value, newPosition); }, buildSpaceContainer: (int index) { - final isHighlighted = + final bool isHighlighted = SpaceHelper.isHighlightedSpace( spaces[index], widget.selectedSpace); @@ -267,9 +267,9 @@ class _CommunityStructureAreaState extends State { canvasHeight += 200; } if (node.position.dx <= 200) { - const double shiftAmount = 200; + double shiftAmount = 200; canvasWidth += shiftAmount; - for (final n in spaces) { + for (var n in spaces) { n.position = Offset(n.position.dx + shiftAmount, n.position.dy); } } @@ -280,7 +280,7 @@ class _CommunityStructureAreaState extends State { } void _adjustCanvasSizeForSpaces() { - for (final space in spaces) { + for (var space in spaces) { if (space.position.dx >= canvasWidth - 200) { canvasWidth = space.position.dx + 200; } @@ -324,7 +324,7 @@ class _CommunityStructureAreaState extends State { position ?? ConnectionHelper.getCenterPosition(screenSize); } - final newSpace = SpaceModel( + SpaceModel newSpace = SpaceModel( name: name, icon: icon, position: newPosition, @@ -336,7 +336,7 @@ class _CommunityStructureAreaState extends State { tags: tags); if (parentIndex != null) { - final parentSpace = spaces[parentIndex]; + SpaceModel parentSpace = spaces[parentIndex]; parentSpace.internalId = spaces[parentIndex].internalId; newSpace.parent = parentSpace; final newConnection = Connection( @@ -406,7 +406,7 @@ class _CommunityStructureAreaState extends State { SpaceStatus.modified; // Mark as modified } - for (final space in spaces) { + for (var space in spaces) { if (space.internalId == widget.selectedSpace?.internalId) { space.status = SpaceStatus.modified; space.subspaces = subspaces; @@ -430,8 +430,8 @@ class _CommunityStructureAreaState extends State { } List flattenSpaces(List spaces) { - final result = []; - final idToSpace = {}; + List result = []; + Map idToSpace = {}; void flatten(SpaceModel space) { if (space.status == SpaceStatus.deleted || @@ -441,16 +441,16 @@ class _CommunityStructureAreaState extends State { result.add(space); idToSpace[space.internalId] = space; - for (final child in space.children) { + for (var child in space.children) { flatten(child); } } - for (final space in spaces) { + for (var space in spaces) { flatten(space); } - for (final space in result) { + for (var space in result) { if (space.parent != null) { space.parent = idToSpace[space.parent!.internalId]; } @@ -460,12 +460,12 @@ class _CommunityStructureAreaState extends State { } List createConnections(List spaces) { - final connections = []; + List connections = []; void addConnections(SpaceModel parent, String direction) { if (parent.status == SpaceStatus.deleted) return; - for (final child in parent.children) { + for (var child in parent.children) { if (child.status == SpaceStatus.deleted) continue; connections.add( @@ -480,8 +480,8 @@ class _CommunityStructureAreaState extends State { } } - for (final space in spaces) { - addConnections(space, 'down'); + for (var space in spaces) { + addConnections(space, "down"); } return connections; @@ -492,7 +492,7 @@ class _CommunityStructureAreaState extends State { return; } - final spacesToSave = spaces.where((space) { + List spacesToSave = spaces.where((space) { return space.status == SpaceStatus.newSpace || space.status == SpaceStatus.modified || space.status == SpaceStatus.deleted; @@ -502,7 +502,7 @@ class _CommunityStructureAreaState extends State { return; } - final communityUuid = widget.selectedCommunity!.uuid; + String communityUuid = widget.selectedCommunity!.uuid; context.read().add(SaveSpacesEvent( context, spaces: spacesToSave, @@ -513,7 +513,7 @@ class _CommunityStructureAreaState extends State { void _onDelete() { if (widget.selectedSpace != null) { setState(() { - for (final space in spaces) { + for (var space in spaces) { if (space.internalId == widget.selectedSpace?.internalId) { space.status = SpaceStatus.deleted; _markChildrenAsDeleted(space); @@ -526,7 +526,7 @@ class _CommunityStructureAreaState extends State { } void _markChildrenAsDeleted(SpaceModel parent) { - for (final child in parent.children) { + for (var child in parent.children) { child.status = SpaceStatus.parentDeleted; _markChildrenAsDeleted(child); @@ -543,11 +543,11 @@ class _CommunityStructureAreaState extends State { } void _moveToSpace(SpaceModel space) { - final viewportWidth = MediaQuery.of(context).size.width; - final viewportHeight = MediaQuery.of(context).size.height; + final double viewportWidth = MediaQuery.of(context).size.width; + final double viewportHeight = MediaQuery.of(context).size.height; - final dx = -space.position.dx + (viewportWidth / 2) - 400; - final dy = -space.position.dy + (viewportHeight / 2) - 300; + final double dx = -space.position.dx + (viewportWidth / 2) - 400; + final double dy = -space.position.dy + (viewportHeight / 2) - 300; _transformationController.value = Matrix4.identity() ..translate(dx, dy) @@ -578,10 +578,10 @@ class _CommunityStructureAreaState extends State { return Offset(parent.position.dx, parent.position.dy + verticalGap); } else { // More children → arrange them spaced horizontally - final totalWidth = (parent.children.length) * (nodeWidth + 60); - final startX = parent.position.dx - (totalWidth / 2); + double totalWidth = (parent.children.length) * (nodeWidth + 60); + double startX = parent.position.dx - (totalWidth / 2); - final childX = startX + (parent.children.length * (nodeWidth + 60)); + double childX = startX + (parent.children.length * (nodeWidth + 60)); return Offset(childX, parent.position.dy + verticalGap); } } @@ -599,15 +599,15 @@ class _CommunityStructureAreaState extends State { double calculateSubtreeWidth(SpaceModel node) { if (node.children.isEmpty) return nodeWidth; double totalWidth = 0; - for (final child in node.children) { + for (var child in node.children) { totalWidth += calculateSubtreeWidth(child) + horizontalGap; } return totalWidth - horizontalGap; } void layoutSubtree(SpaceModel node, double startX, double y) { - final subtreeWidth = calculateSubtreeWidth(node); - final centerX = startX + subtreeWidth / 2 - nodeWidth / 2; + double subtreeWidth = calculateSubtreeWidth(node); + double centerX = startX + subtreeWidth / 2 - nodeWidth / 2; node.position = Offset(centerX, y); canvasRightEdge = max(canvasRightEdge, centerX + nodeWidth); @@ -617,9 +617,9 @@ class _CommunityStructureAreaState extends State { final child = node.children.first; layoutSubtree(child, centerX, y + verticalGap); } else { - var childX = startX; - for (final child in node.children) { - final childWidth = calculateSubtreeWidth(child); + double childX = startX; + for (var child in node.children) { + double childWidth = calculateSubtreeWidth(child); layoutSubtree(child, childX, y + verticalGap); childX += childWidth + horizontalGap; } @@ -627,7 +627,7 @@ class _CommunityStructureAreaState extends State { } // ⚡ New: layout each root separately - final roots = spaces + final List roots = spaces .where((s) => s.parent == null && s.status != SpaceStatus.deleted && @@ -635,11 +635,11 @@ class _CommunityStructureAreaState extends State { .toList(); double currentX = 100; // start some margin from left - const double currentY = 100; // top margin + double currentY = 100; // top margin - for (final root in roots) { + for (var root in roots) { layoutSubtree(root, currentX, currentY); - final rootWidth = calculateSubtreeWidth(root); + double rootWidth = calculateSubtreeWidth(root); currentX += rootWidth + rootGap; } @@ -659,7 +659,7 @@ class _CommunityStructureAreaState extends State { return AlertDialog( backgroundColor: ColorsManager.whiteColors, title: Text( - 'Duplicate Space', + "Duplicate Space", textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -671,11 +671,11 @@ class _CommunityStructureAreaState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text('Are you sure you want to duplicate?', + Text("Are you sure you want to duplicate?", textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineSmall), const SizedBox(height: 15), - Text('All the child spaces will be duplicated.', + Text("All the child spaces will be duplicated.", textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -693,7 +693,7 @@ class _CommunityStructureAreaState extends State { onPressed: () { Navigator.of(context).pop(); }, - label: 'Cancel', + label: "Cancel", ), ), const SizedBox(width: 10), @@ -731,16 +731,16 @@ class _CommunityStructureAreaState extends State { void _duplicateSpace(SpaceModel space) { setState(() { - final parent = space.parent; + SpaceModel? parent = space.parent; - final duplicated = _deepCloneSpaceTree(space, parent: parent); + SpaceModel duplicated = _deepCloneSpaceTree(space, parent: parent); duplicated.position = Offset(space.position.dx + 300, space.position.dy + 100); - final duplicatedSubtree = []; + List duplicatedSubtree = []; void collectSubtree(SpaceModel node) { duplicatedSubtree.add(node); - for (final child in node.children) { + for (var child in node.children) { collectSubtree(child); } } @@ -782,7 +782,7 @@ class _CommunityStructureAreaState extends State { parent: parent, ); - for (final child in original.children) { + for (var child in original.children) { final duplicatedChild = _deepCloneSpaceTree(child, parent: newSpace); newSpace.children.add(duplicatedChild); diff --git a/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart index bd8c0a98..2289819b 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/counter_widget.dart @@ -7,10 +7,11 @@ class CounterWidget extends StatefulWidget { final bool isCreate; const CounterWidget( - {super.key, + {Key? key, this.initialCount = 0, required this.onCountChanged, - required this.isCreate}); + required this.isCreate}) + : super(key: key); @override State createState() => _CounterWidgetState(); @@ -54,8 +55,7 @@ class _CounterWidgetState extends State { child: Row( mainAxisSize: MainAxisSize.min, children: [ - _buildCounterButton( - Icons.remove, _decrementCounter, !widget.isCreate), + _buildCounterButton(Icons.remove, _decrementCounter,!widget.isCreate ), const SizedBox(width: 8), Text( '$_counter', @@ -69,15 +69,12 @@ class _CounterWidgetState extends State { ); } - Widget _buildCounterButton( - IconData icon, VoidCallback onPressed, bool isDisabled) { + Widget _buildCounterButton(IconData icon, VoidCallback onPressed, bool isDisabled) { return GestureDetector( - onTap: isDisabled ? null : onPressed, + onTap: isDisabled? null: onPressed, child: Icon( icon, - color: isDisabled - ? ColorsManager.spaceColor.withValues(alpha: 0.3) - : ColorsManager.spaceColor, + color: isDisabled? ColorsManager.spaceColor.withOpacity(0.3): ColorsManager.spaceColor, size: 18, ), ); diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart index caa71183..94896554 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:syncrow_web/common/edit_chip.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; -import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; + +import '../../../../../common/edit_chip.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../../helper/tag_helper.dart'; +import '../../../space_model/widgets/button_content_widget.dart'; +import '../../model/subspace_model.dart'; +import '../../model/tag.dart'; class DevicesPartWidget extends StatelessWidget { const DevicesPartWidget({ @@ -27,73 +28,73 @@ class DevicesPartWidget extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - if (tags?.isNotEmpty == true || - subspaces?.any((subspace) => subspace.tags?.isNotEmpty == true) == - true) - SizedBox( - width: screenWidth * 0.25, - child: Container( - padding: const EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: ColorsManager.textFieldGreyColor, - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: ColorsManager.textFieldGreyColor, - width: 3.0, // Border width - ), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - // Combine tags from spaceModel and subspaces - ...TagHelper.groupTags([ - ...?tags, - ...?subspaces?.expand((subspace) => subspace.tags ?? []) - ]).entries.map( - (entry) => Chip( - avatar: SizedBox( - width: 24, - height: 24, - child: SvgPicture.asset( - entry.key.icon ?? 'assets/icons/gateway.svg', - fit: BoxFit.contain, + (tags?.isNotEmpty == true || + subspaces?.any( + (subspace) => subspace.tags?.isNotEmpty == true) == + true) + ? SizedBox( + width: screenWidth * 0.25, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: ColorsManager.textFieldGreyColor, + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: ColorsManager.textFieldGreyColor, + width: 3.0, // Border width + ), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + // Combine tags from spaceModel and subspaces + ...TagHelper.groupTags([ + ...?tags, + ...?subspaces?.expand((subspace) => subspace.tags ?? []) + ]).entries.map( + (entry) => Chip( + avatar: SizedBox( + width: 24, + height: 24, + child: SvgPicture.asset( + entry.key.icon ?? 'assets/icons/gateway.svg', + fit: BoxFit.contain, + ), + ), + label: Text( + 'x${entry.value}', // Show count + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: ColorsManager.spaceColor), + ), + backgroundColor: ColorsManager.whiteColors, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: const BorderSide( + color: ColorsManager.spaceColor, + ), + ), ), ), - label: Text( - 'x${entry.value}', // Show count - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(color: ColorsManager.spaceColor), - ), - backgroundColor: ColorsManager.whiteColors, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - side: const BorderSide( - color: ColorsManager.spaceColor, - ), - ), - ), - ), - EditChip(onTap: onEditChip) - ], - ), - ), - ) - else - TextButton( - onPressed: onTextButtonPressed, - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - ), - child: ButtonContentWidget( - icon: Icons.add, - label: 'Add Devices', - disabled: isTagsAndSubspaceModelDisabled, - ), - ) + EditChip(onTap: onEditChip) + ], + ), + ), + ) + : TextButton( + onPressed: onTextButtonPressed, + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + ), + child: ButtonContentWidget( + icon: Icons.add, + label: 'Add Devices', + disabled: isTagsAndSubspaceModelDisabled, + ), + ) ], ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart index 94467180..59a100a3 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/utils/constants/assets.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../../../../utils/constants/assets.dart'; class IconChoosePartWidget extends StatelessWidget { const IconChoosePartWidget({ diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart index ceedad63..cd9ae470 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/utils/constants/assets.dart'; + +import '../../../../../utils/color_manager.dart'; +import '../../../../../utils/constants/assets.dart'; +import '../../../space_model/models/space_template_model.dart'; +import '../../../space_model/widgets/button_content_widget.dart'; class SpaceModelLinkingWidget extends StatelessWidget { const SpaceModelLinkingWidget({ @@ -22,67 +23,66 @@ class SpaceModelLinkingWidget extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - if (selectedSpaceModel == null) - TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - ), - onPressed: onPressed, - child: ButtonContentWidget( - svgAssets: Assets.link, - label: 'Link a space model', - disabled: isSpaceModelDisabled, - ), - ) - else - Container( - width: screenWidth * 0.25, - padding: - const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0), - decoration: BoxDecoration( - color: ColorsManager.boxColor, - borderRadius: BorderRadius.circular(10), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - Chip( - label: Text( - selectedSpaceModel?.modelName ?? '', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: ColorsManager.spaceColor), - ), - backgroundColor: ColorsManager.whiteColors, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - side: const BorderSide( - color: ColorsManager.transparentColor, - width: 0, - ), - ), - deleteIcon: Container( - width: 24, - height: 24, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.lightGrayColor, - width: 1.5, + selectedSpaceModel == null + ? TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + ), + onPressed: onPressed, + child: ButtonContentWidget( + svgAssets: Assets.link, + label: 'Link a space model', + disabled: isSpaceModelDisabled, + ), + ) + : Container( + width: screenWidth * 0.25, + padding: const EdgeInsets.symmetric( + vertical: 10.0, horizontal: 16.0), + decoration: BoxDecoration( + color: ColorsManager.boxColor, + borderRadius: BorderRadius.circular(10), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + Chip( + label: Text( + selectedSpaceModel?.modelName ?? '', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: ColorsManager.spaceColor), ), - ), - child: const Icon( - Icons.close, - size: 16, - color: ColorsManager.lightGrayColor, - ), - ), - onDeleted: onDeleted), - ], - ), - ), + backgroundColor: ColorsManager.whiteColors, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: const BorderSide( + color: ColorsManager.transparentColor, + width: 0, + ), + ), + deleteIcon: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: ColorsManager.lightGrayColor, + width: 1.5, + ), + ), + child: const Icon( + Icons.close, + size: 16, + color: ColorsManager.lightGrayColor, + ), + ), + onDeleted: onDeleted), + ], + ), + ), ], ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart index 5700b9c5..600cb8ad 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; +import '../../../../../utils/color_manager.dart'; class SpaceNameTextfieldWidget extends StatelessWidget { SpaceNameTextfieldWidget({ diff --git a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart index 868eefe5..e518877a 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/common/edit_chip.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; + +import '../../../../../common/edit_chip.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../../space_model/widgets/button_content_widget.dart'; +import '../../../space_model/widgets/subspace_name_label_widget.dart'; +import '../../model/subspace_model.dart'; class SubSpacePartWidget extends StatefulWidget { SubSpacePartWidget({ @@ -29,72 +30,71 @@ class _SubSpacePartWidgetState extends State { Widget build(BuildContext context) { return Column( children: [ - if (widget.subspaces == null || widget.subspaces!.isEmpty) - TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.zero, - overlayColor: ColorsManager.transparentColor, - ), - onPressed: widget.onPressed, - child: ButtonContentWidget( - icon: Icons.add, - label: 'Create Sub Spaces', - disabled: widget.isTagsAndSubspaceModelDisabled, - ), - ) - else - SizedBox( - width: widget.screenWidth * 0.25, - child: Container( - padding: const EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: ColorsManager.textFieldGreyColor, - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: ColorsManager.textFieldGreyColor, - width: 3.0, // Border width + widget.subspaces == null || widget.subspaces!.isEmpty + ? TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + overlayColor: ColorsManager.transparentColor, ), - ), - child: Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: [ - if (widget.subspaces != null) - ...widget.subspaces!.map((subspace) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SubspaceNameDisplayWidget( - text: subspace.subspaceName, - validateName: (updatedName) { - final nameExists = widget.subspaces!.any((s) { - final isSameId = - s.internalId == subspace.internalId; - final isSameName = - s.subspaceName.trim().toLowerCase() == - updatedName.trim().toLowerCase(); + onPressed: widget.onPressed, + child: ButtonContentWidget( + icon: Icons.add, + label: 'Create Sub Spaces', + disabled: widget.isTagsAndSubspaceModelDisabled, + ), + ) + : SizedBox( + width: widget.screenWidth * 0.25, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: ColorsManager.textFieldGreyColor, + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: ColorsManager.textFieldGreyColor, + width: 3.0, // Border width + ), + ), + child: Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: [ + if (widget.subspaces != null) + ...widget.subspaces!.map((subspace) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SubspaceNameDisplayWidget( + text: subspace.subspaceName, + validateName: (updatedName) { + bool nameExists = widget.subspaces!.any((s) { + bool isSameId = + s.internalId == subspace.internalId; + bool isSameName = + s.subspaceName.trim().toLowerCase() == + updatedName.trim().toLowerCase(); - return !isSameId && isSameName; - }); + return !isSameId && isSameName; + }); - return !nameExists; - }, - onNameChanged: (updatedName) { - setState(() { - subspace.subspaceName = updatedName; - }); - }, - ), - ], - ); - }), - EditChip( - onTap: widget.editChipOnTap, - ) - ], - ), - ), - ) + return !nameExists; + }, + onNameChanged: (updatedName) { + setState(() { + subspace.subspaceName = updatedName; + }); + }, + ), + ], + ); + }), + EditChip( + onTap: widget.editChipOnTap, + ) + ], + ), + ), + ) ], ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart index d0c3bd83..d8291110 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart @@ -19,11 +19,15 @@ class CurvedLinePainter extends CustomPainter { return; // Nothing to paint if there are no connections } - for (final connection in connections) { + for (var connection in connections) { // Ensure positions are valid before drawing lines - final start = connection.startSpace.position + + if (connection.endSpace.position == null) { + continue; + } + + Offset start = connection.startSpace.position + const Offset(75, 60); // Center bottom of start space - final end = connection.endSpace.position + + Offset end = connection.endSpace.position + const Offset(75, 0); // Center top of end space // Curved line for down connections diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index f6f7bded..8cf30f7c 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -9,6 +9,7 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_mo import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/devices_part_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/icon_choose_part_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_model_linking_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/space_name_textfield_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/create_space_widgets/sub_space_part_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart'; @@ -98,9 +99,9 @@ class CreateSpaceDialogState extends State { @override Widget build(BuildContext context) { - final isSpaceModelDisabled = tags != null && tags!.isNotEmpty || - subspaces != null && subspaces!.isNotEmpty; - final isTagsAndSubspaceModelDisabled = (selectedSpaceModel != null); + bool isSpaceModelDisabled = (tags != null && tags!.isNotEmpty || + subspaces != null && subspaces!.isNotEmpty); + bool isTagsAndSubspaceModelDisabled = (selectedSpaceModel != null); final screenWidth = MediaQuery.of(context).size.width; return AlertDialog( @@ -297,7 +298,7 @@ class CreateSpaceDialogState extends State { } else if (isNameFieldExist) { return; } else { - final newName = enteredName.isNotEmpty + String newName = enteredName.isNotEmpty ? enteredName : (widget.name ?? ''); if (newName.isNotEmpty) { @@ -380,7 +381,7 @@ class CreateSpaceDialogState extends State { products: products, existingSubSpaces: existingSubSpaces, onSave: (slectedSubspaces, updatedSubSpaces) { - final tagsToAppendToSpace = []; + final List tagsToAppendToSpace = []; if (slectedSubspaces != null && slectedSubspaces.isNotEmpty) { final updatedIds = @@ -389,11 +390,11 @@ class CreateSpaceDialogState extends State { final deletedSubspaces = existingSubSpaces .where((s) => !updatedIds.contains(s.internalId)) .toList(); - for (final s in deletedSubspaces) { + for (var s in deletedSubspaces) { if (s.tags != null) { - for (final tag in s.tags!) { - tag.location = null; - } + s.tags!.forEach( + (tag) => tag.location = null, + ); tagsToAppendToSpace.addAll(s.tags!); } } @@ -402,11 +403,11 @@ class CreateSpaceDialogState extends State { if (existingSubSpaces != null) { final deletedSubspaces = existingSubSpaces; - for (final s in deletedSubspaces) { + for (var s in deletedSubspaces) { if (s.tags != null) { - for (final tag in s.tags!) { - tag.location = null; - } + s.tags!.forEach( + (tag) => tag.location = null, + ); tagsToAppendToSpace.addAll(s.tags!); } } diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart index dd04bec6..27275be1 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/delete_dialogue.dart @@ -2,10 +2,9 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -void showDeleteConfirmationDialog( - BuildContext context, VoidCallback onConfirm, bool isSpace) { - final title = isSpace ? 'Delete Space' : 'Delete Community'; - final subtitle = isSpace +void showDeleteConfirmationDialog(BuildContext context, VoidCallback onConfirm, bool isSpace) { + final String title = isSpace ? 'Delete Space' : 'Delete Community'; + final String subtitle = isSpace ? 'All the data in the space will be lost' : 'All the data in the community will be lost'; @@ -14,8 +13,7 @@ void showDeleteConfirmationDialog( barrierDismissible: false, builder: (BuildContext context) { return Dialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), child: SizedBox( width: 500, child: Container( @@ -43,8 +41,7 @@ void showDeleteConfirmationDialog( showProcessingPopup(context, isSpace, onConfirm); }, style: _dialogButtonStyle(ColorsManager.spaceColor), - child: const Text('Continue', - style: TextStyle(color: ColorsManager.whiteColors)), + child: const Text('Continue', style: TextStyle(color: ColorsManager.whiteColors)), ), ], ), @@ -57,17 +54,15 @@ void showDeleteConfirmationDialog( ); } -void showProcessingPopup( - BuildContext context, bool isSpace, VoidCallback onDelete) { - final title = isSpace ? 'Delete Space' : 'Delete Community'; +void showProcessingPopup(BuildContext context, bool isSpace, VoidCallback onDelete) { + final String title = isSpace ? 'Delete Space' : 'Delete Community'; showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return Dialog( - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), child: SizedBox( width: 500, child: Container( @@ -80,8 +75,7 @@ void showProcessingPopup( const SizedBox(height: 20), _buildDialogTitle(context, title), const SizedBox(height: 10), - _buildDialogSubtitle( - context, 'Are you sure you want to delete?'), + _buildDialogSubtitle(context, 'Are you sure you want to delete?'), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -89,8 +83,7 @@ void showProcessingPopup( ElevatedButton( onPressed: onDelete, style: _dialogButtonStyle(ColorsManager.warningRed), - child: const Text('Delete', - style: TextStyle(color: ColorsManager.whiteColors)), + child: const Text('Delete', style: TextStyle(color: ColorsManager.whiteColors)), ), CancelButton( label: 'Cancel', @@ -111,7 +104,7 @@ Widget _buildWarningIcon() { return Container( width: 50, height: 50, - decoration: const BoxDecoration( + decoration: BoxDecoration( color: ColorsManager.warningRed, shape: BoxShape.circle, ), @@ -130,10 +123,7 @@ Widget _buildDialogSubtitle(BuildContext context, String subtitle) { return Text( subtitle, textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith(color: ColorsManager.grayColor), + style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: ColorsManager.grayColor), ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart index f3c7dda6..1f719b1a 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart @@ -4,7 +4,8 @@ import 'package:syncrow_web/utils/color_manager.dart'; class DuplicateProcessDialog extends StatefulWidget { final VoidCallback onDuplicate; - const DuplicateProcessDialog({required this.onDuplicate, super.key}); + const DuplicateProcessDialog({required this.onDuplicate, Key? key}) + : super(key: key); @override _DuplicateProcessDialogState createState() => _DuplicateProcessDialogState(); @@ -19,7 +20,7 @@ class _DuplicateProcessDialogState extends State { _startDuplication(); } - Future _startDuplication() async { + void _startDuplication() async { WidgetsBinding.instance.addPostFrameCallback((_) { widget.onDuplicate(); }); @@ -54,7 +55,7 @@ class _DuplicateProcessDialogState extends State { ), const SizedBox(height: 15), Text( - 'Duplicating in progress', + "Duplicating in progress", style: Theme.of(context) .textTheme .headlineSmall @@ -69,7 +70,7 @@ class _DuplicateProcessDialogState extends State { ), const SizedBox(height: 15), Text( - 'Duplicating successful', + "Duplicating successful", textAlign: TextAlign.center, style: Theme.of(context) .textTheme diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart index 71b9efef..b2a01988 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart @@ -7,10 +7,10 @@ class IconSelectionDialog extends StatelessWidget { final Function(String selectedIcon) onIconSelected; const IconSelectionDialog({ - super.key, + Key? key, required this.spaceIconList, required this.onIconSelected, - }); + }) : super(key: key); @override Widget build(BuildContext context) { @@ -21,23 +21,21 @@ class IconSelectionDialog extends StatelessWidget { elevation: 0, backgroundColor: ColorsManager.transparentColor, child: Container( - width: screenWidth * 0.44, + width: screenWidth * 0.44, height: screenHeight * 0.45, decoration: BoxDecoration( color: ColorsManager.whiteColors, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( - color: ColorsManager.blackColor - .withValues(alpha: 0.2), // Shadow color + color: ColorsManager.blackColor.withOpacity(0.2), // Shadow color blurRadius: 20, // Spread of the blur offset: const Offset(0, 8), // Offset of the shadow ), ], ), child: AlertDialog( - title: Text('Space Icon', - style: Theme.of(context).textTheme.headlineMedium), + title: Text('Space Icon',style: Theme.of(context).textTheme.headlineMedium), backgroundColor: ColorsManager.whiteColors, content: Container( width: screenWidth * 0.4, diff --git a/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart index e0ca8827..e1d4e11b 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart @@ -28,7 +28,7 @@ class GradientCanvasBorderWidget extends StatelessWidget { begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ - ColorsManager.semiTransparentBlackColor.withValues(alpha: 0.1), + ColorsManager.semiTransparentBlackColor.withOpacity(0.1), ColorsManager.transparentColor, ], ), diff --git a/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart b/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart index e545f26b..49a863b6 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/hoverable_button.dart @@ -8,11 +8,11 @@ class HoverableButton extends StatefulWidget { final VoidCallback onTap; const HoverableButton({ - super.key, + Key? key, required this.iconPath, required this.text, required this.onTap, - }); + }) : super(key: key); @override State createState() => _HoverableButtonState(); @@ -34,17 +34,14 @@ class _HoverableButtonState extends State { child: SizedBox( width: screenWidth * .07, child: Container( - padding: - const EdgeInsets.symmetric(horizontal: 13, vertical: 8), + padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 8), decoration: BoxDecoration( - color: isHovered - ? ColorsManager.warningRed - : ColorsManager.whiteColors, + color: isHovered ? ColorsManager.warningRed : ColorsManager.whiteColors, borderRadius: BorderRadius.circular(16), boxShadow: [ if (isHovered) BoxShadow( - color: ColorsManager.warningRed.withValues(alpha: 0.4), + color: ColorsManager.warningRed.withOpacity(0.4), blurRadius: 8, offset: const Offset(0, 4), ), diff --git a/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart index d2a7c3de..d2c72fa7 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart @@ -81,51 +81,49 @@ class _LoadedSpaceViewState extends State { return Stack( clipBehavior: Clip.none, children: [ - if (widget.shouldNavigateToSpaceModelPage) - Row( - children: [ - SizedBox(width: 300, child: SpaceTreeView(onSelect: () {})), - Expanded( - child: BlocProvider( - create: (context) => SpaceModelBloc( - BlocProvider.of(context), - api: SpaceModelManagementApi(), - initialSpaceModels: widget.spaceModels ?? [], + widget.shouldNavigateToSpaceModelPage + ? Row( + children: [ + SizedBox(width: 300, child: SpaceTreeView(onSelect: () {})), + Expanded( + child: BlocProvider( + create: (context) => SpaceModelBloc( + BlocProvider.of(context), + api: SpaceModelManagementApi(), + initialSpaceModels: widget.spaceModels ?? [], + ), + child: SpaceModelPage( + products: widget.products, + onSpaceModelsUpdated: _onSpaceModelsUpdated, + projectTags: widget.projectTags, + ), + ), ), - child: SpaceModelPage( + ], + ) + : Row( + children: [ + SidebarWidget( + communities: widget.communities, + selectedSpaceUuid: + widget.selectedSpace?.uuid ?? widget.selectedCommunity?.uuid ?? '', + onCreateCommunity: (name, description) { + context.read().add( + CreateCommunityEvent(name, description, context), + ); + }, + ), + CommunityStructureArea( + selectedCommunity: widget.selectedCommunity, + selectedSpace: widget.selectedSpace, + spaces: widget.selectedCommunity?.spaces ?? [], products: widget.products, - onSpaceModelsUpdated: _onSpaceModelsUpdated, + communities: widget.communities, + spaceModels: _spaceModels, projectTags: widget.projectTags, ), - ), + ], ), - ], - ) - else - Row( - children: [ - SidebarWidget( - communities: widget.communities, - selectedSpaceUuid: widget.selectedSpace?.uuid ?? - widget.selectedCommunity?.uuid ?? - '', - onCreateCommunity: (name, description) { - context.read().add( - CreateCommunityEvent(name, description, context), - ); - }, - ), - CommunityStructureArea( - selectedCommunity: widget.selectedCommunity, - selectedSpace: widget.selectedSpace, - spaces: widget.selectedCommunity?.spaces ?? [], - products: widget.products, - communities: widget.communities, - spaceModels: _spaceModels, - projectTags: widget.projectTags, - ), - ], - ), const GradientCanvasBorderWidget(), ], ); diff --git a/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart index 283bffac..7076a580 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart @@ -13,12 +13,12 @@ class SelectedProductsButtons extends StatelessWidget { final BuildContext context; const SelectedProductsButtons({ - super.key, + Key? key, required this.products, required this.selectedProducts, required this.onProductsUpdated, required this.context, - }); + }) : super(key: key); @override Widget build(BuildContext context) { @@ -86,7 +86,9 @@ class SelectedProductsButtons extends StatelessWidget { builder: (context) => AddDeviceWidget( products: products, initialSelectedProducts: selectedProducts, - onProductsSelected: onProductsUpdated, + onProductsSelected: (selectedProductsMap) { + onProductsUpdated(selectedProductsMap); + }, ), ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart index 3e2ad4dd..6149dbda 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart @@ -5,7 +5,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/common/widgets/search_bar.dart'; import 'package:syncrow_web/common/widgets/sidebar_communities_list.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/space_tree/bloc/space_tree_state.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_event.dart'; @@ -19,6 +18,8 @@ import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/cent import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_event.dart'; import 'package:syncrow_web/utils/style.dart'; +import '../../../space_tree/bloc/space_tree_event.dart'; + class SidebarWidget extends StatefulWidget { final List communities; final String? selectedSpaceUuid; @@ -54,15 +55,13 @@ class _SidebarWidgetState extends State { } void _onScroll() { - if (_scrollController.position.pixels >= - _scrollController.position.maxScrollExtent - 100) { + if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 100) { // Trigger pagination event final bloc = context.read(); - if (!bloc.state.paginationIsLoading && - bloc.state.paginationModel.hasNext == true) { + if (!bloc.state.paginationIsLoading && bloc.state.paginationModel?.hasNext == true) { bloc.add( PaginationEvent( - bloc.state.paginationModel, + bloc.state.paginationModel!, bloc.state.communityList, ), ); @@ -135,28 +134,24 @@ class _SidebarWidgetState extends State { communities: filteredCommunities, itemBuilder: (context, index) { if (index == filteredCommunities.length) { - final spaceTreeState = - context.read().state; + final spaceTreeState = context.read().state; if (spaceTreeState.paginationIsLoading) { return const Padding( padding: EdgeInsets.all(8.0), - child: - Center(child: CircularProgressIndicator()), + child: Center(child: CircularProgressIndicator()), ); } else { return const SizedBox.shrink(); } } - return _buildCommunityTile( - context, filteredCommunities[index]); + return _buildCommunityTile(context, filteredCommunities[index]); }, ); }, ), ), - if (spaceTreeState.paginationIsLoading || - spaceTreeState.isSearching) - const Center( + if (spaceTreeState.paginationIsLoading || spaceTreeState.isSearching) + Center( child: CircularProgressIndicator(), ) ], @@ -219,8 +214,7 @@ class _SidebarWidgetState extends State { }); context.read().add( - SelectSpaceEvent( - selectedCommunity: community, selectedSpace: space), + SelectSpaceEvent(selectedCommunity: community, selectedSpace: space), ); }, children: space.children @@ -235,9 +229,8 @@ class _SidebarWidgetState extends State { ); } - void _onAddCommunity() => _selectedId?.isNotEmpty ?? true - ? _clearSelection() - : _showCreateCommunityDialog(); + void _onAddCommunity() => + _selectedId?.isNotEmpty ?? true ? _clearSelection() : _showCreateCommunityDialog(); void _clearSelection() { setState(() => _selectedId = ''); diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart index 344eddd3..7e6e132f 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart'; // Make sure to import your PlusButtonWidget +import 'plus_button_widget.dart'; // Make sure to import your PlusButtonWidget class SpaceCardWidget extends StatelessWidget { final int index; diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart index e43bccd3..6f52eb50 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_container_widget.dart @@ -78,7 +78,7 @@ class SpaceContainerWidget extends StatelessWidget { borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: ColorsManager.lightGrayColor.withValues(alpha: 0.5), + color: ColorsManager.lightGrayColor.withOpacity(0.5), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3), // Shadow position diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart index 1e805cb3..62d8197c 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_widget.dart @@ -27,7 +27,7 @@ class SpaceWidget extends StatelessWidget { borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( - color: ColorsManager.lightGrayColor.withValues(alpha: 0.5), + color: ColorsManager.lightGrayColor.withOpacity(0.5), spreadRadius: 5, blurRadius: 7, offset: const Offset(0, 3), diff --git a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart index 7496eb16..afc0c852 100644 --- a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart +++ b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart @@ -11,7 +11,7 @@ class AssignTagBloc extends Bloc { final initialTags = event.initialTags ?? []; final existingTagCounts = {}; - for (final tag in initialTags) { + for (var tag in initialTags) { if (tag.product != null) { existingTagCounts[tag.product!.uuid] = (existingTagCounts[tag.product!.uuid] ?? 0) + 1; @@ -20,7 +20,7 @@ class AssignTagBloc extends Bloc { final tags = []; - for (final selectedProduct in event.addedProducts) { + for (var selectedProduct in event.addedProducts) { final existingCount = existingTagCounts[selectedProduct.productId] ?? 0; if (selectedProduct.count == 0 || @@ -171,7 +171,7 @@ class AssignTagBloc extends Bloc { List _calculateAvailableTags(List allTags, List selectedTags) { final selectedTagSet = selectedTags - .where((tag) => tag.tag?.trim().isNotEmpty ?? false) + .where((tag) => (tag.tag?.trim().isNotEmpty ?? false)) .map((tag) => tag.tag!.trim()) .toSet(); diff --git a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart index b79fb699..7d81ffdb 100644 --- a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart +++ b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart @@ -1,6 +1,6 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; abstract class AssignTagEvent extends Equatable { const AssignTagEvent(); diff --git a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart index 3fda79bf..53700a33 100644 --- a/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart +++ b/lib/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart @@ -27,8 +27,7 @@ class AssignTagLoaded extends AssignTagState { }); @override - List get props => - [tags, updatedTags, isSaveEnabled, errorMessage ?? '']; + List get props => [tags, updatedTags, isSaveEnabled, errorMessage ?? '']; } class AssignTagError extends AssignTagState { diff --git a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart index 809dff64..21ba141c 100644 --- a/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart +++ b/lib/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart @@ -7,10 +7,11 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag/bloc/assign_tag_state.dart'; -import 'package:syncrow_web/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'widgets/save_add_device_row_widget.dart'; + class AssignTagDialog extends StatelessWidget { final List? products; final List? subspaces; @@ -38,7 +39,7 @@ class AssignTagDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final locations = (subspaces ?? []) + final List locations = (subspaces ?? []) .map((subspace) => subspace.subspaceName) .toList() ..add('Main Space'); diff --git a/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart b/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart index c5b164cf..a81b7ad0 100644 --- a/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart +++ b/lib/pages/spaces_management/assign_tag/views/widgets/save_add_device_row_widget.dart @@ -1,13 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; -import 'package:syncrow_web/pages/common/buttons/default_button.dart'; -import 'package:syncrow_web/pages/spaces_management/add_device_type/views/add_device_type_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; -import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; +import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import '../../../add_device_type/views/add_device_type_widget.dart'; +import '../../../helper/tag_helper.dart'; + class SaveAddDeviceRowWidget extends StatelessWidget { const SaveAddDeviceRowWidget({ super.key, diff --git a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart index 4a6548f8..7df82b5e 100644 --- a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart +++ b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart @@ -3,8 +3,7 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart'; -class AssignTagModelBloc - extends Bloc { +class AssignTagModelBloc extends Bloc { final List projectTags; AssignTagModelBloc(this.projectTags) : super(AssignTagModelInitial()) { @@ -12,29 +11,25 @@ class AssignTagModelBloc final initialTags = event.initialTags; final existingTagCounts = {}; - for (final tag in initialTags) { + for (var tag in initialTags) { if (tag.product != null) { - existingTagCounts[tag.product!.uuid] = - (existingTagCounts[tag.product!.uuid] ?? 0) + 1; + existingTagCounts[tag.product!.uuid] = (existingTagCounts[tag.product!.uuid] ?? 0) + 1; } } final tags = []; - for (final selectedProduct in event.addedProducts) { + for (var selectedProduct in event.addedProducts) { final existingCount = existingTagCounts[selectedProduct.productId] ?? 0; - if (selectedProduct.count == 0 || - selectedProduct.count <= existingCount) { - tags.addAll(initialTags - .where((tag) => tag.product?.uuid == selectedProduct.productId)); + if (selectedProduct.count == 0 || selectedProduct.count <= existingCount) { + tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId)); continue; } final missingCount = selectedProduct.count - existingCount; - tags.addAll(initialTags - .where((tag) => tag.product?.uuid == selectedProduct.productId)); + tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId)); if (missingCount > 0) { tags.addAll(List.generate( @@ -59,8 +54,7 @@ class AssignTagModelBloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && - currentState.tags.isNotEmpty) { + if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { final tags = List.from(currentState.tags); if (event.index < 0 || event.index >= tags.length) return; @@ -87,12 +81,10 @@ class AssignTagModelBloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && - currentState.tags.isNotEmpty) { + if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { final tags = List.from(currentState.tags); // Use copyWith for immutability - tags[event.index] = - tags[event.index].copyWith(location: event.location); + tags[event.index] = tags[event.index].copyWith(location: event.location); final updatedTags = _calculateAvailableTags(projectTags, tags); @@ -108,8 +100,7 @@ class AssignTagModelBloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && - currentState.tags.isNotEmpty) { + if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { final tags = List.from(currentState.tags); emit(AssignTagModelLoaded( @@ -124,10 +115,8 @@ class AssignTagModelBloc on((event, emit) { final currentState = state; - if (currentState is AssignTagModelLoaded && - currentState.tags.isNotEmpty) { - final tags = List.from(currentState.tags) - ..remove(event.tagToDelete); + if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) { + final tags = List.from(currentState.tags)..remove(event.tagToDelete); final updatedTags = _calculateAvailableTags(projectTags, tags); @@ -151,10 +140,8 @@ class AssignTagModelBloc String? _getValidationError(List tags) { // Check for duplicate tags - final nonEmptyTags = tags - .map((tag) => tag.tag?.trim() ?? '') - .where((tag) => tag.isNotEmpty) - .toList(); + final nonEmptyTags = + tags.map((tag) => tag.tag?.trim() ?? '').where((tag) => tag.isNotEmpty).toList(); final duplicateTags = nonEmptyTags .fold>({}, (map, tag) { @@ -175,13 +162,12 @@ class AssignTagModelBloc List _calculateAvailableTags(List allTags, List selectedTags) { final selectedTagSet = selectedTags - .where((tag) => tag.tag?.trim().isNotEmpty ?? false) + .where((tag) => (tag.tag?.trim().isNotEmpty ?? false)) .map((tag) => tag.tag!.trim()) .toSet(); final availableTags = allTags - .where((tag) => - tag.tag != null && !selectedTagSet.contains(tag.tag!.trim())) + .where((tag) => tag.tag != null && !selectedTagSet.contains(tag.tag!.trim())) .toList(); return availableTags; diff --git a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart index d62e1523..cb878bde 100644 --- a/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart +++ b/lib/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart @@ -1,6 +1,6 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; abstract class AssignTagModelEvent extends Equatable { const AssignTagModelEvent(); diff --git a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart index 4f0fcee5..57ed93df 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart @@ -6,12 +6,13 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart'; -import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart'; -import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.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/subspace_template_model.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'widgets/RowOfCancelSaveWidget.dart'; +import 'widgets/assign_tags_tables_widget.dart'; + class AssignTagModelsDialog extends StatelessWidget { final List? products; final List? subspaces; @@ -29,7 +30,7 @@ class AssignTagModelsDialog extends StatelessWidget { final List projectTags; const AssignTagModelsDialog( - {super.key, + {Key? key, required this.products, required this.subspaces, required this.addedProducts, @@ -42,11 +43,12 @@ class AssignTagModelsDialog extends StatelessWidget { this.otherSpaceModels, this.spaceModel, this.allSpaceModels, - required this.projectTags}); + required this.projectTags}) + : super(key: key); @override Widget build(BuildContext context) { - final locations = (subspaces ?? []) + final List locations = (subspaces ?? []) .map((subspace) => subspace.subspaceName) .toList() ..add('Main Space'); diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart index 72f8be87..9b2a1367 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart @@ -1,17 +1,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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/spaces_management/all_spaces/model/product_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; -import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart'; -import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart'; -import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.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/subspace_template_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart'; -import 'package:syncrow_web/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; + +import '../../../../../utils/color_manager.dart'; +import '../../../../common/buttons/cancel_button.dart'; +import '../../../../common/buttons/default_button.dart'; +import '../../../all_spaces/model/product_model.dart'; +import '../../../all_spaces/model/tag.dart'; +import '../../../helper/tag_helper.dart'; +import '../../../space_model/models/space_template_model.dart'; +import '../../../space_model/models/subspace_template_model.dart'; +import '../../../space_model/widgets/dialog/create_space_model_dialog.dart'; +import '../../../tag_model/views/add_device_type_model_widget.dart'; +import '../../bloc/assign_tag_model_bloc.dart'; +import '../../bloc/assign_tag_model_state.dart'; class RowOfSaveCancelWidget extends StatelessWidget { const RowOfSaveCancelWidget({ diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart index ee335637..0e17a0d7 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/common/dialog_dropdown.dart'; -import 'package:syncrow_web/common/tag_dialog_textfield_dropdown.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:uuid/uuid.dart'; +import '../../../../../common/dialog_dropdown.dart'; +import '../../../../../common/tag_dialog_textfield_dropdown.dart'; +import '../../../../../utils/color_manager.dart'; + class AssignTagsTable extends StatelessWidget { const AssignTagsTable({ super.key, diff --git a/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart b/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart index e52f09bf..724ed51a 100644 --- a/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart +++ b/lib/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart @@ -1,9 +1,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_event.dart'; -import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_state.dart'; +import 'community_dialog_event.dart'; +import 'community_dialog_state.dart'; -class CommunityDialogBloc - extends Bloc { +class CommunityDialogBloc extends Bloc { final List existingCommunityNames; CommunityDialogBloc(this.existingCommunityNames) diff --git a/lib/pages/spaces_management/create_community/view/create_community_dialog.dart b/lib/pages/spaces_management/create_community/view/create_community_dialog.dart index 9321cc1e..13e676b5 100644 --- a/lib/pages/spaces_management/create_community/view/create_community_dialog.dart +++ b/lib/pages/spaces_management/create_community/view/create_community_dialog.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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/spaces_management/create_community/bloc/community_dialog_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_event.dart'; import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_state.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; class CreateCommunityDialog extends StatelessWidget { final Function(String name, String description) onCreateCommunity; @@ -43,7 +43,7 @@ class CreateCommunityDialog extends StatelessWidget { borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( - color: ColorsManager.blackColor.withValues(alpha: 0.25), + color: ColorsManager.blackColor.withOpacity(0.25), blurRadius: 20, spreadRadius: 5, offset: const Offset(0, 5), @@ -53,8 +53,8 @@ class CreateCommunityDialog extends StatelessWidget { child: SingleChildScrollView( child: BlocBuilder( builder: (context, state) { - var isNameValid = true; - var isNameEmpty = false; + bool isNameValid = true; + bool isNameEmpty = false; if (state is CommunityNameValidationState) { isNameValid = state.isNameValid; @@ -139,7 +139,7 @@ class CreateCommunityDialog extends StatelessWidget { if (isNameValid && !isNameEmpty) { onCreateCommunity( nameController.text.trim(), - '', + "", ); Navigator.of(context).pop(); } diff --git a/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart b/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart index bd14ff61..a2d44553 100644 --- a/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart +++ b/lib/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart @@ -1,9 +1,10 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_state.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart'; +import 'subspace_event.dart'; +import 'subspace_state.dart'; + class SubSpaceBloc extends Bloc { SubSpaceBloc() : super(SubSpaceState([], [], '', {})) { on((event, emit) { @@ -76,7 +77,7 @@ class SubSpaceBloc extends Bloc { emit(SubSpaceState( updatedSubSpaces, updatedSubspaceModels, - errorMessage, + errorMessage , updatedDuplicates, )); }); diff --git a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart index 3e54288d..82df866a 100644 --- a/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart +++ b/lib/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart @@ -5,11 +5,12 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_mo import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_state.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import 'widgets/ok_cancel_sub_space_widget.dart'; +import 'widgets/textfield_sub_space_dialog_widget.dart'; + class CreateSubSpaceDialog extends StatefulWidget { final String dialogTitle; final List? existingSubSpaces; diff --git a/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart index 65bd0193..3952e105 100644 --- a/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart +++ b/lib/pages/spaces_management/create_subspace/views/widgets/ok_cancel_sub_space_widget.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; +import 'package:syncrow_web/utils/color_manager.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/spaces_management/all_spaces/model/subspace_model.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; + +import '../../bloc/subspace_bloc.dart'; +import '../../bloc/subspace_event.dart'; class OkCancelSubSpaceWidget extends StatelessWidget { const OkCancelSubSpaceWidget({ diff --git a/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart b/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart index 7375a228..f655e178 100644 --- a/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart +++ b/lib/pages/spaces_management/create_subspace/views/widgets/textfield_sub_space_dialog_widget.dart @@ -1,13 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_bloc.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace/bloc/subspace_event.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../../all_spaces/model/subspace_model.dart'; +import '../../../create_subspace_model/widgets/subspace_chip.dart'; +import '../../../space_model/models/subspace_template_model.dart'; +import '../../bloc/subspace_bloc.dart'; +import '../../bloc/subspace_event.dart'; + class TextFieldSubSpaceDialogWidget extends StatelessWidget { const TextFieldSubSpaceDialogWidget({ super.key, diff --git a/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart b/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart index 3337ce04..a331aed2 100644 --- a/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart +++ b/lib/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart @@ -60,7 +60,7 @@ class SubSpaceModelBloc extends Bloc { if (event.subSpace.uuid?.isNotEmpty ?? false) { updatedSubspaceModels.add(UpdateSubspaceTemplateModel( action: Action.delete, - uuid: event.subSpace.uuid, + uuid: event.subSpace.uuid!, )); } @@ -104,7 +104,7 @@ class SubSpaceModelBloc extends Bloc { updatedSubspaceModels.add(UpdateSubspaceTemplateModel( action: Action.update, - uuid: event.updatedSubSpace.uuid, + uuid: event.updatedSubSpace.uuid!, )); emit(SubSpaceModelState( diff --git a/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart b/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart index 0a9c9610..098b4804 100644 --- a/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart +++ b/lib/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart @@ -28,8 +28,7 @@ class SubspaceChip extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), side: BorderSide( - color: - isDuplicate ? ColorsManager.red : ColorsManager.transparentColor, + color: isDuplicate ? ColorsManager.red : ColorsManager.transparentColor, width: 0, ), ), diff --git a/lib/pages/spaces_management/helper/space_helper.dart b/lib/pages/spaces_management/helper/space_helper.dart index 45ee9777..4049eb7e 100644 --- a/lib/pages/spaces_management/helper/space_helper.dart +++ b/lib/pages/spaces_management/helper/space_helper.dart @@ -2,20 +2,18 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_m import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; class SpaceHelper { - static SpaceModel? findSpaceByUuid( - String? uuid, List communities) { - for (final community in communities) { - for (final space in community.spaces) { + static SpaceModel? findSpaceByUuid(String? uuid, List communities) { + for (var community in communities) { + for (var space in community.spaces) { if (space.uuid == uuid) return space; } } return null; } - static SpaceModel? findSpaceByInternalId( - String? internalId, List spaces) { + static SpaceModel? findSpaceByInternalId(String? internalId, List spaces) { if (internalId != null) { - for (final space in spaces) { + for (var space in spaces) { if (space.internalId == internalId) return space; } } @@ -23,22 +21,21 @@ class SpaceHelper { return null; } - static String generateUniqueSpaceName( - String originalName, List spaces) { + static String generateUniqueSpaceName(String originalName, List spaces) { final baseName = originalName.replaceAll(RegExp(r'\(\d+\)$'), '').trim(); - var maxNumber = 0; + int maxNumber = 0; - for (final space in spaces) { + for (var space in spaces) { final match = RegExp(r'^(.*?)\((\d+)\)$').firstMatch(space.name); if (match != null && match.group(1)?.trim() == baseName) { - final existingNumber = int.parse(match.group(2)!); + int existingNumber = int.parse(match.group(2)!); if (existingNumber > maxNumber) { maxNumber = existingNumber; } } } - return '$baseName(${maxNumber + 1})'; + return "$baseName(${maxNumber + 1})"; } static bool isSave(List spaces) { @@ -54,13 +51,10 @@ class SpaceHelper { return space == selectedSpace || selectedSpace.parent?.internalId == space.internalId || - selectedSpace.children - .any((child) => child.internalId == space.internalId) == - true; + selectedSpace.children?.any((child) => child.internalId == space.internalId) == true; } - static bool isNameConflict( - String value, SpaceModel? parentSpace, SpaceModel? editSpace) { + static bool isNameConflict(String value, SpaceModel? parentSpace, SpaceModel? editSpace) { final siblings = parentSpace?.children .where((child) => child.internalId != editSpace?.internalId) .toList() ?? @@ -71,19 +65,17 @@ class SpaceHelper { .toList() ?? []; - final editSiblingConflict = - editSiblings.any((child) => child.name == value); + final editSiblingConflict = editSiblings.any((child) => child.name == value); final siblingConflict = siblings.any((child) => child.name == value); - final parentConflict = parentSpace?.name == value && - parentSpace?.internalId != editSpace?.internalId; + final parentConflict = + parentSpace?.name == value && parentSpace?.internalId != editSpace?.internalId; - final parentOfEditSpaceConflict = editSpace?.parent?.name == value && - editSpace?.parent?.internalId != editSpace?.internalId; + final parentOfEditSpaceConflict = + editSpace?.parent?.name == value && editSpace?.parent?.internalId != editSpace?.internalId; - final childConflict = - editSpace?.children.any((child) => child.name == value) ?? false; + final childConflict = editSpace?.children.any((child) => child.name == value) ?? false; return siblingConflict || parentConflict || diff --git a/lib/pages/spaces_management/helper/tag_helper.dart b/lib/pages/spaces_management/helper/tag_helper.dart index f810b8ba..e1dc3cc3 100644 --- a/lib/pages/spaces_management/helper/tag_helper.dart +++ b/lib/pages/spaces_management/helper/tag_helper.dart @@ -24,7 +24,7 @@ class TagHelper { final modifiedSubspaces = List.from(subspaces ?? []); if (subspaces != null) { - for (final subspace in subspaces) { + for (var subspace in subspaces) { getSubspaceTags(subspace)?.removeWhere( (tag) => !modifiedTags.any( (updatedTag) => getInternalId(updatedTag) == getInternalId(tag)), @@ -32,7 +32,7 @@ class TagHelper { } } - for (final tag in modifiedTags.toList()) { + for (var tag in modifiedTags.toList()) { if (modifiedSubspaces.isEmpty) continue; final prevIndice = checkTagExistInSubspace(tag, modifiedSubspaces); @@ -131,7 +131,8 @@ class TagHelper { static List getAvailableTagModels( List allTags, List currentTags, Tag currentTag) { - final availableTagsForTagModel = TagHelper.getAvailableTags( + List availableTagsForTagModel = + TagHelper.getAvailableTags( allTags: allTags, currentTags: currentTags, currentTag: currentTag, @@ -144,14 +145,14 @@ class TagHelper { List? spaceTagModels, List? subspaces, }) { - final initialTags = []; + final List initialTags = []; if (spaceTagModels != null) { initialTags.addAll(spaceTagModels); } if (subspaces != null) { - for (final subspace in subspaces) { + for (var subspace in subspaces) { if (subspace.tags != null) { initialTags.addAll( subspace.tags!.map( @@ -173,14 +174,14 @@ class TagHelper { List? spaceTags, List? subspaces, }) { - final initialTags = []; + final List initialTags = []; if (spaceTags != null) { initialTags.addAll(spaceTags); } if (subspaces != null) { - for (final subspace in subspaces) { + for (var subspace in subspaces) { if (subspace.tags != null) { initialTags.addAll( subspace.tags!.map( @@ -199,8 +200,8 @@ class TagHelper { } static Map groupTags(List tags) { - final groupedTags = {}; - for (final tag in tags) { + final Map groupedTags = {}; + for (var tag in tags) { if (tag.product != null) { final product = tag.product!; groupedTags[product] = (groupedTags[product] ?? 0) + 1; @@ -211,10 +212,10 @@ class TagHelper { static List createInitialSelectedProducts( List? tags, List? subspaces) { - final productCounts = {}; + final Map productCounts = {}; if (tags != null) { - for (final tag in tags) { + for (var tag in tags) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; } @@ -222,9 +223,9 @@ class TagHelper { } if (subspaces != null) { - for (final subspace in subspaces) { + for (var subspace in subspaces) { if (subspace.tags != null) { - for (final tag in subspace.tags!) { + for (var tag in subspace.tags!) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; @@ -246,10 +247,10 @@ class TagHelper { static List createInitialSelectedProductsForTags( List? tags, List? subspaces) { - final productCounts = {}; + final Map productCounts = {}; if (tags != null) { - for (final tag in tags) { + for (var tag in tags) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; } @@ -257,9 +258,9 @@ class TagHelper { } if (subspaces != null) { - for (final subspace in subspaces) { + for (var subspace in subspaces) { if (subspace.tags != null) { - for (final tag in subspace.tags!) { + for (var tag in subspace.tags!) { if (tag.product != null) { productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1; @@ -279,13 +280,14 @@ class TagHelper { .toList(); } - static int? checkTagExistInSubspaceModels(Tag tag, List? subspaces) { + static int? checkTagExistInSubspaceModels( + Tag tag, List? subspaces) { if (subspaces == null) return null; - for (var i = 0; i < subspaces.length; i++) { + for (int i = 0; i < subspaces.length; i++) { final subspace = subspaces[i] as SubspaceTemplateModel; // Explicit cast if (subspace.tags == null) continue; - for (final t in subspace.tags!) { + for (var t in subspace.tags!) { if (tag.internalId == t.internalId) { return i; } @@ -312,11 +314,11 @@ class TagHelper { final processedSubspaces = List.from(result['subspaces'] as List); - for (final subspace in processedSubspaces) { + for (var subspace in processedSubspaces) { final subspaceTags = subspace.tags; if (subspaceTags != null) { - for (var i = 0; i < subspaceTags.length; i++) { + for (int i = 0; i < subspaceTags.length; i++) { final tag = subspaceTags[i]; // Find the updated tag inside processedTags @@ -339,10 +341,10 @@ class TagHelper { static int? checkTagExistInSubspace(Tag tag, List? subspaces) { if (subspaces == null) return null; - for (var i = 0; i < subspaces.length; i++) { + for (int i = 0; i < subspaces.length; i++) { final subspace = subspaces[i]; if (subspace.tags == null) continue; - for (final t in subspace.tags!) { + for (var t in subspace.tags!) { if (tag.internalId == t.internalId) { return i; } @@ -369,11 +371,11 @@ class TagHelper { final processedSubspaces = List.from(result['subspaces'] as List); - for (final subspace in processedSubspaces) { + for (var subspace in processedSubspaces) { final subspaceTags = subspace.tags; if (subspaceTags != null) { - for (var i = 0; i < subspaceTags.length; i++) { + for (int i = 0; i < subspaceTags.length; i++) { final tag = subspaceTags[i]; final changedTag = updatedTags.firstWhere( @@ -395,10 +397,10 @@ class TagHelper { static List getAllTagValues( List communities, List? spaceModels) { - final allTags = {}; + final Set allTags = {}; if (spaceModels != null) { - for (final model in spaceModels) { + for (var model in spaceModels) { allTags.addAll(model.listAllTagValues()); } } diff --git a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart index aab51b59..5b85e17e 100644 --- a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart +++ b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart @@ -26,27 +26,27 @@ class LinkSpaceToModelBloc Future _getSpaceIds(LinkSpaceModelSelectedIdsEvent event, Emitter emit) async { try { - final context = NavigationService.navigatorKey.currentContext!; - final spaceBloc = context.read(); - spacesListIds.clear(); - for (final communityId in spaceBloc.state.selectedCommunities) { - final spacesList = + BuildContext context = NavigationService.navigatorKey.currentContext!; + var spaceBloc = context.read(); + spacesListIds.clear(); + for (var communityId in spaceBloc.state.selectedCommunities) { + List spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; - spacesListIds.addAll(spacesList); + spacesListIds.addAll(spacesList); } hasSelectedSpaces = spaceBloc.state.selectedCommunities.any((communityId) { - final spacesList = + List spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; return spacesList.isNotEmpty; }); if (hasSelectedSpaces) { - debugPrint('At least one space is selected.'); + debugPrint("At least one space is selected."); } else { - debugPrint('No spaces selected.'); + debugPrint("No spaces selected."); } } catch (e) { - debugPrint('Error in _getSpaceIds: $e'); + debugPrint("Error in _getSpaceIds: $e"); } } diff --git a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart index ec358985..ad18b3c7 100644 --- a/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart +++ b/lib/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.dart @@ -5,9 +5,9 @@ abstract class LinkSpaceToModelState { class SpaceModelInitial extends LinkSpaceToModelState {} class SpaceModelLoading extends LinkSpaceToModelState {} - class LinkSpaceModelLoading extends LinkSpaceToModelState {} + class SpaceModelSelectedState extends LinkSpaceToModelState { final int selectedIndex; const SpaceModelSelectedState(this.selectedIndex); diff --git a/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart b/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart index 9e50b881..bbd0de36 100644 --- a/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart +++ b/lib/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart @@ -15,11 +15,11 @@ class LinkSpaceModelDialog extends StatelessWidget { final List spaceModels; const LinkSpaceModelDialog({ - super.key, + Key? key, this.onSave, this.initialSelectedIndex, required this.spaceModels, - }); + }) : super(key: key); @override Widget build(BuildContext context) { @@ -39,10 +39,9 @@ class LinkSpaceModelDialog extends StatelessWidget { color: ColorsManager.textFieldGreyColor, width: MediaQuery.of(context).size.width * 0.7, height: MediaQuery.of(context).size.height * 0.6, - child: BlocBuilder( + child: BlocBuilder( builder: (context, state) { - var selectedIndex = -1; + int selectedIndex = -1; if (state is SpaceModelSelectedState) { selectedIndex = state.selectedIndex; } @@ -73,9 +72,7 @@ class LinkSpaceModelDialog extends StatelessWidget { ), borderRadius: BorderRadius.circular(8.0), ), - child: SpaceModelCardWidget( - model: model, - ), + child: SpaceModelCardWidget(model: model,), ), ); }, diff --git a/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart b/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart index e386b186..5428c343 100644 --- a/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart +++ b/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart @@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_spac 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/space_template_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_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/utils/constants/action_enum.dart'; @@ -20,7 +21,7 @@ class CreateSpaceModelBloc try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - late final spaceTemplate = event.spaceTemplate; + late SpaceTemplateModel spaceTemplate = event.spaceTemplate; final tagBodyModels = spaceTemplate.tags?.map((tag) => tag.toTagBodyModel()).toList() ?? @@ -54,7 +55,7 @@ class CreateSpaceModelBloc } } } catch (e) { - emit(const CreateSpaceModelError('Error creating space model')); + emit(CreateSpaceModelError('Error creating space model')); } }); @@ -64,14 +65,14 @@ class CreateSpaceModelBloc if (_space != null) { emit(CreateSpaceModelLoaded(_space!)); } else { - emit(const CreateSpaceModelError('No space template found')); + emit(CreateSpaceModelError("No space template found")); } }); }); on((event, emit) { _space = event.spaceTemplate; - final errorMessage = _checkDuplicateModelName( + final String? errorMessage = _checkDuplicateModelName( event.allModels ?? [], event.spaceTemplate.modelName); emit(CreateSpaceModelLoaded(_space!, errorMessage: errorMessage)); }); @@ -93,8 +94,9 @@ class CreateSpaceModelBloc orElse: () => subspace, ); + final updatedTags = [ - ...subspace.tags?.map((tag) { + ...?subspace.tags?.map((tag) { final matchingTag = matchingEventSubspace.tags?.firstWhere( (e) => e.internalId == tag.internalId, @@ -106,7 +108,7 @@ class CreateSpaceModelBloc : tag; }) ?? [], - ...matchingEventSubspace.tags?.where( + ...?matchingEventSubspace.tags?.where( (e) => subspace.tags ?.every((t) => t.internalId != e.internalId) ?? @@ -125,7 +127,9 @@ class CreateSpaceModelBloc event.subspaces .where((e) => updatedSubspaces.every((s) => s.internalId != e.internalId)) - .forEach(updatedSubspaces.add); + .forEach((newSubspace) { + updatedSubspaces.add(newSubspace); + }); final updatedSpace = currentState.space.copyWith(subspaceModels: updatedSubspaces); @@ -133,7 +137,7 @@ class CreateSpaceModelBloc emit(CreateSpaceModelLoaded(updatedSpace, errorMessage: currentState.errorMessage)); } else { - emit(const CreateSpaceModelError('Space template not initialized')); + emit(CreateSpaceModelError("Space template not initialized")); } }); @@ -159,12 +163,14 @@ class CreateSpaceModelBloc event.tags .where( (e) => updatedTags.every((t) => t.internalId != e.internalId)) - .forEach(updatedTags.add); + .forEach((e) { + updatedTags.add(e); + }); emit(CreateSpaceModelLoaded( currentState.space.copyWith(tags: updatedTags))); } else { - emit(const CreateSpaceModelError('Space template not initialized')); + emit(CreateSpaceModelError("Space template not initialized")); } }); @@ -174,12 +180,12 @@ class CreateSpaceModelBloc if (event.allModels.contains(event.name) == true) { emit(CreateSpaceModelLoaded( currentState.space, - errorMessage: 'Duplicate Model name', + errorMessage: "Duplicate Model name", )); } else if (event.name.trim().isEmpty) { emit(CreateSpaceModelLoaded( currentState.space, - errorMessage: 'Model name cannot be empty', + errorMessage: "Model name cannot be empty", )); } else { final updatedSpaceModel = @@ -188,7 +194,7 @@ class CreateSpaceModelBloc emit(CreateSpaceModelLoaded(updatedSpaceModel)); } } else { - emit(const CreateSpaceModelError('Space template not initialized')); + emit(CreateSpaceModelError("Space template not initialized")); } }); @@ -205,17 +211,19 @@ class CreateSpaceModelBloc if (prevSpaceModel?.modelName != newSpaceModel.modelName) { spaceModelName = newSpaceModel.modelName; } - var tagUpdates = []; - final subspaceUpdates = []; - final prevSubspaces = prevSpaceModel?.subspaceModels; - final newSubspaces = newSpaceModel.subspaceModels; + List tagUpdates = []; + final List subspaceUpdates = []; + final List? prevSubspaces = + prevSpaceModel?.subspaceModels; + final List? newSubspaces = + newSpaceModel.subspaceModels; tagUpdates = processTagUpdates(prevSpaceModel?.tags, newSpaceModel.tags); if (prevSubspaces != null || newSubspaces != null) { if (prevSubspaces != null && newSubspaces != null) { - for (final prevSubspace in prevSubspaces) { + for (var prevSubspace in prevSubspaces) { final existsInNew = newSubspaces .any((subspace) => subspace.uuid == prevSubspace.uuid); if (!existsInNew) { @@ -224,20 +232,20 @@ class CreateSpaceModelBloc } } } else if (prevSubspaces != null && newSubspaces == null) { - for (final prevSubspace in prevSubspaces) { + for (var prevSubspace in prevSubspaces) { subspaceUpdates.add(UpdateSubspaceTemplateModel( action: Action.delete, uuid: prevSubspace.uuid)); } } if (newSubspaces != null) { - for (final newSubspace in newSubspaces) { + for (var newSubspace in newSubspaces) { // Tag without UUID - if (newSubspace.uuid == null || newSubspace.uuid!.isEmpty) { - final tagUpdates = []; + if ((newSubspace.uuid == null || newSubspace.uuid!.isEmpty)) { + final List tagUpdates = []; if (newSubspace.tags != null) { - for (final tag in newSubspace.tags!) { + for (var tag in newSubspace.tags!) { tagUpdates.add(TagModelUpdate( action: Action.add, newTagUuid: tag.uuid == '' ? null : tag.uuid, @@ -255,14 +263,14 @@ class CreateSpaceModelBloc if (prevSubspaces != null && newSubspaces != null) { final newSubspaceMap = { - for (final subspace in newSubspaces) subspace.uuid: subspace + for (var subspace in newSubspaces) subspace.uuid: subspace }; - for (final prevSubspace in prevSubspaces) { + for (var prevSubspace in prevSubspaces) { final newSubspace = newSubspaceMap[prevSubspace.uuid]; if (newSubspace != null) { - final tagSubspaceUpdates = + final List tagSubspaceUpdates = processTagUpdates(prevSubspace.tags, newSubspace.tags); subspaceUpdates.add(UpdateSubspaceTemplateModel( action: Action.update, @@ -290,7 +298,7 @@ class CreateSpaceModelBloc } } } catch (e) { - emit(const CreateSpaceModelError('Error creating space model')); + emit(CreateSpaceModelError('Error creating space model')); } }); } @@ -299,11 +307,11 @@ class CreateSpaceModelBloc List? prevTags, List? newTags, ) { - final tagUpdates = []; + final List tagUpdates = []; final processedTags = {}; if (prevTags == null && newTags != null) { - for (final newTag in newTags) { + for (var newTag in newTags) { tagUpdates.add(TagModelUpdate( action: Action.add, tag: newTag.tag, @@ -317,7 +325,7 @@ class CreateSpaceModelBloc if (newTags != null || prevTags != null) { // Case 1: Tags deleted if (prevTags != null && newTags != null) { - for (final prevTag in prevTags) { + for (var prevTag in prevTags) { final existsInNew = newTags.any((newTag) => newTag.uuid == prevTag.uuid); if (!existsInNew) { @@ -326,7 +334,7 @@ class CreateSpaceModelBloc } } } else if (prevTags != null && newTags == null) { - for (final prevTag in prevTags) { + for (var prevTag in prevTags) { tagUpdates .add(TagModelUpdate(action: Action.delete, uuid: prevTag.uuid)); } @@ -336,7 +344,7 @@ class CreateSpaceModelBloc if (newTags != null) { final prevTagUuids = prevTags?.map((t) => t.uuid).toSet() ?? {}; - for (final newTag in newTags) { + for (var newTag in newTags) { // Tag without UUID if ((newTag.uuid == null || !prevTagUuids.contains(newTag.uuid)) && !processedTags.contains(newTag.tag)) { @@ -352,9 +360,9 @@ class CreateSpaceModelBloc // Case 3: Tags updated if (prevTags != null && newTags != null) { - final newTagMap = {for (final tag in newTags) tag.uuid: tag}; + final newTagMap = {for (var tag in newTags) tag.uuid: tag}; - for (final prevTag in prevTags) { + for (var prevTag in prevTags) { final newTag = newTagMap[prevTag.uuid]; if (newTag != null) { tagUpdates.add(TagModelUpdate( @@ -373,7 +381,7 @@ class CreateSpaceModelBloc String? _checkDuplicateModelName(List allModels, String name) { if (allModels.contains(name)) { - return 'Duplicate Model name'; + return "Duplicate Model name"; } return null; } diff --git a/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart b/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart index 897bc59c..0d2a3a4f 100644 --- a/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart +++ b/lib/pages/spaces_management/space_model/bloc/create_space_model_event.dart @@ -16,7 +16,7 @@ class UpdateSpaceTemplate extends CreateSpaceModelEvent { final SpaceTemplateModel spaceTemplate; List? allModels; - UpdateSpaceTemplate(this.spaceTemplate, this.allModels); + UpdateSpaceTemplate(this.spaceTemplate,this.allModels); } class CreateSpaceTemplate extends CreateSpaceModelEvent { @@ -36,7 +36,7 @@ class UpdateSpaceTemplateName extends CreateSpaceModelEvent { final String name; final List allModels; - const UpdateSpaceTemplateName({required this.name, required this.allModels}); + UpdateSpaceTemplateName({required this.name, required this.allModels}); @override List get props => [name, allModels]; @@ -45,19 +45,19 @@ class UpdateSpaceTemplateName extends CreateSpaceModelEvent { class AddSubspacesToSpaceTemplate extends CreateSpaceModelEvent { final List subspaces; - const AddSubspacesToSpaceTemplate(this.subspaces); + AddSubspacesToSpaceTemplate(this.subspaces); } class AddTagsToSpaceTemplate extends CreateSpaceModelEvent { final List tags; - const AddTagsToSpaceTemplate(this.tags); + AddTagsToSpaceTemplate(this.tags); } class ValidateSpaceTemplateName extends CreateSpaceModelEvent { final String name; - const ValidateSpaceTemplateName({required this.name}); + ValidateSpaceTemplateName({required this.name}); } class ModifySpaceTemplate extends CreateSpaceModelEvent { @@ -65,7 +65,7 @@ class ModifySpaceTemplate extends CreateSpaceModelEvent { final SpaceTemplateModel updatedSpaceTemplate; final Function(SpaceTemplateModel)? onUpdate; - const ModifySpaceTemplate( + ModifySpaceTemplate( {required this.spaceTemplate, required this.updatedSpaceTemplate, this.onUpdate}); diff --git a/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart b/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart index d28913b5..0fc5c48d 100644 --- a/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart +++ b/lib/pages/spaces_management/space_model/bloc/create_space_model_state.dart @@ -16,7 +16,7 @@ class CreateSpaceModelLoaded extends CreateSpaceModelState { final SpaceTemplateModel space; final String? errorMessage; - const CreateSpaceModelLoaded(this.space, {this.errorMessage}); + CreateSpaceModelLoaded(this.space, {this.errorMessage}); @override List get props => [space, errorMessage]; @@ -25,5 +25,5 @@ class CreateSpaceModelLoaded extends CreateSpaceModelState { class CreateSpaceModelError extends CreateSpaceModelState { final String message; - const CreateSpaceModelError(this.message); + CreateSpaceModelError(this.message); } diff --git a/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart b/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart index 0450d4ec..37a8c0a9 100644 --- a/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart +++ b/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart @@ -21,21 +21,18 @@ class SpaceModelBloc extends Bloc { on(_onDeleteSpaceModel); } - Future _onCreateSpaceModel( - CreateSpaceModel event, Emitter emit) async { + Future _onCreateSpaceModel(CreateSpaceModel event, Emitter emit) async { final currentState = state; if (currentState is SpaceModelLoaded) { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final newSpaceModel = await api.getSpaceModel( - event.newSpaceModel.uuid ?? '', projectUuid); + final newSpaceModel = await api.getSpaceModel(event.newSpaceModel.uuid ?? '', projectUuid); if (newSpaceModel != null) { - final updatedSpaceModels = - List.from(currentState.spaceModels) - ..add(newSpaceModel); + final updatedSpaceModels = List.from(currentState.spaceModels) + ..add(newSpaceModel); emit(SpaceModelLoaded(spaceModels: updatedSpaceModels)); } } catch (e) { @@ -44,15 +41,13 @@ class SpaceModelBloc extends Bloc { } } - Future _onUpdateSpaceModel( - UpdateSpaceModel event, Emitter emit) async { + Future _onUpdateSpaceModel(UpdateSpaceModel event, Emitter emit) async { final currentState = state; if (currentState is SpaceModelLoaded) { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final newSpaceModel = - await api.getSpaceModel(event.spaceModelUuid, projectUuid); + final newSpaceModel = await api.getSpaceModel(event.spaceModelUuid, projectUuid); if (newSpaceModel != null) { final updatedSpaceModels = currentState.spaceModels.map((model) { return model.uuid == event.spaceModelUuid ? newSpaceModel : model; @@ -66,16 +61,14 @@ class SpaceModelBloc extends Bloc { } } - Future _onDeleteSpaceModel( - DeleteSpaceModel event, Emitter emit) async { + Future _onDeleteSpaceModel(DeleteSpaceModel event, Emitter emit) async { final currentState = state; if (currentState is SpaceModelLoaded) { try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final deletedSuccessfully = - await api.deleteSpaceModel(event.spaceModelUuid, projectUuid); + final deletedSuccessfully = await api.deleteSpaceModel(event.spaceModelUuid, projectUuid); if (deletedSuccessfully) { final updatedSpaceModels = currentState.spaceModels diff --git a/lib/pages/spaces_management/space_model/models/space_template_model.dart b/lib/pages/spaces_management/space_model/models/space_template_model.dart index 1481dec4..f8926051 100644 --- a/lib/pages/spaces_management/space_model/models/space_template_model.dart +++ b/lib/pages/spaces_management/space_model/models/space_template_model.dart @@ -30,18 +30,19 @@ class SpaceTemplateModel extends Equatable { return SpaceTemplateModel( uuid: json['uuid'] ?? '', createdAt: json['createdAt'] != null - ? DateTime.tryParse(json['createdAt']) + ? DateTime.tryParse(json['createdAt']) : null, internalId: internalId, modelName: json['modelName'] ?? '', subspaceModels: (json['subspaceModels'] as List?) - ?.whereType>() - .map(SubspaceTemplateModel.fromJson) + ?.where((e) => e is Map) + .map((e) => + SubspaceTemplateModel.fromJson(e as Map)) .toList() ?? [], tags: (json['tags'] as List?) - ?.whereType>() // Validate type - .map(Tag.fromJson) + ?.where((item) => item is Map) // Validate type + .map((item) => Tag.fromJson(item as Map)) .toList() ?? [], ); @@ -108,7 +109,7 @@ class UpdateSubspaceTemplateModel { extension SpaceTemplateExtensions on SpaceTemplateModel { List listAllTagValues() { - final tagValues = []; + final List tagValues = []; if (tags != null) { tagValues.addAll( diff --git a/lib/pages/spaces_management/space_model/view/space_model_page.dart b/lib/pages/spaces_management/space_model/view/space_model_page.dart index 69829f4a..eef196be 100644 --- a/lib/pages/spaces_management/space_model/view/space_model_page.dart +++ b/lib/pages/spaces_management/space_model/view/space_model_page.dart @@ -18,10 +18,8 @@ class SpaceModelPage extends StatelessWidget { final List projectTags; const SpaceModelPage( - {super.key, - this.products, - this.onSpaceModelsUpdated, - required this.projectTags}); + {Key? key, this.products, this.onSpaceModelsUpdated, required this.projectTags}) + : super(key: key); @override Widget build(BuildContext context) { @@ -79,8 +77,7 @@ class SpaceModelPage extends StatelessWidget { } // Render existing space model final model = spaceModels[index]; - final otherModel = - List.from(allSpaceModelNames); + final otherModel = List.from(allSpaceModelNames); otherModel.remove(model.modelName); return GestureDetector( onTap: () { @@ -118,10 +115,8 @@ class SpaceModelPage extends StatelessWidget { return Center( child: Text( 'Error: ${state.message}', - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(color: ColorsManager.warningRed), + style: + Theme.of(context).textTheme.bodySmall?.copyWith(color: ColorsManager.warningRed), ), ); } @@ -131,7 +126,7 @@ class SpaceModelPage extends StatelessWidget { } double _calculateChildAspectRatio(BuildContext context) { - final screenWidth = MediaQuery.of(context).size.width; + double screenWidth = MediaQuery.of(context).size.width; if (screenWidth > 1600) { return 1.5; // Decrease to make cards taller } @@ -145,7 +140,7 @@ class SpaceModelPage extends StatelessWidget { } List _getAllTagValues(List spaceModels) { - final allTags = []; + final List allTags = []; for (final spaceModel in spaceModels) { if (spaceModel.tags != null) { allTags.addAll(spaceModel.listAllTagValues()); @@ -155,7 +150,7 @@ class SpaceModelPage extends StatelessWidget { } List _getAllSpaceModelName(List spaceModels) { - final names = []; + final List names = []; for (final spaceModel in spaceModels) { names.add(spaceModel.modelName); } diff --git a/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart b/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart index 23377f7d..20876a39 100644 --- a/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/add_space_model_widget.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class AddSpaceModelWidget extends StatelessWidget { - const AddSpaceModelWidget({super.key}); + const AddSpaceModelWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart b/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart index 303ef187..2cd338e4 100644 --- a/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/button_content_widget.dart @@ -9,12 +9,12 @@ class ButtonContentWidget extends StatelessWidget { final bool disabled; const ButtonContentWidget({ - super.key, + Key? key, this.icon, required this.label, this.svgAssets, this.disabled = false, - }); + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart index 8079ad4a..2a39d67b 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_merge_dialog.dart @@ -45,7 +45,7 @@ class ConfirmMergeDialog extends StatelessWidget { elevation: 3, ), child: Text( - 'Cancel', + "Cancel", style: Theme.of(context) .textTheme .bodyMedium @@ -66,7 +66,7 @@ class ConfirmMergeDialog extends StatelessWidget { elevation: 3, ), child: Text( - 'Ok', + "Ok", style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, fontSize: 16, diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart index 51a555a3..0497b570 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart @@ -56,7 +56,7 @@ class ConfirmOverwriteDialog extends StatelessWidget { elevation: 3, ), child: Text( - 'Cancel', + "Cancel", style: Theme.of(context) .textTheme .bodyMedium @@ -86,7 +86,7 @@ class ConfirmOverwriteDialog extends StatelessWidget { elevation: 3, ), child: Text( - 'Ok', + "Ok", style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, fontSize: 16, diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart index 1a429d4c..70dde231 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart @@ -9,12 +9,13 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_bloc.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/space_model_bloc.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/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/widgets/subspace_model_create_widget.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; + +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart'; import 'package:syncrow_web/services/space_model_mang_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -28,21 +29,22 @@ class CreateSpaceModelDialog extends StatelessWidget { final List projectTags; const CreateSpaceModelDialog( - {super.key, + {Key? key, this.products, this.allTags, this.spaceModel, this.pageContext, this.otherSpaceModels, this.allSpaceModels, - required this.projectTags}); + required this.projectTags}) + : super(key: key); @override Widget build(BuildContext context) { - final spaceModelApi = SpaceModelManagementApi(); + final SpaceModelManagementApi _spaceModelApi = SpaceModelManagementApi(); final screenWidth = MediaQuery.of(context).size.width; - final spaceNameController = TextEditingController( + final TextEditingController spaceNameController = TextEditingController( text: spaceModel?.modelName ?? '', ); @@ -54,7 +56,7 @@ class CreateSpaceModelDialog extends StatelessWidget { child: BlocProvider( create: (_) { final bloc = CreateSpaceModelBloc( - spaceModelApi, + _spaceModelApi, ); if (spaceModel != null) { bloc.add(UpdateSpaceTemplate(spaceModel!, otherSpaceModels)); @@ -69,8 +71,7 @@ class CreateSpaceModelDialog extends StatelessWidget { spaceNameController.addListener(() { bloc.add(UpdateSpaceTemplateName( - name: spaceNameController.text, - allModels: otherSpaceModels ?? [])); + name: spaceNameController.text, allModels: otherSpaceModels ?? [])); }); return bloc; @@ -88,9 +89,7 @@ class CreateSpaceModelDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text( - spaceModel?.uuid == null - ? 'Create New Space Model' - : 'Edit Space Model', + spaceModel?.uuid == null ? 'Create New Space Model' : 'Edit Space Model', style: Theme.of(context) .textTheme .headlineLarge @@ -102,10 +101,8 @@ class CreateSpaceModelDialog extends StatelessWidget { child: TextField( controller: spaceNameController, onChanged: (value) { - context.read().add( - UpdateSpaceTemplateName( - name: value, - allModels: otherSpaceModels ?? [])); + context.read().add(UpdateSpaceTemplateName( + name: value, allModels: otherSpaceModels ?? [])); }, style: Theme.of(context) .textTheme @@ -179,84 +176,55 @@ class CreateSpaceModelDialog extends StatelessWidget { !isNameValid) ? null : () { - final updatedSpaceTemplate = - updatedSpaceModel.copyWith( - modelName: - spaceNameController.text.trim(), + final updatedSpaceTemplate = updatedSpaceModel.copyWith( + modelName: spaceNameController.text.trim(), ); if (updatedSpaceModel.uuid == null) { - context - .read() - .add( + context.read().add( CreateSpaceTemplate( - spaceTemplate: - updatedSpaceTemplate, + spaceTemplate: updatedSpaceTemplate, onCreate: (newModel) { if (pageContext != null) { + pageContext!.read().add( + CreateSpaceModel(newSpaceModel: newModel)); pageContext! - .read() - .add(CreateSpaceModel( - newSpaceModel: - newModel)); - pageContext! - .read< - SpaceManagementBloc>() - .add( - UpdateSpaceModelCache( - newModel)); + .read() + .add(UpdateSpaceModelCache(newModel)); } - Navigator.of(context) - .pop(); // Close the dialog + Navigator.of(context).pop(); // Close the dialog }, ), ); } else { if (pageContext != null) { - final currentState = pageContext! - .read() - .state; - if (currentState - is SpaceModelLoaded) { - final spaceModels = - List.from( - currentState.spaceModels); + final currentState = + pageContext!.read().state; + if (currentState is SpaceModelLoaded) { + final spaceModels = List.from( + currentState.spaceModels); - final currentSpaceModel = - spaceModels - .cast() - .firstWhere( - (sm) => - sm?.uuid == - updatedSpaceModel - .uuid, + final SpaceTemplateModel? currentSpaceModel = + spaceModels.cast().firstWhere( + (sm) => sm?.uuid == updatedSpaceModel.uuid, orElse: () => null, ); if (currentSpaceModel != null) { context .read() .add(ModifySpaceTemplate( - spaceTemplate: - currentSpaceModel, - updatedSpaceTemplate: - updatedSpaceTemplate, + spaceTemplate: currentSpaceModel, + updatedSpaceTemplate: updatedSpaceTemplate, onUpdate: (newModel) { - if (pageContext != - null) { - pageContext! - .read< - SpaceModelBloc>() - .add(UpdateSpaceModel( + if (pageContext != null) { + pageContext!.read().add( + UpdateSpaceModel( spaceModelUuid: - newModel.uuid ?? - '')); + newModel.uuid ?? '')); pageContext! - .read< - SpaceManagementBloc>() - .add(UpdateSpaceModelCache( - newModel)); + .read() + .add(UpdateSpaceModelCache(newModel)); } - Navigator.of(context) - .pop(); + Navigator.of(context).pop(); })); } } @@ -265,11 +233,11 @@ class CreateSpaceModelDialog extends StatelessWidget { }, backgroundColor: ColorsManager.secondaryColor, borderRadius: 10, - foregroundColor: ((state.errorMessage != null && - state.errorMessage != '') || - !isNameValid) - ? ColorsManager.whiteColorsWithOpacity - : ColorsManager.whiteColors, + foregroundColor: + ((state.errorMessage != null && state.errorMessage != '') || + !isNameValid) + ? ColorsManager.whiteColorsWithOpacity + : ColorsManager.whiteColors, child: const Text('OK'), ), ), diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart index 8313360c..e0260887 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart @@ -1,10 +1,9 @@ import 'dart:math'; - import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart'; + class CustomLoadingIndicator extends StatefulWidget { - const CustomLoadingIndicator({super.key}); - @override _CustomLoadingIndicatorState createState() => _CustomLoadingIndicatorState(); } @@ -51,22 +50,22 @@ class _CustomLoadingIndicatorState extends State class LoadingPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final paint = Paint() + final Paint paint = Paint() ..strokeWidth = 5 ..strokeCap = StrokeCap.round ..style = PaintingStyle.stroke; - final radius = size.width / 2; - final center = Offset(size.width / 2, size.height / 2); + final double radius = size.width / 2; + final Offset center = Offset(size.width / 2, size.height / 2); - for (var i = 0; i < 12; i++) { - final angle = (i * 30) * (pi / 180); - final startX = center.dx + radius * cos(angle); - final startY = center.dy + radius * sin(angle); - final endX = center.dx + (radius - 8) * cos(angle); - final endY = center.dy + (radius - 8) * sin(angle); + for (int i = 0; i < 12; i++) { + final double angle = (i * 30) * (pi / 180); + final double startX = center.dx + radius * cos(angle); + final double startY = center.dy + radius * sin(angle); + final double endX = center.dx + (radius - 8) * cos(angle); + final double endY = center.dy + (radius - 8) * sin(angle); - paint.color = Colors.blue.withValues(alpha: i / 12); // Gradient effect + paint.color = Colors.blue.withOpacity(i / 12); // Gradient effect canvas.drawLine(Offset(startX, startY), Offset(endX, endY), paint); } } diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart index c5a11c4a..8349baa4 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart @@ -6,7 +6,8 @@ import 'package:syncrow_web/utils/color_manager.dart'; class DeleteSpaceModelDialog extends StatelessWidget { final VoidCallback onConfirmDelete; - const DeleteSpaceModelDialog({super.key, required this.onConfirmDelete}); + const DeleteSpaceModelDialog({Key? key, required this.onConfirmDelete}) + : super(key: key); @override Widget build(BuildContext context) { @@ -19,7 +20,7 @@ class DeleteSpaceModelDialog extends StatelessWidget { backgroundColor: ColorsManager.whiteColors, title: Center( child: Text( - 'Delete Space Model', + "Delete Space Model", textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -33,13 +34,13 @@ class DeleteSpaceModelDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text( - 'Are you sure you want to delete?', + "Are you sure you want to delete?", textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 15), Text( - 'The existing sub-spaces, devices, and routines will remain associated with the spaces, but the connection will be removed.', + "The existing sub-spaces, devices, and routines will remain associated with the spaces, but the connection will be removed.", textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -59,7 +60,7 @@ class DeleteSpaceModelDialog extends StatelessWidget { onPressed: () { Navigator.of(context).pop(); // Close dialog }, - label: 'Cancel', + label: "Cancel", ), ), const SizedBox(width: 10), diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart index 8a4b1a67..4da0c642 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart @@ -47,9 +47,9 @@ class _LinkSpaceModelSpacesDialogState Widget _buildDialogContent() { widget.spaceModel.createdAt.toString(); - final formattedDate = + String formattedDate = DateFormat('yyyy-MM-dd').format(widget.spaceModel.createdAt!); - final formattedTime = + String formattedTime = DateFormat('HH:mm:ss').format(widget.spaceModel.createdAt!); return Expanded( @@ -70,7 +70,7 @@ class _LinkSpaceModelSpacesDialogState children: [ const Center( child: Text( - 'Link Space Model to Spaces', + "Link Space Model to Spaces", style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, @@ -81,21 +81,22 @@ class _LinkSpaceModelSpacesDialogState const Divider(), const SizedBox(height: 16), _buildDetailRow( - 'Space model name:', widget.spaceModel.modelName), + "Space model name:", widget.spaceModel.modelName), Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( children: [ const Expanded( child: Text( - 'Creation date and time:', - style: TextStyle(fontWeight: FontWeight.bold), + "Creation date and time:", + style: const TextStyle( + fontWeight: FontWeight.bold), ), ), const SizedBox(width: 8), Expanded( child: Text( - '$formattedDate $formattedTime', + "$formattedDate $formattedTime", style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.black), @@ -106,14 +107,14 @@ class _LinkSpaceModelSpacesDialogState ), // _buildDetailRow("Creation date and time:", // widget.spaceModel.createdAt.toString()), - _buildDetailRow('Created by:', 'Admin'), + _buildDetailRow("Created by:", "Admin"), const SizedBox(height: 12), const Text( - 'Link to:', + "Link to:", style: TextStyle(fontWeight: FontWeight.bold), ), const Text( - 'Please select all the spaces where you would like to link the Routine.', + "Please select all the spaces where you would like to link the Routine.", style: TextStyle(fontSize: 12, color: Colors.grey), ), const SizedBox(height: 8), @@ -123,7 +124,7 @@ class _LinkSpaceModelSpacesDialogState children: [ Expanded( flex: 7, - child: ColoredBox( + child: Container( color: ColorsManager.whiteColors, child: SpaceTreeView( isSide: true, @@ -169,7 +170,7 @@ class _LinkSpaceModelSpacesDialogState ), ), ), - child: _buildButton('Cancel', Colors.grey, () { + child: _buildButton("Cancel", Colors.grey, () { Navigator.of(context).pop(); }), ), @@ -190,14 +191,14 @@ class _LinkSpaceModelSpacesDialogState ), ), child: _buildButton( - 'Confirm', + "Confirm", ColorsManager.onSecondaryColor, () { final spaceModelBloc = context.read(); if (!spaceModelBloc.hasSelectedSpaces) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( - content: Text('Please select at least one space')), + content: Text("Please select at least one space")), ); return; } else { diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart index d16f2c7e..15d92029 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart @@ -62,7 +62,7 @@ class LinkingAttentionDialog extends StatelessWidget { elevation: 3, ), child: Text( - 'Overwrite', + "Overwrite", style: Theme.of(context) .textTheme .bodyMedium @@ -93,7 +93,7 @@ class LinkingAttentionDialog extends StatelessWidget { elevation: 3, ), child: Text( - 'Merge', + "Merge", style: Theme.of(context) .textTheme .bodyMedium diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart index ca8f3aeb..9f57a4b1 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart @@ -23,7 +23,7 @@ void showOverwriteDialog( mainAxisSize: MainAxisSize.min, children: [ const Text( - 'Overwrite', + "Overwrite", style: TextStyle( fontSize: 22, fontWeight: FontWeight.bold, @@ -32,13 +32,13 @@ void showOverwriteDialog( ), const SizedBox(height: 15), const Text( - 'Are you sure you want to overwrite?', + "Are you sure you want to overwrite?", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), textAlign: TextAlign.center, ), const SizedBox(height: 5), Text( - 'Selected spaces already have linked space model / sub-spaces and devices', + "Selected spaces already have linked space model / sub-spaces and devices", style: TextStyle( fontSize: 14, color: Colors.grey[600], @@ -61,7 +61,7 @@ void showOverwriteDialog( elevation: 0, ), child: const Text( - 'Cancel', + "Cancel", style: TextStyle( fontSize: 16, color: Colors.black, @@ -88,7 +88,7 @@ void showOverwriteDialog( elevation: 3, ), child: const Text( - 'OK', + "OK", style: TextStyle( fontSize: 16, color: Colors.white, diff --git a/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart b/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart index 475b24ed..4f42e3bf 100644 --- a/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart @@ -10,28 +10,28 @@ class DynamicProductWidget extends StatelessWidget { final double maxHeight; const DynamicProductWidget({ - super.key, + Key? key, required this.productTagCount, required this.maxWidth, required this.maxHeight, - }); + }) : super(key: key); @override Widget build(BuildContext context) { - const itemSpacing = 8.0; - const lineSpacing = 8.0; - const textPadding = 16.0; - const itemHeight = 40.0; + const double itemSpacing = 8.0; + const double lineSpacing = 8.0; + const double textPadding = 16.0; + const double itemHeight = 40.0; - final productWidgets = []; - var currentLineWidth = 0.0; - var currentHeight = itemHeight; + List productWidgets = []; + double currentLineWidth = 0.0; + double currentHeight = itemHeight; for (final product in productTagCount.entries) { - final prodType = product.key; - final count = product.value; + final String prodType = product.key; + final int count = product.value; - final textPainter = TextPainter( + final TextPainter textPainter = TextPainter( text: TextSpan( text: 'x$count', style: Theme.of(context) @@ -42,7 +42,7 @@ class DynamicProductWidget extends StatelessWidget { textDirection: TextDirection.ltr, )..layout(); - final itemWidth = textPainter.width + textPadding + 20; + final double itemWidth = textPainter.width + textPadding + 20; if (currentLineWidth + itemWidth + itemSpacing > maxWidth) { currentHeight += itemHeight + lineSpacing; diff --git a/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart b/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart index d9610ff9..f3da4122 100644 --- a/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart @@ -8,37 +8,38 @@ class DynamicRoomWidget extends StatelessWidget { final double maxHeight; const DynamicRoomWidget({ - super.key, + Key? key, required this.subspaceModels, required this.maxWidth, required this.maxHeight, - }); + }) : super(key: key); @override Widget build(BuildContext context) { - const itemSpacing = 8.0; - const lineSpacing = 8.0; - const textPadding = 16.0; - const itemHeight = 30.0; + const double itemSpacing = 8.0; + const double lineSpacing = 8.0; + const double textPadding = 16.0; + const double itemHeight = 30.0; - final roomWidgets = []; - var currentLineWidth = 0.0; - var currentHeight = itemHeight; + List roomWidgets = []; + double currentLineWidth = 0.0; + double currentHeight = itemHeight; for (final subspace in subspaceModels!) { - final textPainter = TextPainter( + final TextPainter textPainter = TextPainter( text: TextSpan( - text: subspace.subspaceName, - style: Theme.of(context).textTheme.bodyMedium), + text: subspace.subspaceName, + style: Theme.of(context).textTheme.bodyMedium + ), textDirection: TextDirection.ltr, )..layout(); - final itemWidth = textPainter.width + textPadding; + final double itemWidth = textPainter.width + textPadding; if (currentLineWidth + itemWidth + itemSpacing > maxWidth) { currentHeight += itemHeight + lineSpacing; if (currentHeight > maxHeight) { - roomWidgets.add(const RoomNameWidget(name: '...')); + roomWidgets.add(const RoomNameWidget(name: "...")); break; } currentLineWidth = 0.0; diff --git a/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart b/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart index 8b3f2965..7ede09a7 100644 --- a/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class EllipsisItemWidget extends StatelessWidget { - const EllipsisItemWidget({super.key}); + const EllipsisItemWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -14,7 +14,7 @@ class EllipsisItemWidget extends StatelessWidget { border: Border.all(color: ColorsManager.transparentColor), ), child: Text( - '...', + "...", style: Theme.of(context) .textTheme .bodySmall diff --git a/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart b/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart index aea3b56a..c28a82b8 100644 --- a/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/flexible_item_widget.dart @@ -7,10 +7,10 @@ class FlexibleItemWidget extends StatelessWidget { final int count; const FlexibleItemWidget({ - super.key, + Key? key, required this.prodType, required this.count, - }); + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart b/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart index 7ba1b095..d59f8c1e 100644 --- a/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/room_name_widget.dart @@ -4,7 +4,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; class RoomNameWidget extends StatelessWidget { final String name; - const RoomNameWidget({super.key, required this.name}); + const RoomNameWidget({Key? key, required this.name}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart index 67a72268..4d72a419 100644 --- a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.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_event.dart'; import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_to_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_to_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_to_model_state.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_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/delete_space_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -27,27 +27,27 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { final bool topActionsDisabled; const SpaceModelCardWidget({ - super.key, + Key? key, required this.model, this.pageContext, this.topActionsDisabled = true, - }); + }) : super(key: key); @override Widget build(BuildContext context) { - final productTagCount = {}; + final Map productTagCount = {}; if (model.tags != null) { - for (final tag in model.tags!) { + for (var tag in model.tags!) { final prodIcon = tag.product?.icon ?? 'Unknown'; productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1; } } if (model.subspaceModels != null) { - for (final subspace in model.subspaceModels!) { + for (var subspace in model.subspaceModels!) { if (subspace.tags != null) { - for (final tag in subspace.tags!) { + for (var tag in subspace.tags!) { final prodIcon = tag.product?.icon ?? 'Unknown'; productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1; } @@ -57,7 +57,7 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { return LayoutBuilder( builder: (context, constraints) { - final showOnlyName = constraints.maxWidth < 250; + bool showOnlyName = constraints.maxWidth < 250; return Container( padding: const EdgeInsets.all(16.0), decoration: BoxDecoration( @@ -65,7 +65,7 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( - color: Colors.grey.withValues(alpha: 0.5), + color: Colors.grey.withOpacity(0.5), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3), @@ -81,12 +81,11 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { Expanded( child: Text( StringUtils.capitalizeFirstLetter(model.modelName), - style: - Theme.of(context).textTheme.headlineMedium?.copyWith( - color: ColorsManager.blackColor, - fontWeight: FontWeight.bold, - fontSize: isSmallScreenSize(context) ? 13 : 20, - ), + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + color: ColorsManager.blackColor, + fontWeight: FontWeight.bold, + fontSize: isSmallScreenSize(context) ? 13 : 20, + ), maxLines: 2, overflow: TextOverflow.ellipsis, ), @@ -101,15 +100,12 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { builder: (BuildContext dialogContext) { return BlocProvider( create: (_) => LinkSpaceToModelBloc(), - child: BlocListener( + child: BlocListener( listenWhen: (previous, current) { return previous != current; }, listener: (context, state) { - final bloc = - BlocProvider.of( - context); + final _bloc = BlocProvider.of(context); if (state is SpaceModelLoading) { showDialog( context: context, @@ -117,18 +113,14 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { builder: (BuildContext context) { return Dialog( shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular( - 20)), + borderRadius: BorderRadius.circular(20)), elevation: 10, backgroundColor: Colors.white, - child: const Padding( - padding: EdgeInsets.symmetric( - vertical: 30, - horizontal: 50), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 30, horizontal: 50), child: Column( - mainAxisSize: - MainAxisSize.min, + mainAxisSize: MainAxisSize.min, children: [ CustomLoadingIndicator(), ], @@ -137,19 +129,14 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { ); }, ); - } else if (state - is AlreadyHaveLinkedState) { + } else if (state is AlreadyHaveLinkedState) { Navigator.of(dialogContext).pop(); - showOverwriteDialog( - context, bloc, model); - } else if (state - is SpaceValidationSuccess) { - bloc.add(LinkSpaceModelEvent( - isOverWrite: false, - selectedSpaceMode: model.uuid)); + showOverwriteDialog(context, _bloc, model); + } else if (state is SpaceValidationSuccess) { + _bloc.add(LinkSpaceModelEvent( + isOverWrite: false, selectedSpaceMode: model.uuid)); - Future.delayed( - const Duration(seconds: 1), () { + Future.delayed(const Duration(seconds: 1), () { Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop(); @@ -157,29 +144,23 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { showDialog( context: context, - builder: - (BuildContext dialogContext) { + builder: (BuildContext dialogContext) { return const LinkingSuccessful(); }, ).then((v) { - Future.delayed( - const Duration(seconds: 2), () { + Future.delayed(const Duration(seconds: 2), () { Navigator.of(dialogContext).pop(); }); }); - } else if (state - is SpaceModelLinkSuccess) { + } else if (state is SpaceModelLinkSuccess) { Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop(); showDialog( context: context, barrierDismissible: false, - builder: (BuildContext - successDialogContext) { - Future.delayed( - const Duration(seconds: 2), () { - Navigator.of(successDialogContext) - .pop(); + builder: (BuildContext successDialogContext) { + Future.delayed(const Duration(seconds: 2), () { + Navigator.of(successDialogContext).pop(); }); return const LinkingSuccessful(); @@ -237,8 +218,7 @@ class SpaceModelCardWidget extends StatelessWidget with HelperResponsiveLayout { ), ), ), - if (productTagCount.isNotEmpty && - model.subspaceModels != null) + if (productTagCount.isNotEmpty && model.subspaceModels != null) Container( width: 1.0, color: ColorsManager.softGray, diff --git a/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart b/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart index 0d66dbac..70ac6e24 100644 --- a/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart @@ -5,9 +5,9 @@ class SubspaceChipWidget extends StatelessWidget { final String subspace; const SubspaceChipWidget({ - super.key, + Key? key, required this.subspace, - }); + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart b/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart index 5cb4a9ff..4ebd65df 100644 --- a/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/subspace_model_create_widget.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/common/edit_chip.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; -import 'package:syncrow_web/pages/spaces_management/create_subspace_model/views/create_subspace_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/create_subspace_model/views/create_subspace_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -15,11 +15,11 @@ class SubspaceModelCreate extends StatefulWidget { final List tags; const SubspaceModelCreate({ - super.key, + Key? key, required this.subspaces, this.onSpaceModelUpdate, required this.tags, - }); + }) : super(key: key); @override _SubspaceModelCreateState createState() => _SubspaceModelCreateState(); @@ -117,9 +117,9 @@ class _SubspaceModelCreateState extends State { .where((s) => !updatedIds.contains(s.internalId)) .toList(); - final tagsToAppendToSpace = []; + final List tagsToAppendToSpace = []; - for (final s in deletedSubspaces) { + for (var s in deletedSubspaces) { if (s.tags != null) { tagsToAppendToSpace.addAll(s.tags!); } diff --git a/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart b/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart index c27a1436..6a6aec44 100644 --- a/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/subspace_name_label_widget.dart @@ -12,7 +12,7 @@ class SubspaceNameDisplayWidget extends StatefulWidget { final bool Function(String updatedName) validateName; const SubspaceNameDisplayWidget({ - super.key, + Key? key, required this.text, this.textStyle, this.backgroundColor = ColorsManager.whiteColors, @@ -21,7 +21,7 @@ class SubspaceNameDisplayWidget extends StatefulWidget { this.borderRadius = const BorderRadius.all(Radius.circular(10)), required this.onNameChanged, required this.validateName, - }); + }) : super(key: key); @override _SubspaceNameDisplayWidgetState createState() => diff --git a/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart b/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart index 2ff1b085..86f99e02 100644 --- a/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/tag_chips_display_widget.dart @@ -50,8 +50,7 @@ class TagChipDisplay extends StatelessWidget { Widget build(BuildContext context) { final hasTags = spaceModel?.tags?.isNotEmpty ?? false; final hasSubspaceTags = - spaceModel?.subspaceModels?.any((e) => e.tags?.isNotEmpty ?? false) ?? - false; + spaceModel?.subspaceModels?.any((e) => e.tags?.isNotEmpty ?? false) ?? false; if (hasTags || hasSubspaceTags) { return Container( diff --git a/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart b/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart index 23cfb1d9..1de2ae13 100644 --- a/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart +++ b/lib/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart @@ -13,7 +13,7 @@ class CenterBodyBloc extends Bloc { emit(SpaceModelState()); }); - on((event, emit) { + on((event, emit) { emit(CommunitySelectedState()); }); } diff --git a/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart b/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart index d70a0b55..72cdbd1c 100644 --- a/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart +++ b/lib/pages/spaces_management/structure_selector/bloc/center_body_event.dart @@ -5,4 +5,4 @@ class CommunityStructureSelectedEvent extends CenterBodyEvent {} class SpaceModelSelectedEvent extends CenterBodyEvent {} -class CommunitySelectedEvent extends CenterBodyEvent {} +class CommunitySelectedEvent extends CenterBodyEvent {} \ No newline at end of file diff --git a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart index 6b0ff481..dbc6c7ef 100644 --- a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart +++ b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart @@ -2,13 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_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_event.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_event.dart'; import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_state.dart'; +import '../bloc/center_body_bloc.dart'; class CenterBodyWidget extends StatelessWidget { - const CenterBodyWidget({super.key}); - @override Widget build(BuildContext context) { return BlocBuilder( @@ -54,7 +52,7 @@ class CenterBodyWidget extends StatelessWidget { .textTheme .bodyLarge! .color! - .withValues(alpha: 0.5), + .withOpacity(0.5), ), ), ), @@ -75,7 +73,7 @@ class CenterBodyWidget extends StatelessWidget { // .textTheme // .bodyLarge! // .color! - // .withValues(alpha:0.5), + // .withOpacity(0.5), // ), // ), // ), diff --git a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart index 5ee52b08..27f183a6 100644 --- a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart +++ b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; @@ -12,7 +13,7 @@ abstract class AddDeviceTypeModelEvent extends Equatable { class UpdateProductCountEvent extends AddDeviceTypeModelEvent { final SelectedProduct selectedProduct; - const UpdateProductCountEvent({required this.selectedProduct}); + UpdateProductCountEvent({required this.selectedProduct}); @override List get props => [selectedProduct]; diff --git a/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart b/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart index e9823fee..c0226ba8 100644 --- a/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart +++ b/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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/spaces_management/all_spaces/model/product_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.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/subspace_template_model.dart'; @@ -80,8 +80,7 @@ class AddDeviceTypeModelWidget extends StatelessWidget { const SizedBox(height: 16), Expanded( child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 20.0), + padding: const EdgeInsets.symmetric(horizontal: 20.0), child: ScrollableGridViewWidget( isCreate: isCreate, products: products, @@ -153,11 +152,10 @@ class AddDeviceTypeModelWidget extends StatelessWidget { ), SizedBox( width: 140, - child: - BlocBuilder( + child: BlocBuilder( builder: (context, state) { - final isDisabled = state is AddDeviceModelLoaded && - state.selectedProducts.isEmpty; + final isDisabled = + state is AddDeviceModelLoaded && state.selectedProducts.isEmpty; return DefaultButton( backgroundColor: ColorsManager.secondaryColor, @@ -170,15 +168,13 @@ class AddDeviceTypeModelWidget extends StatelessWidget { : () async { if (state is AddDeviceModelLoaded && state.selectedProducts.isNotEmpty) { - final initialTags = - TagHelper.generateInitialTags( + final initialTags = TagHelper.generateInitialTags( spaceTagModels: spaceTagModels, subspaces: subspaces, ); - final dialogTitle = initialTags.isNotEmpty - ? 'Edit Device' - : 'Assign Tags'; + final dialogTitle = + initialTags.isNotEmpty ? 'Edit Device' : 'Assign Tags'; Navigator.of(context).pop(); await showDialog( context: context, diff --git a/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart b/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart index 8a64fe41..d1775c66 100644 --- a/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart +++ b/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart @@ -12,12 +12,13 @@ class ScrollableGridViewWidget extends StatelessWidget { final List? initialProductCounts; final bool isCreate; - const ScrollableGridViewWidget( - {super.key, - required this.products, - required this.crossAxisCount, - this.initialProductCounts, - required this.isCreate}); + const ScrollableGridViewWidget({ + super.key, + required this.products, + required this.crossAxisCount, + this.initialProductCounts, + required this.isCreate + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart index 6bcd8b62..438b1abf 100644 --- a/lib/pages/visitor_password/bloc/visitor_password_bloc.dart +++ b/lib/pages/visitor_password/bloc/visitor_password_bloc.dart @@ -14,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/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; +import 'package:syncrow_web/utils/constants/strings_manager.dart'; +import 'package:syncrow_web/utils/constants/temp_const.dart'; +import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; class VisitorPasswordBloc extends Bloc { + VisitorPasswordBloc() : super(VisitorPasswordInitial()) { on(selectUsageFrequency); on(_onFetchDevice); @@ -67,13 +71,13 @@ class VisitorPasswordBloc String startTimeAccess = 'Start Time'; String endTimeAccess = 'End Time'; PasswordStatus? passwordStatus; - void selectAccessType( + selectAccessType( SelectPasswordType event, Emitter emit) { accessTypeSelected = event.type; emit(PasswordTypeSelected(event.type)); } - void selectUsageFrequency( + selectUsageFrequency( SelectUsageFrequency event, Emitter emit) { usageFrequencySelected = event.usageType; emit(UsageFrequencySelected(event.usageType)); @@ -83,7 +87,7 @@ class VisitorPasswordBloc SelectTimeVisitorPassword event, Emitter emit, ) async { - final picked = await showDatePicker( + final DateTime? picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), firstDate: DateTime(2015, 8), @@ -91,7 +95,7 @@ class VisitorPasswordBloc ); if (picked != null) { - final timePicked = await showTimePicker( + final TimeOfDay? timePicked = await showTimePicker( context: event.context, initialTime: TimeOfDay.now(), builder: (context, child) { @@ -160,13 +164,13 @@ class VisitorPasswordBloc } List> days = [ - {'day': 'Sun', 'key': 'Sun'}, - {'day': 'Mon', 'key': 'Mon'}, - {'day': 'Tue', 'key': 'Tue'}, - {'day': 'Wed', 'key': 'Wed'}, - {'day': 'Thu', 'key': 'Thu'}, - {'day': 'Fri', 'key': 'Fri'}, - {'day': 'Sat', 'key': 'Sat'}, + {"day": "Sun", "key": "Sun"}, + {"day": "Mon", "key": "Mon"}, + {"day": "Tue", "key": "Tue"}, + {"day": "Wed", "key": "Wed"}, + {"day": "Thu", "key": "Thu"}, + {"day": "Fri", "key": "Fri"}, + {"day": "Sat", "key": "Sat"}, ]; List selectedDays = []; @@ -188,12 +192,12 @@ class VisitorPasswordBloc FetchDevice event, Emitter emit) async { try { emit(DeviceLoaded()); - final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; data = await AccessMangApi().fetchDoorLockDeviceList(projectUuid); emit(TableLoaded(data)); } catch (e) { - print('error: $e'); + print("error: $e"); emit(FailedState(e.toString())); } } @@ -204,7 +208,7 @@ class VisitorPasswordBloc try { emit(LoadingInitialState()); generate7DigitNumber(); - final res = await AccessMangApi().postOnlineOneTime( + var res = await AccessMangApi().postOnlineOneTime( email: event.email, password: passwordController, devicesUuid: selectedDevices, @@ -218,8 +222,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - final String errorMessage = errorData['message']; - emit(FailedState(errorMessage)); + String errorMessage = errorData['message']; + emit(FailedState(errorMessage.toString())); } } @@ -230,12 +234,13 @@ class VisitorPasswordBloc emit(LoadingInitialState()); await generate7DigitNumber(); - final res = await AccessMangApi().postOnlineMultipleTime( + var res = await AccessMangApi().postOnlineMultipleTime( scheduleList: [ if (repeat) Schedule( effectiveTime: getTimeFromDateTimeString(effectiveTime), - invalidTime: getTimeFromDateTimeString(expirationTime), + invalidTime: + getTimeFromDateTimeString(expirationTime).toString(), workingDay: selectedDays, ), ], @@ -252,8 +257,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - final String errorMessage = errorData['message']; - emit(FailedState(errorMessage)); + String errorMessage = errorData['message']; + emit(FailedState(errorMessage.toString())); } } @@ -263,7 +268,7 @@ class VisitorPasswordBloc try { emit(LoadingInitialState()); await generate7DigitNumber(); - final res = await AccessMangApi().postOffLineOneTime( + var res = await AccessMangApi().postOffLineOneTime( email: event.email, devicesUuid: selectedDevices, passwordName: event.passwordName); @@ -274,8 +279,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - final String errorMessage = errorData['message']; - emit(FailedState(errorMessage)); + String errorMessage = errorData['message']; + emit(FailedState(errorMessage.toString())); } } @@ -285,7 +290,7 @@ class VisitorPasswordBloc try { emit(LoadingInitialState()); await generate7DigitNumber(); - final res = await AccessMangApi().postOffLineMultipleTime( + var res = await AccessMangApi().postOffLineMultipleTime( email: event.email, devicesUuid: selectedDevices, passwordName: event.passwordName, @@ -299,8 +304,8 @@ class VisitorPasswordBloc emit(TableLoaded(data)); } on DioException catch (e) { final errorData = e.response!.data; - final String errorMessage = errorData['message']; - emit(FailedState(errorMessage)); + String errorMessage = errorData['message']; + emit(FailedState(errorMessage.toString())); } } @@ -322,9 +327,9 @@ class VisitorPasswordBloc Future generate7DigitNumber() async { passwordController = ''; - final random = Random(); - const min = 1000000; - const max = 9999999; + Random random = Random(); + int min = 1000000; + int max = 9999999; passwordController = (min + random.nextInt(max - min + 1)).toString(); return passwordController; } @@ -360,7 +365,7 @@ class VisitorPasswordBloc emit(TableLoaded(event.filteredData)); } - void addDeviceToList(context) { + addDeviceToList(context) { selectedDevices = selectedDeviceIds; Navigator.of(context).pop(selectedDevices); } @@ -368,14 +373,14 @@ class VisitorPasswordBloc Future selectTimeOfLinePassword( SelectTimeEvent event, Emitter emit) async { emit(ChangeTimeState()); - final picked = await showDatePicker( + final DateTime? picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 2095)), ); if (picked != null) { - final timePicked = await showHourPicker( + final TimeOfDay? timePicked = await showHourPicker( context: event.context, initialTime: TimeOfDay.now(), ); @@ -400,7 +405,7 @@ class VisitorPasswordBloc if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) { accessPeriodValidate = - 'Effective Time cannot be later than Expiration Time.'; + "Effective Time cannot be later than Expiration Time."; } else { accessPeriodValidate = ''; effectiveTime = selectedDateTime.toString().split('.').first; @@ -422,7 +427,7 @@ class VisitorPasswordBloc } } - void changeTime(ChangeTimeEvent event, Emitter emit) { + changeTime(ChangeTimeEvent event, Emitter emit) { if (event.isStartEndTime == true) { startTime = event.val; } else { @@ -432,8 +437,8 @@ class VisitorPasswordBloc DateTime? convertStringToDateTime(String dateTimeString) { try { - final inputFormat = DateFormat('yyyy-MM-dd HH:mm:ss'); - final dateTime = inputFormat.parse(dateTimeString); + final DateFormat inputFormat = DateFormat('yyyy-MM-dd HH:mm:ss'); + DateTime dateTime = inputFormat.parse(dateTimeString); return dateTime; } catch (e) { return null; @@ -441,7 +446,7 @@ class VisitorPasswordBloc } String getTimeFromDateTimeString(String dateTimeString) { - final dateTime = convertStringToDateTime(dateTimeString); + DateTime? dateTime = convertStringToDateTime(dateTimeString); if (dateTime == null) return ''; return DateFormat('HH:mm').format(dateTime); } diff --git a/lib/pages/visitor_password/bloc/visitor_password_event.dart b/lib/pages/visitor_password/bloc/visitor_password_event.dart index 6e7b056b..6ecae200 100644 --- a/lib/pages/visitor_password/bloc/visitor_password_event.dart +++ b/lib/pages/visitor_password/bloc/visitor_password_event.dart @@ -140,7 +140,7 @@ class FilterDataEvent extends VisitorPasswordEvent { class UpdateFilteredDevicesEvent extends VisitorPasswordEvent { final List filteredData; - const UpdateFilteredDevicesEvent(this.filteredData); + UpdateFilteredDevicesEvent(this.filteredData); } class SelectTimeEvent extends VisitorPasswordEvent { diff --git a/lib/pages/visitor_password/model/device_model.dart b/lib/pages/visitor_password/model/device_model.dart index dc6c4858..f9711eed 100644 --- a/lib/pages/visitor_password/model/device_model.dart +++ b/lib/pages/visitor_password/model/device_model.dart @@ -51,8 +51,8 @@ class DeviceModel { // Deserialize from JSON factory DeviceModel.fromJson(Map json) { - var tempIcon = ''; - final type = devicesTypesMap[json['productType']] ?? DeviceType.Other; + String tempIcon = ''; + DeviceType type = devicesTypesMap[json['productType']] ?? DeviceType.Other; if (type == DeviceType.LightBulb) { tempIcon = Assets.lightBulb; } else if (type == DeviceType.CeilingSensor || diff --git a/lib/pages/visitor_password/model/failed_operation.dart b/lib/pages/visitor_password/model/failed_operation.dart index 02bd6802..223f9ac5 100644 --- a/lib/pages/visitor_password/model/failed_operation.dart +++ b/lib/pages/visitor_password/model/failed_operation.dart @@ -26,6 +26,8 @@ class FailedOperation { } } + + class SuccessOperation { final bool success; // final Result result; @@ -90,6 +92,8 @@ class SuccessOperation { // } // } + + class PasswordStatus { final List successOperations; final List failedOperations; @@ -117,3 +121,4 @@ class PasswordStatus { }; } } + diff --git a/lib/pages/visitor_password/view/add_device_dialog.dart b/lib/pages/visitor_password/view/add_device_dialog.dart index 68f970b3..d69aa21d 100644 --- a/lib/pages/visitor_password/view/add_device_dialog.dart +++ b/lib/pages/visitor_password/view/add_device_dialog.dart @@ -2,14 +2,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/common/access_device_table.dart'; -import 'package:syncrow_web/pages/common/buttons/default_button.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.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/visitor_password/bloc/visitor_password_bloc.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/utils/constants/app_enum.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; +import 'package:syncrow_web/utils/constants/app_enum.dart'; import 'package:syncrow_web/utils/style.dart'; class AddDeviceDialog extends StatelessWidget { @@ -17,14 +18,15 @@ class AddDeviceDialog extends StatelessWidget { const AddDeviceDialog({super.key, this.selectedDeviceIds}); @override Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; + Size size = MediaQuery.of(context).size; return BlocProvider( - create: (context) => VisitorPasswordBloc()..add(FetchDevice()), + create: (context) => + VisitorPasswordBloc()..add(FetchDevice()), child: BlocBuilder( builder: (BuildContext context, VisitorPasswordState state) { final visitorBloc = BlocProvider.of(context); if (state is TableLoaded) { - for (final device in selectedDeviceIds!) { + for (var device in selectedDeviceIds!) { if (selectedDeviceIds!.contains(device)) { visitorBloc.add(SelectDeviceEvent(device)); } @@ -52,7 +54,7 @@ class AddDeviceDialog extends StatelessWidget { padding: const EdgeInsets.all(15), decoration: containerDecoration.copyWith( color: ColorsManager.worningColor, - border: Border.all(color: const Color(0xffFFD22F)), + border: Border.all(color: Color(0xffFFD22F)), boxShadow: []), child: Row( children: [ @@ -126,7 +128,9 @@ class AddDeviceDialog extends StatelessWidget { width: size.width * 0.06, child: Center( child: DefaultButton( - onPressed: visitorBloc.filterDevices, + onPressed: () { + visitorBloc.filterDevices(); + }, borderRadius: 9, child: const Text('Search'), ), @@ -137,7 +141,7 @@ class AddDeviceDialog extends StatelessWidget { const SizedBox(width: 10), Expanded( flex: 2, - child: SizedBox( + child: Container( width: size.width * 0.06, child: DefaultButton( backgroundColor: ColorsManager.whiteColors, @@ -173,7 +177,7 @@ class AddDeviceDialog extends StatelessWidget { isEmpty: visitorBloc.data.isEmpty, selectAll: (p0) { visitorBloc.selectedDeviceIds.clear(); - for (final item in state.data) { + for (var item in state.data) { visitorBloc .add(SelectDeviceEvent(item.uuid)); } @@ -197,7 +201,7 @@ class AddDeviceDialog extends StatelessWidget { item.uuid.toString(), item.productType.toString(), item.spaceName.toString(), - item.online.value, + item.online.value.toString(), ]; }).toList(), ) @@ -219,7 +223,7 @@ class AddDeviceDialog extends StatelessWidget { backgroundColor: Colors.white, child: Text( 'Cancel', - style: Theme.of(context).textTheme.bodyMedium, + style: Theme.of(context).textTheme.bodyMedium!, ), ), ), @@ -231,7 +235,7 @@ class AddDeviceDialog extends StatelessWidget { visitorBloc.addDeviceToList(context); }, borderRadius: 8, - child: const Text('Ok'), + child: Text('Ok'), ), ), ], diff --git a/lib/pages/visitor_password/view/repeat_widget.dart b/lib/pages/visitor_password/view/repeat_widget.dart index 621dbbba..8b40b580 100644 --- a/lib/pages/visitor_password/view/repeat_widget.dart +++ b/lib/pages/visitor_password/view/repeat_widget.dart @@ -14,7 +14,7 @@ class RepeatWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; + Size size = MediaQuery.of(context).size; return BlocBuilder( builder: (context, state) { final visitorBloc = BlocProvider.of(context); @@ -29,7 +29,7 @@ class RepeatWidget extends StatelessWidget { children: visitorBloc.days.map((day) { return Container( width: 70, // Adjust width as needed - margin: const EdgeInsets.all(5), + margin: EdgeInsets.all(5), child: CheckboxListTile( contentPadding: EdgeInsets.zero, title: Text( diff --git a/lib/pages/visitor_password/view/visitor_password_dialog.dart b/lib/pages/visitor_password/view/visitor_password_dialog.dart index 1849ccf2..1e43af46 100644 --- a/lib/pages/visitor_password/view/visitor_password_dialog.dart +++ b/lib/pages/visitor_password/view/visitor_password_dialog.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.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/text_field/custom_web_textfield.dart'; @@ -19,11 +20,8 @@ class VisitorPasswordDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; - final text = Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.black, fontSize: 13); + Size size = MediaQuery.of(context).size; + var text = Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black, fontSize: 13); return BlocProvider( create: (context) => VisitorPasswordBloc(), child: BlocListener( @@ -37,8 +35,7 @@ class VisitorPasswordDialog extends StatelessWidget { title: 'Sent Successfully', widgeta: Column( children: [ - if (visitorBloc - .passwordStatus!.failedOperations.isNotEmpty) + if (visitorBloc.passwordStatus!.failedOperations.isNotEmpty) Column( children: [ const Text('Failed Devices'), @@ -48,26 +45,22 @@ class VisitorPasswordDialog extends StatelessWidget { child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, - itemCount: visitorBloc - .passwordStatus!.failedOperations.length, + itemCount: visitorBloc.passwordStatus!.failedOperations.length, itemBuilder: (context, index) { return Container( - margin: const EdgeInsets.all(5), + margin: EdgeInsets.all(5), decoration: containerDecoration, height: 45, child: Center( child: Text(visitorBloc - .passwordStatus! - .failedOperations[index] - .deviceUuid)), + .passwordStatus!.failedOperations[index].deviceUuid)), ); }, ), ), ], ), - if (visitorBloc - .passwordStatus!.successOperations.isNotEmpty) + if (visitorBloc.passwordStatus!.successOperations.isNotEmpty) Column( children: [ const Text('Success Devices'), @@ -77,18 +70,15 @@ class VisitorPasswordDialog extends StatelessWidget { child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, - itemCount: visitorBloc - .passwordStatus!.successOperations.length, + itemCount: visitorBloc.passwordStatus!.successOperations.length, itemBuilder: (context, index) { return Container( - margin: const EdgeInsets.all(5), + margin: EdgeInsets.all(5), decoration: containerDecoration, height: 45, child: Center( - child: Text(visitorBloc - .passwordStatus! - .successOperations[index] - .deviceUuid)), + child: Text(visitorBloc.passwordStatus! + .successOperations[index].deviceUuid)), ); }, ), @@ -99,6 +89,7 @@ class VisitorPasswordDialog extends StatelessWidget { )) .then((v) { Navigator.of(context).pop(true); + }); } else if (state is FailedState) { visitorBloc.stateDialog( @@ -111,16 +102,15 @@ class VisitorPasswordDialog extends StatelessWidget { child: BlocBuilder( builder: (BuildContext context, VisitorPasswordState state) { final visitorBloc = BlocProvider.of(context); - final isRepeat = - state is IsRepeatState ? state.repeat : visitorBloc.repeat; + bool isRepeat = state is IsRepeatState ? state.repeat : visitorBloc.repeat; return AlertDialog( backgroundColor: Colors.white, title: Text( 'Create visitor password', - style: Theme.of(context).textTheme.headlineLarge!.copyWith( - fontWeight: FontWeight.w400, - fontSize: 24, - color: Colors.black), + style: Theme.of(context) + .textTheme + .headlineLarge! + .copyWith(fontWeight: FontWeight.w400, fontSize: 24, color: Colors.black), ), content: state is LoadingInitialState ? const Center(child: CircularProgressIndicator()) @@ -138,8 +128,7 @@ class VisitorPasswordDialog extends StatelessWidget { flex: 2, child: CustomWebTextField( validator: visitorBloc.validate, - controller: - visitorBloc.userNameController, + controller: visitorBloc.userNameController, isRequired: true, textFieldName: 'Name', description: '', @@ -188,26 +177,20 @@ class VisitorPasswordDialog extends StatelessWidget { SizedBox( width: size.width * 0.12, child: RadioListTile( - contentPadding: - EdgeInsets.zero, + contentPadding: EdgeInsets.zero, title: Text( 'Online Password', style: text, ), value: 'Online Password', - groupValue: (state - is PasswordTypeSelected) + groupValue: (state is PasswordTypeSelected) ? state.selectedType - : visitorBloc - .accessTypeSelected, + : visitorBloc.accessTypeSelected, onChanged: (String? value) { if (value != null) { context - .read< - VisitorPasswordBloc>() - .add( - SelectPasswordType( - value)); + .read() + .add(SelectPasswordType(value)); } }, ), @@ -215,25 +198,17 @@ class VisitorPasswordDialog extends StatelessWidget { SizedBox( width: size.width * 0.12, child: RadioListTile( - contentPadding: - EdgeInsets.zero, - title: Text( - 'Offline Password', - style: text), + contentPadding: EdgeInsets.zero, + title: Text('Offline Password', style: text), value: 'Offline Password', - groupValue: (state - is PasswordTypeSelected) + groupValue: (state is PasswordTypeSelected) ? state.selectedType - : visitorBloc - .accessTypeSelected, + : visitorBloc.accessTypeSelected, onChanged: (String? value) { if (value != null) { context - .read< - VisitorPasswordBloc>() - .add( - SelectPasswordType( - value)); + .read() + .add(SelectPasswordType(value)); } }, ), @@ -267,29 +242,21 @@ class VisitorPasswordDialog extends StatelessWidget { ), ], ), - if (visitorBloc.accessTypeSelected == - 'Online Password') + if (visitorBloc.accessTypeSelected == 'Online Password') Text( 'Only currently online devices can be selected. It is recommended to use when the device network is stable, and the system randomly generates a digital password', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.grayColor, - fontSize: 9), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.grayColor, + fontSize: 9), ), - if (visitorBloc.accessTypeSelected == - 'Offline Password') + if (visitorBloc.accessTypeSelected == 'Offline Password') Text( 'Unaffected by the online status of the device, you can select online or offline device, and the system randomly generates a digital password', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.grayColor, - fontSize: 9), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.grayColor, + fontSize: 9), ), // if (visitorBloc.accessTypeSelected == 'Dynamic Password') // Text( @@ -304,206 +271,143 @@ class VisitorPasswordDialog extends StatelessWidget { ) ], ), - if (visitorBloc.accessTypeSelected == - 'Dynamic Password') - const SizedBox() - else - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( + visitorBloc.accessTypeSelected == 'Dynamic Password' + ? const SizedBox() + : Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - '* ', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: Colors.red), - ), - Text( - 'Usage Frequency', - style: text, - ), - ], - ), - Row( - children: [ - SizedBox( - width: size.width * 0.12, - child: RadioListTile( - contentPadding: EdgeInsets.zero, - title: Text( - 'One-Time', + Row( + children: [ + Text( + '* ', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.red), + ), + Text( + 'Usage Frequency', style: text, ), - value: 'One-Time', - groupValue: (state - is UsageFrequencySelected) - ? state.selectedFrequency - : visitorBloc - .usageFrequencySelected, - onChanged: (String? value) { - if (value != null) { - context - .read() - .add(SelectUsageFrequency( - value)); - } - }, - ), + ], ), - SizedBox( - width: size.width * 0.12, - child: RadioListTile( - contentPadding: EdgeInsets.zero, - title: - Text('Periodic', style: text), - value: 'Periodic', - groupValue: (state - is UsageFrequencySelected) - ? state.selectedFrequency - : visitorBloc - .usageFrequencySelected, - onChanged: (String? value) { - if (value != null) { - context - .read() - .add(SelectUsageFrequency( - value)); - } - }, - ), + Row( + children: [ + SizedBox( + width: size.width * 0.12, + child: RadioListTile( + contentPadding: EdgeInsets.zero, + title: Text( + 'One-Time', + style: text, + ), + value: 'One-Time', + groupValue: (state is UsageFrequencySelected) + ? state.selectedFrequency + : visitorBloc.usageFrequencySelected, + onChanged: (String? value) { + if (value != null) { + context + .read() + .add(SelectUsageFrequency(value)); + } + }, + ), + ), + SizedBox( + width: size.width * 0.12, + child: RadioListTile( + contentPadding: EdgeInsets.zero, + title: Text('Periodic', style: text), + value: 'Periodic', + groupValue: (state is UsageFrequencySelected) + ? state.selectedFrequency + : visitorBloc.usageFrequencySelected, + onChanged: (String? value) { + if (value != null) { + context.read() + .add(SelectUsageFrequency(value)); + } + }, + ), + ), + ], ), + + //One-Time + if (visitorBloc.usageFrequencySelected == 'One-Time' && + visitorBloc.accessTypeSelected == 'Online Password') + Text( + 'Within the validity period, each device can be unlocked only once.', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, fontSize: 9), + ), + if (visitorBloc.usageFrequencySelected == 'One-Time' && + visitorBloc.accessTypeSelected == 'Offline Password') + Text( + 'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, fontSize: 9), + ), + + // Periodic + if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Offline Password') + Text( + 'Within the validity period, there is no limit to the number of times each device can be unlocked, and it should be used at least once within 24 hours after the entry into force.', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, fontSize: 9), + ), + + if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Online Password') + Text( + 'Within the validity period, there is no limit to the number of times each device can be unlocked.', + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, fontSize: 9), + ), ], ), - - //One-Time - if (visitorBloc.usageFrequencySelected == - 'One-Time' && - visitorBloc.accessTypeSelected == - 'Online Password') - Text( - 'Within the validity period, each device can be unlocked only once.', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - color: ColorsManager.grayColor, - fontSize: 9), - ), - if (visitorBloc.usageFrequencySelected == - 'One-Time' && - visitorBloc.accessTypeSelected == - 'Offline Password') - Text( - 'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - color: ColorsManager.grayColor, - fontSize: 9), - ), - - // Periodic - if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Offline Password') - Text( - 'Within the validity period, there is no limit to the number of times each device can be unlocked, and it should be used at least once within 24 hours after the entry into force.', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - color: ColorsManager.grayColor, - fontSize: 9), - ), - - if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Online Password') - Text( - 'Within the validity period, there is no limit to the number of times each device can be unlocked.', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - color: ColorsManager.grayColor, - fontSize: 9), - ), - ], - ), const SizedBox( height: 20, ), - if ((visitorBloc.usageFrequencySelected != - 'One-Time' || - visitorBloc.accessTypeSelected != - 'Offline Password') && + if ((visitorBloc.usageFrequencySelected != 'One-Time' || + visitorBloc.accessTypeSelected != 'Offline Password') && (visitorBloc.usageFrequencySelected != '')) DateTimeWebWidget( isRequired: true, title: 'Access Period', size: size, endTime: () { - if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Offline Password') { - visitorBloc.add(SelectTimeEvent( - context: context, - isEffective: false)); + if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Offline Password') { + visitorBloc.add(SelectTimeEvent(context: context, isEffective: false)); } else { - visitorBloc.add( - SelectTimeVisitorPassword( - context: context, - isStart: false, - isRepeat: false)); + visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false, isRepeat: false)); } }, startTime: () { - if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Offline Password') { - visitorBloc.add(SelectTimeEvent( - context: context, - isEffective: true)); - } else { + if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Offline Password') { visitorBloc.add( - SelectTimeVisitorPassword( - context: context, - isStart: true, - isRepeat: false)); + SelectTimeEvent(context: context, isEffective: true)); + } else { + visitorBloc.add(SelectTimeVisitorPassword( + context: context, isStart: true, isRepeat: false)); } }, - firstString: (visitorBloc - .usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Offline Password') + firstString: (visitorBloc.usageFrequencySelected == + 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') ? visitorBloc.effectiveTime - : visitorBloc.startTimeAccess, - secondString: (visitorBloc - .usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Offline Password') + : visitorBloc.startTimeAccess.toString(), + secondString: (visitorBloc.usageFrequencySelected == + 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') ? visitorBloc.expirationTime - : visitorBloc.endTimeAccess, + : visitorBloc.endTimeAccess.toString(), icon: Assets.calendarIcon), - const SizedBox( - height: 10, - ), - Text( - visitorBloc.accessPeriodValidate, - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: ColorsManager.red), - ), + const SizedBox(height: 10,), + Text(visitorBloc.accessPeriodValidate, + style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: ColorsManager.red),), const SizedBox( height: 20, ), @@ -527,21 +431,16 @@ class VisitorPasswordDialog extends StatelessWidget { ), Text( 'Within the validity period, each device can be unlocked only once.', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.grayColor, - fontSize: 9), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.grayColor, + fontSize: 9), ), const SizedBox( height: 20, ), - if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Online Password') + if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Online Password') SizedBox( width: 100, child: Column( @@ -552,8 +451,7 @@ class VisitorPasswordDialog extends StatelessWidget { child: CupertinoSwitch( value: visitorBloc.repeat, onChanged: (value) { - visitorBloc - .add(ToggleRepeatEvent()); + visitorBloc.add(ToggleRepeatEvent()); }, applyTheme: true, ), @@ -561,13 +459,9 @@ class VisitorPasswordDialog extends StatelessWidget { ], ), ), - if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Online Password') - isRepeat - ? const RepeatWidget() - : const SizedBox(), + if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Online Password') + isRepeat ? const RepeatWidget() : const SizedBox(), Container( decoration: containerDecoration, width: size.width / 9, @@ -578,28 +472,22 @@ class VisitorPasswordDialog extends StatelessWidget { barrierDismissible: false, builder: (BuildContext context) { return AddDeviceDialog( - selectedDeviceIds: - visitorBloc.selectedDevices, + selectedDeviceIds: visitorBloc.selectedDevices, ); }, ).then((listDevice) { if (listDevice != null) { - visitorBloc.selectedDevices = - listDevice; + visitorBloc.selectedDevices = listDevice; } }); }, borderRadius: 8, child: Text( '+ Add Device', - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - fontWeight: FontWeight.w400, - color: - ColorsManager.whiteColors, - fontSize: 12), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.whiteColors, + fontSize: 12), ), ), ), @@ -637,35 +525,30 @@ class VisitorPasswordDialog extends StatelessWidget { onPressed: () { if (visitorBloc.forgetFormKey.currentState!.validate()) { if (visitorBloc.selectedDevices.isNotEmpty) { - if (visitorBloc.usageFrequencySelected == - 'One-Time' && - visitorBloc.accessTypeSelected == - 'Offline Password') { + if (visitorBloc.usageFrequencySelected == 'One-Time' && + visitorBloc.accessTypeSelected == 'Offline Password') { setPasswordFunction(context, size, visitorBloc); - } else if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Offline Password') { + } else if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Offline Password') { if (visitorBloc.expirationTime != 'End Time' && - visitorBloc.effectiveTime != 'Start Time') { + visitorBloc.effectiveTime != 'Start Time' ) { setPasswordFunction(context, size, visitorBloc); - } else { + }else{ visitorBloc.stateDialog( context: context, - message: - 'Please select Access Period to continue', + message: 'Please select Access Period to continue', title: 'Access Period'); } - } else if (visitorBloc.endTimeAccess != 'End Time' && - visitorBloc.startTimeAccess != 'Start Time') { + } else if( + visitorBloc.endTimeAccess.toString()!='End Time' + &&visitorBloc.startTimeAccess.toString()!='Start Time') { if (visitorBloc.effectiveTimeTimeStamp != null && visitorBloc.expirationTimeTimeStamp != null) { if (isRepeat == true) { if (visitorBloc.expirationTime != 'End Time' && visitorBloc.effectiveTime != 'Start Time' && visitorBloc.selectedDays.isNotEmpty) { - setPasswordFunction( - context, size, visitorBloc); + setPasswordFunction(context, size, visitorBloc); } else { visitorBloc.stateDialog( context: context, @@ -679,16 +562,14 @@ class VisitorPasswordDialog extends StatelessWidget { } else { visitorBloc.stateDialog( context: context, - message: - 'Please select Access Period to continue', + message: 'Please select Access Period to continue', title: 'Access Period'); } - } else { - visitorBloc.stateDialog( - context: context, - message: - 'Please select Access Period to continue', - title: 'Access Period'); + }else{ + visitorBloc.stateDialog( + context: context, + message: 'Please select Access Period to continue', + title: 'Access Period'); } } else { visitorBloc.stateDialog( @@ -733,9 +614,8 @@ class VisitorPasswordDialog extends StatelessWidget { alignment: Alignment.center, content: SizedBox( height: size.height * 0.25, - child: const Center( - child: - CircularProgressIndicator(), // Display a loading spinner + child: Center( + child: CircularProgressIndicator(), // Display a loading spinner ), ), ); @@ -759,10 +639,7 @@ class VisitorPasswordDialog extends StatelessWidget { ), Text( 'Set Password', - style: Theme.of(context) - .textTheme - .headlineLarge! - .copyWith( + style: Theme.of(context).textTheme.headlineLarge!.copyWith( fontSize: 30, fontWeight: FontWeight.w400, color: Colors.black, @@ -812,45 +689,37 @@ class VisitorPasswordDialog extends StatelessWidget { onPressed: () { Navigator.pop(context); if (visitorBloc.usageFrequencySelected == 'One-Time' && - visitorBloc.accessTypeSelected == - 'Online Password') { + visitorBloc.accessTypeSelected == 'Online Password') { visitorBloc.add(OnlineOneTimePasswordEvent( context: context, passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, )); - } else if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Online Password') { + } + else if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Online Password') { visitorBloc.add(OnlineMultipleTimePasswordEvent( passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, - effectiveTime: - visitorBloc.effectiveTimeTimeStamp.toString(), - invalidTime: - visitorBloc.expirationTimeTimeStamp.toString(), + effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), + invalidTime: visitorBloc.expirationTimeTimeStamp.toString(), )); - } else if (visitorBloc.usageFrequencySelected == - 'One-Time' && - visitorBloc.accessTypeSelected == - 'Offline Password') { + } + else if (visitorBloc.usageFrequencySelected == 'One-Time' && + visitorBloc.accessTypeSelected == 'Offline Password') { visitorBloc.add(OfflineOneTimePasswordEvent( context: context, passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, )); - } else if (visitorBloc.usageFrequencySelected == - 'Periodic' && - visitorBloc.accessTypeSelected == - 'Offline Password') { + } + else if (visitorBloc.usageFrequencySelected == 'Periodic' && + visitorBloc.accessTypeSelected == 'Offline Password') { visitorBloc.add(OfflineMultipleTimePasswordEvent( passwordName: visitorBloc.userNameController.text, email: visitorBloc.emailController.text, - effectiveTime: - visitorBloc.effectiveTimeTimeStamp.toString(), - invalidTime: - visitorBloc.expirationTimeTimeStamp.toString(), + effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(), + invalidTime: visitorBloc.expirationTimeTimeStamp.toString(), )); } }, diff --git a/lib/services/access_mang_api.dart b/lib/services/access_mang_api.dart index a10292c5..a780a12b 100644 --- a/lib/services/access_mang_api.dart +++ b/lib/services/access_mang_api.dart @@ -12,8 +12,7 @@ class AccessMangApi { void _validateEndpoints() { if (!ApiEndpoints.getDevices.contains('{projectId}')) { - throw Exception( - "Endpoint 'getDevices' must contain '{projectId}' placeholder."); + throw Exception("Endpoint 'getDevices' must contain '{projectId}' placeholder."); } } @@ -23,8 +22,8 @@ class AccessMangApi { path: ApiEndpoints.visitorPassword, showServerMessage: true, expectedResponseModel: (json) { - final List jsonData = json['data'] ?? []; - final passwordList = jsonData.map((jsonItem) { + List jsonData = json['data'] ?? []; + List passwordList = jsonData.map((jsonItem) { return PasswordModel.fromJson(jsonItem); }).toList(); return passwordList; @@ -47,8 +46,8 @@ class AccessMangApi { }, showServerMessage: true, expectedResponseModel: (json) { - final List jsonData = json['data'] ?? []; - final deviceList = jsonData.map((jsonItem) { + List jsonData = json['data'] ?? []; + List deviceList = jsonData.map((jsonItem) { return DeviceModel.fromJson(jsonItem); }).toList(); return deviceList; @@ -70,13 +69,13 @@ class AccessMangApi { final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, body: jsonEncode({ - 'email': email, - 'passwordName': passwordName, - 'password': password, - 'devicesUuid': devicesUuid, - 'effectiveTime': effectiveTime, - 'invalidTime': invalidTime, - 'operationType': 'ONLINE_ONE_TIME', + "email": email, + "passwordName": passwordName, + "password": password, + "devicesUuid": devicesUuid, + "effectiveTime": effectiveTime, + "invalidTime": invalidTime, + "operationType": "ONLINE_ONE_TIME", }), showServerMessage: true, expectedResponseModel: (json) { @@ -94,18 +93,17 @@ class AccessMangApi { String? passwordName, List? scheduleList, List? devicesUuid}) async { - final body = { - 'email': email, - 'devicesUuid': devicesUuid, - 'passwordName': passwordName, - 'password': password, - 'effectiveTime': effectiveTime, - 'invalidTime': invalidTime, - 'operationType': 'ONLINE_MULTIPLE_TIME', + Map body = { + "email": email, + "devicesUuid": devicesUuid, + "passwordName": passwordName, + "password": password, + "effectiveTime": effectiveTime, + "invalidTime": invalidTime, + "operationType": "ONLINE_MULTIPLE_TIME", }; if (scheduleList != null) { - body['scheduleList'] = - scheduleList.map((schedule) => schedule.toJson()).toList(); + body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList(); } final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, @@ -125,10 +123,10 @@ class AccessMangApi { final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, body: jsonEncode({ - 'operationType': 'OFFLINE_ONE_TIME', - 'email': email, - 'passwordName': passwordName, - 'devicesUuid': devicesUuid + "operationType": "OFFLINE_ONE_TIME", + "email": email, + "passwordName": passwordName, + "devicesUuid": devicesUuid }), showServerMessage: true, expectedResponseModel: (json) { @@ -147,12 +145,12 @@ class AccessMangApi { final response = await HTTPService().post( path: ApiEndpoints.visitorPassword, body: jsonEncode({ - 'email': email, - 'devicesUuid': devicesUuid, - 'passwordName': passwordName, - 'effectiveTime': effectiveTime, - 'invalidTime': invalidTime, - 'operationType': 'OFFLINE_MULTIPLE_TIME', + "email": email, + "devicesUuid": devicesUuid, + "passwordName": passwordName, + "effectiveTime": effectiveTime, + "invalidTime": invalidTime, + "operationType": "OFFLINE_MULTIPLE_TIME", }), showServerMessage: true, expectedResponseModel: (json) { diff --git a/lib/services/api/http_interceptor.dart b/lib/services/api/http_interceptor.dart index f6762daf..bef8d804 100644 --- a/lib/services/api/http_interceptor.dart +++ b/lib/services/api/http_interceptor.dart @@ -1,10 +1,10 @@ -import 'dart:async'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:syncrow_web/pages/auth/model/token.dart'; import 'package:syncrow_web/services/api/network_exception.dart'; +import 'dart:async'; import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; @@ -18,8 +18,7 @@ class HTTPInterceptor extends InterceptorsWrapper { ]; @override - Future onResponse( - Response response, ResponseInterceptorHandler handler) async { + void onResponse(Response response, ResponseInterceptorHandler handler) async { if (await validateResponse(response)) { super.onResponse(response, handler); } else { @@ -29,27 +28,26 @@ class HTTPInterceptor extends InterceptorsWrapper { } @override - Future onRequest( + void onRequest( RequestOptions options, RequestInterceptorHandler handler) async { - const storage = FlutterSecureStorage(); - final token = await storage.read(key: Token.loginAccessTokenKey); + var storage = const FlutterSecureStorage(); + var token = await storage.read(key: Token.loginAccessTokenKey); if (checkHeaderExclusionListOfAddedParameters(options.path)) { options.headers - .putIfAbsent(HttpHeaders.authorizationHeader, () => 'Bearer $token'); + .putIfAbsent(HttpHeaders.authorizationHeader, () => "Bearer $token"); } // options.headers['Authorization'] = 'Bearer ${'${token!}123'}'; super.onRequest(options, handler); } @override - Future onError( - DioException err, ErrorInterceptorHandler handler) async { - final failure = ServerFailure.fromDioError(err); + void onError(DioException err, ErrorInterceptorHandler handler) async { + ServerFailure failure = ServerFailure.fromDioError(err); if (failure.toString().isNotEmpty) { CustomSnackBar.displaySnackBar(failure.toString()); } - const storage = FlutterSecureStorage(); - final token = await storage.read(key: Token.loginAccessTokenKey); + var storage = const FlutterSecureStorage(); + var token = await storage.read(key: Token.loginAccessTokenKey); if (err.response?.statusCode == 401 && token != null) { // await AuthCubit.get(NavigationService.navigatorKey.currentContext!).logout(); } @@ -74,10 +72,10 @@ class HTTPInterceptor extends InterceptorsWrapper { } } - bool checkHeaderExclusionListOfAddedParameters(String path) { - var shouldAddHeader = true; + checkHeaderExclusionListOfAddedParameters(String path) { + bool shouldAddHeader = true; - for (final urlConstant in headerExclusionListOfAddedParameters) { + for (var urlConstant in headerExclusionListOfAddedParameters) { if (path.contains(urlConstant)) { shouldAddHeader = false; } diff --git a/lib/services/api/http_service.dart b/lib/services/api/http_service.dart index 8e0d0616..c76291bf 100644 --- a/lib/services/api/http_service.dart +++ b/lib/services/api/http_service.dart @@ -8,10 +8,10 @@ class HTTPService { // final navigatorKey = GlobalKey(); - String certificateString = ''; + String certificateString = ""; static Dio setupDioClient() { - final client = Dio( + Dio client = Dio( BaseOptions( baseUrl: ApiEndpoints.baseUrl, receiveDataWhenStatusError: true, diff --git a/lib/services/api/network_exception.dart b/lib/services/api/network_exception.dart index 9ebc8486..d85ef27c 100644 --- a/lib/services/api/network_exception.dart +++ b/lib/services/api/network_exception.dart @@ -17,34 +17,34 @@ class ServerFailure extends Failure { factory ServerFailure.fromDioError(DioException dioError) { switch (dioError.type) { case DioExceptionType.connectionTimeout: - return ServerFailure('Connection timeout with the Server.'); + return ServerFailure("Connection timeout with the Server."); case DioExceptionType.sendTimeout: - return ServerFailure('Send timeout with the Server.'); + return ServerFailure("Send timeout with the Server."); case DioExceptionType.receiveTimeout: - return ServerFailure('Receive timeout with the Server.'); + return ServerFailure("Receive timeout with the Server."); case DioExceptionType.badCertificate: - return ServerFailure('Bad certificate!'); + return ServerFailure("Bad certificate!"); case DioExceptionType.badResponse: { // var document = parser.parse(dioError.response!.data.toString()); // var message = document.body!.text; - return ServerFailure.fromResponse(dioError.response!.statusCode, - dioError.response?.data['message'] ?? 'Error'); + return ServerFailure.fromResponse(dioError.response!.statusCode!, + dioError.response?.data['message'] ?? "Error"); } case DioExceptionType.cancel: - return ServerFailure('The request to ApiServer was canceled'); + return ServerFailure("The request to ApiServer was canceled"); case DioExceptionType.connectionError: - return ServerFailure('No Internet Connection'); + return ServerFailure("No Internet Connection"); case DioExceptionType.unknown: - return ServerFailure('Unexpected Error, Please try again!'); + return ServerFailure("Unexpected Error, Please try again!"); default: - return ServerFailure('Unexpected Error, Please try again!'); + return ServerFailure("Unexpected Error, Please try again!"); } } @@ -54,9 +54,9 @@ class ServerFailure extends Failure { case 403: return ServerFailure(responseMessage); case 400: - final errors = []; + List errors = []; if (responseMessage is List) { - for (final error in responseMessage) { + for (var error in responseMessage) { errors.add(error); } } else { @@ -64,11 +64,11 @@ class ServerFailure extends Failure { } return ServerFailure(errors.join('\n')); case 404: - return ServerFailure(''); + return ServerFailure(""); case 500: return ServerFailure(responseMessage); default: - return ServerFailure('Opps there was an Error, Please try again!'); + return ServerFailure("Opps there was an Error, Please try again!"); } } } diff --git a/lib/services/auth_api.dart b/lib/services/auth_api.dart index ad4fec5f..18d951c1 100644 --- a/lib/services/auth_api.dart +++ b/lib/services/auth_api.dart @@ -31,7 +31,7 @@ class AuthenticationAPI { try { final response = await HTTPService().post( path: ApiEndpoints.forgetPassword, - body: {'email': email, 'password': password, 'otpCode': otpCode}, + body: {"email": email, "password": password, "otpCode": otpCode}, showServerMessage: true, expectedResponseModel: (json) {}); return response; @@ -45,7 +45,7 @@ class AuthenticationAPI { static Future sendOtp({required String email}) async { final response = await HTTPService().post( path: ApiEndpoints.sendOtp, - body: {'email': email, 'type': 'PASSWORD'}, + body: {"email": email, "type": "PASSWORD"}, showServerMessage: true, expectedResponseModel: (json) { return json['data']['cooldown']; @@ -58,7 +58,7 @@ class AuthenticationAPI { try { final response = await HTTPService().post( path: ApiEndpoints.verifyOtp, - body: {'email': email, 'type': 'PASSWORD', 'otpCode': otpCode}, + body: {"email": email, "type": "PASSWORD", "otpCode": otpCode}, showServerMessage: true, expectedResponseModel: (json) { if (json['message'] == 'Otp Verified Successfully') { diff --git a/lib/services/batch_control_devices_service.dart b/lib/services/batch_control_devices_service.dart index 16542c8c..f78cdef4 100644 --- a/lib/services/batch_control_devices_service.dart +++ b/lib/services/batch_control_devices_service.dart @@ -11,8 +11,7 @@ abstract interface class BatchControlDevicesService { }); } -final class RemoteBatchControlDevicesService - implements BatchControlDevicesService { +final class RemoteBatchControlDevicesService implements BatchControlDevicesService { @override Future batchControlDevices({ required List uuids, diff --git a/lib/services/devices_mang_api.dart b/lib/services/devices_mang_api.dart index 06fe635c..6f60e34f 100644 --- a/lib/services/devices_mang_api.dart +++ b/lib/services/devices_mang_api.dart @@ -23,8 +23,8 @@ class DevicesManagementApi { : ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId), showServerMessage: true, expectedResponseModel: (json) { - final List jsonData = json['data']; - final devicesList = jsonData.map((jsonItem) { + List jsonData = json['data']; + List devicesList = jsonData.map((jsonItem) { return AllDevicesModel.fromJson(jsonItem); }).toList(); return devicesList; @@ -123,11 +123,11 @@ class DevicesManagementApi { path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId), showServerMessage: false, expectedResponseModel: (json) { - final devices = []; + List devices = []; if (json == null || json.isEmpty || json == []) { return devices; } - for (final device in json['data']['devices']) { + for (var device in json['data']['devices']) { devices.add(DeviceModel.fromJson(device)); } return devices; @@ -203,7 +203,7 @@ class DevicesManagementApi { } } - Future getPowerStatus(List uuids) async { + getPowerStatus(List uuids) async { try { final queryParameters = { 'devicesUuid': uuids.join(','), @@ -254,8 +254,8 @@ class DevicesManagementApi { .replaceAll('{category}', category), showServerMessage: true, expectedResponseModel: (json) { - final schedules = []; - for (final schedule in json) { + List schedules = []; + for (var schedule in json) { schedules.add(ScheduleModel.fromMap(schedule)); } return schedules; @@ -350,7 +350,7 @@ class DevicesManagementApi { try { final response = await HTTPService().put( path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), - body: {'deviceName': deviceName}, + body: {"deviceName": deviceName}, expectedResponseModel: (json) { return json['data']; }, @@ -378,7 +378,7 @@ class DevicesManagementApi { path: ApiEndpoints.resetDevice.replaceAll('{deviceUuid}', devicesUuid!), showServerMessage: false, body: { - 'devicesUuid': [devicesUuid] + "devicesUuid": [devicesUuid] }, expectedResponseModel: (json) { return json; diff --git a/lib/services/locator.dart b/lib/services/locator.dart index 27f78ab9..055deb05 100644 --- a/lib/services/locator.dart +++ b/lib/services/locator.dart @@ -5,7 +5,7 @@ import 'package:syncrow_web/services/api/http_service.dart'; final GetIt serviceLocator = GetIt.instance; //setupLocator() // to search for dependency injection in flutter -void initialSetup() { +initialSetup() { serviceLocator.registerSingleton(HTTPInterceptor()); //Base classes serviceLocator.registerSingleton(HTTPService.setupDioClient()); diff --git a/lib/services/product_api.dart b/lib/services/product_api.dart index 90dab310..02c9f143 100644 --- a/lib/services/product_api.dart +++ b/lib/services/product_api.dart @@ -9,9 +9,9 @@ class ProductApi { final response = await HTTPService().get( path: ApiEndpoints.listProducts, expectedResponseModel: (json) { - final List jsonData = json['data']; + List jsonData = json['data']; - final productList = jsonData.map((jsonItem) { + List productList = jsonData.map((jsonItem) { return ProductModel.fromMap(jsonItem); }).toList(); return productList; diff --git a/lib/services/routines_api.dart b/lib/services/routines_api.dart index f0d0b52a..bdc46ac1 100644 --- a/lib/services/routines_api.dart +++ b/lib/services/routines_api.dart @@ -29,7 +29,7 @@ class SceneApi { debugPrint('create scene response: $response'); return response; } on DioException catch (e) { - final String errorMessage = + String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -52,7 +52,7 @@ class SceneApi { debugPrint('create automation response: $response'); return response; } on DioException catch (e) { - final String errorMessage = + String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -63,7 +63,7 @@ class SceneApi { path: ApiEndpoints.getIconScene, showServerMessage: false, expectedResponseModel: (json) { - final iconsList = []; + List iconsList = []; json.forEach((element) { iconsList.add(IconModel.fromJson(element)); }); @@ -89,8 +89,8 @@ class SceneApi { expectedResponseModel: (json) { final scenesJson = json['data'] as List; - final scenes = []; - for (final scene in scenesJson) { + List scenes = []; + for (var scene in scenesJson) { scenes.add(ScenesModel.fromJson(scene, isAutomation: false)); } return scenes; @@ -114,8 +114,8 @@ class SceneApi { .replaceAll('{projectId}', projectId), showServerMessage: false, expectedResponseModel: (json) { - final scenes = []; - for (final scene in json) { + List scenes = []; + for (var scene in json) { scenes.add(ScenesModel.fromJson(scene, isAutomation: true)); } return scenes; @@ -158,8 +158,7 @@ class SceneApi { } //update Scene - static Future updateScene( - CreateSceneModel createSceneModel, String sceneId) async { + static updateScene(CreateSceneModel createSceneModel, String sceneId) async { try { final response = await _httpService.put( path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId), @@ -171,14 +170,14 @@ class SceneApi { ); return response; } on DioException catch (e) { - final String errorMessage = + String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } } //update automation - static Future updateAutomation(CreateAutomationModel createAutomationModel, + static updateAutomation(CreateAutomationModel createAutomationModel, String automationId, String projectId) async { try { final response = await _httpService.put( @@ -193,7 +192,7 @@ class SceneApi { ); return response; } on DioException catch (e) { - final String errorMessage = + String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -227,7 +226,7 @@ class SceneApi { ); return response; } on DioException catch (e) { - final String errorMessage = + String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -248,7 +247,7 @@ class SceneApi { ); return response; } on DioException catch (e) { - final String errorMessage = + String errorMessage = e.response?.data['error']['message'][0] ?? 'something went wrong'; throw APIException(errorMessage); } @@ -296,8 +295,8 @@ class SceneApi { .replaceAll('{projectId}', projectId), showServerMessage: false, expectedResponseModel: (json) { - final scenes = []; - for (final scene in json) { + List scenes = []; + for (var scene in json) { scenes.add(ScenesModel.fromJson(scene)); } return scenes; diff --git a/lib/services/space_mana_api.dart b/lib/services/space_mana_api.dart index 901d623f..14902bca 100644 --- a/lib/services/space_mana_api.dart +++ b/lib/services/space_mana_api.dart @@ -5,19 +5,22 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_m import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_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_response_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/tag_body_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/utils/constants/api_const.dart'; +import '../pages/spaces_management/all_spaces/model/subspace_model.dart'; + class CommunitySpaceManagementApi { // Community Management APIs Future> fetchCommunities(String projectId, {int page = 1}) async { try { - final allCommunities = []; - var hasNext = true; + List allCommunities = []; + bool hasNext = true; while (hasNext) { await HTTPService().get( @@ -28,10 +31,10 @@ class CommunitySpaceManagementApi { }, expectedResponseModel: (json) { try { - final List jsonData = json['data'] ?? []; + List jsonData = json['data'] ?? []; hasNext = json['hasNext'] ?? false; - final int currentPage = json['page'] ?? 1; - final communityList = jsonData.map((jsonItem) { + int currentPage = json['page'] ?? 1; + List communityList = jsonData.map((jsonItem) { return CommunityModel.fromJson(jsonItem); }).toList(); allCommunities.addAll(communityList); @@ -53,10 +56,10 @@ class CommunitySpaceManagementApi { Future fetchCommunitiesAndSpaces( {required String projectId, int page = 1, String search = ''}) async { - var paginationModel = const PaginationModel.emptyConstructor(); + PaginationModel paginationModel = const PaginationModel.emptyConstructor(); try { - var hasNext = false; + bool hasNext = false; await HTTPService().get( path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId), @@ -68,10 +71,10 @@ class CommunitySpaceManagementApi { }, expectedResponseModel: (json) { try { - final List jsonData = json['data'] ?? []; + List jsonData = json['data'] ?? []; hasNext = json['hasNext'] ?? false; - final int currentPage = json['page'] ?? 1; - final communityList = jsonData.map((jsonItem) { + int currentPage = json['page'] ?? 1; + List communityList = jsonData.map((jsonItem) { return CommunityModel.fromJson(jsonItem); }).toList(); @@ -376,12 +379,12 @@ class CommunitySpaceManagementApi { final response = await HTTPService().get( path: path, - queryParameters: {'page': 1, 'pageSize': 10}, + queryParameters: {"page": 1, "pageSize": 10}, showServerMessage: false, expectedResponseModel: (json) { - final rooms = []; + List rooms = []; if (json['data'] != null) { - for (final subspace in json['data']) { + for (var subspace in json['data']) { rooms.add(SubSpaceModel.fromJson(subspace)); } } @@ -390,7 +393,7 @@ class CommunitySpaceManagementApi { ); return response; - } catch (error) { + } catch (error, stackTrace) { return []; } } diff --git a/lib/services/space_model_mang_api.dart b/lib/services/space_model_mang_api.dart index c6fff07d..cbb9cfeb 100644 --- a/lib/services/space_model_mang_api.dart +++ b/lib/services/space_model_mang_api.dart @@ -79,7 +79,7 @@ class SpaceModelManagementApi { .replaceAll('{projectId}', projectId) .replaceAll('{spaceModelUuid}', spaceModelUuid), showServerMessage: true, - body: {'spaceUuids': spaceUuids, 'overwrite': isOverWrite}, + body: {"spaceUuids": spaceUuids, "overwrite": isOverWrite}, expectedResponseModel: (json) { return json; }, @@ -92,7 +92,7 @@ class SpaceModelManagementApi { path: ApiEndpoints.validateSpaceModel .replaceAll('{projectId}', projectId), showServerMessage: true, - body: {'spacesUuids': spaceUuids}, + body: {"spacesUuids": spaceUuids}, expectedResponseModel: (json) { return json; }); @@ -116,7 +116,7 @@ class SpaceModelManagementApi { final response = await HTTPService().get( path: ApiEndpoints.listTags.replaceAll('{projectId}', projectId), expectedResponseModel: (json) { - final List jsonData = json['data']; + List jsonData = json['data']; return jsonData.map((jsonItem) { return Tag.fromJson(jsonItem); }).toList(); diff --git a/lib/services/user_permission.dart b/lib/services/user_permission.dart index 881f92df..3f02663d 100644 --- a/lib/services/user_permission.dart +++ b/lib/services/user_permission.dart @@ -23,18 +23,18 @@ class UserPermissionApi { }, ); return response; - } catch (e) { + } catch (e, stackTrace) { debugPrint('Error in fetchUsers: $e'); rethrow; } } - Future> fetchRoles() async { + fetchRoles() async { final response = await _httpService.get( path: ApiEndpoints.roleTypes, showServerMessage: true, expectedResponseModel: (json) { - final fetchedRoles = (json['data'] as List) + final List fetchedRoles = (json['data'] as List) .map((item) => RoleTypeModel.fromJson(item)) .toList(); return fetchedRoles; @@ -45,7 +45,7 @@ class UserPermissionApi { Future> fetchPermission(roleUuid) async { final response = await _httpService.get( - path: ApiEndpoints.permission.replaceAll('roleUuid', roleUuid), + path: ApiEndpoints.permission.replaceAll("roleUuid", roleUuid), showServerMessage: true, expectedResponseModel: (json) { return (json as List) @@ -68,14 +68,14 @@ class UserPermissionApi { }) async { try { final body = { - 'firstName': firstName, - 'lastName': lastName, - 'email': email, - 'jobTitle': jobTitle != '' ? jobTitle : null, - 'phoneNumber': phoneNumber != '' ? phoneNumber : null, - 'roleUuid': roleUuid, - 'projectUuid': projectUuid, - 'spaceUuids': spaceUuids, + "firstName": firstName, + "lastName": lastName, + "email": email, + "jobTitle": jobTitle != '' ? jobTitle : null, + "phoneNumber": phoneNumber != '' ? phoneNumber : null, + "roleUuid": roleUuid, + "projectUuid": projectUuid, + "spaceUuids": spaceUuids, }; final response = await _httpService.post( path: ApiEndpoints.inviteUser, @@ -83,7 +83,7 @@ class UserPermissionApi { body: jsonEncode(body), expectedResponseModel: (json) { if (json['statusCode'] != 400) { - return json['success']; + return json["success"]; } else { return false; } @@ -91,7 +91,7 @@ class UserPermissionApi { ); return response ?? []; - } on DioException { + } on DioException catch (e) { return false; } catch (e) { return false; @@ -103,10 +103,10 @@ class UserPermissionApi { final response = await _httpService.post( path: ApiEndpoints.checkEmail, showServerMessage: true, - body: {'email': email}, + body: {"email": email}, expectedResponseModel: (json) { if (json['statusCode'] != 400) { - final message = json['message']; + var message = json["message"]; if (message is String) { return message; } else { @@ -128,11 +128,11 @@ class UserPermissionApi { Future fetchUserById(userUuid, String projectId) async { final response = await _httpService.get( path: ApiEndpoints.getUserById - .replaceAll('{userUuid}', userUuid) - .replaceAll('{projectId}', projectId), + .replaceAll("{userUuid}", userUuid) + .replaceAll("{projectId}", projectId), showServerMessage: true, expectedResponseModel: (json) { - final res = EditUserModel.fromJson(json['data']); + EditUserModel res = EditUserModel.fromJson(json['data']); return res; }, ); @@ -151,27 +151,27 @@ class UserPermissionApi { }) async { try { final body = { - 'firstName': firstName, - 'lastName': lastName, - 'jobTitle': jobTitle != '' ? jobTitle : ' ', - 'phoneNumber': phoneNumber != '' ? phoneNumber : ' ', - 'roleUuid': roleUuid, - 'projectUuid': projectUuid, - 'spaceUuids': spaceUuids, + "firstName": firstName, + "lastName": lastName, + "jobTitle": jobTitle != '' ? jobTitle : " ", + "phoneNumber": phoneNumber != '' ? phoneNumber : " ", + "roleUuid": roleUuid, + "projectUuid": projectUuid, + "spaceUuids": spaceUuids, }; final response = await _httpService.put( path: ApiEndpoints.editUser.replaceAll('{inviteUserUuid}', userId!), body: jsonEncode(body), expectedResponseModel: (json) { if (json['statusCode'] != 400) { - return json['success']; + return json["success"]; } else { return false; } }, ); return response; - } on DioException { + } on DioException catch (e) { return false; } catch (e) { return false; @@ -181,7 +181,7 @@ class UserPermissionApi { Future deleteUserById(userUuid) async { try { final response = await _httpService.delete( - path: ApiEndpoints.deleteUser.replaceAll('{inviteUserUuid}', userUuid), + path: ApiEndpoints.deleteUser.replaceAll("{inviteUserUuid}", userUuid), showServerMessage: true, expectedResponseModel: (json) { return json['success']; @@ -193,17 +193,16 @@ class UserPermissionApi { } } - Future changeUserStatusById( - userUuid, status, String projectUuid) async { + Future changeUserStatusById(userUuid, status, String projectUuid) async { try { - final bodya = { - 'disable': status, - 'projectUuid': projectUuid + Map bodya = { + "disable": status, + "projectUuid": projectUuid }; final response = await _httpService.put( path: ApiEndpoints.changeUserStatus - .replaceAll('{invitedUserUuid}', userUuid), + .replaceAll("{invitedUserUuid}", userUuid), body: bodya, expectedResponseModel: (json) { return json['success']; diff --git a/lib/utils/color_manager.dart b/lib/utils/color_manager.dart index 2b164590..50170ed9 100644 --- a/lib/utils/color_manager.dart +++ b/lib/utils/color_manager.dart @@ -6,15 +6,15 @@ abstract class ColorsManager { static const Color primaryColor = Color(0xFF0030CB); //023DFE static const Color secondaryTextColor = Color(0xFF848484); static Color primaryColorWithOpacity = - const Color(0xFF023DFE).withValues(alpha: 0.6); + const Color(0xFF023DFE).withOpacity(0.6); static const Color whiteColors = Colors.white; - static Color whiteColorsWithOpacity = Colors.white.withValues(alpha: 0.6); + static Color whiteColorsWithOpacity = Colors.white.withOpacity(0.6); static const Color secondaryColor = Color(0xFF023DFE); static const Color onSecondaryColor = Color(0xFF023DFE); - static Color shadowBlackColor = Colors.black.withValues(alpha: 0.2); + static Color shadowBlackColor = Colors.black.withOpacity(0.2); - static Color dialogBlueTitle = const Color(0xFF023DFE).withValues(alpha: 0.6); + static Color dialogBlueTitle = const Color(0xFF023DFE).withOpacity(0.6); static const Color primaryTextColor = Colors.black; @@ -83,5 +83,7 @@ abstract class ColorsManager { static const Color maxPurpleDot = Color(0xFF5F00BD); static const Color minBlue = Color(0xFF93AAFD); static const Color minBlueDot = Color(0xFF023DFE); - static const Color grey25 = Color(0xFFF9F9F9); + static const Color grey25 = Color(0xFFF9F9F9); + + } diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index bfdb729d..411e72a5 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -1,7 +1,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; abstract class ApiEndpoints { - static const String projectUuid = '0e62577c-06fa-41b9-8a92-99a21fbaf51c'; + static const String projectUuid = "0e62577c-06fa-41b9-8a92-99a21fbaf51c"; static String baseUrl = dotenv.env['BASE_URL'] ?? ''; static const String signUp = '/authentication/user/signup'; static const String login = '/authentication/user/login'; diff --git a/lib/utils/constants/app_enum.dart b/lib/utils/constants/app_enum.dart index ec5aeb2d..d603c3ea 100644 --- a/lib/utils/constants/app_enum.dart +++ b/lib/utils/constants/app_enum.dart @@ -9,28 +9,28 @@ extension AccessTypeExtension on AccessType { String get value { switch (this) { case AccessType.onlineOnetime: - return 'Online Password'; + return "Online Password"; case AccessType.onlineMultiple: - return 'online Multiple Password'; + return "online Multiple Password"; case AccessType.offlineOnetime: - return 'Offline Onetime Password'; + return "Offline Onetime Password"; case AccessType.offlineMultiple: - return 'Offline Multiple Password'; + return "Offline Multiple Password"; } } static AccessType fromString(String value) { switch (value) { - case 'ONLINE_ONETIME': + case "ONLINE_ONETIME": return AccessType.onlineOnetime; - case 'ONLINE_MULTIPLE': + case "ONLINE_MULTIPLE": return AccessType.onlineMultiple; - case 'OFFLINE_ONETIME': + case "OFFLINE_ONETIME": return AccessType.offlineOnetime; - case 'OFFLINE_MULTIPLE': + case "OFFLINE_MULTIPLE": return AccessType.offlineMultiple; default: - throw ArgumentError('Invalid access type: $value'); + throw ArgumentError("Invalid access type: $value"); } } } @@ -44,9 +44,9 @@ extension OnlineTypeExtension on DeviseStatus { String get value { switch (this) { case DeviseStatus.online: - return 'Online'; + return "Online"; case DeviseStatus.offline: - return 'Offline'; + return "Offline"; } } @@ -57,7 +57,7 @@ extension OnlineTypeExtension on DeviseStatus { case true: return DeviseStatus.online; default: - throw ArgumentError('Invalid access type: $value'); + throw ArgumentError("Invalid access type: $value"); } } } @@ -72,24 +72,24 @@ extension AccessStatusExtension on AccessStatus { String get value { switch (this) { case AccessStatus.expired: - return 'Expired'; + return "Expired"; case AccessStatus.effective: - return 'Effective'; + return "Effective"; case AccessStatus.toBeEffective: - return 'To be effective'; + return "To be effective"; } } static AccessStatus fromString(String value) { switch (value) { - case 'EXPIRED': + case "EXPIRED": return AccessStatus.expired; - case 'EFFECTIVE': + case "EFFECTIVE": return AccessStatus.effective; - case 'TO_BE_EFFECTIVE': + case "TO_BE_EFFECTIVE": return AccessStatus.toBeEffective; default: - throw ArgumentError('Invalid access type: $value'); + throw ArgumentError("Invalid access type: $value"); } } } diff --git a/lib/utils/constants/assets.dart b/lib/utils/constants/assets.dart index 5f030841..dfc0b394 100644 --- a/lib/utils/constants/assets.dart +++ b/lib/utils/constants/assets.dart @@ -1,138 +1,138 @@ class Assets { Assets._(); - static const String background = 'assets/images/Background.png'; - static const String webBackground = 'assets/images/web_Background.svg'; - static const String webBackgroundPng = 'assets/images/web_Background.png'; - static const String blackLogo = 'assets/images/black-logo.png'; - static const String logo = 'assets/images/Logo.svg'; - static const String logoHorizontal = 'assets/images/logo_horizontal.png'; - static const String vector = 'assets/images/Vector.png'; - static const String loginLogo = 'assets/images/login_logo.svg'; - static const String whiteLogo = 'assets/images/white-logo.png'; - static const String window = 'assets/images/Window.png'; - static const String liftLine = 'assets/images/lift_line.png'; - static const String rightLine = 'assets/images/right_line.png'; - static const String google = 'assets/images/google.svg'; - static const String facebook = 'assets/images/facebook.svg'; + static const String background = "assets/images/Background.png"; + static const String webBackground = "assets/images/web_Background.svg"; + static const String webBackgroundPng = "assets/images/web_Background.png"; + static const String blackLogo = "assets/images/black-logo.png"; + static const String logo = "assets/images/Logo.svg"; + static const String logoHorizontal = "assets/images/logo_horizontal.png"; + static const String vector = "assets/images/Vector.png"; + static const String loginLogo = "assets/images/login_logo.svg"; + static const String whiteLogo = "assets/images/white-logo.png"; + static const String window = "assets/images/Window.png"; + static const String liftLine = "assets/images/lift_line.png"; + static const String rightLine = "assets/images/right_line.png"; + static const String google = "assets/images/google.svg"; + static const String facebook = "assets/images/facebook.svg"; static const String invisiblePassword = - 'assets/images/Password_invisible.svg'; - static const String visiblePassword = 'assets/images/password_visible.svg'; - static const String accessIcon = 'assets/images/access_icon.svg'; + "assets/images/Password_invisible.svg"; + static const String visiblePassword = "assets/images/password_visible.svg"; + static const String accessIcon = "assets/images/access_icon.svg"; static const String spaseManagementIcon = - 'assets/images/spase_management_icon.svg'; - static const String devicesIcon = 'assets/images/devices_icon.svg'; - static const String analyticsIcon = 'assets/icons/landing_analytics.svg'; + "assets/images/spase_management_icon.svg"; + static const String devicesIcon = "assets/images/devices_icon.svg"; + static const String analyticsIcon = "assets/icons/landing_analytics.svg"; - static const String moveinIcon = 'assets/images/movein_icon.svg'; - static const String constructionIcon = 'assets/images/construction_icon.svg'; - static const String energyIcon = 'assets/images/energy_icon.svg'; - static const String integrationsIcon = 'assets/images/Integrations_icon.svg'; - static const String assetIcon = 'assets/images/asset_icon.svg'; - static const String calendarIcon = 'assets/images/calendar_icon.svg'; - static const String deviceNoteIcon = 'assets/images/device_note.svg'; - static const String timeIcon = 'assets/images/time_icon.svg'; - static const String emptyTable = 'assets/images/empty_table.svg'; + static const String moveinIcon = "assets/images/movein_icon.svg"; + static const String constructionIcon = "assets/images/construction_icon.svg"; + static const String energyIcon = "assets/images/energy_icon.svg"; + static const String integrationsIcon = "assets/images/Integrations_icon.svg"; + static const String assetIcon = "assets/images/asset_icon.svg"; + static const String calendarIcon = "assets/images/calendar_icon.svg"; + static const String deviceNoteIcon = "assets/images/device_note.svg"; + static const String timeIcon = "assets/images/time_icon.svg"; + static const String emptyTable = "assets/images/empty_table.svg"; // General assets static const String motionlessDetection = - 'assets/icons/motionless_detection.svg'; - static const String acHeating = 'assets/icons/ac_heating.svg'; - static const String acPowerOff = 'assets/icons/ac_power_off.svg'; - static const String acFanMiddle = 'assets/icons/ac_fan_middle.svg'; - static const String switchAlarmSound = 'assets/icons/switch_alarm_sound.svg'; - static const String resetOff = 'assets/icons/reset_off.svg'; + "assets/icons/motionless_detection.svg"; + static const String acHeating = "assets/icons/ac_heating.svg"; + static const String acPowerOff = "assets/icons/ac_power_off.svg"; + static const String acFanMiddle = "assets/icons/ac_fan_middle.svg"; + static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg"; + static const String resetOff = "assets/icons/reset_off.svg"; static const String sensitivityOperationIcon = - 'assets/icons/sesitivity_operation_icon.svg'; - static const String motionDetection = 'assets/icons/motion_detection.svg'; - static const String freezing = 'assets/icons/freezing.svg'; - static const String indicator = 'assets/icons/indicator.svg'; - static const String sceneRefresh = 'assets/icons/scene_refresh.svg'; - static const String temperature = 'assets/icons/tempreture.svg'; - static const String acFanHigh = 'assets/icons/ac_fan_high.svg'; - static const String fanSpeed = 'assets/icons/fan_speed.svg'; - static const String acFanLow = 'assets/icons/ac_fan_low.svg'; - static const String sensitivity = 'assets/icons/sensitivity.svg'; - static const String lightCountdown = 'assets/icons/light_countdown.svg'; - static const String farDetection = 'assets/icons/far_detection.svg'; - static const String sceneChildUnlock = 'assets/icons/scene_child_unlock.svg'; - static const String acFanAuto = 'assets/icons/ac_fan_auto.svg'; - static const String childLock = 'assets/icons/child_lock.svg'; - static const String factoryReset = 'assets/icons/factory_reset.svg'; - static const String acCooling = 'assets/icons/ac_cooling.svg'; - static const String sceneChildLock = 'assets/icons/scene_child_lock.svg'; - static const String celsiusDegrees = 'assets/icons/celsius_degrees.svg'; - static const String masterState = 'assets/icons/master_state.svg'; - static const String acPower = 'assets/icons/ac_power.svg'; + "assets/icons/sesitivity_operation_icon.svg"; + static const String motionDetection = "assets/icons/motion_detection.svg"; + static const String freezing = "assets/icons/freezing.svg"; + static const String indicator = "assets/icons/indicator.svg"; + static const String sceneRefresh = "assets/icons/scene_refresh.svg"; + static const String temperature = "assets/icons/tempreture.svg"; + static const String acFanHigh = "assets/icons/ac_fan_high.svg"; + static const String fanSpeed = "assets/icons/fan_speed.svg"; + static const String acFanLow = "assets/icons/ac_fan_low.svg"; + static const String sensitivity = "assets/icons/sensitivity.svg"; + static const String lightCountdown = "assets/icons/light_countdown.svg"; + static const String farDetection = "assets/icons/far_detection.svg"; + static const String sceneChildUnlock = "assets/icons/scene_child_unlock.svg"; + static const String acFanAuto = "assets/icons/ac_fan_auto.svg"; + static const String childLock = "assets/icons/child_lock.svg"; + static const String factoryReset = "assets/icons/factory_reset.svg"; + static const String acCooling = "assets/icons/ac_cooling.svg"; + static const String sceneChildLock = "assets/icons/scene_child_lock.svg"; + static const String celsiusDegrees = "assets/icons/celsius_degrees.svg"; + static const String masterState = "assets/icons/master_state.svg"; + static const String acPower = "assets/icons/ac_power.svg"; static const String farDetectionFunction = - 'assets/icons/far_detection_function.svg'; - static const String nobodyTime = 'assets/icons/nobody_time.svg'; + "assets/icons/far_detection_function.svg"; + static const String nobodyTime = "assets/icons/nobody_time.svg"; // Automation functions static const String tempPasswordUnlock = - 'assets/icons/automation_functions/temp_password_unlock.svg'; + "assets/icons/automation_functions/temp_password_unlock.svg"; static const String doorlockNormalOpen = - 'assets/icons/automation_functions/doorlock_normal_open.svg'; + "assets/icons/automation_functions/doorlock_normal_open.svg"; static const String doorbell = - 'assets/icons/automation_functions/doorbell.svg'; + "assets/icons/automation_functions/doorbell.svg"; static const String remoteUnlockViaApp = - 'assets/icons/automation_functions/remote_unlock_via_app.svg'; + "assets/icons/automation_functions/remote_unlock_via_app.svg"; static const String doubleLock = - 'assets/icons/automation_functions/double_lock.svg'; + "assets/icons/automation_functions/double_lock.svg"; static const String selfTestResult = - 'assets/icons/automation_functions/self_test_result.svg'; + "assets/icons/automation_functions/self_test_result.svg"; static const String lockAlarm = - 'assets/icons/automation_functions/lock_alarm.svg'; + "assets/icons/automation_functions/lock_alarm.svg"; static const String presenceState = - 'assets/icons/automation_functions/presence_state.svg'; + "assets/icons/automation_functions/presence_state.svg"; static const String currentTemp = - 'assets/icons/automation_functions/current_temp.svg'; + "assets/icons/automation_functions/current_temp.svg"; static const String presence = - 'assets/icons/automation_functions/presence.svg'; + "assets/icons/automation_functions/presence.svg"; static const String residualElectricity = - 'assets/icons/automation_functions/residual_electricity.svg'; + "assets/icons/automation_functions/residual_electricity.svg"; static const String hijackAlarm = - 'assets/icons/automation_functions/hijack_alarm.svg'; + "assets/icons/automation_functions/hijack_alarm.svg"; static const String passwordUnlock = - 'assets/icons/automation_functions/password_unlock.svg'; + "assets/icons/automation_functions/password_unlock.svg"; static const String remoteUnlockRequest = - 'assets/icons/automation_functions/remote_unlock_req.svg'; + "assets/icons/automation_functions/remote_unlock_req.svg"; static const String cardUnlock = - 'assets/icons/automation_functions/card_unlock.svg'; - static const String motion = 'assets/icons/automation_functions/motion.svg'; + "assets/icons/automation_functions/card_unlock.svg"; + static const String motion = "assets/icons/automation_functions/motion.svg"; static const String fingerprintUnlock = - 'assets/icons/automation_functions/fingerprint_unlock.svg'; + "assets/icons/automation_functions/fingerprint_unlock.svg"; // Presence Sensor Assets - static const String sensorMotionIcon = 'assets/icons/sensor_motion_ic.svg'; + static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg"; static const String sensorPresenceIcon = - 'assets/icons/sensor_presence_ic.svg'; - static const String sensorVacantIcon = 'assets/icons/sensor_vacant_ic.svg'; + "assets/icons/sensor_presence_ic.svg"; + static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg"; static const String illuminanceRecordIcon = - 'assets/icons/illuminance_record_ic.svg'; + "assets/icons/illuminance_record_ic.svg"; static const String presenceRecordIcon = - 'assets/icons/presence_record_ic.svg'; + "assets/icons/presence_record_ic.svg"; static const String helpDescriptionIcon = - 'assets/icons/help_description_ic.svg'; + "assets/icons/help_description_ic.svg"; - static const String lightPulp = 'assets/icons/light_pulb.svg'; - static const String acDevice = 'assets/icons/ac_device.svg'; - static const String acAirConditioner = 'assets/icons/ac_air.svg'; - static const String acSun = 'assets/icons/ac_sun.svg'; + static const String lightPulp = "assets/icons/light_pulb.svg"; + static const String acDevice = "assets/icons/ac_device.svg"; + static const String acAirConditioner = "assets/icons/ac_air.svg"; + static const String acSun = "assets/icons/ac_sun.svg"; //assets/icons/3GangSwitch.svg - static const String gangSwitch = 'assets/icons/3GangSwitch.svg'; + static const String gangSwitch = "assets/icons/3GangSwitch.svg"; //assets/icons/AC.svg - static const String ac = 'assets/icons/AC.svg'; + static const String ac = "assets/icons/AC.svg"; //assets/icons/Curtain.svg - static const String curtain = 'assets/icons/Curtain.svg'; + static const String curtain = "assets/icons/Curtain.svg"; //assets/icons/doorLock.svg - static const String doorLock = 'assets/icons/doorLock.svg'; + static const String doorLock = "assets/icons/doorLock.svg"; //assets/icons/Gateway.svg - static const String gateway = 'assets/icons/Gateway.svg'; + static const String gateway = "assets/icons/Gateway.svg"; //assets/icons/Light.svg - static const String lightBulb = 'assets/icons/Light.svg'; + static const String lightBulb = "assets/icons/Light.svg"; //assets/icons/sensors.svg - static const String sensors = 'assets/icons/sensors.svg'; + static const String sensors = "assets/icons/sensors.svg"; //assets/icons/door_un_look_ic.svg static const String doorUnlock = 'assets/icons/door_un_look_ic.svg'; @@ -175,7 +175,7 @@ class Assets { static const String Gang1SwitchIcon = 'assets/icons/1_Gang_switch_icon.svg'; static const String DoorLockIcon = 'assets/icons/door_lock.svg'; static const String SmartGatewayIcon = 'assets/icons/smart_gateway_icon.svg'; - static const String curtainIcon = 'assets/images/curtain.svg'; + static const String curtainIcon = "assets/images/curtain.svg"; static const String unlock = 'assets/icons/unlock_ic.svg'; static const String firmware = 'assets/icons/firmware.svg'; //assets/images/scheduling.svg @@ -227,12 +227,12 @@ class Assets { //assets/icons/2gang.svg static const String twoGang = 'assets/icons/2gang.svg'; - static const String frequencyIcon = 'assets/icons/frequency_icon.svg'; - static const String voltMeterIcon = 'assets/icons/volt_meter_icon.svg'; - static const String powerActiveIcon = 'assets/icons/power_active_icon.svg'; - static const String searchIcon = 'assets/icons/search_icon.svg'; - static const String voltageIcon = 'assets/icons/voltage_icon.svg'; - static const String speedoMeter = 'assets/icons/speedo_meter.svg'; + static const String frequencyIcon = "assets/icons/frequency_icon.svg"; + static const String voltMeterIcon = "assets/icons/volt_meter_icon.svg"; + static const String powerActiveIcon = "assets/icons/power_active_icon.svg"; + static const String searchIcon = "assets/icons/search_icon.svg"; + static const String voltageIcon = "assets/icons/voltage_icon.svg"; + static const String speedoMeter = "assets/icons/speedo_meter.svg"; //assets/icons/account_setting.svg static const String accountSetting = 'assets/icons/account_setting.svg'; @@ -284,99 +284,99 @@ class Assets { // Assets for functions_icons static const String assetsSensitivityFunction = - 'assets/icons/functions_icons/sensitivity.svg'; + "assets/icons/functions_icons/sensitivity.svg"; static const String assetsSensitivityOperationIcon = - 'assets/icons/functions_icons/sesitivity_operation_icon.svg'; + "assets/icons/functions_icons/sesitivity_operation_icon.svg"; static const String assetsAcPower = - 'assets/icons/functions_icons/ac_power.svg'; + "assets/icons/functions_icons/ac_power.svg"; static const String assetsAcPowerOFF = - 'assets/icons/functions_icons/ac_power_off.svg'; + "assets/icons/functions_icons/ac_power_off.svg"; static const String assetsChildLock = - 'assets/icons/functions_icons/child_lock.svg'; + "assets/icons/functions_icons/child_lock.svg"; static const String assetsFreezing = - 'assets/icons/functions_icons/freezing.svg'; + "assets/icons/functions_icons/freezing.svg"; static const String assetsFanSpeed = - 'assets/icons/functions_icons/fan_speed.svg'; + "assets/icons/functions_icons/fan_speed.svg"; static const String assetsAcCooling = - 'assets/icons/functions_icons/ac_cooling.svg'; + "assets/icons/functions_icons/ac_cooling.svg"; static const String assetsAcHeating = - 'assets/icons/functions_icons/ac_heating.svg'; + "assets/icons/functions_icons/ac_heating.svg"; static const String assetsCelsiusDegrees = - 'assets/icons/functions_icons/celsius_degrees.svg'; + "assets/icons/functions_icons/celsius_degrees.svg"; static const String assetsTempreture = - 'assets/icons/functions_icons/tempreture.svg'; + "assets/icons/functions_icons/tempreture.svg"; static const String assetsAcFanLow = - 'assets/icons/functions_icons/ac_fan_low.svg'; + "assets/icons/functions_icons/ac_fan_low.svg"; static const String assetsAcFanMiddle = - 'assets/icons/functions_icons/ac_fan_middle.svg'; + "assets/icons/functions_icons/ac_fan_middle.svg"; static const String assetsAcFanHigh = - 'assets/icons/functions_icons/ac_fan_high.svg'; + "assets/icons/functions_icons/ac_fan_high.svg"; static const String assetsAcFanAuto = - 'assets/icons/functions_icons/ac_fan_auto.svg'; + "assets/icons/functions_icons/ac_fan_auto.svg"; static const String assetsSceneChildLock = - 'assets/icons/functions_icons/scene_child_lock.svg'; + "assets/icons/functions_icons/scene_child_lock.svg"; static const String assetsSceneChildUnlock = - 'assets/icons/functions_icons/scene_child_unlock.svg'; + "assets/icons/functions_icons/scene_child_unlock.svg"; static const String assetsSceneRefresh = - 'assets/icons/functions_icons/scene_refresh.svg'; + "assets/icons/functions_icons/scene_refresh.svg"; static const String assetsLightCountdown = - 'assets/icons/functions_icons/light_countdown.svg'; + "assets/icons/functions_icons/light_countdown.svg"; static const String assetsFarDetection = - 'assets/icons/functions_icons/far_detection.svg'; + "assets/icons/functions_icons/far_detection.svg"; static const String assetsFarDetectionFunction = - 'assets/icons/functions_icons/far_detection_function.svg'; + "assets/icons/functions_icons/far_detection_function.svg"; static const String assetsIndicator = - 'assets/icons/functions_icons/indicator.svg'; + "assets/icons/functions_icons/indicator.svg"; static const String assetsMotionDetection = - 'assets/icons/functions_icons/motion_detection.svg'; + "assets/icons/functions_icons/motion_detection.svg"; static const String assetsMotionlessDetection = - 'assets/icons/functions_icons/motionless_detection.svg'; + "assets/icons/functions_icons/motionless_detection.svg"; static const String assetsNobodyTime = - 'assets/icons/functions_icons/nobody_time.svg'; + "assets/icons/functions_icons/nobody_time.svg"; static const String assetsFactoryReset = - 'assets/icons/functions_icons/factory_reset.svg'; + "assets/icons/functions_icons/factory_reset.svg"; static const String assetsMasterState = - 'assets/icons/functions_icons/master_state.svg'; + "assets/icons/functions_icons/master_state.svg"; static const String assetsSwitchAlarmSound = - 'assets/icons/functions_icons/switch_alarm_sound.svg'; + "assets/icons/functions_icons/switch_alarm_sound.svg"; static const String assetsResetOff = - 'assets/icons/functions_icons/reset_off.svg'; + "assets/icons/functions_icons/reset_off.svg"; // Assets for automation_functions static const String assetsCardUnlock = - 'assets/icons/functions_icons/automation_functions/card_unlock.svg'; + "assets/icons/functions_icons/automation_functions/card_unlock.svg"; static const String assetsDoorbell = - 'assets/icons/functions_icons/automation_functions/doorbell.svg'; + "assets/icons/functions_icons/automation_functions/doorbell.svg"; static const String assetsDoorlockNormalOpen = - 'assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg'; + "assets/icons/functions_icons/automation_functions/doorlock_normal_open.svg"; static const String assetsDoubleLock = - 'assets/icons/functions_icons/automation_functions/double_lock.svg'; + "assets/icons/functions_icons/automation_functions/double_lock.svg"; static const String assetsFingerprintUnlock = - 'assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg'; + "assets/icons/functions_icons/automation_functions/fingerprint_unlock.svg"; static const String assetsHijackAlarm = - 'assets/icons/functions_icons/automation_functions/hijack_alarm.svg'; + "assets/icons/functions_icons/automation_functions/hijack_alarm.svg"; static const String assetsLockAlarm = - 'assets/icons/functions_icons/automation_functions/lock_alarm.svg'; + "assets/icons/functions_icons/automation_functions/lock_alarm.svg"; static const String assetsPasswordUnlock = - 'assets/icons/functions_icons/automation_functions/password_unlock.svg'; + "assets/icons/functions_icons/automation_functions/password_unlock.svg"; static const String assetsRemoteUnlockReq = - 'assets/icons/functions_icons/automation_functions/remote_unlock_req.svg'; + "assets/icons/functions_icons/automation_functions/remote_unlock_req.svg"; static const String assetsRemoteUnlockViaApp = - 'assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg'; + "assets/icons/functions_icons/automation_functions/remote_unlock_via_app.svg"; static const String assetsResidualElectricity = - 'assets/icons/functions_icons/automation_functions/residual_electricity.svg'; + "assets/icons/functions_icons/automation_functions/residual_electricity.svg"; static const String assetsTempPasswordUnlock = - 'assets/icons/functions_icons/automation_functions/temp_password_unlock.svg'; + "assets/icons/functions_icons/automation_functions/temp_password_unlock.svg"; static const String assetsSelfTestResult = - 'assets/icons/functions_icons/automation_functions/self_test_result.svg'; + "assets/icons/functions_icons/automation_functions/self_test_result.svg"; static const String assetsPresence = - 'assets/icons/functions_icons/automation_functions/presence.svg'; + "assets/icons/functions_icons/automation_functions/presence.svg"; static const String assetsMotion = - 'assets/icons/functions_icons/automation_functions/motion.svg'; + "assets/icons/functions_icons/automation_functions/motion.svg"; static const String assetsCurrentTemp = - 'assets/icons/functions_icons/automation_functions/current_temp.svg'; + "assets/icons/functions_icons/automation_functions/current_temp.svg"; static const String assetsPresenceState = - 'assets/icons/functions_icons/automation_functions/presence_state.svg'; + "assets/icons/functions_icons/automation_functions/presence_state.svg"; //assets/icons/routine/automation.svg static const String automation = 'assets/icons/routine/automation.svg'; static const String searchIconUser = 'assets/icons/search_icon_user.svg'; diff --git a/lib/utils/constants/strings_manager.dart b/lib/utils/constants/strings_manager.dart index 3f70b347..2ea63fe4 100644 --- a/lib/utils/constants/strings_manager.dart +++ b/lib/utils/constants/strings_manager.dart @@ -22,13 +22,13 @@ class StringsManager { static const String on = 'ON'; static const String off = 'OFF'; static const String timer = 'Timer'; - static const String dimmerAndColor = 'Dimmer & color'; - static const String recentlyUsed = 'Recently used colors'; - static const String lightingModes = 'Lighting modes'; - static const String doze = 'Doze'; - static const String relax = 'Relax'; - static const String reading = 'Reading'; - static const String energizing = 'Energizing'; + static const String dimmerAndColor = "Dimmer & color"; + static const String recentlyUsed = "Recently used colors"; + static const String lightingModes = "Lighting modes"; + static const String doze = "Doze"; + static const String relax = "Relax"; + static const String reading = "Reading"; + static const String energizing = "Energizing"; static const String createScene = 'Create Scene'; static const String tapToRun = 'Launch: Tap - To - Run'; static const String turnOffAllLights = @@ -36,8 +36,8 @@ class StringsManager { static const String whenDeviceStatusChanges = 'When device status changes'; static const String whenUnusualActivityIsDetected = 'Example: when an unusual activity is detected.'; - static const String functions = 'Functions'; - static const String firstLaunch = 'firstLaunch'; + static const String functions = "Functions"; + static const String firstLaunch = "firstLaunch"; static const String deleteScene = 'Delete Scene'; static const String deleteAutomation = 'Delete Automation'; static const String projectKey = 'selected_project_uuid'; diff --git a/lib/utils/enum/device_types.dart b/lib/utils/enum/device_types.dart index 0af5510b..9bfd322f 100644 --- a/lib/utils/enum/device_types.dart +++ b/lib/utils/enum/device_types.dart @@ -43,20 +43,20 @@ enum DeviceType { */ Map devicesTypesMap = { - 'AC': DeviceType.AC, - 'GW': DeviceType.Gateway, - 'CPS': DeviceType.CeilingSensor, - 'DL': DeviceType.DoorLock, - 'WPS': DeviceType.WallSensor, - '3G': DeviceType.ThreeGang, - '2G': DeviceType.TwoGang, - '1G': DeviceType.OneGang, - 'CUR': DeviceType.Curtain, - 'WH': DeviceType.WH, + "AC": DeviceType.AC, + "GW": DeviceType.Gateway, + "CPS": DeviceType.CeilingSensor, + "DL": DeviceType.DoorLock, + "WPS": DeviceType.WallSensor, + "3G": DeviceType.ThreeGang, + "2G": DeviceType.TwoGang, + "1G": DeviceType.OneGang, + "CUR": DeviceType.Curtain, + "WH": DeviceType.WH, 'DS': DeviceType.DoorSensor, - '1GT': DeviceType.OneGang, - '2GT': DeviceType.TwoGang, - '3GT': DeviceType.ThreeGang, + "1GT": DeviceType.OneGang, + "2GT": DeviceType.TwoGang, + "3GT": DeviceType.ThreeGang, 'GD': DeviceType.GarageDoor, 'WL': DeviceType.WaterLeak, 'NCPS': DeviceType.NCPS, diff --git a/lib/utils/extension/build_context_x.dart b/lib/utils/extension/build_context_x.dart index 1c3a5dbc..0abd16a1 100644 --- a/lib/utils/extension/build_context_x.dart +++ b/lib/utils/extension/build_context_x.dart @@ -22,14 +22,14 @@ extension BuildContextExt on BuildContext { required VoidCallback onConfirm, VoidCallback? onDismiss, bool? hideConfirmButton, - double? dialogWidth, + final double? dialogWidth, TextStyle? titleStyle, String? onDismissText, String? onConfirmText, Color? onDismissColor, Color? onConfirmColor, }) { - showDialog( + showDialog( context: this, builder: (BuildContext context) { return AlertDialog( @@ -74,59 +74,58 @@ extension BuildContextExt on BuildContext { width: double.infinity, color: ColorsManager.greyColor, ), - if (hideConfirmButton != true) - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: onDismiss ?? - () { - Navigator.pop(context); - }, - child: Center( - child: Text( - onDismissText ?? 'Cancel', - style: context.textTheme.bodyMedium!.copyWith( - color: - onDismissColor ?? ColorsManager.greyColor), + hideConfirmButton != true + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: onDismiss ?? + () { + Navigator.pop(context); + }, + child: Center( + child: Text( + onDismissText ?? 'Cancel', + style: context.textTheme.bodyMedium!.copyWith( + color: onDismissColor ?? + ColorsManager.greyColor), + ), + ), + ), + Container( + height: 50, + width: 1, + color: ColorsManager.greyColor, + ), + GestureDetector( + onTap: onConfirm, + child: Center( + child: Text( + onConfirmText ?? 'Confirm', + style: context.textTheme.bodyMedium!.copyWith( + color: onConfirmColor ?? + ColorsManager.primaryColorWithOpacity), + ), + ), + ), + ], + ) + : Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: GestureDetector( + onTap: onDismiss ?? + () { + Navigator.pop(context); + }, + child: Center( + child: Text( + 'Cancel', + style: context.textTheme.bodyMedium! + .copyWith(color: ColorsManager.greyColor), + ), ), ), ), - Container( - height: 50, - width: 1, - color: ColorsManager.greyColor, - ), - GestureDetector( - onTap: onConfirm, - child: Center( - child: Text( - onConfirmText ?? 'Confirm', - style: context.textTheme.bodyMedium!.copyWith( - color: onConfirmColor ?? - ColorsManager.primaryColorWithOpacity), - ), - ), - ), - ], - ) - else - Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: GestureDetector( - onTap: onDismiss ?? - () { - Navigator.pop(context); - }, - child: Center( - child: Text( - 'Cancel', - style: context.textTheme.bodyMedium! - .copyWith(color: ColorsManager.greyColor), - ), - ), - ), - ), ], ), ), diff --git a/lib/utils/format_date_time.dart b/lib/utils/format_date_time.dart index 2b63b1d4..98d0eb5e 100644 --- a/lib/utils/format_date_time.dart +++ b/lib/utils/format_date_time.dart @@ -5,8 +5,8 @@ String formatDateTime(DateTime? dateTime) { if (dateTime == null) { return '-'; } - final dateFormatter = DateFormat('dd/MM/yyyy'); - final timeFormatter = DateFormat('HH:mm'); + final DateFormat dateFormatter = DateFormat('dd/MM/yyyy'); + final DateFormat timeFormatter = DateFormat('HH:mm'); return '${dateFormatter.format(dateTime)} ${timeFormatter.format(dateTime)}'; } diff --git a/lib/utils/helpers/decodeBase64.dart b/lib/utils/helpers/decodeBase64.dart index d94bd090..e0473992 100644 --- a/lib/utils/helpers/decodeBase64.dart +++ b/lib/utils/helpers/decodeBase64.dart @@ -2,7 +2,7 @@ import 'dart:convert'; String decodeBase64(String str) { //'-', '+' 62nd char of encoding, '_', '/' 63rd char of encoding - var output = str.replaceAll('-', '+').replaceAll('_', '/'); + String output = str.replaceAll('-', '+').replaceAll('_', '/'); switch (output.length % 4) { // Pad with trailing '=' case 0: // No pad chars in this case diff --git a/lib/utils/helpers/shared_preferences_helper.dart b/lib/utils/helpers/shared_preferences_helper.dart index 97a504e0..b9c7e0f4 100644 --- a/lib/utils/helpers/shared_preferences_helper.dart +++ b/lib/utils/helpers/shared_preferences_helper.dart @@ -1,52 +1,52 @@ import 'package:shared_preferences/shared_preferences.dart'; class SharedPreferencesHelper { - static Future saveStringToSP(String key, String value) async { + static saveStringToSP(String key, String value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(key, value); } - static Future saveBoolToSP(String key, bool value) async { + static saveBoolToSP(String key, bool value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool(key, value); } - static Future saveIntToSP(String key, int value) async { + static saveIntToSP(String key, int value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setInt(key, value); } - static Future saveDoubleToSP(String key, double value) async { + static saveDoubleToSP(String key, double value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setDouble(key, value); } - static Future saveStringListToSP(String key, List value) async { + static saveStringListToSP(String key, List value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setStringList(key, value); } static Future readStringFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - final value = prefs.getString(key) ?? ''; + String value = prefs.getString(key) ?? ''; return value; } static Future readBoolFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - final value = prefs.getBool(key); + bool? value = prefs.getBool(key); return value; } static Future readIntFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - final value = prefs.getInt(key) ?? 0; + int value = prefs.getInt(key) ?? 0; return value; } static Future> readStringListFromSP(String key) async { final prefs = await SharedPreferences.getInstance(); - final value = prefs.getStringList(key) ?? []; + List? value = prefs.getStringList(key) ?? []; return value; } diff --git a/lib/utils/navigation_service.dart b/lib/utils/navigation_service.dart index c0b12167..c9d654e6 100644 --- a/lib/utils/navigation_service.dart +++ b/lib/utils/navigation_service.dart @@ -5,3 +5,6 @@ class NavigationService { static GlobalKey? snackbarKey = GlobalKey(); } + + + diff --git a/lib/utils/snack_bar.dart b/lib/utils/snack_bar.dart index ae65541d..0a312e5a 100644 --- a/lib/utils/snack_bar.dart +++ b/lib/utils/snack_bar.dart @@ -3,7 +3,7 @@ import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/navigation_service.dart'; class CustomSnackBar { - static void displaySnackBar(String message) { + static displaySnackBar(String message) { final key = NavigationService.snackbarKey; if (key != null) { final snackBar = SnackBar(content: Text(message)); @@ -12,9 +12,9 @@ class CustomSnackBar { } } - static void redSnackBar(String message) { + static redSnackBar(String message) { final key = NavigationService.snackbarKey; - final currentContext = key?.currentContext; + BuildContext? currentContext = key?.currentContext; if (key != null && currentContext != null) { final snackBar = SnackBar( padding: const EdgeInsets.all(16), @@ -30,8 +30,10 @@ class CustomSnackBar { ), Text( message, - style: Theme.of(currentContext).textTheme.bodySmall!.copyWith( - fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), + style: Theme.of(currentContext) + .textTheme + .bodySmall! + .copyWith(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), ) ]), ); @@ -39,9 +41,9 @@ class CustomSnackBar { } } - static void greenSnackBar(String message) { + static greenSnackBar(String message) { final key = NavigationService.snackbarKey; - final currentContext = key?.currentContext; + BuildContext? currentContext = key?.currentContext; if (key != null && currentContext != null) { final snackBar = SnackBar( padding: const EdgeInsets.all(16), @@ -57,8 +59,10 @@ class CustomSnackBar { ), Text( message, - style: Theme.of(currentContext).textTheme.bodySmall!.copyWith( - fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), + style: Theme.of(currentContext) + .textTheme + .bodySmall! + .copyWith(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.green), ) ]), ); diff --git a/lib/utils/style.dart b/lib/utils/style.dart index 9964cf41..905bb7a8 100644 --- a/lib/utils/style.dart +++ b/lib/utils/style.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_web/utils/color_manager.dart'; -InputDecoration? textBoxDecoration( - {bool suffixIcon = false, double radios = 8}) => +import 'color_manager.dart'; + +InputDecoration? textBoxDecoration({bool suffixIcon = false, double radios = 8}) => InputDecoration( focusColor: ColorsManager.grayColor, suffixIcon: suffixIcon ? const Icon(Icons.search) : null, @@ -34,7 +34,7 @@ InputDecoration? textBoxDecoration( BoxDecoration containerDecoration = BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.grey.withValues(alpha: 0.3), + color: Colors.grey.withOpacity(0.3), spreadRadius: 2, blurRadius: 4, offset: const Offset(0, 5), // changes position of shadow @@ -46,7 +46,7 @@ BoxDecoration containerDecoration = BoxDecoration( BoxDecoration containerWhiteDecoration = BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.grey.withValues(alpha: 0.3), + color: Colors.grey.withOpacity(0.3), spreadRadius: 2, blurRadius: 4, offset: const Offset(0, 5), // changes position of shadow @@ -59,7 +59,7 @@ BoxDecoration subSectionContainerDecoration = BoxDecoration( color: ColorsManager.whiteColors, boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.1), + color: Colors.black.withOpacity(0.1), blurRadius: 10, spreadRadius: 1, offset: const Offset(0, 2), @@ -70,7 +70,7 @@ BoxDecoration subSectionContainerDecoration = BoxDecoration( final secondarySection = BoxDecoration( boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.1), + color: Colors.black.withOpacity(0.1), spreadRadius: 1, blurRadius: 7, offset: const Offset(0, 10), diff --git a/lib/utils/theme/theme.dart b/lib/utils/theme/theme.dart index 27ddd487..5ac61afa 100644 --- a/lib/utils/theme/theme.dart +++ b/lib/utils/theme/theme.dart @@ -34,7 +34,7 @@ final myTheme = ThemeData( }), trackColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { - return ColorsManager.blueColor.withValues(alpha: 0.5); + return ColorsManager.blueColor.withOpacity(0.5); } return ColorsManager.whiteColors; }), diff --git a/lib/utils/user_drop_down_menu.dart b/lib/utils/user_drop_down_menu.dart index f70b90c1..15da1f3a 100644 --- a/lib/utils/user_drop_down_menu.dart +++ b/lib/utils/user_drop_down_menu.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.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/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -64,9 +66,9 @@ class _UserDropdownMenuState extends State { } Future _showPopupMenu(BuildContext context) async { - final overlay = - Overlay.of(context).context.findRenderObject()! as RenderBox; - final position = RelativeRect.fromRect( + final RenderBox overlay = + Overlay.of(context).context.findRenderObject() as RenderBox; + final RelativeRect position = RelativeRect.fromRect( Rect.fromLTRB( overlay.size.width, 75, @@ -104,7 +106,7 @@ class _UserDropdownMenuState extends State { child: ListTile( leading: SvgPicture.asset(Assets.userManagement), title: Text( - 'User Management', + "User Management", style: context.textTheme.bodyMedium, ), ), @@ -253,7 +255,7 @@ class _UserDropdownMenuState extends State { child: ListTile( leading: SvgPicture.asset(Assets.signOut), title: Text( - 'Log Out', + "Log Out", style: context.textTheme.bodyMedium, ), ), diff --git a/lib/web_layout/default_container.dart b/lib/web_layout/default_container.dart index c156ecd5..e0a71b04 100644 --- a/lib/web_layout/default_container.dart +++ b/lib/web_layout/default_container.dart @@ -21,7 +21,7 @@ class DefaultContainer extends StatelessWidget { final EdgeInsets? margin; final EdgeInsets? padding; final Color? color; - final void Function()? onTap; + final Function()? onTap; final BorderRadius? borderRadius; @override Widget build(BuildContext context) { diff --git a/lib/web_layout/web_app_bar.dart b/lib/web_layout/web_app_bar.dart index 03e2e8a8..3cfe171e 100644 --- a/lib/web_layout/web_app_bar.dart +++ b/lib/web_layout/web_app_bar.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_web/pages/auth/model/user_model.dart'; import 'package:syncrow_web/pages/home/bloc/home_bloc.dart'; import 'package:syncrow_web/pages/home/bloc/home_state.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -50,7 +49,7 @@ class DesktopAppBar extends StatelessWidget { final Widget? title; final Widget? centerBody; final Widget? rightBody; - final UserModel? user; + final dynamic user; const DesktopAppBar({ super.key, @@ -76,7 +75,7 @@ class DesktopAppBar extends StatelessWidget { if (centerBody != null) Padding( padding: const EdgeInsets.only(left: 80), - child: centerBody, + child: centerBody!, ), ], ), @@ -103,7 +102,7 @@ class TabletAppBar extends StatelessWidget { final Widget? title; final Widget? centerBody; final Widget? rightBody; - final UserModel? user; + final dynamic user; const TabletAppBar({ super.key, @@ -150,7 +149,7 @@ class MobileAppBar extends StatelessWidget { final Widget? title; final Widget? centerBody; final Widget? rightBody; - final UserModel? user; + final dynamic user; const MobileAppBar({ super.key, @@ -183,12 +182,12 @@ class MobileAppBar extends StatelessWidget { if (centerBody != null) Padding( padding: const EdgeInsets.only(top: 8), - child: centerBody, + child: centerBody!, ), if (rightBody != null) Padding( padding: const EdgeInsets.only(top: 8), - child: rightBody, + child: rightBody!, ), ], ), diff --git a/lib/web_layout/web_scaffold.dart b/lib/web_layout/web_scaffold.dart index 812ea49e..a37727db 100644 --- a/lib/web_layout/web_scaffold.dart +++ b/lib/web_layout/web_scaffold.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.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/web_layout/menu_sidebar.dart'; import 'package:syncrow_web/web_layout/web_app_bar.dart'; +import 'menu_sidebar.dart'; + class WebScaffold extends StatelessWidget with HelperResponsiveLayout { final bool enableMenuSidebar; final Widget? appBarTitle; diff --git a/test/widget_test.dart b/test/widget_test.dart index 8b137891..e69de29b 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -1 +0,0 @@ -