From 1cd18b002c383b6763da146a47c14887f3169638 Mon Sep 17 00:00:00 2001 From: aitorarana Date: Thu, 5 Feb 2026 17:51:52 +0100 Subject: [PATCH 1/8] added functions module and functions and contacts screens, state and use cases --- .idea/modules.xml | 4 +- .../mobile_app/lib/navigation/app_router.dart | 15 + apps/mobile_app/pubspec.yaml | 2 + modules/legacy/melos_legacy.iml | 5 +- .../functions_remote_datasource.dart | 5 + .../functions_remote_datasource_impl.dart | 82 +++++ .../functions_repository_impl.dart | 14 + .../repositories/functions_repository.dart | 5 + .../functions_remote_datasource_provider.dart | 9 + .../functions_repository_provider.dart | 9 + .../features/contacts/contacts_builder.dart | 18 + .../domain/entities/contact_list_entity.dart | 19 ++ .../entities/contact_list_entity.freezed.dart | 301 +++++++++++++++++ .../domain/entities/list_contact_entity.dart | 11 + .../entities/list_contact_entity.freezed.dart | 274 ++++++++++++++++ .../domain/get_contacts_use_case.dart | 5 + .../domain/get_contacts_use_case_impl.dart | 14 + .../presentation/contacts_screen.dart | 212 ++++++++++++ .../presentation/edit_contact_screen.dart | 0 .../providers/get_contacts_provider.dart | 9 + .../state/contacts_view_model.dart | 56 ++++ .../state/contacts_view_state.dart | 16 + .../state/contacts_view_state.freezed.dart | 310 ++++++++++++++++++ .../features/functions/functions_builder.dart | 18 + .../features/functions/functions_screen.dart | 179 ++++++++++ .../features/hub/presentation/hub_screen.dart | 2 +- packages/navigation/lib/app_routes.dart | 3 + .../lib/src/generated/i18n.dart | 21 ++ 28 files changed, 1615 insertions(+), 3 deletions(-) create mode 100644 modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/providers/functions_remote_datasource_provider.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/providers/functions_repository_provider.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/contacts_builder.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_provider.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/functions/functions_builder.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart diff --git a/.idea/modules.xml b/.idea/modules.xml index cfa0d987..b7aa4bbc 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,17 +2,19 @@ + + + - diff --git a/apps/mobile_app/lib/navigation/app_router.dart b/apps/mobile_app/lib/navigation/app_router.dart index 485f4469..e28987b5 100644 --- a/apps/mobile_app/lib/navigation/app_router.dart +++ b/apps/mobile_app/lib/navigation/app_router.dart @@ -1,4 +1,5 @@ import 'package:auth/auth.dart'; +import 'package:functions/functions.dart'; import 'package:legacy_dashboard_shell/legacy_dashboard_builder.dart'; import 'package:dashboard_shell/dashboard_builder.dart'; import 'package:flutter/material.dart'; @@ -40,8 +41,22 @@ void configureAppRouter() { ), ], ), + StatefulShellBranch( + routes: [ + GoRoute( + path: AppRoutes.dashboardFunctions, + name: 'functions', + pageBuilder: FunctionsBuilder().buildPage, + ), + ], + ), ], ), + GoRoute( + path: AppRoutes.contacts, + name: 'contacts', + pageBuilder: ContactsBuilder().buildPage, + ), GoRoute( path: AppRoutes.login, diff --git a/apps/mobile_app/pubspec.yaml b/apps/mobile_app/pubspec.yaml index 9fdc39d3..4e4247a9 100644 --- a/apps/mobile_app/pubspec.yaml +++ b/apps/mobile_app/pubspec.yaml @@ -53,6 +53,8 @@ dependencies: path: ../../modules/legacy/modules/legacy_dashboard_shell splash: path: ../../modules/splash + functions: + path: ../../modules/legacy/modules/functions #packages dependencies go here navigation: path: ../../packages/navigation diff --git a/modules/legacy/melos_legacy.iml b/modules/legacy/melos_legacy.iml index 26a45e79..e8a4d511 100644 --- a/modules/legacy/melos_legacy.iml +++ b/modules/legacy/melos_legacy.iml @@ -17,10 +17,13 @@ + + + - + \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart new file mode 100644 index 00000000..bae23bbc --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart @@ -0,0 +1,5 @@ +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; + +abstract class FunctionsRemoteDatasource { + Future getContacts({required String deviceId}); +} diff --git a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart new file mode 100644 index 00000000..ffef59af --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart @@ -0,0 +1,82 @@ +import 'dart:convert'; + +import 'package:dio/dio.dart'; +// import 'package:flutter/material.dart'; +import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:sf_infrastructure/sf_infrastructure.dart'; + +class FunctionsRemoteDatasourceImpl implements FunctionsRemoteDatasource { + FunctionsRemoteDatasourceImpl(this._repository); + + final QuestiaRepository _repository; + + @override + Future getContacts({required String deviceId}) async { + /*try { + final response = await _repository.post>( + '/devices/$deviceId/contact-lists', + ); + + final data = response.data; + if (data == null || data.isEmpty) { + throw Exception('Empty response from /devices/:deviceId/contact-lists'); + } + + final model = GetContactsResponseModel.fromJson(data); + return model.toEntity(); + } on DioException catch (error) { + throw _mapDioError(error, defaultMessage: 'Error to get contacts'); + }*/ + return ContactListEntity( + id: 'id', + delegationId: 'delegationId', + userId: 'userId', + groupId: 'groupId', + deviceId: 'deviceId', + type: 'type', + contacts: [ + ListContactEntity(name: 'Ana', phone: '111111111'), + ListContactEntity(name: 'Carlos', phone: '222222222'), + ], + createdAt: 'createdAt', + updatedAt: 'updatedAt' + ); + } +} + +Exception _mapDioError(DioException error, {required String defaultMessage}) { + final apiMsg = _extractApiMessage(error.response?.data); + final msg = apiMsg ?? error.message ?? defaultMessage; + return Exception(msg); +} + +String? _extractApiMessage(Object? data) { + if (data == null) return null; + + if (data is Map) { + final errorObj = data['error']; + if (errorObj is Map && errorObj['message'] is String) { + return (errorObj['message'] as String).trim(); + } + if (data['message'] is String) { + return (data['message'] as String).trim(); + } + return null; + } + + if (data is String) { + final raw = data.trim(); + if (raw.isEmpty) return null; + + try { + final decoded = jsonDecode(raw); + return _extractApiMessage(decoded); + } catch (_) { + return raw; + } + } + + return null; +} diff --git a/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart new file mode 100644 index 00000000..4ee55fae --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart @@ -0,0 +1,14 @@ +import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart'; +import 'package:functions/src/core/domain/repositories/functions_repository.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; + +class FunctionsRepositoryImpl implements FunctionsRepository { + const FunctionsRepositoryImpl(this._remote); + + final FunctionsRemoteDatasource _remote; + + @override + Future getContacts({required String deviceId}) { + return _remote.getContacts(deviceId: deviceId); + } +} diff --git a/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart b/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart new file mode 100644 index 00000000..3df7fc4e --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart @@ -0,0 +1,5 @@ +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; + +abstract class FunctionsRepository { + Future getContacts({required String deviceId}); +} diff --git a/modules/legacy/modules/functions/lib/src/core/providers/functions_remote_datasource_provider.dart b/modules/legacy/modules/functions/lib/src/core/providers/functions_remote_datasource_provider.dart new file mode 100644 index 00000000..062ca5d4 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/providers/functions_remote_datasource_provider.dart @@ -0,0 +1,9 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart'; +import 'package:functions/src/core/data/datasources/functions_remote_datasource_impl.dart'; +import 'package:sf_infrastructure/sf_infrastructure.dart'; + +final functionsRemoteDatasourceProvider = Provider((ref) { + final questiaRepository = getIt(); + return FunctionsRemoteDatasourceImpl(questiaRepository); +}); diff --git a/modules/legacy/modules/functions/lib/src/core/providers/functions_repository_provider.dart b/modules/legacy/modules/functions/lib/src/core/providers/functions_repository_provider.dart new file mode 100644 index 00000000..325fa7f8 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/providers/functions_repository_provider.dart @@ -0,0 +1,9 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/core/providers/functions_remote_datasource_provider.dart'; +import 'package:functions/src/core/data/repositories/functions_repository_impl.dart'; +import 'package:functions/src/core/domain/repositories/functions_repository.dart'; + +final functionsRepositoryProvider = Provider((ref) { + final remote = ref.read(functionsRemoteDatasourceProvider); + return FunctionsRepositoryImpl(remote); +}); diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/contacts_builder.dart b/modules/legacy/modules/functions/lib/src/features/contacts/contacts_builder.dart new file mode 100644 index 00000000..df0822e7 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/contacts_builder.dart @@ -0,0 +1,18 @@ +import 'presentation/contacts_screen.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:get_it/get_it.dart'; +import 'package:navigation/navigation.dart'; + +class ContactsBuilder { + const ContactsBuilder(); + + Page buildPage(BuildContext context, GoRouterState state) { + final NavigationContract navigationContract = GetIt.I(); + + return MaterialPage( + key: state.pageKey, + child: ContactsScreen(navigationContract: navigationContract), + ); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart new file mode 100644 index 00000000..ba87d9eb --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart @@ -0,0 +1,19 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; + +part 'contact_list_entity.freezed.dart'; + +@freezed +abstract class ContactListEntity with _$ContactListEntity { + const factory ContactListEntity({ + required String id, + required String delegationId, + required String userId, + required String groupId, + required String deviceId, + required String type, + required List contacts, + required String createdAt, + required String updatedAt + }) = _ContactListEntity; +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart new file mode 100644 index 00000000..a32a2dea --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart @@ -0,0 +1,301 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'contact_list_entity.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$ContactListEntity { + + String get id; String get delegationId; String get userId; String get groupId; String get deviceId; String get type; List get contacts; String get createdAt; String get updatedAt; +/// Create a copy of ContactListEntity +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ContactListEntityCopyWith get copyWith => _$ContactListEntityCopyWithImpl(this as ContactListEntity, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactListEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.contacts, contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,delegationId,userId,groupId,deviceId,type,const DeepCollectionEquality().hash(contacts),createdAt,updatedAt); + +@override +String toString() { + return 'ContactListEntity(id: $id, delegationId: $delegationId, userId: $userId, groupId: $groupId, deviceId: $deviceId, type: $type, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt)'; +} + + +} + +/// @nodoc +abstract mixin class $ContactListEntityCopyWith<$Res> { + factory $ContactListEntityCopyWith(ContactListEntity value, $Res Function(ContactListEntity) _then) = _$ContactListEntityCopyWithImpl; +@useResult +$Res call({ + String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt +}); + + + + +} +/// @nodoc +class _$ContactListEntityCopyWithImpl<$Res> + implements $ContactListEntityCopyWith<$Res> { + _$ContactListEntityCopyWithImpl(this._self, this._then); + + final ContactListEntity _self; + final $Res Function(ContactListEntity) _then; + +/// Create a copy of ContactListEntity +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? delegationId = null,Object? userId = null,Object? groupId = null,Object? deviceId = null,Object? type = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable +as String,groupId: null == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable +as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable +as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable +as String,contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable +as List,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [ContactListEntity]. +extension ContactListEntityPatterns on ContactListEntity { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _ContactListEntity value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ContactListEntity() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _ContactListEntity value) $default,){ +final _that = this; +switch (_that) { +case _ContactListEntity(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ContactListEntity value)? $default,){ +final _that = this; +switch (_that) { +case _ContactListEntity() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ContactListEntity() when $default != null: +return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt) $default,) {final _that = this; +switch (_that) { +case _ContactListEntity(): +return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt)? $default,) {final _that = this; +switch (_that) { +case _ContactListEntity() when $default != null: +return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _ContactListEntity implements ContactListEntity { + const _ContactListEntity({required this.id, required this.delegationId, required this.userId, required this.groupId, required this.deviceId, required this.type, required final List contacts, required this.createdAt, required this.updatedAt}): _contacts = contacts; + + +@override final String id; +@override final String delegationId; +@override final String userId; +@override final String groupId; +@override final String deviceId; +@override final String type; + final List _contacts; +@override List get contacts { + if (_contacts is EqualUnmodifiableListView) return _contacts; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_contacts); +} + +@override final String createdAt; +@override final String updatedAt; + +/// Create a copy of ContactListEntity +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ContactListEntityCopyWith<_ContactListEntity> get copyWith => __$ContactListEntityCopyWithImpl<_ContactListEntity>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactListEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,delegationId,userId,groupId,deviceId,type,const DeepCollectionEquality().hash(_contacts),createdAt,updatedAt); + +@override +String toString() { + return 'ContactListEntity(id: $id, delegationId: $delegationId, userId: $userId, groupId: $groupId, deviceId: $deviceId, type: $type, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$ContactListEntityCopyWith<$Res> implements $ContactListEntityCopyWith<$Res> { + factory _$ContactListEntityCopyWith(_ContactListEntity value, $Res Function(_ContactListEntity) _then) = __$ContactListEntityCopyWithImpl; +@override @useResult +$Res call({ + String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt +}); + + + + +} +/// @nodoc +class __$ContactListEntityCopyWithImpl<$Res> + implements _$ContactListEntityCopyWith<$Res> { + __$ContactListEntityCopyWithImpl(this._self, this._then); + + final _ContactListEntity _self; + final $Res Function(_ContactListEntity) _then; + +/// Create a copy of ContactListEntity +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? delegationId = null,Object? userId = null,Object? groupId = null,Object? deviceId = null,Object? type = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,}) { + return _then(_ContactListEntity( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable +as String,groupId: null == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable +as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable +as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable +as String,contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable +as List,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart new file mode 100644 index 00000000..32bcab66 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart @@ -0,0 +1,11 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'list_contact_entity.freezed.dart'; + +@freezed +abstract class ListContactEntity with _$ListContactEntity { + const factory ListContactEntity({ + required String name, + required String phone, + }) = _ListContactEntity; +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart new file mode 100644 index 00000000..efd95bd7 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart @@ -0,0 +1,274 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'list_contact_entity.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$ListContactEntity { + + String get name; String get phone; +/// Create a copy of ListContactEntity +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ListContactEntityCopyWith get copyWith => _$ListContactEntityCopyWithImpl(this as ListContactEntity, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ListContactEntity&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)); +} + + +@override +int get hashCode => Object.hash(runtimeType,name,phone); + +@override +String toString() { + return 'ListContactEntity(name: $name, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class $ListContactEntityCopyWith<$Res> { + factory $ListContactEntityCopyWith(ListContactEntity value, $Res Function(ListContactEntity) _then) = _$ListContactEntityCopyWithImpl; +@useResult +$Res call({ + String name, String phone +}); + + + + +} +/// @nodoc +class _$ListContactEntityCopyWithImpl<$Res> + implements $ListContactEntityCopyWith<$Res> { + _$ListContactEntityCopyWithImpl(this._self, this._then); + + final ListContactEntity _self; + final $Res Function(ListContactEntity) _then; + +/// Create a copy of ListContactEntity +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? phone = null,}) { + return _then(_self.copyWith( +name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [ListContactEntity]. +extension ListContactEntityPatterns on ListContactEntity { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _ListContactEntity value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ListContactEntity() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _ListContactEntity value) $default,){ +final _that = this; +switch (_that) { +case _ListContactEntity(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ListContactEntity value)? $default,){ +final _that = this; +switch (_that) { +case _ListContactEntity() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String name, String phone)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ListContactEntity() when $default != null: +return $default(_that.name,_that.phone);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String name, String phone) $default,) {final _that = this; +switch (_that) { +case _ListContactEntity(): +return $default(_that.name,_that.phone);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String name, String phone)? $default,) {final _that = this; +switch (_that) { +case _ListContactEntity() when $default != null: +return $default(_that.name,_that.phone);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _ListContactEntity implements ListContactEntity { + const _ListContactEntity({required this.name, required this.phone}); + + +@override final String name; +@override final String phone; + +/// Create a copy of ListContactEntity +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ListContactEntityCopyWith<_ListContactEntity> get copyWith => __$ListContactEntityCopyWithImpl<_ListContactEntity>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ListContactEntity&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)); +} + + +@override +int get hashCode => Object.hash(runtimeType,name,phone); + +@override +String toString() { + return 'ListContactEntity(name: $name, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class _$ListContactEntityCopyWith<$Res> implements $ListContactEntityCopyWith<$Res> { + factory _$ListContactEntityCopyWith(_ListContactEntity value, $Res Function(_ListContactEntity) _then) = __$ListContactEntityCopyWithImpl; +@override @useResult +$Res call({ + String name, String phone +}); + + + + +} +/// @nodoc +class __$ListContactEntityCopyWithImpl<$Res> + implements _$ListContactEntityCopyWith<$Res> { + __$ListContactEntityCopyWithImpl(this._self, this._then); + + final _ListContactEntity _self; + final $Res Function(_ListContactEntity) _then; + +/// Create a copy of ListContactEntity +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? phone = null,}) { + return _then(_ListContactEntity( +name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart new file mode 100644 index 00000000..bf0dde3f --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart @@ -0,0 +1,5 @@ +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; + +abstract class GetContactsUseCase { + Future getContacts({required String deviceId}); +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart new file mode 100644 index 00000000..250f0cfb --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart @@ -0,0 +1,14 @@ +import 'package:functions/src/core/domain/repositories/functions_repository.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart'; + +class GetContactsUseCaseImpl implements GetContactsUseCase { + GetContactsUseCaseImpl(this._repository); + + final FunctionsRepository _repository; + + @override + Future getContacts({required String deviceId}) { + return _repository.getContacts(deviceId: deviceId); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart new file mode 100644 index 00000000..ea57f14b --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart @@ -0,0 +1,212 @@ +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:functions/src/features/contacts/presentation/state/contacts_view_model.dart'; +import 'package:navigation/navigation.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:utils/utils.dart'; + +class ContactsScreen extends ConsumerWidget { + final NavigationContract navigationContract; + + const ContactsScreen({super.key, required this.navigationContract}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final vm = ref.read(contactsViewModelProvider.notifier); + final state = ref.watch(contactsViewModelProvider); + + final theme = ref.watch(themePortProvider); + + return Scaffold( + backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary), + body: SafeArea( + child: Column( + children: [ + Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + child: Stack( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconButton(onPressed: () {Navigator.pop(context);}, + icon: Icon(Icons.arrow_back)), + if (!state.isEditing) ...[ + DecoratedBox( + decoration: BoxDecoration( + color: Color(0xFF588EA5), + shape: BoxShape.circle + ), + child: IconButton(onPressed: vm.toggleIsEditing, + icon: Icon(Icons.edit_outlined, + color: Colors.white, + size: SizeUtils.getByScreen(small: 30, big: 28), + ) + ), + ) + ] + ], + ), + Center( + child: Text(context.translate('Agenda'), + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 28, big: 27) + ), + ) + ) + ], + ), + ), + SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)), + Expanded( child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + child: ListView.separated( + itemBuilder: (BuildContext context, int index)=>ContactCard( + contact: state.contactList!.contacts[index], + isEditing: state.isEditing, + ), + separatorBuilder: (BuildContext context, int index)=>SizedBox( + height: SizeUtils.getByScreen(small: 18, big: 17) + ), + itemCount: state.contactList?.contacts.length ?? 0 + ), + )), + if (state.isEditing) ...[ + Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 26, vertical: 14), + big: EdgeInsets.symmetric(horizontal: 24, vertical: 12) + ), + ), + ] + ], + ) + ), + ); + } +} + +class ContactCard extends ConsumerWidget { + + final ListContactEntity contact; + final bool isEditing; + + const ContactCard({ + required this.contact, + required this.isEditing, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final theme = ref.read(themePortProvider); + + return Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(SizeUtils.getByScreen(small: 12, big: 18))), + color: theme.getColorFor(ThemeCode.backgroundSecondary), + ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: theme.getColorFor(ThemeCode.backgroundPrimary), + ), + padding: EdgeInsets.all(SizeUtils.getByScreen(small: 4, big: 12)), + child: Icon(SFIcons.account, + size: SizeUtils.getByScreen(small: 40, big: 44), + color: Color(0xFF588EA5), + weight: 30, + ), + ), + SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(contact.name, + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 18, big: 19), + fontWeight: FontWeight.w500 + ) + ), + Text(contact.phone, + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 14, big: 13), + ) + ) + ], + ) + ), + if (isEditing) ...[ + DecoratedBox( + decoration: BoxDecoration( + color: Color(0xFFFF5D52), + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + child: IconButton( + onPressed: (){showDialog(context: context, builder: (context)=>Dialog( + child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 32, vertical: 30), + big: EdgeInsets.symmetric(horizontal: 30, vertical: 28) + ), + width: SizeUtils.getByScreen(small: 360, big: 350), + height: SizeUtils.getByScreen(small: 195, big: 185), + child: Column( + children: [ + Text(context.translate(I18n.legacyDeleteUserDialog), + textAlign: TextAlign.center, + style: TextStyle(fontSize: SizeUtils.getByScreen(small: 19, big: 18)), + ), + SizedBox(height: SizeUtils.getByScreen(small: 28, big: 27)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: PrimaryButton( + onPressed: (){Navigator.pop(context);}, + text: context.translate(I18n.legacyCancel), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 38, big: 36), + radius: SizeUtils.getByScreen(small: 32, big: 34), + )), + SizedBox(width: SizeUtils.getByScreen(small: 4, big: 16)), + Expanded(child: PrimaryButton( + onPressed: (){ + Navigator.pop(context); + }, + text: context.translate(I18n.legacyDelete), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 38, big: 36), + radius: SizeUtils.getByScreen(small: 32, big: 34), + )) + ], + ) + ], + ), + ), + ));}, + icon: Icon( + Icons.close, + color: Colors.white, + ), + ), + ), + ] + ], + ), + ); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart new file mode 100644 index 00000000..e69de29b diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_provider.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_provider.dart new file mode 100644 index 00000000..913d152f --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_provider.dart @@ -0,0 +1,9 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/core/providers/functions_repository_provider.dart'; +import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart'; +import 'package:functions/src/features/contacts/domain/get_contacts_use_case_impl.dart'; + +final getContactsUseCaseProvider = Provider.autoDispose((ref) { + final functionsRepository = ref.read(functionsRepositoryProvider); + return GetContactsUseCaseImpl(functionsRepository); +}); diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart new file mode 100644 index 00000000..1c3d2c98 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart'; +import 'package:functions/src/features/contacts/presentation/providers/get_contacts_provider.dart'; +import 'package:functions/src/features/contacts/presentation/state/contacts_view_state.dart'; +// import 'package:sf_localizations/sf_localizations.dart'; + +final contactsViewModelProvider = +NotifierProvider.autoDispose( + ContactsViewModel.new, +); + +class ContactsViewModel extends Notifier { + late final GetContactsUseCase _getContactsUseCase; + + late final TextEditingController nameController; + + @override + ContactsViewState build() { + _getContactsUseCase = ref.read(getContactsUseCaseProvider); + + nameController = TextEditingController(); + + nameController.addListener(_onNameChanged); + + _getContactsUseCase.getContacts(deviceId: '').then(setContacts); + + ref.onDispose(disposeControllers); + + return const ContactsViewState(); + } + + void setContacts(ContactListEntity contactList) { + state = state.copyWith( + contactList: contactList + ); + } + + void toggleIsEditing() { + state = state.copyWith(isEditing: !state.isEditing); + } + + void _onNameChanged() { + final text = nameController.text; + if (text == state.name) return; + + state = state.copyWith(name: text, errorMessage: ''); + } + + void disposeControllers() { + nameController.removeListener(_onNameChanged); + + nameController.dispose(); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart new file mode 100644 index 00000000..439ee615 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart @@ -0,0 +1,16 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; + +part 'contacts_view_state.freezed.dart'; + +@freezed +abstract class ContactsViewState with _$ContactsViewState { + const factory ContactsViewState({ + @Default(null) ContactListEntity? contactList, + @Default(false) bool isLoading, + @Default(false) bool isEditing, + @Default('') String name, + @Default('') String phone, + @Default('') String errorMessage, + }) = _ContactsViewState; +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart new file mode 100644 index 00000000..1d74938c --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart @@ -0,0 +1,310 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'contacts_view_state.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$ContactsViewState { + + ContactListEntity? get contactList; bool get isLoading; bool get isEditing; String get name; String get phone; String get errorMessage; +/// Create a copy of ContactsViewState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ContactsViewStateCopyWith get copyWith => _$ContactsViewStateCopyWithImpl(this as ContactsViewState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactsViewState&&(identical(other.contactList, contactList) || other.contactList == contactList)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,contactList,isLoading,isEditing,name,phone,errorMessage); + +@override +String toString() { + return 'ContactsViewState(contactList: $contactList, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class $ContactsViewStateCopyWith<$Res> { + factory $ContactsViewStateCopyWith(ContactsViewState value, $Res Function(ContactsViewState) _then) = _$ContactsViewStateCopyWithImpl; +@useResult +$Res call({ + ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage +}); + + +$ContactListEntityCopyWith<$Res>? get contactList; + +} +/// @nodoc +class _$ContactsViewStateCopyWithImpl<$Res> + implements $ContactsViewStateCopyWith<$Res> { + _$ContactsViewStateCopyWithImpl(this._self, this._then); + + final ContactsViewState _self; + final $Res Function(ContactsViewState) _then; + +/// Create a copy of ContactsViewState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? contactList = freezed,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) { + return _then(_self.copyWith( +contactList: freezed == contactList ? _self.contactList : contactList // ignore: cast_nullable_to_non_nullable +as ContactListEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable +as bool,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable +as bool,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} +/// Create a copy of ContactsViewState +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$ContactListEntityCopyWith<$Res>? get contactList { + if (_self.contactList == null) { + return null; + } + + return $ContactListEntityCopyWith<$Res>(_self.contactList!, (value) { + return _then(_self.copyWith(contactList: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [ContactsViewState]. +extension ContactsViewStatePatterns on ContactsViewState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _ContactsViewState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ContactsViewState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _ContactsViewState value) $default,){ +final _that = this; +switch (_that) { +case _ContactsViewState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ContactsViewState value)? $default,){ +final _that = this; +switch (_that) { +case _ContactsViewState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ContactsViewState() when $default != null: +return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage) $default,) {final _that = this; +switch (_that) { +case _ContactsViewState(): +return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,) {final _that = this; +switch (_that) { +case _ContactsViewState() when $default != null: +return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _ContactsViewState implements ContactsViewState { + const _ContactsViewState({this.contactList = null, this.isLoading = false, this.isEditing = false, this.name = '', this.phone = '', this.errorMessage = ''}); + + +@override@JsonKey() final ContactListEntity? contactList; +@override@JsonKey() final bool isLoading; +@override@JsonKey() final bool isEditing; +@override@JsonKey() final String name; +@override@JsonKey() final String phone; +@override@JsonKey() final String errorMessage; + +/// Create a copy of ContactsViewState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ContactsViewStateCopyWith<_ContactsViewState> get copyWith => __$ContactsViewStateCopyWithImpl<_ContactsViewState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactsViewState&&(identical(other.contactList, contactList) || other.contactList == contactList)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,contactList,isLoading,isEditing,name,phone,errorMessage); + +@override +String toString() { + return 'ContactsViewState(contactList: $contactList, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class _$ContactsViewStateCopyWith<$Res> implements $ContactsViewStateCopyWith<$Res> { + factory _$ContactsViewStateCopyWith(_ContactsViewState value, $Res Function(_ContactsViewState) _then) = __$ContactsViewStateCopyWithImpl; +@override @useResult +$Res call({ + ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage +}); + + +@override $ContactListEntityCopyWith<$Res>? get contactList; + +} +/// @nodoc +class __$ContactsViewStateCopyWithImpl<$Res> + implements _$ContactsViewStateCopyWith<$Res> { + __$ContactsViewStateCopyWithImpl(this._self, this._then); + + final _ContactsViewState _self; + final $Res Function(_ContactsViewState) _then; + +/// Create a copy of ContactsViewState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? contactList = freezed,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) { + return _then(_ContactsViewState( +contactList: freezed == contactList ? _self.contactList : contactList // ignore: cast_nullable_to_non_nullable +as ContactListEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable +as bool,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable +as bool,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +/// Create a copy of ContactsViewState +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$ContactListEntityCopyWith<$Res>? get contactList { + if (_self.contactList == null) { + return null; + } + + return $ContactListEntityCopyWith<$Res>(_self.contactList!, (value) { + return _then(_self.copyWith(contactList: value)); + }); +} +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/functions/functions_builder.dart b/modules/legacy/modules/functions/lib/src/features/functions/functions_builder.dart new file mode 100644 index 00000000..186a46cb --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/functions/functions_builder.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:functions/src/features/functions/functions_screen.dart'; +import 'package:go_router/go_router.dart'; +import 'package:get_it/get_it.dart'; +import 'package:navigation/navigation.dart'; + +class FunctionsBuilder { + const FunctionsBuilder(); + + Page buildPage(BuildContext context, GoRouterState state) { + final NavigationContract navigationContract = GetIt.I(); + + return MaterialPage( + key: state.pageKey, + child: FunctionsScreen(navigationContract: navigationContract), + ); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart new file mode 100644 index 00000000..390cee00 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart @@ -0,0 +1,179 @@ +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:navigation/navigation.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:utils/utils.dart'; + +class FunctionsScreen extends ConsumerWidget { + final NavigationContract navigationContract; + + const FunctionsScreen({super.key, required this.navigationContract}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final theme = ref.watch(themePortProvider); + + return Scaffold( + backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary), + body: SafeArea( + child: Column( + children: [ + Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + child: Stack( + children: [ + IconButton(onPressed: () {Navigator.pop(context);}, + icon: Icon(Icons.arrow_back)), + Center( + child: Text(context.translate('Device Features'), + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 28, big: 27) + ), + ) + ) + ], + ), + ), + SizedBox(height: SizeUtils.getByScreen(small: 30, big: 28)), + Expanded(child: SingleChildScrollView(child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + child: Column( + children: [ + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Remote connection' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Calendar' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){navigationContract.pushTo(AppRoutes.contacts);}, + icon: Icons.menu, + text: 'Contacts' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Do not disturb' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Safety zone' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Video call' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Fall notice' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Medication reminder' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Activity meter' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Rewards' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.menu, + text: 'Locate your SaveFamily' + ), + ], + ), + ))), + ], + ) + ), + ); + } +} + +class AppSectionButton extends ConsumerWidget { + + final GestureTapCallback onPressed; + final IconData icon; + final String text; + + const AppSectionButton({ + required this.onPressed, + required this.icon, + required this.text, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final theme = ref.read(themePortProvider); + + return GestureDetector( + onTap: onPressed, + child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 14), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 12) + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(SizeUtils.getByScreen(small: 12, big: 18))), + color: theme.getColorFor(ThemeCode.backgroundSecondary), + ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF588EA5), + ), + padding: EdgeInsets.all(SizeUtils.getByScreen(small: 4, big: 12)), + child: Icon(icon, + size: SizeUtils.getByScreen(small: 40, big: 44), + color: theme.getColorFor(ThemeCode.backgroundPrimary), + weight: 30, + ), + ), + SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)), + Expanded( + child: Text(context.translate(text), + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 18, big: 19), + fontWeight: FontWeight.w500 + ) + ) + ) + ], + ), + ) + ); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/hub/lib/src/features/hub/presentation/hub_screen.dart b/modules/legacy/modules/hub/lib/src/features/hub/presentation/hub_screen.dart index 47eb7af8..dc9898d6 100644 --- a/modules/legacy/modules/hub/lib/src/features/hub/presentation/hub_screen.dart +++ b/modules/legacy/modules/hub/lib/src/features/hub/presentation/hub_screen.dart @@ -61,7 +61,7 @@ class HubScreen extends ConsumerWidget { text: I18n.sfPay), SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)), AppSectionButton( - onPressed: (){}, + onPressed: (){navigationContract.pushTo(AppRoutes.dashboardFunctions);}, icon: SFIcons.functions, text: I18n.functions), SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)), diff --git a/packages/navigation/lib/app_routes.dart b/packages/navigation/lib/app_routes.dart index 45ba35c8..63dd0af8 100644 --- a/packages/navigation/lib/app_routes.dart +++ b/packages/navigation/lib/app_routes.dart @@ -20,4 +20,7 @@ class AppRoutes { static const legacyDashboard = '$legacy/dashboard'; static const dashboardHub = '$legacyDashboard/hub'; + static const dashboardFunctions = '$legacyDashboard/functions'; + + static const contacts = '$dashboardFunctions/contacts'; } diff --git a/packages/sf_localizations/lib/src/generated/i18n.dart b/packages/sf_localizations/lib/src/generated/i18n.dart index bd01ab75..4b254ea3 100755 --- a/packages/sf_localizations/lib/src/generated/i18n.dart +++ b/packages/sf_localizations/lib/src/generated/i18n.dart @@ -170,4 +170,25 @@ class I18n { static const String home = 'home'; static const String location = 'location'; static const String chat = 'chat'; + static const String legacyPersonalData = 'personalData'; + static const String legacyAddNewSF = 'addNewSF'; + static const String legacyLinkedDevices = 'linkedDevices'; + static const String legacyAppUsers = 'appUsers'; + static const String legacyPrivacyPolicy = 'privacyPolicy'; + static const String legacyLogOut = 'logOut'; + static const String legacyLoginEmail = 'loginEmail'; + static const String legacyUserNameLabel = 'userNameLabel'; + static const String legacyUserPhoneLabel = 'userPhoneLabel'; + static const String legacyContactEmailLabel = 'contactEmailLabel'; + static const String passwordLabel = 'passwordLabel'; + static const String legacySubmit = 'submit'; + static const String legacySave = 'save'; + static const String legacyEditDeviceTitle = 'editDeviceTitle'; + static const String legacyName = 'name'; + static const String legacyDeleteDeviceDialog = 'deleteDeviceDialog'; + static const String legacyDeleteUserDialog = 'deleteUserDialog'; + static const String legacyCancel = 'cancel'; + static const String legacyDelete = 'delete'; + static const String legacyUserAccount = 'userAccount'; + static const String legacyUserRole = 'userRole'; } From 6049ce0bee34db0bce0c25edef11f7a5d1ad3c4a Mon Sep 17 00:00:00 2001 From: aitorarana Date: Mon, 9 Feb 2026 09:38:58 +0100 Subject: [PATCH 2/8] added edit_contact screen and functions icons --- apps/mobile_app/assets/images/ui/profile.svg | 12 + .../presentation/contacts_screen.dart | 51 ++- .../presentation/edit_contact_screen.dart | 136 +++++++ .../state/contacts_view_model.dart | 15 + .../features/functions/functions_screen.dart | 32 +- .../legacy_main_shell_screen.dart | 2 +- packages/design_system/fonts/SFIcons.ttf | Bin 0 -> 27592 bytes packages/design_system/lib/fonts/SFIcons.ttf | Bin 15708 -> 0 bytes packages/design_system/lib/fonts/config.json | 310 +++++++++++++- .../design_system/lib/src/icons/sf_icons.dart | 383 ++++-------------- packages/design_system/pubspec.yaml | 4 + packages/sf_localizations/assets/l10n/en.json | 22 +- packages/sf_localizations/assets/l10n/es.json | 22 +- 13 files changed, 661 insertions(+), 328 deletions(-) create mode 100644 apps/mobile_app/assets/images/ui/profile.svg create mode 100644 packages/design_system/fonts/SFIcons.ttf delete mode 100755 packages/design_system/lib/fonts/SFIcons.ttf diff --git a/apps/mobile_app/assets/images/ui/profile.svg b/apps/mobile_app/assets/images/ui/profile.svg new file mode 100644 index 00000000..3e1a697c --- /dev/null +++ b/apps/mobile_app/assets/images/ui/profile.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart index ea57f14b..a90a0b13 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart @@ -2,6 +2,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:functions/src/features/contacts/presentation/edit_contact_screen.dart'; import 'package:functions/src/features/contacts/presentation/state/contacts_view_model.dart'; import 'package:navigation/navigation.dart'; import 'package:sf_localizations/sf_localizations.dart'; @@ -35,18 +36,18 @@ class ContactsScreen extends ConsumerWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton(onPressed: () {Navigator.pop(context);}, - icon: Icon(Icons.arrow_back)), + icon: Icon(Icons.arrow_back)), if (!state.isEditing) ...[ DecoratedBox( decoration: BoxDecoration( - color: Color(0xFF588EA5), - shape: BoxShape.circle + color: Color(0xFF588EA5), + shape: BoxShape.circle ), child: IconButton(onPressed: vm.toggleIsEditing, - icon: Icon(Icons.edit_outlined, - color: Colors.white, - size: SizeUtils.getByScreen(small: 30, big: 28), - ) + icon: Icon(Icons.edit_outlined, + color: Colors.white, + size: SizeUtils.getByScreen(small: 30, big: 28), + ) ), ) ] @@ -86,7 +87,20 @@ class ContactsScreen extends ConsumerWidget { big: EdgeInsets.symmetric(horizontal: 24, vertical: 12) ), ), - ] + ], + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF588EA5), + ), + width: SizeUtils.getByScreen(small: 48, big: 46), + child: CustomTextButton( + onPressed: (){}, + text: '+', + color: Colors.white, + size: SizeUtils.getByScreen(small: 48, big: 47), + ), + ), ], ) ), @@ -204,6 +218,27 @@ class ContactCard extends ConsumerWidget { ), ), ), + SizedBox(width: SizeUtils.getByScreen(small: 16, big: 14)), + DecoratedBox( + decoration: BoxDecoration( + color: Color(0xFF588EA5), + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + child: + IconButton( + onPressed: (){Navigator.push( + context, + MaterialPageRoute(builder: (_) => EditContactScreen( + contact: contact, + /*navigationContract: navigationContract*/ + )), + );}, + icon: Icon( + Icons.edit_outlined, + color: Colors.white, + ), + ), + ), ] ], ), diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart index e69de29b..dbe78eb8 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart @@ -0,0 +1,136 @@ +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:functions/src/features/contacts/presentation/state/contacts_view_model.dart'; +// import 'package:navigation/navigation.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:utils/utils.dart'; + +class EditContactScreen extends ConsumerWidget { + //final NavigationContract navigationContract; + final ListContactEntity contact; + + const EditContactScreen({super.key, required this.contact +// required this.navigationContract +}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final vm = ref.read(contactsViewModelProvider.notifier); + // final state = ref.watch(linkedDevicesViewModelProvider); + + final theme = ref.watch(themePortProvider); + + return Scaffold( + backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary), + body: SafeArea( + child: Column( + children: [ + Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + child: Stack( + children: [ + IconButton(onPressed: () {Navigator.pop(context);}, + icon: Icon(Icons.arrow_back)), + Center( + child: Text(context.translate('Edit Contact'), + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 28, big: 27) + ), + ) + ) + ], + ), + ), + SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)), + Expanded(child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 48, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 47, vertical: 8) + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Stack( + children: [ + Center(child: SvgPicture.asset('assets/images/ui/profile.svg')), + Center(child: SizedBox( + width: 160, + height: 160, + child: Align(alignment: Alignment.bottomRight, + child: IconButton( + onPressed: (){}, + icon: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFFCAC9C9) + ), + padding: EdgeInsets.all(8), + child: Icon( + Icons.edit_outlined, + color: Colors.white, + size: SizeUtils.getByScreen(small: 32, big: 30), + ), + ), + ) + ) + )) + ], + ), + SizedBox(height: SizeUtils.getByScreen(small: 24, big: 22)), + CustomTextField( + controller: vm.nameController, + hint: contact.name, + label: context.translate(I18n.legacyName), + ), + SizedBox(height: SizeUtils.getByScreen(small: 28, big: 26)), + Stack( + children: [ + CustomTextField( + controller: vm.phoneController, + keyboardType: TextInputType.number, + hint: contact.phone, + label: context.translate('Phone number'), + ), + Align( + alignment: Alignment.centerRight, + child: IconButton( + onPressed: (){}, + icon: DecoratedBox( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF588EA5) + ), + child: Icon( + SFIcons.contactsCircle, + color: Colors.white, + ) + ) + ), + ) + ], + ) + ], + ), + PrimaryButton( + onPressed: (){vm.updateContact(contact);}, + text: context.translate(I18n.legacySave), + color: Color(0xFF588EA5) + ) + ], + )) + ), + ], + ) + ), + ); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart index 1c3d2c98..b792c2a5 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart'; import 'package:functions/src/features/contacts/presentation/providers/get_contacts_provider.dart'; import 'package:functions/src/features/contacts/presentation/state/contacts_view_state.dart'; @@ -15,14 +16,17 @@ class ContactsViewModel extends Notifier { late final GetContactsUseCase _getContactsUseCase; late final TextEditingController nameController; + late final TextEditingController phoneController; @override ContactsViewState build() { _getContactsUseCase = ref.read(getContactsUseCaseProvider); nameController = TextEditingController(); + phoneController = TextEditingController(); nameController.addListener(_onNameChanged); + phoneController.addListener(_onPhoneChanged); _getContactsUseCase.getContacts(deviceId: '').then(setContacts); @@ -48,9 +52,20 @@ class ContactsViewModel extends Notifier { state = state.copyWith(name: text, errorMessage: ''); } + void _onPhoneChanged() { + final text = phoneController.text; + if (text == state.phone) return; + + state = state.copyWith(phone: text, errorMessage: ''); + } + + void updateContact(ListContactEntity contact) {} + void disposeControllers() { nameController.removeListener(_onNameChanged); + phoneController.removeListener(_onPhoneChanged); nameController.dispose(); + phoneController.dispose(); } } diff --git a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart index 390cee00..e51d970d 100644 --- a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart @@ -48,67 +48,67 @@ class FunctionsScreen extends ConsumerWidget { children: [ AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.connection, text: 'Remote connection' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.calendarCircle, text: 'Calendar' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){navigationContract.pushTo(AppRoutes.contacts);}, - icon: Icons.menu, + icon: SFIcons.contactsCircle, text: 'Contacts' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.doNotDisturbCircle, text: 'Do not disturb' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.locationAreaCircle, text: 'Safety zone' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.videoCallCircle, text: 'Video call' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.fallCircle, text: 'Fall notice' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.medicationCircle, text: 'Medication reminder' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.activityCircle, text: 'Activity meter' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.rewardsCircle, text: 'Rewards' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: Icons.menu, + icon: SFIcons.locateSfCircle, text: 'Locate your SaveFamily' ), ], @@ -153,12 +153,12 @@ class AppSectionButton extends ConsumerWidget { Container( decoration: BoxDecoration( shape: BoxShape.circle, - color: Color(0xFF588EA5), - ), - padding: EdgeInsets.all(SizeUtils.getByScreen(small: 4, big: 12)), - child: Icon(icon, - size: SizeUtils.getByScreen(small: 40, big: 44), color: theme.getColorFor(ThemeCode.backgroundPrimary), + ), + padding: EdgeInsets.all(SizeUtils.getByScreen(small: 0, big: 0)), + child: Icon(icon, + size: SizeUtils.getByScreen(small: 52, big: 48), + color: Color(0xFF588EA5), weight: 30, ), ), diff --git a/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart b/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart index b86d9016..7c49bca7 100644 --- a/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart +++ b/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart @@ -51,7 +51,7 @@ class LegacyDashboardScreen extends ConsumerWidget { label: context.translate(I18n.location), ), NavigationDestination( - icon: Icon(Icons.chat_outlined), + icon: Icon(SFIcons.chat), label: context.translate(I18n.chat), ), ], diff --git a/packages/design_system/fonts/SFIcons.ttf b/packages/design_system/fonts/SFIcons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2703601ac085604f116cec273f8ebc018c313ebd GIT binary patch literal 27592 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 literal 0 HcmV?d00001 diff --git a/packages/design_system/lib/fonts/SFIcons.ttf b/packages/design_system/lib/fonts/SFIcons.ttf deleted file mode 100755 index 8c2c553fb7966bf6586a04bf5af6ed8163f4858a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15708 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 TC#nmyL|WOVu{nMBHMIY~JX Date: Tue, 10 Feb 2026 17:25:23 +0100 Subject: [PATCH 3/8] fix contacts endpoint and entity --- .../domain/entities/contact_entity.dart | 17 + .../entities/contact_entity.freezed.dart | 292 +++++++++++++++++ .../domain/entities/contact_list_entity.dart | 19 -- .../entities/contact_list_entity.freezed.dart | 301 ------------------ .../domain/entities/list_contact_entity.dart | 11 - .../entities/list_contact_entity.freezed.dart | 274 ---------------- .../presentation/contacts_screen.dart | 18 +- .../presentation/edit_contact_screen.dart | 4 +- .../state/contacts_view_model.dart | 21 +- .../state/contacts_view_state.dart | 4 +- .../state/contacts_view_state.freezed.dart | 80 ++--- 11 files changed, 367 insertions(+), 674 deletions(-) create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.freezed.dart delete mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart delete mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart delete mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart delete mode 100644 modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.dart new file mode 100644 index 00000000..8b64a666 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.dart @@ -0,0 +1,17 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'contact_entity.freezed.dart'; + +@freezed +abstract class ContactEntity with _$ContactEntity { + const factory ContactEntity({ + required String id, + required String name, + required String phone, + required String? delegationId, + required String? groupId, + required String? userId, + required int createdAt, + required int? updatedAt, + }) = _ContactEntity; +} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.freezed.dart new file mode 100644 index 00000000..07643816 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_entity.freezed.dart @@ -0,0 +1,292 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'contact_entity.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$ContactEntity { + + String get id; String get name; String get phone; String? get delegationId; String? get groupId; String? get userId; int get createdAt; int? get updatedAt; +/// Create a copy of ContactEntity +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ContactEntityCopyWith get copyWith => _$ContactEntityCopyWithImpl(this as ContactEntity, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,name,phone,delegationId,groupId,userId,createdAt,updatedAt); + +@override +String toString() { + return 'ContactEntity(id: $id, name: $name, phone: $phone, delegationId: $delegationId, groupId: $groupId, userId: $userId, createdAt: $createdAt, updatedAt: $updatedAt)'; +} + + +} + +/// @nodoc +abstract mixin class $ContactEntityCopyWith<$Res> { + factory $ContactEntityCopyWith(ContactEntity value, $Res Function(ContactEntity) _then) = _$ContactEntityCopyWithImpl; +@useResult +$Res call({ + String id, String name, String phone, String? delegationId, String? groupId, String? userId, int createdAt, int? updatedAt +}); + + + + +} +/// @nodoc +class _$ContactEntityCopyWithImpl<$Res> + implements $ContactEntityCopyWith<$Res> { + _$ContactEntityCopyWithImpl(this._self, this._then); + + final ContactEntity _self; + final $Res Function(ContactEntity) _then; + +/// Create a copy of ContactEntity +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? phone = null,Object? delegationId = freezed,Object? groupId = freezed,Object? userId = freezed,Object? createdAt = null,Object? updatedAt = freezed,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable +as String?,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable +as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [ContactEntity]. +extension ContactEntityPatterns on ContactEntity { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _ContactEntity value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ContactEntity() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _ContactEntity value) $default,){ +final _that = this; +switch (_that) { +case _ContactEntity(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ContactEntity value)? $default,){ +final _that = this; +switch (_that) { +case _ContactEntity() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String name, String phone, String? delegationId, String? groupId, String? userId, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ContactEntity() when $default != null: +return $default(_that.id,_that.name,_that.phone,_that.delegationId,_that.groupId,_that.userId,_that.createdAt,_that.updatedAt);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String id, String name, String phone, String? delegationId, String? groupId, String? userId, int createdAt, int? updatedAt) $default,) {final _that = this; +switch (_that) { +case _ContactEntity(): +return $default(_that.id,_that.name,_that.phone,_that.delegationId,_that.groupId,_that.userId,_that.createdAt,_that.updatedAt);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String name, String phone, String? delegationId, String? groupId, String? userId, int createdAt, int? updatedAt)? $default,) {final _that = this; +switch (_that) { +case _ContactEntity() when $default != null: +return $default(_that.id,_that.name,_that.phone,_that.delegationId,_that.groupId,_that.userId,_that.createdAt,_that.updatedAt);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _ContactEntity implements ContactEntity { + const _ContactEntity({required this.id, required this.name, required this.phone, required this.delegationId, required this.groupId, required this.userId, required this.createdAt, required this.updatedAt}); + + +@override final String id; +@override final String name; +@override final String phone; +@override final String? delegationId; +@override final String? groupId; +@override final String? userId; +@override final int createdAt; +@override final int? updatedAt; + +/// Create a copy of ContactEntity +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ContactEntityCopyWith<_ContactEntity> get copyWith => __$ContactEntityCopyWithImpl<_ContactEntity>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,name,phone,delegationId,groupId,userId,createdAt,updatedAt); + +@override +String toString() { + return 'ContactEntity(id: $id, name: $name, phone: $phone, delegationId: $delegationId, groupId: $groupId, userId: $userId, createdAt: $createdAt, updatedAt: $updatedAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$ContactEntityCopyWith<$Res> implements $ContactEntityCopyWith<$Res> { + factory _$ContactEntityCopyWith(_ContactEntity value, $Res Function(_ContactEntity) _then) = __$ContactEntityCopyWithImpl; +@override @useResult +$Res call({ + String id, String name, String phone, String? delegationId, String? groupId, String? userId, int createdAt, int? updatedAt +}); + + + + +} +/// @nodoc +class __$ContactEntityCopyWithImpl<$Res> + implements _$ContactEntityCopyWith<$Res> { + __$ContactEntityCopyWithImpl(this._self, this._then); + + final _ContactEntity _self; + final $Res Function(_ContactEntity) _then; + +/// Create a copy of ContactEntity +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? phone = null,Object? delegationId = freezed,Object? groupId = freezed,Object? userId = freezed,Object? createdAt = null,Object? updatedAt = freezed,}) { + return _then(_ContactEntity( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable +as String?,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable +as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart deleted file mode 100644 index ba87d9eb..00000000 --- a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; - -part 'contact_list_entity.freezed.dart'; - -@freezed -abstract class ContactListEntity with _$ContactListEntity { - const factory ContactListEntity({ - required String id, - required String delegationId, - required String userId, - required String groupId, - required String deviceId, - required String type, - required List contacts, - required String createdAt, - required String updatedAt - }) = _ContactListEntity; -} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart deleted file mode 100644 index a32a2dea..00000000 --- a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/contact_list_entity.freezed.dart +++ /dev/null @@ -1,301 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -// coverage:ignore-file -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'contact_list_entity.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -// dart format off -T _$identity(T value) => value; -/// @nodoc -mixin _$ContactListEntity { - - String get id; String get delegationId; String get userId; String get groupId; String get deviceId; String get type; List get contacts; String get createdAt; String get updatedAt; -/// Create a copy of ContactListEntity -/// with the given fields replaced by the non-null parameter values. -@JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') -$ContactListEntityCopyWith get copyWith => _$ContactListEntityCopyWithImpl(this as ContactListEntity, _$identity); - - - -@override -bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactListEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.contacts, contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)); -} - - -@override -int get hashCode => Object.hash(runtimeType,id,delegationId,userId,groupId,deviceId,type,const DeepCollectionEquality().hash(contacts),createdAt,updatedAt); - -@override -String toString() { - return 'ContactListEntity(id: $id, delegationId: $delegationId, userId: $userId, groupId: $groupId, deviceId: $deviceId, type: $type, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt)'; -} - - -} - -/// @nodoc -abstract mixin class $ContactListEntityCopyWith<$Res> { - factory $ContactListEntityCopyWith(ContactListEntity value, $Res Function(ContactListEntity) _then) = _$ContactListEntityCopyWithImpl; -@useResult -$Res call({ - String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt -}); - - - - -} -/// @nodoc -class _$ContactListEntityCopyWithImpl<$Res> - implements $ContactListEntityCopyWith<$Res> { - _$ContactListEntityCopyWithImpl(this._self, this._then); - - final ContactListEntity _self; - final $Res Function(ContactListEntity) _then; - -/// Create a copy of ContactListEntity -/// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? delegationId = null,Object? userId = null,Object? groupId = null,Object? deviceId = null,Object? type = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,}) { - return _then(_self.copyWith( -id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable -as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable -as String,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable -as String,groupId: null == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable -as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable -as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable -as String,contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable -as List,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable -as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable -as String, - )); -} - -} - - -/// Adds pattern-matching-related methods to [ContactListEntity]. -extension ContactListEntityPatterns on ContactListEntity { -/// A variant of `map` that fallback to returning `orElse`. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case _: -/// return orElse(); -/// } -/// ``` - -@optionalTypeArgs TResult maybeMap(TResult Function( _ContactListEntity value)? $default,{required TResult orElse(),}){ -final _that = this; -switch (_that) { -case _ContactListEntity() when $default != null: -return $default(_that);case _: - return orElse(); - -} -} -/// A `switch`-like method, using callbacks. -/// -/// Callbacks receives the raw object, upcasted. -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case final Subclass2 value: -/// return ...; -/// } -/// ``` - -@optionalTypeArgs TResult map(TResult Function( _ContactListEntity value) $default,){ -final _that = this; -switch (_that) { -case _ContactListEntity(): -return $default(_that);case _: - throw StateError('Unexpected subclass'); - -} -} -/// A variant of `map` that fallback to returning `null`. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case _: -/// return null; -/// } -/// ``` - -@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ContactListEntity value)? $default,){ -final _that = this; -switch (_that) { -case _ContactListEntity() when $default != null: -return $default(_that);case _: - return null; - -} -} -/// A variant of `when` that fallback to an `orElse` callback. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case _: -/// return orElse(); -/// } -/// ``` - -@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt)? $default,{required TResult orElse(),}) {final _that = this; -switch (_that) { -case _ContactListEntity() when $default != null: -return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);case _: - return orElse(); - -} -} -/// A `switch`-like method, using callbacks. -/// -/// As opposed to `map`, this offers destructuring. -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case Subclass2(:final field2): -/// return ...; -/// } -/// ``` - -@optionalTypeArgs TResult when(TResult Function( String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt) $default,) {final _that = this; -switch (_that) { -case _ContactListEntity(): -return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);case _: - throw StateError('Unexpected subclass'); - -} -} -/// A variant of `when` that fallback to returning `null` -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case _: -/// return null; -/// } -/// ``` - -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt)? $default,) {final _that = this; -switch (_that) { -case _ContactListEntity() when $default != null: -return $default(_that.id,_that.delegationId,_that.userId,_that.groupId,_that.deviceId,_that.type,_that.contacts,_that.createdAt,_that.updatedAt);case _: - return null; - -} -} - -} - -/// @nodoc - - -class _ContactListEntity implements ContactListEntity { - const _ContactListEntity({required this.id, required this.delegationId, required this.userId, required this.groupId, required this.deviceId, required this.type, required final List contacts, required this.createdAt, required this.updatedAt}): _contacts = contacts; - - -@override final String id; -@override final String delegationId; -@override final String userId; -@override final String groupId; -@override final String deviceId; -@override final String type; - final List _contacts; -@override List get contacts { - if (_contacts is EqualUnmodifiableListView) return _contacts; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_contacts); -} - -@override final String createdAt; -@override final String updatedAt; - -/// Create a copy of ContactListEntity -/// with the given fields replaced by the non-null parameter values. -@override @JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') -_$ContactListEntityCopyWith<_ContactListEntity> get copyWith => __$ContactListEntityCopyWithImpl<_ContactListEntity>(this, _$identity); - - - -@override -bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactListEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)); -} - - -@override -int get hashCode => Object.hash(runtimeType,id,delegationId,userId,groupId,deviceId,type,const DeepCollectionEquality().hash(_contacts),createdAt,updatedAt); - -@override -String toString() { - return 'ContactListEntity(id: $id, delegationId: $delegationId, userId: $userId, groupId: $groupId, deviceId: $deviceId, type: $type, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt)'; -} - - -} - -/// @nodoc -abstract mixin class _$ContactListEntityCopyWith<$Res> implements $ContactListEntityCopyWith<$Res> { - factory _$ContactListEntityCopyWith(_ContactListEntity value, $Res Function(_ContactListEntity) _then) = __$ContactListEntityCopyWithImpl; -@override @useResult -$Res call({ - String id, String delegationId, String userId, String groupId, String deviceId, String type, List contacts, String createdAt, String updatedAt -}); - - - - -} -/// @nodoc -class __$ContactListEntityCopyWithImpl<$Res> - implements _$ContactListEntityCopyWith<$Res> { - __$ContactListEntityCopyWithImpl(this._self, this._then); - - final _ContactListEntity _self; - final $Res Function(_ContactListEntity) _then; - -/// Create a copy of ContactListEntity -/// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? delegationId = null,Object? userId = null,Object? groupId = null,Object? deviceId = null,Object? type = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,}) { - return _then(_ContactListEntity( -id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable -as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable -as String,userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable -as String,groupId: null == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable -as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable -as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable -as String,contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable -as List,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable -as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable -as String, - )); -} - - -} - -// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart deleted file mode 100644 index 32bcab66..00000000 --- a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'list_contact_entity.freezed.dart'; - -@freezed -abstract class ListContactEntity with _$ListContactEntity { - const factory ListContactEntity({ - required String name, - required String phone, - }) = _ListContactEntity; -} diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart deleted file mode 100644 index efd95bd7..00000000 --- a/modules/legacy/modules/functions/lib/src/features/contacts/domain/entities/list_contact_entity.freezed.dart +++ /dev/null @@ -1,274 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -// coverage:ignore-file -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'list_contact_entity.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -// dart format off -T _$identity(T value) => value; -/// @nodoc -mixin _$ListContactEntity { - - String get name; String get phone; -/// Create a copy of ListContactEntity -/// with the given fields replaced by the non-null parameter values. -@JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') -$ListContactEntityCopyWith get copyWith => _$ListContactEntityCopyWithImpl(this as ListContactEntity, _$identity); - - - -@override -bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is ListContactEntity&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)); -} - - -@override -int get hashCode => Object.hash(runtimeType,name,phone); - -@override -String toString() { - return 'ListContactEntity(name: $name, phone: $phone)'; -} - - -} - -/// @nodoc -abstract mixin class $ListContactEntityCopyWith<$Res> { - factory $ListContactEntityCopyWith(ListContactEntity value, $Res Function(ListContactEntity) _then) = _$ListContactEntityCopyWithImpl; -@useResult -$Res call({ - String name, String phone -}); - - - - -} -/// @nodoc -class _$ListContactEntityCopyWithImpl<$Res> - implements $ListContactEntityCopyWith<$Res> { - _$ListContactEntityCopyWithImpl(this._self, this._then); - - final ListContactEntity _self; - final $Res Function(ListContactEntity) _then; - -/// Create a copy of ListContactEntity -/// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? phone = null,}) { - return _then(_self.copyWith( -name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable -as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable -as String, - )); -} - -} - - -/// Adds pattern-matching-related methods to [ListContactEntity]. -extension ListContactEntityPatterns on ListContactEntity { -/// A variant of `map` that fallback to returning `orElse`. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case _: -/// return orElse(); -/// } -/// ``` - -@optionalTypeArgs TResult maybeMap(TResult Function( _ListContactEntity value)? $default,{required TResult orElse(),}){ -final _that = this; -switch (_that) { -case _ListContactEntity() when $default != null: -return $default(_that);case _: - return orElse(); - -} -} -/// A `switch`-like method, using callbacks. -/// -/// Callbacks receives the raw object, upcasted. -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case final Subclass2 value: -/// return ...; -/// } -/// ``` - -@optionalTypeArgs TResult map(TResult Function( _ListContactEntity value) $default,){ -final _that = this; -switch (_that) { -case _ListContactEntity(): -return $default(_that);case _: - throw StateError('Unexpected subclass'); - -} -} -/// A variant of `map` that fallback to returning `null`. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case _: -/// return null; -/// } -/// ``` - -@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ListContactEntity value)? $default,){ -final _that = this; -switch (_that) { -case _ListContactEntity() when $default != null: -return $default(_that);case _: - return null; - -} -} -/// A variant of `when` that fallback to an `orElse` callback. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case _: -/// return orElse(); -/// } -/// ``` - -@optionalTypeArgs TResult maybeWhen(TResult Function( String name, String phone)? $default,{required TResult orElse(),}) {final _that = this; -switch (_that) { -case _ListContactEntity() when $default != null: -return $default(_that.name,_that.phone);case _: - return orElse(); - -} -} -/// A `switch`-like method, using callbacks. -/// -/// As opposed to `map`, this offers destructuring. -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case Subclass2(:final field2): -/// return ...; -/// } -/// ``` - -@optionalTypeArgs TResult when(TResult Function( String name, String phone) $default,) {final _that = this; -switch (_that) { -case _ListContactEntity(): -return $default(_that.name,_that.phone);case _: - throw StateError('Unexpected subclass'); - -} -} -/// A variant of `when` that fallback to returning `null` -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case _: -/// return null; -/// } -/// ``` - -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String name, String phone)? $default,) {final _that = this; -switch (_that) { -case _ListContactEntity() when $default != null: -return $default(_that.name,_that.phone);case _: - return null; - -} -} - -} - -/// @nodoc - - -class _ListContactEntity implements ListContactEntity { - const _ListContactEntity({required this.name, required this.phone}); - - -@override final String name; -@override final String phone; - -/// Create a copy of ListContactEntity -/// with the given fields replaced by the non-null parameter values. -@override @JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') -_$ListContactEntityCopyWith<_ListContactEntity> get copyWith => __$ListContactEntityCopyWithImpl<_ListContactEntity>(this, _$identity); - - - -@override -bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _ListContactEntity&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)); -} - - -@override -int get hashCode => Object.hash(runtimeType,name,phone); - -@override -String toString() { - return 'ListContactEntity(name: $name, phone: $phone)'; -} - - -} - -/// @nodoc -abstract mixin class _$ListContactEntityCopyWith<$Res> implements $ListContactEntityCopyWith<$Res> { - factory _$ListContactEntityCopyWith(_ListContactEntity value, $Res Function(_ListContactEntity) _then) = __$ListContactEntityCopyWithImpl; -@override @useResult -$Res call({ - String name, String phone -}); - - - - -} -/// @nodoc -class __$ListContactEntityCopyWithImpl<$Res> - implements _$ListContactEntityCopyWith<$Res> { - __$ListContactEntityCopyWithImpl(this._self, this._then); - - final _ListContactEntity _self; - final $Res Function(_ListContactEntity) _then; - -/// Create a copy of ListContactEntity -/// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? phone = null,}) { - return _then(_ListContactEntity( -name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable -as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable -as String, - )); -} - - -} - -// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart index a90a0b13..4b5f2f24 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/contacts_screen.dart @@ -1,7 +1,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/contacts/presentation/edit_contact_screen.dart'; import 'package:functions/src/features/contacts/presentation/state/contacts_view_model.dart'; import 'package:navigation/navigation.dart'; @@ -66,25 +66,25 @@ class ContactsScreen extends ConsumerWidget { SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)), Expanded( child: Container( padding: SizeUtils.getByScreen( - small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), - big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) ), child: ListView.separated( itemBuilder: (BuildContext context, int index)=>ContactCard( - contact: state.contactList!.contacts[index], + contact: state.contacts[index], isEditing: state.isEditing, ), separatorBuilder: (BuildContext context, int index)=>SizedBox( - height: SizeUtils.getByScreen(small: 18, big: 17) + height: SizeUtils.getByScreen(small: 18, big: 17) ), - itemCount: state.contactList?.contacts.length ?? 0 + itemCount: state.contacts.length ), )), if (state.isEditing) ...[ Container( padding: SizeUtils.getByScreen( - small: EdgeInsets.symmetric(horizontal: 26, vertical: 14), - big: EdgeInsets.symmetric(horizontal: 24, vertical: 12) + small: EdgeInsets.symmetric(horizontal: 26, vertical: 14), + big: EdgeInsets.symmetric(horizontal: 24, vertical: 12) ), ), ], @@ -110,7 +110,7 @@ class ContactsScreen extends ConsumerWidget { class ContactCard extends ConsumerWidget { - final ListContactEntity contact; + final ContactEntity contact; final bool isEditing; const ContactCard({ diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart index dbe78eb8..519fdf98 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart @@ -2,7 +2,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/contacts/presentation/state/contacts_view_model.dart'; // import 'package:navigation/navigation.dart'; import 'package:sf_localizations/sf_localizations.dart'; @@ -10,7 +10,7 @@ import 'package:utils/utils.dart'; class EditContactScreen extends ConsumerWidget { //final NavigationContract navigationContract; - final ListContactEntity contact; + final ContactEntity contact; const EditContactScreen({super.key, required this.contact // required this.navigationContract diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart index b792c2a5..d199d571 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_model.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; -import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart'; -import 'package:functions/src/features/contacts/presentation/providers/get_contacts_provider.dart'; +import 'package:functions/src/features/contacts/presentation/providers/get_contacts_use_case_provider.dart'; import 'package:functions/src/features/contacts/presentation/state/contacts_view_state.dart'; +// import 'package:legacy_shared/src/providers/logged_user_provider.dart'; +// import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; // import 'package:sf_localizations/sf_localizations.dart'; final contactsViewModelProvider = @@ -18,26 +19,30 @@ class ContactsViewModel extends Notifier { late final TextEditingController nameController; late final TextEditingController phoneController; + // late final UserEntity loggedUser; + @override ContactsViewState build() { _getContactsUseCase = ref.read(getContactsUseCaseProvider); + // loggedUser = ref.read(loggedUserProvider); + nameController = TextEditingController(); phoneController = TextEditingController(); nameController.addListener(_onNameChanged); phoneController.addListener(_onPhoneChanged); - _getContactsUseCase.getContacts(deviceId: '').then(setContacts); + _getContactsUseCase.getContacts(userId: '').then(setContacts); ref.onDispose(disposeControllers); return const ContactsViewState(); } - void setContacts(ContactListEntity contactList) { + void setContacts(List contacts) { state = state.copyWith( - contactList: contactList + contacts: contacts ); } @@ -59,7 +64,9 @@ class ContactsViewModel extends Notifier { state = state.copyWith(phone: text, errorMessage: ''); } - void updateContact(ListContactEntity contact) {} + void updateContact(ContactEntity contact) { + + } void disposeControllers() { nameController.removeListener(_onNameChanged); diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart index 439ee615..b3b17bd5 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.dart @@ -1,12 +1,12 @@ import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; part 'contacts_view_state.freezed.dart'; @freezed abstract class ContactsViewState with _$ContactsViewState { const factory ContactsViewState({ - @Default(null) ContactListEntity? contactList, + @Default([]) List contacts, @Default(false) bool isLoading, @Default(false) bool isEditing, @Default('') String name, diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart index 1d74938c..b6647030 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/state/contacts_view_state.freezed.dart @@ -14,7 +14,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$ContactsViewState { - ContactListEntity? get contactList; bool get isLoading; bool get isEditing; String get name; String get phone; String get errorMessage; + List get contacts; bool get isLoading; bool get isEditing; String get name; String get phone; String get errorMessage; /// Create a copy of ContactsViewState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -25,16 +25,16 @@ $ContactsViewStateCopyWith get copyWith => _$ContactsViewStat @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactsViewState&&(identical(other.contactList, contactList) || other.contactList == contactList)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactsViewState&&const DeepCollectionEquality().equals(other.contacts, contacts)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); } @override -int get hashCode => Object.hash(runtimeType,contactList,isLoading,isEditing,name,phone,errorMessage); +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(contacts),isLoading,isEditing,name,phone,errorMessage); @override String toString() { - return 'ContactsViewState(contactList: $contactList, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)'; + return 'ContactsViewState(contacts: $contacts, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)'; } @@ -45,11 +45,11 @@ abstract mixin class $ContactsViewStateCopyWith<$Res> { factory $ContactsViewStateCopyWith(ContactsViewState value, $Res Function(ContactsViewState) _then) = _$ContactsViewStateCopyWithImpl; @useResult $Res call({ - ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage + List contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage }); -$ContactListEntityCopyWith<$Res>? get contactList; + } /// @nodoc @@ -62,10 +62,10 @@ class _$ContactsViewStateCopyWithImpl<$Res> /// Create a copy of ContactsViewState /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? contactList = freezed,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? contacts = null,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) { return _then(_self.copyWith( -contactList: freezed == contactList ? _self.contactList : contactList // ignore: cast_nullable_to_non_nullable -as ContactListEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable +contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable +as List,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable as bool,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable @@ -73,19 +73,7 @@ as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage as String, )); } -/// Create a copy of ContactsViewState -/// with the given fields replaced by the non-null parameter values. -@override -@pragma('vm:prefer-inline') -$ContactListEntityCopyWith<$Res>? get contactList { - if (_self.contactList == null) { - return null; - } - return $ContactListEntityCopyWith<$Res>(_self.contactList!, (value) { - return _then(_self.copyWith(contactList: value)); - }); -} } @@ -167,10 +155,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( List contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _ContactsViewState() when $default != null: -return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: +return $default(_that.contacts,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: return orElse(); } @@ -188,10 +176,10 @@ return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_th /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( List contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage) $default,) {final _that = this; switch (_that) { case _ContactsViewState(): -return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: +return $default(_that.contacts,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: throw StateError('Unexpected subclass'); } @@ -208,10 +196,10 @@ return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_th /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( List contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage)? $default,) {final _that = this; switch (_that) { case _ContactsViewState() when $default != null: -return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: +return $default(_that.contacts,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _: return null; } @@ -223,10 +211,16 @@ return $default(_that.contactList,_that.isLoading,_that.isEditing,_that.name,_th class _ContactsViewState implements ContactsViewState { - const _ContactsViewState({this.contactList = null, this.isLoading = false, this.isEditing = false, this.name = '', this.phone = '', this.errorMessage = ''}); + const _ContactsViewState({final List contacts = const [], this.isLoading = false, this.isEditing = false, this.name = '', this.phone = '', this.errorMessage = ''}): _contacts = contacts; -@override@JsonKey() final ContactListEntity? contactList; + final List _contacts; +@override@JsonKey() List get contacts { + if (_contacts is EqualUnmodifiableListView) return _contacts; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_contacts); +} + @override@JsonKey() final bool isLoading; @override@JsonKey() final bool isEditing; @override@JsonKey() final String name; @@ -243,16 +237,16 @@ _$ContactsViewStateCopyWith<_ContactsViewState> get copyWith => __$ContactsViewS @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactsViewState&&(identical(other.contactList, contactList) || other.contactList == contactList)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactsViewState&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isEditing, isEditing) || other.isEditing == isEditing)&&(identical(other.name, name) || other.name == name)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); } @override -int get hashCode => Object.hash(runtimeType,contactList,isLoading,isEditing,name,phone,errorMessage); +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_contacts),isLoading,isEditing,name,phone,errorMessage); @override String toString() { - return 'ContactsViewState(contactList: $contactList, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)'; + return 'ContactsViewState(contacts: $contacts, isLoading: $isLoading, isEditing: $isEditing, name: $name, phone: $phone, errorMessage: $errorMessage)'; } @@ -263,11 +257,11 @@ abstract mixin class _$ContactsViewStateCopyWith<$Res> implements $ContactsViewS factory _$ContactsViewStateCopyWith(_ContactsViewState value, $Res Function(_ContactsViewState) _then) = __$ContactsViewStateCopyWithImpl; @override @useResult $Res call({ - ContactListEntity? contactList, bool isLoading, bool isEditing, String name, String phone, String errorMessage + List contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage }); -@override $ContactListEntityCopyWith<$Res>? get contactList; + } /// @nodoc @@ -280,10 +274,10 @@ class __$ContactsViewStateCopyWithImpl<$Res> /// Create a copy of ContactsViewState /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? contactList = freezed,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? contacts = null,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) { return _then(_ContactsViewState( -contactList: freezed == contactList ? _self.contactList : contactList // ignore: cast_nullable_to_non_nullable -as ContactListEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable +contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable +as List,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool,isEditing: null == isEditing ? _self.isEditing : isEditing // ignore: cast_nullable_to_non_nullable as bool,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable @@ -292,19 +286,7 @@ as String, )); } -/// Create a copy of ContactsViewState -/// with the given fields replaced by the non-null parameter values. -@override -@pragma('vm:prefer-inline') -$ContactListEntityCopyWith<$Res>? get contactList { - if (_self.contactList == null) { - return null; - } - return $ContactListEntityCopyWith<$Res>(_self.contactList!, (value) { - return _then(_self.copyWith(contactList: value)); - }); -} } // dart format on From da90ed94ea097ca19ec1f2ab95536ecedee252ed Mon Sep 17 00:00:00 2001 From: aitorarana Date: Tue, 10 Feb 2026 17:30:58 +0100 Subject: [PATCH 4/8] create legacy_shared package and added page_layout and logged_user_provider --- .idea/modules.xml | 1 + modules/legacy/melos_legacy.iml | 3 + modules/legacy/modules/functions/pubspec.yaml | 114 ++++ .../legacy_shared_remote_datasource.dart | 5 + .../legacy_shared_remote_datasource_impl.dart | 75 +++ .../src/data/models/entities/user_entity.dart | 23 + .../models/entities/user_entity.freezed.dart | 310 +++++++++ .../get_logged_user_response_model.dart | 60 ++ ...et_logged_user_response_model.freezed.dart | 597 ++++++++++++++++++ .../get_logged_user_response_model.g.dart | 57 ++ .../legacy_shared_repository.dart | 6 + .../legacy_shared_repository_impl.dart | 15 + ...acy_shared_remote_datasource_provider.dart | 9 + .../legacy_shared_repository_provider.dart | 10 + .../src/providers/logged_user_provider.dart | 20 + .../lib/src/widgets/layouts/page_layout.dart | 52 ++ .../packages/legacy_shared/pubspec.yaml | 69 ++ 17 files changed, 1426 insertions(+) create mode 100644 modules/legacy/modules/functions/pubspec.yaml create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource_impl.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.freezed.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.freezed.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.g.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository_impl.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_remote_datasource_provider.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_repository_provider.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/providers/logged_user_provider.dart create mode 100644 modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart create mode 100644 modules/legacy/packages/legacy_shared/pubspec.yaml diff --git a/.idea/modules.xml b/.idea/modules.xml index b7aa4bbc..54a5b847 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -13,6 +13,7 @@ + diff --git a/modules/legacy/melos_legacy.iml b/modules/legacy/melos_legacy.iml index e8a4d511..f4ba9b32 100644 --- a/modules/legacy/melos_legacy.iml +++ b/modules/legacy/melos_legacy.iml @@ -20,6 +20,9 @@ + + + diff --git a/modules/legacy/modules/functions/pubspec.yaml b/modules/legacy/modules/functions/pubspec.yaml new file mode 100644 index 00000000..d6fedac9 --- /dev/null +++ b/modules/legacy/modules/functions/pubspec.yaml @@ -0,0 +1,114 @@ +name: functions +description: "A new Flutter project." + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# +# This version is used _only_ for the Runner app, which is used if you just do +# a `flutter run`. It has no impact on any other native host app that you embed +# your Flutter project into. +version: 1.0.0+1 + +environment: + sdk: ^3.9.2 + +dependencies: + flutter: + sdk: flutter + #modules dependencies go here + + #packages dependencies go here + design_system: + path: ../../../../packages/design_system + navigation: + path: ../../../../packages/navigation + sf_localizations: + path: ../../../../packages/sf_localizations + sf_infrastructure: + path: ../../../../packages/sf_infrastructure + utils: + path: ../../../../packages/utils + fonts: + path: ../../../../packages/fonts + legacy_shared: + path: ../../packages/legacy_shared + #dependencies go here + flutter_svg: ^2.2.1 + get_it: ^9.0.5 + go_router: ^17.0.0 + flutter_riverpod: ^3.0.3 + freezed_annotation: ^3.1.0 + freezed: ^3.2.3 + dio: ^5.9.0 + json_annotation: ^4.9.0 + json_serializable: ^6.11.2 + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.8 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add Flutter specific assets to your application, add an assets section, + # like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # To add Flutter specific custom fonts to your application, add a fonts + # section here, in this "flutter" section. Each entry in this list should + # have a "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/to/font-from-package + + + # This section identifies your Flutter project as a module meant for + # embedding in a native host app. These identifiers should _not_ ordinarily + # be changed after generation - they are used to ensure that the tooling can + # maintain consistency when adding or modifying assets and plugins. + # They also do not have any bearing on your native host application's + # identifiers, which may be completely independent or the same as these. + module: + androidX: true + androidPackage: com.example.functions + iosBundleIdentifier: com.example.functions diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource.dart b/modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource.dart new file mode 100644 index 00000000..f760be5d --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource.dart @@ -0,0 +1,5 @@ +import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; + +abstract class LegacySharedRemoteDatasource { + Future getLoggedUser({required String token}); +} diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource_impl.dart b/modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource_impl.dart new file mode 100644 index 00000000..30a09326 --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/datasource/legacy_shared_remote_datasource_impl.dart @@ -0,0 +1,75 @@ +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:legacy_shared/src/data/datasource/legacy_shared_remote_datasource.dart'; +import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; +import 'package:legacy_shared/src/data/models/get_logged_user_response_model.dart'; +import 'package:sf_infrastructure/sf_infrastructure.dart'; + +class LegacySharedRemoteDatasourceImpl implements LegacySharedRemoteDatasource { + LegacySharedRemoteDatasourceImpl(this._repository); + + final QuestiaRepository _repository; + + @override + Future getLoggedUser({required String token}) async { + try { + final response = await _repository.get>( + '/users/api/auth/me', + ); + final data = response.data!['item']; + if (data == null || data.isEmpty) { + throw Exception('Empty response from /auth/me'); + } + + final model = GetLoggedUserResponseModel.fromJson(data); + /*final model = GetLoggedUserResponseModel(item: + GetLoggedUserItemResponseModel( + id: '1111', + firstName: 'Juan', + email: 'juan@test.com', + phone: '111111111'));*/ + return model.toEntity(); + } on DioException catch (error) { + throw _mapDioError( + error, + defaultMessage: error.message ?? 'Error getting logged user', + ); + } + } +} + +Exception _mapDioError(DioException error, {required String defaultMessage}) { + final apiMsg = _extractApiMessage(error.response?.data); + final msg = apiMsg ?? error.message ?? defaultMessage; + return Exception(msg); +} + +String? _extractApiMessage(Object? data) { + if (data == null) return null; + + if (data is Map) { + final errorObj = data['error']; + if (errorObj is Map && errorObj['message'] is String) { + return (errorObj['message'] as String).trim(); + } + if (data['message'] is String) { + return (data['message'] as String).trim(); + } + return null; + } + + if (data is String) { + final raw = data.trim(); + if (raw.isEmpty) return null; + + try { + final decoded = jsonDecode(raw); + return _extractApiMessage(decoded); + } catch (_) { + return raw; + } + } + + return null; +} diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.dart b/modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.dart new file mode 100644 index 00000000..ccea2ef5 --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.dart @@ -0,0 +1,23 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'user_entity.freezed.dart'; + +@freezed +abstract class UserEntity with _$UserEntity { + const factory UserEntity({ + required String id, + required String delegationId, + required String email, + required String createdAt, + required String updatedAt, + required String status, + required String role, + required String lastLogin, + required String currentLogin, + required String language, + required String firstName, + required String lastName, + required String hasApiKey, + required String phone, + }) = _UserEntity; +} diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.freezed.dart b/modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.freezed.dart new file mode 100644 index 00000000..5b9e7aee --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/models/entities/user_entity.freezed.dart @@ -0,0 +1,310 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'user_entity.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$UserEntity { + + String get id; String get delegationId; String get email; String get createdAt; String get updatedAt; String get status; String get role; String get lastLogin; String get currentLogin; String get language; String get firstName; String get lastName; String get hasApiKey; String get phone; +/// Create a copy of UserEntity +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$UserEntityCopyWith get copyWith => _$UserEntityCopyWithImpl(this as UserEntity, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is UserEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.email, email) || other.email == email)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.status, status) || other.status == status)&&(identical(other.role, role) || other.role == role)&&(identical(other.lastLogin, lastLogin) || other.lastLogin == lastLogin)&&(identical(other.currentLogin, currentLogin) || other.currentLogin == currentLogin)&&(identical(other.language, language) || other.language == language)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.hasApiKey, hasApiKey) || other.hasApiKey == hasApiKey)&&(identical(other.phone, phone) || other.phone == phone)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,delegationId,email,createdAt,updatedAt,status,role,lastLogin,currentLogin,language,firstName,lastName,hasApiKey,phone); + +@override +String toString() { + return 'UserEntity(id: $id, delegationId: $delegationId, email: $email, createdAt: $createdAt, updatedAt: $updatedAt, status: $status, role: $role, lastLogin: $lastLogin, currentLogin: $currentLogin, language: $language, firstName: $firstName, lastName: $lastName, hasApiKey: $hasApiKey, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class $UserEntityCopyWith<$Res> { + factory $UserEntityCopyWith(UserEntity value, $Res Function(UserEntity) _then) = _$UserEntityCopyWithImpl; +@useResult +$Res call({ + String id, String delegationId, String email, String createdAt, String updatedAt, String status, String role, String lastLogin, String currentLogin, String language, String firstName, String lastName, String hasApiKey, String phone +}); + + + + +} +/// @nodoc +class _$UserEntityCopyWithImpl<$Res> + implements $UserEntityCopyWith<$Res> { + _$UserEntityCopyWithImpl(this._self, this._then); + + final UserEntity _self; + final $Res Function(UserEntity) _then; + +/// Create a copy of UserEntity +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? delegationId = null,Object? email = null,Object? createdAt = null,Object? updatedAt = null,Object? status = null,Object? role = null,Object? lastLogin = null,Object? currentLogin = null,Object? language = null,Object? firstName = null,Object? lastName = null,Object? hasApiKey = null,Object? phone = null,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as String,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as String,lastLogin: null == lastLogin ? _self.lastLogin : lastLogin // ignore: cast_nullable_to_non_nullable +as String,currentLogin: null == currentLogin ? _self.currentLogin : currentLogin // ignore: cast_nullable_to_non_nullable +as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable +as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable +as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String,hasApiKey: null == hasApiKey ? _self.hasApiKey : hasApiKey // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [UserEntity]. +extension UserEntityPatterns on UserEntity { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _UserEntity value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _UserEntity() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _UserEntity value) $default,){ +final _that = this; +switch (_that) { +case _UserEntity(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _UserEntity value)? $default,){ +final _that = this; +switch (_that) { +case _UserEntity() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String delegationId, String email, String createdAt, String updatedAt, String status, String role, String lastLogin, String currentLogin, String language, String firstName, String lastName, String hasApiKey, String phone)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _UserEntity() when $default != null: +return $default(_that.id,_that.delegationId,_that.email,_that.createdAt,_that.updatedAt,_that.status,_that.role,_that.lastLogin,_that.currentLogin,_that.language,_that.firstName,_that.lastName,_that.hasApiKey,_that.phone);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String id, String delegationId, String email, String createdAt, String updatedAt, String status, String role, String lastLogin, String currentLogin, String language, String firstName, String lastName, String hasApiKey, String phone) $default,) {final _that = this; +switch (_that) { +case _UserEntity(): +return $default(_that.id,_that.delegationId,_that.email,_that.createdAt,_that.updatedAt,_that.status,_that.role,_that.lastLogin,_that.currentLogin,_that.language,_that.firstName,_that.lastName,_that.hasApiKey,_that.phone);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String delegationId, String email, String createdAt, String updatedAt, String status, String role, String lastLogin, String currentLogin, String language, String firstName, String lastName, String hasApiKey, String phone)? $default,) {final _that = this; +switch (_that) { +case _UserEntity() when $default != null: +return $default(_that.id,_that.delegationId,_that.email,_that.createdAt,_that.updatedAt,_that.status,_that.role,_that.lastLogin,_that.currentLogin,_that.language,_that.firstName,_that.lastName,_that.hasApiKey,_that.phone);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _UserEntity implements UserEntity { + const _UserEntity({required this.id, required this.delegationId, required this.email, required this.createdAt, required this.updatedAt, required this.status, required this.role, required this.lastLogin, required this.currentLogin, required this.language, required this.firstName, required this.lastName, required this.hasApiKey, required this.phone}); + + +@override final String id; +@override final String delegationId; +@override final String email; +@override final String createdAt; +@override final String updatedAt; +@override final String status; +@override final String role; +@override final String lastLogin; +@override final String currentLogin; +@override final String language; +@override final String firstName; +@override final String lastName; +@override final String hasApiKey; +@override final String phone; + +/// Create a copy of UserEntity +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$UserEntityCopyWith<_UserEntity> get copyWith => __$UserEntityCopyWithImpl<_UserEntity>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _UserEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.email, email) || other.email == email)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.status, status) || other.status == status)&&(identical(other.role, role) || other.role == role)&&(identical(other.lastLogin, lastLogin) || other.lastLogin == lastLogin)&&(identical(other.currentLogin, currentLogin) || other.currentLogin == currentLogin)&&(identical(other.language, language) || other.language == language)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.hasApiKey, hasApiKey) || other.hasApiKey == hasApiKey)&&(identical(other.phone, phone) || other.phone == phone)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,delegationId,email,createdAt,updatedAt,status,role,lastLogin,currentLogin,language,firstName,lastName,hasApiKey,phone); + +@override +String toString() { + return 'UserEntity(id: $id, delegationId: $delegationId, email: $email, createdAt: $createdAt, updatedAt: $updatedAt, status: $status, role: $role, lastLogin: $lastLogin, currentLogin: $currentLogin, language: $language, firstName: $firstName, lastName: $lastName, hasApiKey: $hasApiKey, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class _$UserEntityCopyWith<$Res> implements $UserEntityCopyWith<$Res> { + factory _$UserEntityCopyWith(_UserEntity value, $Res Function(_UserEntity) _then) = __$UserEntityCopyWithImpl; +@override @useResult +$Res call({ + String id, String delegationId, String email, String createdAt, String updatedAt, String status, String role, String lastLogin, String currentLogin, String language, String firstName, String lastName, String hasApiKey, String phone +}); + + + + +} +/// @nodoc +class __$UserEntityCopyWithImpl<$Res> + implements _$UserEntityCopyWith<$Res> { + __$UserEntityCopyWithImpl(this._self, this._then); + + final _UserEntity _self; + final $Res Function(_UserEntity) _then; + +/// Create a copy of UserEntity +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? delegationId = null,Object? email = null,Object? createdAt = null,Object? updatedAt = null,Object? status = null,Object? role = null,Object? lastLogin = null,Object? currentLogin = null,Object? language = null,Object? firstName = null,Object? lastName = null,Object? hasApiKey = null,Object? phone = null,}) { + return _then(_UserEntity( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,delegationId: null == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as String,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as String,lastLogin: null == lastLogin ? _self.lastLogin : lastLogin // ignore: cast_nullable_to_non_nullable +as String,currentLogin: null == currentLogin ? _self.currentLogin : currentLogin // ignore: cast_nullable_to_non_nullable +as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable +as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable +as String,lastName: null == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String,hasApiKey: null == hasApiKey ? _self.hasApiKey : hasApiKey // ignore: cast_nullable_to_non_nullable +as String,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.dart b/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.dart new file mode 100644 index 00000000..02bd7f91 --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.dart @@ -0,0 +1,60 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; + +part 'get_logged_user_response_model.freezed.dart'; +part 'get_logged_user_response_model.g.dart'; + +@freezed +abstract class GetLoggedUserResponseModel with _$GetLoggedUserResponseModel { + const factory GetLoggedUserResponseModel({ + required GetLoggedUserItemResponseModel item, + }) = _GetLoggedUserResponseModel; + + factory GetLoggedUserResponseModel.fromJson(Map json) => + _$GetLoggedUserResponseModelFromJson(json); +} + +@freezed +abstract class GetLoggedUserItemResponseModel with _$GetLoggedUserItemResponseModel { + const factory GetLoggedUserItemResponseModel({ + required String id, + String? delegationId, + String? email, + String? createdAt, + String? updatedAt, + String? status, + String? role, + String? lastLogin, + String? currentLogin, + String? language, + String? firstName, + String? lastName, + String? hasApiKey, + String? phone, + }) = + _GetLoggedUserItemResponseModel; + + factory GetLoggedUserItemResponseModel.fromJson(Map json) => + _$GetLoggedUserItemResponseModelFromJson(json); +} + +extension GetLoggedUserResponseModelMapper on GetLoggedUserResponseModel { + UserEntity toEntity() { + return UserEntity( + id: item.id, + delegationId: item.delegationId ?? '', + email: item.email ?? '', + createdAt: item.createdAt ?? '', + updatedAt: item.updatedAt ?? '', + status: item.status ?? '', + role: item.role ?? '', + lastLogin: item.lastLogin ?? '', + currentLogin: item.currentLogin ?? '', + language: item.language ?? '', + firstName: item.firstName ?? '', + lastName: item.lastName ?? '', + hasApiKey: item.hasApiKey ?? '', + phone: item.phone ?? '' + ); + } +} \ No newline at end of file diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.freezed.dart b/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.freezed.dart new file mode 100644 index 00000000..15722cae --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.freezed.dart @@ -0,0 +1,597 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'get_logged_user_response_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$GetLoggedUserResponseModel { + + GetLoggedUserItemResponseModel get item; +/// Create a copy of GetLoggedUserResponseModel +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$GetLoggedUserResponseModelCopyWith get copyWith => _$GetLoggedUserResponseModelCopyWithImpl(this as GetLoggedUserResponseModel, _$identity); + + /// Serializes this GetLoggedUserResponseModel to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is GetLoggedUserResponseModel&&(identical(other.item, item) || other.item == item)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,item); + +@override +String toString() { + return 'GetLoggedUserResponseModel(item: $item)'; +} + + +} + +/// @nodoc +abstract mixin class $GetLoggedUserResponseModelCopyWith<$Res> { + factory $GetLoggedUserResponseModelCopyWith(GetLoggedUserResponseModel value, $Res Function(GetLoggedUserResponseModel) _then) = _$GetLoggedUserResponseModelCopyWithImpl; +@useResult +$Res call({ + GetLoggedUserItemResponseModel item +}); + + +$GetLoggedUserItemResponseModelCopyWith<$Res> get item; + +} +/// @nodoc +class _$GetLoggedUserResponseModelCopyWithImpl<$Res> + implements $GetLoggedUserResponseModelCopyWith<$Res> { + _$GetLoggedUserResponseModelCopyWithImpl(this._self, this._then); + + final GetLoggedUserResponseModel _self; + final $Res Function(GetLoggedUserResponseModel) _then; + +/// Create a copy of GetLoggedUserResponseModel +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? item = null,}) { + return _then(_self.copyWith( +item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable +as GetLoggedUserItemResponseModel, + )); +} +/// Create a copy of GetLoggedUserResponseModel +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$GetLoggedUserItemResponseModelCopyWith<$Res> get item { + + return $GetLoggedUserItemResponseModelCopyWith<$Res>(_self.item, (value) { + return _then(_self.copyWith(item: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [GetLoggedUserResponseModel]. +extension GetLoggedUserResponseModelPatterns on GetLoggedUserResponseModel { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _GetLoggedUserResponseModel value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _GetLoggedUserResponseModel() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _GetLoggedUserResponseModel value) $default,){ +final _that = this; +switch (_that) { +case _GetLoggedUserResponseModel(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _GetLoggedUserResponseModel value)? $default,){ +final _that = this; +switch (_that) { +case _GetLoggedUserResponseModel() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( GetLoggedUserItemResponseModel item)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _GetLoggedUserResponseModel() when $default != null: +return $default(_that.item);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( GetLoggedUserItemResponseModel item) $default,) {final _that = this; +switch (_that) { +case _GetLoggedUserResponseModel(): +return $default(_that.item);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( GetLoggedUserItemResponseModel item)? $default,) {final _that = this; +switch (_that) { +case _GetLoggedUserResponseModel() when $default != null: +return $default(_that.item);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _GetLoggedUserResponseModel implements GetLoggedUserResponseModel { + const _GetLoggedUserResponseModel({required this.item}); + factory _GetLoggedUserResponseModel.fromJson(Map json) => _$GetLoggedUserResponseModelFromJson(json); + +@override final GetLoggedUserItemResponseModel item; + +/// Create a copy of GetLoggedUserResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$GetLoggedUserResponseModelCopyWith<_GetLoggedUserResponseModel> get copyWith => __$GetLoggedUserResponseModelCopyWithImpl<_GetLoggedUserResponseModel>(this, _$identity); + +@override +Map toJson() { + return _$GetLoggedUserResponseModelToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetLoggedUserResponseModel&&(identical(other.item, item) || other.item == item)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,item); + +@override +String toString() { + return 'GetLoggedUserResponseModel(item: $item)'; +} + + +} + +/// @nodoc +abstract mixin class _$GetLoggedUserResponseModelCopyWith<$Res> implements $GetLoggedUserResponseModelCopyWith<$Res> { + factory _$GetLoggedUserResponseModelCopyWith(_GetLoggedUserResponseModel value, $Res Function(_GetLoggedUserResponseModel) _then) = __$GetLoggedUserResponseModelCopyWithImpl; +@override @useResult +$Res call({ + GetLoggedUserItemResponseModel item +}); + + +@override $GetLoggedUserItemResponseModelCopyWith<$Res> get item; + +} +/// @nodoc +class __$GetLoggedUserResponseModelCopyWithImpl<$Res> + implements _$GetLoggedUserResponseModelCopyWith<$Res> { + __$GetLoggedUserResponseModelCopyWithImpl(this._self, this._then); + + final _GetLoggedUserResponseModel _self; + final $Res Function(_GetLoggedUserResponseModel) _then; + +/// Create a copy of GetLoggedUserResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? item = null,}) { + return _then(_GetLoggedUserResponseModel( +item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable +as GetLoggedUserItemResponseModel, + )); +} + +/// Create a copy of GetLoggedUserResponseModel +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$GetLoggedUserItemResponseModelCopyWith<$Res> get item { + + return $GetLoggedUserItemResponseModelCopyWith<$Res>(_self.item, (value) { + return _then(_self.copyWith(item: value)); + }); +} +} + + +/// @nodoc +mixin _$GetLoggedUserItemResponseModel { + + String get id; String? get delegationId; String? get email; String? get createdAt; String? get updatedAt; String? get status; String? get role; String? get lastLogin; String? get currentLogin; String? get language; String? get firstName; String? get lastName; String? get hasApiKey; String? get phone; +/// Create a copy of GetLoggedUserItemResponseModel +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$GetLoggedUserItemResponseModelCopyWith get copyWith => _$GetLoggedUserItemResponseModelCopyWithImpl(this as GetLoggedUserItemResponseModel, _$identity); + + /// Serializes this GetLoggedUserItemResponseModel to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is GetLoggedUserItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.email, email) || other.email == email)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.status, status) || other.status == status)&&(identical(other.role, role) || other.role == role)&&(identical(other.lastLogin, lastLogin) || other.lastLogin == lastLogin)&&(identical(other.currentLogin, currentLogin) || other.currentLogin == currentLogin)&&(identical(other.language, language) || other.language == language)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.hasApiKey, hasApiKey) || other.hasApiKey == hasApiKey)&&(identical(other.phone, phone) || other.phone == phone)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,delegationId,email,createdAt,updatedAt,status,role,lastLogin,currentLogin,language,firstName,lastName,hasApiKey,phone); + +@override +String toString() { + return 'GetLoggedUserItemResponseModel(id: $id, delegationId: $delegationId, email: $email, createdAt: $createdAt, updatedAt: $updatedAt, status: $status, role: $role, lastLogin: $lastLogin, currentLogin: $currentLogin, language: $language, firstName: $firstName, lastName: $lastName, hasApiKey: $hasApiKey, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class $GetLoggedUserItemResponseModelCopyWith<$Res> { + factory $GetLoggedUserItemResponseModelCopyWith(GetLoggedUserItemResponseModel value, $Res Function(GetLoggedUserItemResponseModel) _then) = _$GetLoggedUserItemResponseModelCopyWithImpl; +@useResult +$Res call({ + String id, String? delegationId, String? email, String? createdAt, String? updatedAt, String? status, String? role, String? lastLogin, String? currentLogin, String? language, String? firstName, String? lastName, String? hasApiKey, String? phone +}); + + + + +} +/// @nodoc +class _$GetLoggedUserItemResponseModelCopyWithImpl<$Res> + implements $GetLoggedUserItemResponseModelCopyWith<$Res> { + _$GetLoggedUserItemResponseModelCopyWithImpl(this._self, this._then); + + final GetLoggedUserItemResponseModel _self; + final $Res Function(GetLoggedUserItemResponseModel) _then; + +/// Create a copy of GetLoggedUserItemResponseModel +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? delegationId = freezed,Object? email = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,Object? status = freezed,Object? role = freezed,Object? lastLogin = freezed,Object? currentLogin = freezed,Object? language = freezed,Object? firstName = freezed,Object? lastName = freezed,Object? hasApiKey = freezed,Object? phone = freezed,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String?,email: freezed == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as String?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as String?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as String?,role: freezed == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as String?,lastLogin: freezed == lastLogin ? _self.lastLogin : lastLogin // ignore: cast_nullable_to_non_nullable +as String?,currentLogin: freezed == currentLogin ? _self.currentLogin : currentLogin // ignore: cast_nullable_to_non_nullable +as String?,language: freezed == language ? _self.language : language // ignore: cast_nullable_to_non_nullable +as String?,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable +as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String?,hasApiKey: freezed == hasApiKey ? _self.hasApiKey : hasApiKey // ignore: cast_nullable_to_non_nullable +as String?,phone: freezed == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [GetLoggedUserItemResponseModel]. +extension GetLoggedUserItemResponseModelPatterns on GetLoggedUserItemResponseModel { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _GetLoggedUserItemResponseModel value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _GetLoggedUserItemResponseModel() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _GetLoggedUserItemResponseModel value) $default,){ +final _that = this; +switch (_that) { +case _GetLoggedUserItemResponseModel(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _GetLoggedUserItemResponseModel value)? $default,){ +final _that = this; +switch (_that) { +case _GetLoggedUserItemResponseModel() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String? delegationId, String? email, String? createdAt, String? updatedAt, String? status, String? role, String? lastLogin, String? currentLogin, String? language, String? firstName, String? lastName, String? hasApiKey, String? phone)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _GetLoggedUserItemResponseModel() when $default != null: +return $default(_that.id,_that.delegationId,_that.email,_that.createdAt,_that.updatedAt,_that.status,_that.role,_that.lastLogin,_that.currentLogin,_that.language,_that.firstName,_that.lastName,_that.hasApiKey,_that.phone);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String id, String? delegationId, String? email, String? createdAt, String? updatedAt, String? status, String? role, String? lastLogin, String? currentLogin, String? language, String? firstName, String? lastName, String? hasApiKey, String? phone) $default,) {final _that = this; +switch (_that) { +case _GetLoggedUserItemResponseModel(): +return $default(_that.id,_that.delegationId,_that.email,_that.createdAt,_that.updatedAt,_that.status,_that.role,_that.lastLogin,_that.currentLogin,_that.language,_that.firstName,_that.lastName,_that.hasApiKey,_that.phone);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String? delegationId, String? email, String? createdAt, String? updatedAt, String? status, String? role, String? lastLogin, String? currentLogin, String? language, String? firstName, String? lastName, String? hasApiKey, String? phone)? $default,) {final _that = this; +switch (_that) { +case _GetLoggedUserItemResponseModel() when $default != null: +return $default(_that.id,_that.delegationId,_that.email,_that.createdAt,_that.updatedAt,_that.status,_that.role,_that.lastLogin,_that.currentLogin,_that.language,_that.firstName,_that.lastName,_that.hasApiKey,_that.phone);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _GetLoggedUserItemResponseModel implements GetLoggedUserItemResponseModel { + const _GetLoggedUserItemResponseModel({required this.id, this.delegationId, this.email, this.createdAt, this.updatedAt, this.status, this.role, this.lastLogin, this.currentLogin, this.language, this.firstName, this.lastName, this.hasApiKey, this.phone}); + factory _GetLoggedUserItemResponseModel.fromJson(Map json) => _$GetLoggedUserItemResponseModelFromJson(json); + +@override final String id; +@override final String? delegationId; +@override final String? email; +@override final String? createdAt; +@override final String? updatedAt; +@override final String? status; +@override final String? role; +@override final String? lastLogin; +@override final String? currentLogin; +@override final String? language; +@override final String? firstName; +@override final String? lastName; +@override final String? hasApiKey; +@override final String? phone; + +/// Create a copy of GetLoggedUserItemResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$GetLoggedUserItemResponseModelCopyWith<_GetLoggedUserItemResponseModel> get copyWith => __$GetLoggedUserItemResponseModelCopyWithImpl<_GetLoggedUserItemResponseModel>(this, _$identity); + +@override +Map toJson() { + return _$GetLoggedUserItemResponseModelToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetLoggedUserItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.email, email) || other.email == email)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.status, status) || other.status == status)&&(identical(other.role, role) || other.role == role)&&(identical(other.lastLogin, lastLogin) || other.lastLogin == lastLogin)&&(identical(other.currentLogin, currentLogin) || other.currentLogin == currentLogin)&&(identical(other.language, language) || other.language == language)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.hasApiKey, hasApiKey) || other.hasApiKey == hasApiKey)&&(identical(other.phone, phone) || other.phone == phone)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,delegationId,email,createdAt,updatedAt,status,role,lastLogin,currentLogin,language,firstName,lastName,hasApiKey,phone); + +@override +String toString() { + return 'GetLoggedUserItemResponseModel(id: $id, delegationId: $delegationId, email: $email, createdAt: $createdAt, updatedAt: $updatedAt, status: $status, role: $role, lastLogin: $lastLogin, currentLogin: $currentLogin, language: $language, firstName: $firstName, lastName: $lastName, hasApiKey: $hasApiKey, phone: $phone)'; +} + + +} + +/// @nodoc +abstract mixin class _$GetLoggedUserItemResponseModelCopyWith<$Res> implements $GetLoggedUserItemResponseModelCopyWith<$Res> { + factory _$GetLoggedUserItemResponseModelCopyWith(_GetLoggedUserItemResponseModel value, $Res Function(_GetLoggedUserItemResponseModel) _then) = __$GetLoggedUserItemResponseModelCopyWithImpl; +@override @useResult +$Res call({ + String id, String? delegationId, String? email, String? createdAt, String? updatedAt, String? status, String? role, String? lastLogin, String? currentLogin, String? language, String? firstName, String? lastName, String? hasApiKey, String? phone +}); + + + + +} +/// @nodoc +class __$GetLoggedUserItemResponseModelCopyWithImpl<$Res> + implements _$GetLoggedUserItemResponseModelCopyWith<$Res> { + __$GetLoggedUserItemResponseModelCopyWithImpl(this._self, this._then); + + final _GetLoggedUserItemResponseModel _self; + final $Res Function(_GetLoggedUserItemResponseModel) _then; + +/// Create a copy of GetLoggedUserItemResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? delegationId = freezed,Object? email = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,Object? status = freezed,Object? role = freezed,Object? lastLogin = freezed,Object? currentLogin = freezed,Object? language = freezed,Object? firstName = freezed,Object? lastName = freezed,Object? hasApiKey = freezed,Object? phone = freezed,}) { + return _then(_GetLoggedUserItemResponseModel( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable +as String?,email: freezed == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as String?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as String?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as String?,role: freezed == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as String?,lastLogin: freezed == lastLogin ? _self.lastLogin : lastLogin // ignore: cast_nullable_to_non_nullable +as String?,currentLogin: freezed == currentLogin ? _self.currentLogin : currentLogin // ignore: cast_nullable_to_non_nullable +as String?,language: freezed == language ? _self.language : language // ignore: cast_nullable_to_non_nullable +as String?,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable +as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String?,hasApiKey: freezed == hasApiKey ? _self.hasApiKey : hasApiKey // ignore: cast_nullable_to_non_nullable +as String?,phone: freezed == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.g.dart b/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.g.dart new file mode 100644 index 00000000..7ad418b7 --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/models/get_logged_user_response_model.g.dart @@ -0,0 +1,57 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'get_logged_user_response_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_GetLoggedUserResponseModel _$GetLoggedUserResponseModelFromJson( + Map json, +) => _GetLoggedUserResponseModel( + item: GetLoggedUserItemResponseModel.fromJson( + json['item'] as Map, + ), +); + +Map _$GetLoggedUserResponseModelToJson( + _GetLoggedUserResponseModel instance, +) => {'item': instance.item}; + +_GetLoggedUserItemResponseModel _$GetLoggedUserItemResponseModelFromJson( + Map json, +) => _GetLoggedUserItemResponseModel( + id: json['id'] as String, + delegationId: json['delegationId'] as String?, + email: json['email'] as String?, + createdAt: json['createdAt'] as String?, + updatedAt: json['updatedAt'] as String?, + status: json['status'] as String?, + role: json['role'] as String?, + lastLogin: json['lastLogin'] as String?, + currentLogin: json['currentLogin'] as String?, + language: json['language'] as String?, + firstName: json['firstName'] as String?, + lastName: json['lastName'] as String?, + hasApiKey: json['hasApiKey'] as String?, + phone: json['phone'] as String?, +); + +Map _$GetLoggedUserItemResponseModelToJson( + _GetLoggedUserItemResponseModel instance, +) => { + 'id': instance.id, + 'delegationId': instance.delegationId, + 'email': instance.email, + 'createdAt': instance.createdAt, + 'updatedAt': instance.updatedAt, + 'status': instance.status, + 'role': instance.role, + 'lastLogin': instance.lastLogin, + 'currentLogin': instance.currentLogin, + 'language': instance.language, + 'firstName': instance.firstName, + 'lastName': instance.lastName, + 'hasApiKey': instance.hasApiKey, + 'phone': instance.phone, +}; diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository.dart b/modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository.dart new file mode 100644 index 00000000..13854552 --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository.dart @@ -0,0 +1,6 @@ +import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; + +abstract class LegacySharedRepository { + + Future getLoggedUser({required String token}); +} diff --git a/modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository_impl.dart b/modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository_impl.dart new file mode 100644 index 00000000..dac7b5df --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/data/repositories/legacy_shared_repository_impl.dart @@ -0,0 +1,15 @@ +import 'package:legacy_shared/src/data/datasource/legacy_shared_remote_datasource.dart'; +import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; + +import 'legacy_shared_repository.dart'; + +class LegacySharedRepositoryImpl implements LegacySharedRepository { + const LegacySharedRepositoryImpl(this._remote); + + final LegacySharedRemoteDatasource _remote; + + @override + Future getLoggedUser({required String token}) { + return _remote.getLoggedUser(token: token); + } +} diff --git a/modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_remote_datasource_provider.dart b/modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_remote_datasource_provider.dart new file mode 100644 index 00000000..8eea29f6 --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_remote_datasource_provider.dart @@ -0,0 +1,9 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:legacy_shared/src/data/datasource/legacy_shared_remote_datasource.dart'; +import 'package:legacy_shared/src/data/datasource/legacy_shared_remote_datasource_impl.dart'; +import 'package:sf_infrastructure/sf_infrastructure.dart'; + +final legacySharedRemoteDatasourceProvider = Provider((ref) { + final questiaRepository = getIt(); + return LegacySharedRemoteDatasourceImpl(questiaRepository); +}); diff --git a/modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_repository_provider.dart b/modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_repository_provider.dart new file mode 100644 index 00000000..a155ffed --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/providers/legacy_shared_repository_provider.dart @@ -0,0 +1,10 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:legacy_shared/src/data/repositories/legacy_shared_repository.dart'; +import 'package:legacy_shared/src/data/repositories/legacy_shared_repository_impl.dart'; + +import 'legacy_shared_remote_datasource_provider.dart'; + +final legacySharedRepositoryProvider = Provider((ref) { + final remote = ref.read(legacySharedRemoteDatasourceProvider); + return LegacySharedRepositoryImpl(remote); +}); diff --git a/modules/legacy/packages/legacy_shared/lib/src/providers/logged_user_provider.dart b/modules/legacy/packages/legacy_shared/lib/src/providers/logged_user_provider.dart new file mode 100644 index 00000000..9b8a5fee --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/providers/logged_user_provider.dart @@ -0,0 +1,20 @@ +import 'dart:async'; + +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; + +import 'legacy_shared_repository_provider.dart'; + +final loggedUserProvider = AsyncNotifierProvider.autoDispose( + LoggedUserNotifier.new, + ); + +class LoggedUserNotifier extends AsyncNotifier { + late final legacySharedRepository; + + @override + FutureOr build() { + legacySharedRepository = ref.read(legacySharedRepositoryProvider); + return legacySharedRepository.getLoggedUser(token: ''); + } +} diff --git a/modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart b/modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart new file mode 100644 index 00000000..beeee9cf --- /dev/null +++ b/modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:utils/src/size_utils.dart'; + +class PageLayout extends StatelessWidget{ + + final String title; + final Widget body; + final Widget? footer; + + const PageLayout({ + super.key, + required this.title, + required this.body, + this.footer + }); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + child: Column( + children: [ + Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + child: Stack( + children: [ + IconButton(onPressed: () {Navigator.pop(context);}, + icon: Icon(Icons.arrow_back)), + Center( + child: Text(title, + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 28, big: 27) + ), + ) + ) + ], + ), + ), + SizedBox(height: SizeUtils.getByScreen(small: 30, big: 28)), + body, + ?footer + ], + ) + ), + ); + } + +} \ No newline at end of file diff --git a/modules/legacy/packages/legacy_shared/pubspec.yaml b/modules/legacy/packages/legacy_shared/pubspec.yaml new file mode 100644 index 00000000..d41caa9e --- /dev/null +++ b/modules/legacy/packages/legacy_shared/pubspec.yaml @@ -0,0 +1,69 @@ +name: legacy_shared +description: "A new Flutter project." +version: 0.0.1 +homepage: + +environment: + sdk: ^3.9.2 + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + #modules dependencies go here + auth: + path: ../../../../modules/auth + #packages dependencies go here + design_system: + path: ../../../../packages/design_system + utils: + path: ../../../../packages/utils + #dependencies go here + get_it: ^9.0.5 + flutter_riverpod: ^3.0.3 + freezed_annotation: ^3.1.0 + freezed: ^3.2.3 + json_annotation: ^4.9.0 + json_serializable: ^6.11.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/to/asset-from-package + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/to/font-from-package From 46b7ba4a1d532a148c6aac5c5dd58f01f6c88c7d Mon Sep 17 00:00:00 2001 From: aitorarana Date: Tue, 10 Feb 2026 17:33:18 +0100 Subject: [PATCH 5/8] added remote_connection screens and state --- .../mobile_app/lib/navigation/app_router.dart | 5 + .../functions_remote_datasource.dart | 9 +- .../functions_remote_datasource_impl.dart | 88 ++++-- .../functions_repository_impl.dart | 17 +- .../repositories/functions_repository.dart | 9 +- .../domain/get_contacts_use_case.dart | 4 +- .../domain/get_contacts_use_case_impl.dart | 6 +- ...rt => get_contacts_use_case_provider.dart} | 0 .../features/functions/functions_screen.dart | 2 +- .../domain/entities/picture_entity.dart | 12 + .../entities/picture_entity.freezed.dart | 277 +++++++++++++++++ .../domain/get_pictures_use_case.dart | 5 + .../domain/get_pictures_use_case_impl.dart | 14 + .../domain/take_picture_use_case.dart | 5 + .../domain/take_picture_use_case_impl.dart | 14 + .../get_pictures_use_case_provider.dart | 9 + .../take_picture_use_case_provider.dart | 9 + .../presentation/remote_camera_screen.dart | 76 +++++ .../remote_connection_screen.dart | 104 +++++++ .../state/remote_connection_view_model.dart | 84 +++++ .../state/remote_connection_view_state.dart | 16 + .../remote_connection_view_state.freezed.dart | 292 ++++++++++++++++++ .../remote_connection_builder.dart | 18 ++ packages/design_system/fonts/SFIcons.ttf | Bin 27592 -> 27984 bytes packages/design_system/lib/fonts/config.json | 14 + .../design_system/lib/src/icons/sf_icons.dart | 1 + packages/navigation/lib/app_routes.dart | 1 + 27 files changed, 1058 insertions(+), 33 deletions(-) rename modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/{get_contacts_provider.dart => get_contacts_use_case_provider.dart} (100%) create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case_impl.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case_impl.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/get_pictures_use_case_provider.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/take_picture_use_case_provider.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/remote_connection/remote_connection_builder.dart diff --git a/apps/mobile_app/lib/navigation/app_router.dart b/apps/mobile_app/lib/navigation/app_router.dart index e28987b5..36c3baee 100644 --- a/apps/mobile_app/lib/navigation/app_router.dart +++ b/apps/mobile_app/lib/navigation/app_router.dart @@ -57,6 +57,11 @@ void configureAppRouter() { name: 'contacts', pageBuilder: ContactsBuilder().buildPage, ), + GoRoute( + path: AppRoutes.remoteConnection, + name: 'remote_connection', + pageBuilder: RemoteConnectionBuilder().buildPage, + ), GoRoute( path: AppRoutes.login, diff --git a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart index bae23bbc..dffa0475 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart @@ -1,5 +1,10 @@ -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; abstract class FunctionsRemoteDatasource { - Future getContacts({required String deviceId}); + Future> getContacts({required String userId}); + + Future> getPictures({required String userId}); + + Future takePicture({required String userId}); } diff --git a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart index ffef59af..37a434ca 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart @@ -3,8 +3,8 @@ import 'dart:convert'; import 'package:dio/dio.dart'; // import 'package:flutter/material.dart'; import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart'; -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; -import 'package:functions/src/features/contacts/domain/entities/list_contact_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; import 'package:sf_infrastructure/sf_infrastructure.dart'; class FunctionsRemoteDatasourceImpl implements FunctionsRemoteDatasource { @@ -13,15 +13,15 @@ class FunctionsRemoteDatasourceImpl implements FunctionsRemoteDatasource { final QuestiaRepository _repository; @override - Future getContacts({required String deviceId}) async { + Future> getContacts({required String userId}) async { /*try { - final response = await _repository.post>( - '/devices/$deviceId/contact-lists', + final response = await _repository.get>( + '/users/$userId/contacts', ); final data = response.data; if (data == null || data.isEmpty) { - throw Exception('Empty response from /devices/:deviceId/contact-lists'); + throw Exception('Empty response from /users/:userId/contacts'); } final model = GetContactsResponseModel.fromJson(data); @@ -29,20 +29,68 @@ class FunctionsRemoteDatasourceImpl implements FunctionsRemoteDatasource { } on DioException catch (error) { throw _mapDioError(error, defaultMessage: 'Error to get contacts'); }*/ - return ContactListEntity( - id: 'id', - delegationId: 'delegationId', - userId: 'userId', - groupId: 'groupId', - deviceId: 'deviceId', - type: 'type', - contacts: [ - ListContactEntity(name: 'Ana', phone: '111111111'), - ListContactEntity(name: 'Carlos', phone: '222222222'), - ], - createdAt: 'createdAt', - updatedAt: 'updatedAt' - ); + return [ + ContactEntity( + id: '1111', + name: 'Ana', + phone: '111111111', + createdAt: 1, + delegationId: null, + groupId: null, + userId: null, + updatedAt: null, + ), + ContactEntity( + id: '1112', + name: 'Carlos', + phone: '222222222', + createdAt: 2, + delegationId: null, + groupId: null, + userId: null, + updatedAt: null, + ), + ]; + } + + @override + Future> getPictures({required String userId}) async { + /*try { + final response = await _repository.get>( + '', + ); + + final data = response.data; + if (data == null || data.isEmpty) { + throw Exception('Empty response from /users/:userId/contacts'); + } + + final model = GetContactsResponseModel.fromJson(data); + return model.toEntity(); + } on DioException catch (error) { + throw _mapDioError(error, defaultMessage: 'Error to get contacts'); + }*/ + return []; + } + + @override + Future takePicture({required String userId}) async { + /*try { + final response = await _repository.get>( + '', + ); + + final data = response.data; + if (data == null || data.isEmpty) { + throw Exception('Empty response from /users/:userId/contacts'); + } + + final model = GetContactsResponseModel.fromJson(data); + return model.toEntity(); + } on DioException catch (error) { + throw _mapDioError(error, defaultMessage: 'Error to get contacts'); + }*/ + return PictureEntity(id: '1', userId: '1111', createdAt: 1111); } } diff --git a/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart index 4ee55fae..05b906cb 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart @@ -1,6 +1,7 @@ import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart'; import 'package:functions/src/core/domain/repositories/functions_repository.dart'; -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; class FunctionsRepositoryImpl implements FunctionsRepository { const FunctionsRepositoryImpl(this._remote); @@ -8,7 +9,17 @@ class FunctionsRepositoryImpl implements FunctionsRepository { final FunctionsRemoteDatasource _remote; @override - Future getContacts({required String deviceId}) { - return _remote.getContacts(deviceId: deviceId); + Future> getContacts({required String userId}) { + return _remote.getContacts(userId: userId); + } + + @override + Future> getPictures({required String userId}) { + return _remote.getPictures(userId: userId); + } + + @override + Future takePicture({required String userId}) { + return _remote.takePicture(userId: userId); } } diff --git a/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart b/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart index 3df7fc4e..567342ca 100644 --- a/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart +++ b/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart @@ -1,5 +1,10 @@ -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; abstract class FunctionsRepository { - Future getContacts({required String deviceId}); + Future> getContacts({required String userId}); + + Future> getPictures({required String userId}); + + Future takePicture({required String userId}); } diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart index bf0dde3f..122ed392 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case.dart @@ -1,5 +1,5 @@ -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; abstract class GetContactsUseCase { - Future getContacts({required String deviceId}); + Future> getContacts({required String userId}); } diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart index 250f0cfb..b94fb73c 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/domain/get_contacts_use_case_impl.dart @@ -1,5 +1,5 @@ import 'package:functions/src/core/domain/repositories/functions_repository.dart'; -import 'package:functions/src/features/contacts/domain/entities/contact_list_entity.dart'; +import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/contacts/domain/get_contacts_use_case.dart'; class GetContactsUseCaseImpl implements GetContactsUseCase { @@ -8,7 +8,7 @@ class GetContactsUseCaseImpl implements GetContactsUseCase { final FunctionsRepository _repository; @override - Future getContacts({required String deviceId}) { - return _repository.getContacts(deviceId: deviceId); + Future> getContacts({required String userId}) { + return _repository.getContacts(userId: userId); } } diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_provider.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_use_case_provider.dart similarity index 100% rename from modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_provider.dart rename to modules/legacy/modules/functions/lib/src/features/contacts/presentation/providers/get_contacts_use_case_provider.dart diff --git a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart index e51d970d..d2a65176 100644 --- a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart @@ -47,7 +47,7 @@ class FunctionsScreen extends ConsumerWidget { child: Column( children: [ AppSectionButton( - onPressed: (){}, + onPressed: (){navigationContract.pushTo(AppRoutes.remoteConnection);}, icon: SFIcons.connection, text: 'Remote connection' ), diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.dart new file mode 100644 index 00000000..22df5bc6 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.dart @@ -0,0 +1,12 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'picture_entity.freezed.dart'; + +@freezed +abstract class PictureEntity with _$PictureEntity { + const factory PictureEntity({ + required String id, + required String? userId, + required int createdAt, + }) = _PictureEntity; +} diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.freezed.dart new file mode 100644 index 00000000..f08a6dcc --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/entities/picture_entity.freezed.dart @@ -0,0 +1,277 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'picture_entity.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$PictureEntity { + + String get id; String? get userId; int get createdAt; +/// Create a copy of PictureEntity +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$PictureEntityCopyWith get copyWith => _$PictureEntityCopyWithImpl(this as PictureEntity, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PictureEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,userId,createdAt); + +@override +String toString() { + return 'PictureEntity(id: $id, userId: $userId, createdAt: $createdAt)'; +} + + +} + +/// @nodoc +abstract mixin class $PictureEntityCopyWith<$Res> { + factory $PictureEntityCopyWith(PictureEntity value, $Res Function(PictureEntity) _then) = _$PictureEntityCopyWithImpl; +@useResult +$Res call({ + String id, String? userId, int createdAt +}); + + + + +} +/// @nodoc +class _$PictureEntityCopyWithImpl<$Res> + implements $PictureEntityCopyWith<$Res> { + _$PictureEntityCopyWithImpl(this._self, this._then); + + final PictureEntity _self; + final $Res Function(PictureEntity) _then; + +/// Create a copy of PictureEntity +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? userId = freezed,Object? createdAt = null,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable +as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as int, + )); +} + +} + + +/// Adds pattern-matching-related methods to [PictureEntity]. +extension PictureEntityPatterns on PictureEntity { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _PictureEntity value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _PictureEntity() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _PictureEntity value) $default,){ +final _that = this; +switch (_that) { +case _PictureEntity(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _PictureEntity value)? $default,){ +final _that = this; +switch (_that) { +case _PictureEntity() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String? userId, int createdAt)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _PictureEntity() when $default != null: +return $default(_that.id,_that.userId,_that.createdAt);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String id, String? userId, int createdAt) $default,) {final _that = this; +switch (_that) { +case _PictureEntity(): +return $default(_that.id,_that.userId,_that.createdAt);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String? userId, int createdAt)? $default,) {final _that = this; +switch (_that) { +case _PictureEntity() when $default != null: +return $default(_that.id,_that.userId,_that.createdAt);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _PictureEntity implements PictureEntity { + const _PictureEntity({required this.id, required this.userId, required this.createdAt}); + + +@override final String id; +@override final String? userId; +@override final int createdAt; + +/// Create a copy of PictureEntity +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$PictureEntityCopyWith<_PictureEntity> get copyWith => __$PictureEntityCopyWithImpl<_PictureEntity>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _PictureEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)); +} + + +@override +int get hashCode => Object.hash(runtimeType,id,userId,createdAt); + +@override +String toString() { + return 'PictureEntity(id: $id, userId: $userId, createdAt: $createdAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$PictureEntityCopyWith<$Res> implements $PictureEntityCopyWith<$Res> { + factory _$PictureEntityCopyWith(_PictureEntity value, $Res Function(_PictureEntity) _then) = __$PictureEntityCopyWithImpl; +@override @useResult +$Res call({ + String id, String? userId, int createdAt +}); + + + + +} +/// @nodoc +class __$PictureEntityCopyWithImpl<$Res> + implements _$PictureEntityCopyWith<$Res> { + __$PictureEntityCopyWithImpl(this._self, this._then); + + final _PictureEntity _self; + final $Res Function(_PictureEntity) _then; + +/// Create a copy of PictureEntity +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? userId = freezed,Object? createdAt = null,}) { + return _then(_PictureEntity( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable +as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as int, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case.dart new file mode 100644 index 00000000..225c09cf --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case.dart @@ -0,0 +1,5 @@ +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; + +abstract class GetPicturesUseCase { + Future> getPictures({required String userId}); +} diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case_impl.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case_impl.dart new file mode 100644 index 00000000..b38a448a --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/get_pictures_use_case_impl.dart @@ -0,0 +1,14 @@ +import 'package:functions/src/core/domain/repositories/functions_repository.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; +import 'package:functions/src/features/remote_connection/domain/get_pictures_use_case.dart'; + +class GetPicturesUseCaseImpl implements GetPicturesUseCase { + GetPicturesUseCaseImpl(this._repository); + + final FunctionsRepository _repository; + + @override + Future> getPictures({required String userId}) { + return _repository.getPictures(userId: userId); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case.dart new file mode 100644 index 00000000..f994cd62 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case.dart @@ -0,0 +1,5 @@ +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; + +abstract class TakePictureUseCase { + Future takePicture({required String userId}); +} diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case_impl.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case_impl.dart new file mode 100644 index 00000000..3ab8c59c --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/domain/take_picture_use_case_impl.dart @@ -0,0 +1,14 @@ +import 'package:functions/src/core/domain/repositories/functions_repository.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; +import 'package:functions/src/features/remote_connection/domain/take_picture_use_case.dart'; + +class TakePictureUseCaseImpl implements TakePictureUseCase { + TakePictureUseCaseImpl(this._repository); + + final FunctionsRepository _repository; + + @override + Future takePicture({required String userId}) { + return _repository.takePicture(userId: userId); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/get_pictures_use_case_provider.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/get_pictures_use_case_provider.dart new file mode 100644 index 00000000..47bcc413 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/get_pictures_use_case_provider.dart @@ -0,0 +1,9 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/core/providers/functions_repository_provider.dart'; +import 'package:functions/src/features/remote_connection/domain/get_pictures_use_case.dart'; +import 'package:functions/src/features/remote_connection/domain/get_pictures_use_case_impl.dart'; + +final getPicturesUseCaseProvider = Provider.autoDispose((ref) { + final functionsRepository = ref.read(functionsRepositoryProvider); + return GetPicturesUseCaseImpl(functionsRepository); +}); diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/take_picture_use_case_provider.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/take_picture_use_case_provider.dart new file mode 100644 index 00000000..9c46b688 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/providers/take_picture_use_case_provider.dart @@ -0,0 +1,9 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/core/providers/functions_repository_provider.dart'; +import 'package:functions/src/features/remote_connection/domain/take_picture_use_case.dart'; +import 'package:functions/src/features/remote_connection/domain/take_picture_use_case_impl.dart'; + +final takePictureUseCaseProvider = Provider.autoDispose((ref) { + final functionsRepository = ref.read(functionsRepositoryProvider); + return TakePictureUseCaseImpl(functionsRepository); +}); diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart new file mode 100644 index 00000000..9d4fc72f --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart @@ -0,0 +1,76 @@ +// import 'package:account/src/features/linked_devices/presentation/app_users_screen.dart'; +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:functions/src/features/remote_connection/presentation/state/remote_connection_view_model.dart'; +import 'package:navigation/navigation.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:utils/utils.dart'; +import 'package:legacy_shared/legacy_shared.dart'; + +class RemoteCameraScreen extends ConsumerWidget { + final NavigationContract navigationContract; + + const RemoteCameraScreen({super.key, required this.navigationContract}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final theme = ref.watch(themePortProvider); + + final viewModel = ref.read(remoteConnectionViewModelProvider.notifier); + final viewState = ref.watch(remoteConnectionViewModelProvider); + + return PageLayout( + title: context.translate('Remote camera'), + body: Expanded(child: GridView.count( + primary: false, + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 24, vertical: 12), + big: EdgeInsets.symmetric(horizontal: 23, vertical: 11) + ), + crossAxisSpacing: 11, + mainAxisSpacing: 11, + crossAxisCount: 3, + childAspectRatio: 0.8, + children: List.generate(12, (int index)=> + Container( + height: SizeUtils.getByScreen(small: 110, big: 105), + width: SizeUtils.getByScreen(small: 60, big: 58), + color: Colors.grey[200], + child: SvgPicture.asset('assets/images/ui/face.svg'), + ) + ), + )), + footer: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(vertical: 12, horizontal: 26), + big: EdgeInsets.symmetric(vertical: 10, horizontal: 25) + ), + child: PrimaryButton( + onPressed: () { + showDialog(context: context, builder: (context)=>Dialog( + child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 32, vertical: 30), + big: EdgeInsets.symmetric(horizontal: 30, vertical: 28) + ), + width: SizeUtils.getByScreen(small: 360, big: 350), + height: SizeUtils.getByScreen(small: 195, big: 185), + child: Text(context.translate('Loading photo...'), + textAlign: TextAlign.center, + style: TextStyle(fontSize: SizeUtils.getByScreen(small: 19, big: 18)), + ), + ), + )); + viewModel.takePicture(); + Navigator.pop(context); + }, + text: context.translate('Take a picture'), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 36, big: 35), + ), + ) + ); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart new file mode 100644 index 00000000..17e0d416 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart @@ -0,0 +1,104 @@ +// import 'package:account/src/features/linked_devices/presentation/app_users_screen.dart'; +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/remote_connection/presentation/remote_camera_screen.dart'; +import 'package:legacy_shared/legacy_shared.dart'; +import 'package:navigation/navigation.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:utils/utils.dart'; + +class RemoteConnectionScreen extends ConsumerWidget { + final NavigationContract navigationContract; + + const RemoteConnectionScreen({super.key, required this.navigationContract}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + // final theme = ref.watch(themePortProvider); + + return PageLayout( + title: 'Remote Connection', + body: SingleChildScrollView(child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) + ), + child: Column( + children: [ + AppSectionButton( + onPressed: (){Navigator.push(context, MaterialPageRoute( + builder: (_)=>RemoteCameraScreen(navigationContract: navigationContract) + ));}, + icon: Icons.photo_camera_outlined, + text: 'Remote camera' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: SFIcons.listen, + text: 'Remote listening' + ), + ], + ), + )), + ); + } +} + +class AppSectionButton extends ConsumerWidget { + + final GestureTapCallback onPressed; + final IconData icon; + final String text; + + const AppSectionButton({ + required this.onPressed, + required this.icon, + required this.text, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final theme = ref.read(themePortProvider); + + return GestureDetector( + onTap: onPressed, + child: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 22, vertical: 20), + big: EdgeInsets.symmetric(horizontal: 21, vertical: 18) + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(SizeUtils.getByScreen(small: 12, big: 18))), + color: theme.getColorFor(ThemeCode.backgroundSecondary), + ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: theme.getColorFor(ThemeCode.backgroundPrimary), + ), + padding: EdgeInsets.all(SizeUtils.getByScreen(small: 4, big: 12)), + child: Icon(icon, + size: SizeUtils.getByScreen(small: 40, big: 44), + color: Color(0xFF588EA5), + weight: 30, + ), + ), + SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)), + Expanded( + child: Text(context.translate(text), + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 18, big: 19), + fontWeight: FontWeight.w500 + ) + ) + ) + ], + ), + ) + ); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart new file mode 100644 index 00000000..b7b8f03a --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; +import 'package:functions/src/features/remote_connection/domain/get_pictures_use_case.dart'; +import 'package:functions/src/features/remote_connection/domain/take_picture_use_case.dart'; +import 'package:functions/src/features/remote_connection/presentation/providers/get_pictures_use_case_provider.dart'; +import 'package:functions/src/features/remote_connection/presentation/providers/take_picture_use_case_provider.dart'; +import 'package:functions/src/features/remote_connection/presentation/state/remote_connection_view_state.dart'; +// import 'package:legacy_shared/src/providers/logged_user_provider.dart'; +// import 'package:legacy_shared/src/data/models/entities/user_entity.dart'; +// import 'package:sf_localizations/sf_localizations.dart'; + +final remoteConnectionViewModelProvider = +NotifierProvider.autoDispose( + RemoteConnectionViewModel.new, +); + +class RemoteConnectionViewModel extends Notifier { + late final GetPicturesUseCase _getPicturesUseCase; + late final TakePictureUseCase _takePictureUseCase; + + late final TextEditingController nameController; + late final TextEditingController phoneController; + + // late final UserEntity loggedUser; + + @override + RemoteConnectionViewState build() { + _getPicturesUseCase = ref.read(getPicturesUseCaseProvider); + _takePictureUseCase = ref.read(takePictureUseCaseProvider); + + // loggedUser = ref.read(loggedUserProvider); + + phoneController = TextEditingController(); + + phoneController.addListener(_onPhoneChanged); + + // _getPicturesUseCase.getImages(userId: '').then(setImages); + + ref.onDispose(disposeControllers); + + return const RemoteConnectionViewState(); + } + + void setImages(List pictures) { + state = state.copyWith( + pictures: pictures + ); + } + + void _onPhoneChanged() { + final text = phoneController.text; + if (text == state.phone) return; + + state = state.copyWith(phone: text, errorMessage: ''); + } + + void takePicture() { + try { + state = state.copyWith(isTakingPicture: true); + + _takePictureUseCase.takePicture(userId: '') + .then((picture) { + List pictures = state.pictures; + pictures.add(picture); + state = state.copyWith( + isTakingPicture: true, + + ); + }); + } catch (e){ + state = state.copyWith( + isTakingPicture: false, + errorMessage: e.toString(), + ); + } + } + + void disposeControllers() { + phoneController.removeListener(_onPhoneChanged); + + phoneController.dispose(); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.dart new file mode 100644 index 00000000..f0475062 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.dart @@ -0,0 +1,16 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; + +part 'remote_connection_view_state.freezed.dart'; + +@freezed +abstract class RemoteConnectionViewState with _$RemoteConnectionViewState { + const factory RemoteConnectionViewState({ + @Default('') String phone, + @Default([]) List pictures, + @Default(true) bool isLoadingImages, + @Default(false) bool isTakingPicture, + @Default(false) bool isCalling, + @Default('') String errorMessage + }) = _RemoteConnectionViewState; +} diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.freezed.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.freezed.dart new file mode 100644 index 00000000..a7111a7f --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_state.freezed.dart @@ -0,0 +1,292 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'remote_connection_view_state.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$RemoteConnectionViewState { + + String get phone; List get pictures; bool get isLoadingImages; bool get isTakingPicture; bool get isCalling; String get errorMessage; +/// Create a copy of RemoteConnectionViewState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$RemoteConnectionViewStateCopyWith get copyWith => _$RemoteConnectionViewStateCopyWithImpl(this as RemoteConnectionViewState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is RemoteConnectionViewState&&(identical(other.phone, phone) || other.phone == phone)&&const DeepCollectionEquality().equals(other.pictures, pictures)&&(identical(other.isLoadingImages, isLoadingImages) || other.isLoadingImages == isLoadingImages)&&(identical(other.isTakingPicture, isTakingPicture) || other.isTakingPicture == isTakingPicture)&&(identical(other.isCalling, isCalling) || other.isCalling == isCalling)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phone,const DeepCollectionEquality().hash(pictures),isLoadingImages,isTakingPicture,isCalling,errorMessage); + +@override +String toString() { + return 'RemoteConnectionViewState(phone: $phone, pictures: $pictures, isLoadingImages: $isLoadingImages, isTakingPicture: $isTakingPicture, isCalling: $isCalling, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class $RemoteConnectionViewStateCopyWith<$Res> { + factory $RemoteConnectionViewStateCopyWith(RemoteConnectionViewState value, $Res Function(RemoteConnectionViewState) _then) = _$RemoteConnectionViewStateCopyWithImpl; +@useResult +$Res call({ + String phone, List pictures, bool isLoadingImages, bool isTakingPicture, bool isCalling, String errorMessage +}); + + + + +} +/// @nodoc +class _$RemoteConnectionViewStateCopyWithImpl<$Res> + implements $RemoteConnectionViewStateCopyWith<$Res> { + _$RemoteConnectionViewStateCopyWithImpl(this._self, this._then); + + final RemoteConnectionViewState _self; + final $Res Function(RemoteConnectionViewState) _then; + +/// Create a copy of RemoteConnectionViewState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? phone = null,Object? pictures = null,Object? isLoadingImages = null,Object? isTakingPicture = null,Object? isCalling = null,Object? errorMessage = null,}) { + return _then(_self.copyWith( +phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,pictures: null == pictures ? _self.pictures : pictures // ignore: cast_nullable_to_non_nullable +as List,isLoadingImages: null == isLoadingImages ? _self.isLoadingImages : isLoadingImages // ignore: cast_nullable_to_non_nullable +as bool,isTakingPicture: null == isTakingPicture ? _self.isTakingPicture : isTakingPicture // ignore: cast_nullable_to_non_nullable +as bool,isCalling: null == isCalling ? _self.isCalling : isCalling // ignore: cast_nullable_to_non_nullable +as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [RemoteConnectionViewState]. +extension RemoteConnectionViewStatePatterns on RemoteConnectionViewState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _RemoteConnectionViewState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _RemoteConnectionViewState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _RemoteConnectionViewState value) $default,){ +final _that = this; +switch (_that) { +case _RemoteConnectionViewState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _RemoteConnectionViewState value)? $default,){ +final _that = this; +switch (_that) { +case _RemoteConnectionViewState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String phone, List pictures, bool isLoadingImages, bool isTakingPicture, bool isCalling, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _RemoteConnectionViewState() when $default != null: +return $default(_that.phone,_that.pictures,_that.isLoadingImages,_that.isTakingPicture,_that.isCalling,_that.errorMessage);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String phone, List pictures, bool isLoadingImages, bool isTakingPicture, bool isCalling, String errorMessage) $default,) {final _that = this; +switch (_that) { +case _RemoteConnectionViewState(): +return $default(_that.phone,_that.pictures,_that.isLoadingImages,_that.isTakingPicture,_that.isCalling,_that.errorMessage);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String phone, List pictures, bool isLoadingImages, bool isTakingPicture, bool isCalling, String errorMessage)? $default,) {final _that = this; +switch (_that) { +case _RemoteConnectionViewState() when $default != null: +return $default(_that.phone,_that.pictures,_that.isLoadingImages,_that.isTakingPicture,_that.isCalling,_that.errorMessage);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _RemoteConnectionViewState implements RemoteConnectionViewState { + const _RemoteConnectionViewState({this.phone = '', final List pictures = const [], this.isLoadingImages = true, this.isTakingPicture = false, this.isCalling = false, this.errorMessage = ''}): _pictures = pictures; + + +@override@JsonKey() final String phone; + final List _pictures; +@override@JsonKey() List get pictures { + if (_pictures is EqualUnmodifiableListView) return _pictures; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_pictures); +} + +@override@JsonKey() final bool isLoadingImages; +@override@JsonKey() final bool isTakingPicture; +@override@JsonKey() final bool isCalling; +@override@JsonKey() final String errorMessage; + +/// Create a copy of RemoteConnectionViewState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$RemoteConnectionViewStateCopyWith<_RemoteConnectionViewState> get copyWith => __$RemoteConnectionViewStateCopyWithImpl<_RemoteConnectionViewState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _RemoteConnectionViewState&&(identical(other.phone, phone) || other.phone == phone)&&const DeepCollectionEquality().equals(other._pictures, _pictures)&&(identical(other.isLoadingImages, isLoadingImages) || other.isLoadingImages == isLoadingImages)&&(identical(other.isTakingPicture, isTakingPicture) || other.isTakingPicture == isTakingPicture)&&(identical(other.isCalling, isCalling) || other.isCalling == isCalling)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phone,const DeepCollectionEquality().hash(_pictures),isLoadingImages,isTakingPicture,isCalling,errorMessage); + +@override +String toString() { + return 'RemoteConnectionViewState(phone: $phone, pictures: $pictures, isLoadingImages: $isLoadingImages, isTakingPicture: $isTakingPicture, isCalling: $isCalling, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class _$RemoteConnectionViewStateCopyWith<$Res> implements $RemoteConnectionViewStateCopyWith<$Res> { + factory _$RemoteConnectionViewStateCopyWith(_RemoteConnectionViewState value, $Res Function(_RemoteConnectionViewState) _then) = __$RemoteConnectionViewStateCopyWithImpl; +@override @useResult +$Res call({ + String phone, List pictures, bool isLoadingImages, bool isTakingPicture, bool isCalling, String errorMessage +}); + + + + +} +/// @nodoc +class __$RemoteConnectionViewStateCopyWithImpl<$Res> + implements _$RemoteConnectionViewStateCopyWith<$Res> { + __$RemoteConnectionViewStateCopyWithImpl(this._self, this._then); + + final _RemoteConnectionViewState _self; + final $Res Function(_RemoteConnectionViewState) _then; + +/// Create a copy of RemoteConnectionViewState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? phone = null,Object? pictures = null,Object? isLoadingImages = null,Object? isTakingPicture = null,Object? isCalling = null,Object? errorMessage = null,}) { + return _then(_RemoteConnectionViewState( +phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,pictures: null == pictures ? _self._pictures : pictures // ignore: cast_nullable_to_non_nullable +as List,isLoadingImages: null == isLoadingImages ? _self.isLoadingImages : isLoadingImages // ignore: cast_nullable_to_non_nullable +as bool,isTakingPicture: null == isTakingPicture ? _self.isTakingPicture : isTakingPicture // ignore: cast_nullable_to_non_nullable +as bool,isCalling: null == isCalling ? _self.isCalling : isCalling // ignore: cast_nullable_to_non_nullable +as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/remote_connection_builder.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/remote_connection_builder.dart new file mode 100644 index 00000000..db019964 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/remote_connection_builder.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:functions/src/features/remote_connection/presentation/remote_connection_screen.dart'; +import 'package:go_router/go_router.dart'; +import 'package:get_it/get_it.dart'; +import 'package:navigation/navigation.dart'; + +class RemoteConnectionBuilder { + const RemoteConnectionBuilder(); + + Page buildPage(BuildContext context, GoRouterState state) { + final NavigationContract navigationContract = GetIt.I(); + + return MaterialPage( + key: state.pageKey, + child: RemoteConnectionScreen(navigationContract: navigationContract), + ); + } +} diff --git a/packages/design_system/fonts/SFIcons.ttf b/packages/design_system/fonts/SFIcons.ttf index 2703601ac085604f116cec273f8ebc018c313ebd..caf8ca272821a0f1e693e7068a3de0d958822c3e 100644 GIT binary patch delta 1072 zcmXw$O>7fK6oB8`-K^KKWgBpu=FbM(ySDRVu(Rv9qKRV%n-EN5aOyUqDs@AMQzgV! zl9r-K4lON^=8(!9dg`GCloLW&;s6{FAcVNU4JjNz2&7fHAT>yBRVjVW&>esK&Aj(! zJUjF7DLz@pRZqDC09ODYH$Iau-hK4$4gkLgK#WXIe|zHoxPJhk-UjfQRG7#g-@S0A zooZhYkpcyzA>kSIZxi0a%>1d;t<8UEy;nqfdUia&uK)QEz*wOC+D!gb5g&60Dfa=5 zcb?48Oq32af8qc*K>==~I6F80)4??=o-zXn@t<#dVp%|{C0=g4xpB<;(K|5lIz{01 zwO{Z3@6CTVr-Z-x9E~O5YEgP>^Rg8umhf$L71PLZ7c1-BMECGk25=DgtzIX&p8kFq z1Z<@_&0woV^e#QDYkFMYr)Mffz6CRtWnONnt=kOqaGKhASf;kJ)mGt3?4;LkR+EGkRmTJU_bc`qYQ)8`Hlex$lo(yhRT3`moIWWXWvIR*@q&of|z ze1QSA4_s!zVe%RS=xFGvj2IUKf3&G>zc}sAtFBhpot^96Mfr1O(bw-!`Tq(mwRg7v z){*HP?z$EfsvE|IXqf}pJk6cu6SNoFEruH%jgAJpK{SX~q?bW#uv^d_#9mZ;LXofw z9c^fLVz>`AwI|XOi6Ol-HHdBt(!7x9_JtIdY79HyhbX`b47G>_JyHA+-AXT()yQ6~ zEfqvh$gRXs>*Fx}@!_olFeLn5|r&yu{&XHCH&!8N}(S Qx%r8c)tg^gkf(e54|bUEX#fBK delta 726 zcmXw$T}YEr7{~wTeYde0~S!OnB zEMAB%DhezXQ8(|c7hXk#ghUWXA6_J!>#&O=T>tIRIsEvY^E~G{=fJbFD&Bn-MR%?X z5O)CtBdKu4wpN=1bT43YjVGtiKfdzt8{pUg&X(e_aJ1_}#}A%eBm3eE*as}DTrZNQ zcxrOW*INF=`*=q9lj%tK>(bk!tRG_jMJha%5g)Wc=IXh3O@vdi?C_2=+kxmKK-MKL6dH7yeIRl^WH(5oviUBkD1u!wCesE3mgyX=&EC%VKs7A zo8wF6j~pXr!TMdxjq+-O9y+8zFFmHfAv&%=ADvd`pA0pAu2c>`iVJ{{VX$&JzFt diff --git a/packages/design_system/lib/fonts/config.json b/packages/design_system/lib/fonts/config.json index c6ebc923..8e472872 100755 --- a/packages/design_system/lib/fonts/config.json +++ b/packages/design_system/lib/fonts/config.json @@ -1131,6 +1131,20 @@ "search": [ "icon" ] + }, + { + "uid": "c2dafca4f49d11a68d647573fb4b3c0c", + "css": "listen", + "code": 59472, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M332.2 16C503.5 15.9 643.6 151.4 643.6 319.4 643.6 454.3 578.7 524 520.1 583.3 461.9 642.2 412.3 689.1 412.3 790.5 412.3 897.9 323 984 214 984 104.9 984 16 897.8 16 790.5V703.7C15.9 696.6 18.8 689.7 23.8 684.7L23.8 684.6C28.9 679.6 35.8 676.7 42.9 676.7 49.2 676.7 55.3 678.9 60.1 682.9L62.1 684.7 63.9 686.7C67.8 691.5 70 697.5 69.9 703.7V790.5C69.9 867.6 133.4 930.3 214 930.3 294.5 930.3 358.3 867.6 358.3 790.5 358.3 667.3 424.3 603.8 481.9 545.6L503.1 523.8C523.7 502.1 542.4 480 557.2 454 576.6 419.6 589.6 377.6 589.6 319.4 589.6 181.8 475 69.7 332.2 69.6 189.4 69.6 74.8 181.8 74.8 319.4 74.8 326.6 72 333.4 66.9 338.4L66.9 338.5C61.8 343.5 54.9 346.4 47.8 346.4 40.6 346.4 33.7 343.5 28.6 338.4L28.6 338.4C23.5 333.3 20.7 326.3 20.8 319.1 20.9 151.2 160.9 16 332.2 16ZM331.5 133C437.6 133 524.6 217.1 524.7 321.5 524.8 328.8 521.9 335.7 516.9 340.8L516.8 340.8C511.7 345.9 504.9 348.7 497.7 348.7 490.6 348.7 483.6 345.9 478.5 340.8 473.5 335.7 470.6 328.8 470.7 321.5 470.6 247.4 409 186.7 331.5 186.7 253.9 186.7 192 247.6 192 321.7V322.5L192 322.9 186.1 435.1C247.9 450.3 290.9 512.6 290.9 583 290.9 663.4 234.7 735.2 158 735.4 157.9 735.4 157.9 735.4 157.9 735.4 157.8 735.4 157.8 735.4 157.8 735.4V735.4C150.7 735.4 143.9 732.7 138.8 727.7 134.2 723.3 131.4 717.5 130.8 711.2L130.6 708.5 130.8 705.8C131.4 699.6 134.2 693.7 138.8 689.3 143.9 684.3 150.7 681.6 157.8 681.7L161.5 681.6C200.3 679.1 237 639.4 237 583 236.9 524.8 198 484.6 157.8 484.6V484.6C150.3 484.6 143.2 481.6 138.1 476.3 133 470.9 130.3 463.6 130.8 456.1L138 321 138.3 311.3C143.9 211.7 229 133 331.5 133Z", + "width": 660 + }, + "search": [ + "icon" + ] } ] } \ No newline at end of file diff --git a/packages/design_system/lib/src/icons/sf_icons.dart b/packages/design_system/lib/src/icons/sf_icons.dart index 3298d941..7447078f 100644 --- a/packages/design_system/lib/src/icons/sf_icons.dart +++ b/packages/design_system/lib/src/icons/sf_icons.dart @@ -86,6 +86,7 @@ class SFIcons { static const IconData privacy = IconData(0xe841, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData watch = IconData(0xe843, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData handshake = IconData(0xe844, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData listen = IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData share = IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData favoriteOutlined = IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData renovationSelected = IconData(0xe862, fontFamily: _kFontFam, fontPackage: _kFontPkg); diff --git a/packages/navigation/lib/app_routes.dart b/packages/navigation/lib/app_routes.dart index 63dd0af8..c5f5de4d 100644 --- a/packages/navigation/lib/app_routes.dart +++ b/packages/navigation/lib/app_routes.dart @@ -23,4 +23,5 @@ class AppRoutes { static const dashboardFunctions = '$legacyDashboard/functions'; static const contacts = '$dashboardFunctions/contacts'; + static const remoteConnection = '$dashboardFunctions/remote_connection'; } From f8ff70c35d87780b3f4818ada5509da2cf702eac Mon Sep 17 00:00:00 2001 From: aitorarana Date: Wed, 11 Feb 2026 11:57:45 +0100 Subject: [PATCH 6/8] fixed remote connection dialogs and edit contact screen --- .../functions_repository_impl.dart | 6 +- .../presentation/edit_contact_screen.dart | 32 ++++---- .../presentation/remote_camera_screen.dart | 14 ++-- .../remote_connection_screen.dart | 78 ++++++++++++++++++- .../state/remote_connection_view_model.dart | 27 +++++-- 5 files changed, 126 insertions(+), 31 deletions(-) diff --git a/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart index 05b906cb..bd6969d5 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart @@ -14,12 +14,14 @@ class FunctionsRepositoryImpl implements FunctionsRepository { } @override - Future> getPictures({required String userId}) { + Future> getPictures({required String userId}) async { + await Future.delayed(const Duration(milliseconds: 2000)); return _remote.getPictures(userId: userId); } @override - Future takePicture({required String userId}) { + Future takePicture({required String userId}) async { + await Future.delayed(const Duration(milliseconds: 2000)); return _remote.takePicture(userId: userId); } } diff --git a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart index 519fdf98..eba3b459 100644 --- a/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/contacts/presentation/edit_contact_screen.dart @@ -100,22 +100,26 @@ class EditContactScreen extends ConsumerWidget { hint: contact.phone, label: context.translate('Phone number'), ), - Align( - alignment: Alignment.centerRight, - child: IconButton( - onPressed: (){}, - icon: DecoratedBox( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Color(0xFF588EA5) - ), - child: Icon( - SFIcons.contactsCircle, - color: Colors.white, + SizedBox( + height: SizeUtils.getByScreen(small: 90, big: 85), + child: Align( + alignment: Alignment.bottomRight, + child: IconButton( + onPressed: (){}, + icon: DecoratedBox( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF588EA5) + ), + child: Icon( + SFIcons.contactsCircle, + color: Colors.white, + size: SizeUtils.getByScreen(small: 40, big: 38), + ) ) - ) + ), ), - ) + ), ], ) ], diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart index 9d4fc72f..12afa923 100644 --- a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_camera_screen.dart @@ -48,22 +48,22 @@ class RemoteCameraScreen extends ConsumerWidget { big: EdgeInsets.symmetric(vertical: 10, horizontal: 25) ), child: PrimaryButton( - onPressed: () { + onPressed: () async { showDialog(context: context, builder: (context)=>Dialog( child: Container( padding: SizeUtils.getByScreen( - small: EdgeInsets.symmetric(horizontal: 32, vertical: 30), - big: EdgeInsets.symmetric(horizontal: 30, vertical: 28) + small: EdgeInsets.symmetric(horizontal: 32, vertical: 30), + big: EdgeInsets.symmetric(horizontal: 30, vertical: 28) ), width: SizeUtils.getByScreen(small: 360, big: 350), height: SizeUtils.getByScreen(small: 195, big: 185), - child: Text(context.translate('Loading photo...'), + child: Center(child: Text(context.translate('Loading photo...'), textAlign: TextAlign.center, - style: TextStyle(fontSize: SizeUtils.getByScreen(small: 19, big: 18)), - ), + style: TextStyle(fontSize: SizeUtils.getByScreen(small: 26, big: 25)), + )), ), )); - viewModel.takePicture(); + await viewModel.takePicture(); Navigator.pop(context); }, text: context.translate('Take a picture'), diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart index 17e0d416..06c92051 100644 --- a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/remote_connection_screen.dart @@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:functions/src/features/remote_connection/presentation/remote_camera_screen.dart'; +import 'package:functions/src/features/remote_connection/presentation/state/remote_connection_view_model.dart'; import 'package:legacy_shared/legacy_shared.dart'; import 'package:navigation/navigation.dart'; import 'package:sf_localizations/sf_localizations.dart'; @@ -17,6 +18,9 @@ class RemoteConnectionScreen extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { // final theme = ref.watch(themePortProvider); + final viewModel = ref.read(remoteConnectionViewModelProvider.notifier); + final viewState = ref.watch(remoteConnectionViewModelProvider); + return PageLayout( title: 'Remote Connection', body: SingleChildScrollView(child: Container( @@ -35,7 +39,10 @@ class RemoteConnectionScreen extends ConsumerWidget { ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( - onPressed: (){}, + onPressed: (){showDialog(context: context, builder: (context)=>Dialog( + child: CallDialog( + ) + ));}, icon: SFIcons.listen, text: 'Remote listening' ), @@ -46,6 +53,75 @@ class RemoteConnectionScreen extends ConsumerWidget { } } +class CallDialog extends ConsumerWidget { + + @override + Widget build(BuildContext context, WidgetRef ref) { + + final viewModel = ref.read(remoteConnectionViewModelProvider.notifier); + final viewState = ref.watch(remoteConnectionViewModelProvider); + + return Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 26, vertical: 20), + big: EdgeInsets.symmetric(horizontal: 24, vertical: 18) + ), + width: SizeUtils.getByScreen(small: 390, big: 380), + height: SizeUtils.getByScreen(small: 250, big: 243), + child: Column( + children: [ + Stack( + children: [ + Center(child: Text(context.translate('Remote listening'), + textAlign: TextAlign.center, + style: TextStyle(fontSize: SizeUtils.getByScreen(small: 19, big: 18)), + )), + Align( + alignment: Alignment.centerRight, + child: IconButton( + onPressed: (){Navigator.pop(context);}, + icon: Icon(Icons.close, color: Color(0xFF588EA5)), + ) + ) + ], + ), + SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)), + CustomTextField( + controller: viewModel.phoneController, + hint: context.translate('Insert your phone number'), + keyboardType: TextInputType.number, + ), + if (viewState.errorMessage.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + viewState.errorMessage, + textAlign: TextAlign.center, + style: const TextStyle( + color: Color.fromRGBO(239, 17, 17, 1), + fontSize: 12, + ), + ), + ], + SizedBox(height: SizeUtils.getByScreen(small: 28, big: 27)), + PrimaryButton( + onPressed: () async { + await viewModel.call(); + if (viewState.errorMessage.isEmpty){ + Navigator.pop(context); + } + }, + text: context.translate('Call me'), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 38, big: 36), + radius: SizeUtils.getByScreen(small: 32, big: 34), + ), + ], + ), + ); + } + +} + class AppSectionButton extends ConsumerWidget { final GestureTapCallback onPressed; diff --git a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart index b7b8f03a..5f56e935 100644 --- a/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart +++ b/modules/legacy/modules/functions/lib/src/features/remote_connection/presentation/state/remote_connection_view_model.dart @@ -19,11 +19,12 @@ class RemoteConnectionViewModel extends Notifier { late final GetPicturesUseCase _getPicturesUseCase; late final TakePictureUseCase _takePictureUseCase; - late final TextEditingController nameController; late final TextEditingController phoneController; // late final UserEntity loggedUser; + static final RegExp _phoneRegex = RegExp(r'^\+?\d{6,15}$'); + @override RemoteConnectionViewState build() { _getPicturesUseCase = ref.read(getPicturesUseCaseProvider); @@ -35,7 +36,7 @@ class RemoteConnectionViewModel extends Notifier { phoneController.addListener(_onPhoneChanged); - // _getPicturesUseCase.getImages(userId: '').then(setImages); + _getPicturesUseCase.getPictures(userId: '').then(setImages); ref.onDispose(disposeControllers); @@ -44,7 +45,7 @@ class RemoteConnectionViewModel extends Notifier { void setImages(List pictures) { state = state.copyWith( - pictures: pictures + pictures: pictures ); } @@ -55,17 +56,16 @@ class RemoteConnectionViewModel extends Notifier { state = state.copyWith(phone: text, errorMessage: ''); } - void takePicture() { + Future takePicture() async { try { state = state.copyWith(isTakingPicture: true); - _takePictureUseCase.takePicture(userId: '') + await _takePictureUseCase.takePicture(userId: '') .then((picture) { List pictures = state.pictures; - pictures.add(picture); + //pictures.add(picture); state = state.copyWith( isTakingPicture: true, - ); }); } catch (e){ @@ -76,6 +76,19 @@ class RemoteConnectionViewModel extends Notifier { } } + Future call() async { + final phone = phoneController.text; + if (phone.isEmpty){ + state = state.copyWith(errorMessage: 'errorMessagePhoneIsEmpty'); + return; + } + if (!_phoneRegex.hasMatch(phone)) { + state = state.copyWith(errorMessage: 'errorMessagePhoneIsInvalid'); + return; + } + + } + void disposeControllers() { phoneController.removeListener(_onPhoneChanged); From a53cfb24eaf7c570fa1a57ef47a3bdd748e5b346 Mon Sep 17 00:00:00 2001 From: aitorarana Date: Thu, 12 Feb 2026 15:48:11 +0100 Subject: [PATCH 7/8] Added locate device screen, state and endpoints --- .../mobile_app/lib/navigation/app_router.dart | 5 + .../functions_remote_datasource.dart | 3 + .../functions_remote_datasource_impl.dart | 18 ++ .../locate_device_request_entity.dart | 11 + .../locate_device_request_entity.freezed.dart | 274 +++++++++++++++++ .../models/send_command_request_model.dart | 24 ++ .../send_command_request_model.freezed.dart | 280 ++++++++++++++++++ .../models/send_command_request_model.g.dart | 21 ++ .../functions_repository_impl.dart | 7 + .../repositories/functions_repository.dart | 3 + .../features/functions/functions_screen.dart | 42 ++- .../domain/locate_device_use_case.dart | 5 + .../domain/locate_device_use_case_impl.dart | 14 + .../locate_device/locate_device_builder.dart | 18 ++ .../presentation/locate_device_screen.dart | 148 +++++++++ .../locate_device_use_case_provider.dart | 9 + .../state/locate_device_view_model.dart | 62 ++++ .../state/locate_device_view_state.dart | 11 + .../locate_device_view_state.freezed.dart | 277 +++++++++++++++++ .../legacy_main_shell_screen.dart | 2 +- .../lib/src/widgets/layouts/page_layout.dart | 2 +- packages/design_system/fonts/SFIcons.ttf | Bin 27984 -> 29300 bytes packages/design_system/lib/fonts/config.json | 84 +++++- .../design_system/lib/src/icons/sf_icons.dart | 6 +- packages/navigation/lib/app_routes.dart | 1 + 25 files changed, 1295 insertions(+), 32 deletions(-) create mode 100644 modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.g.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case_impl.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/locate_device_builder.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/presentation/locate_device_screen.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/presentation/providers/locate_device_use_case_provider.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_model.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.freezed.dart diff --git a/apps/mobile_app/lib/navigation/app_router.dart b/apps/mobile_app/lib/navigation/app_router.dart index 36c3baee..fea0972e 100644 --- a/apps/mobile_app/lib/navigation/app_router.dart +++ b/apps/mobile_app/lib/navigation/app_router.dart @@ -62,6 +62,11 @@ void configureAppRouter() { name: 'remote_connection', pageBuilder: RemoteConnectionBuilder().buildPage, ), + GoRoute( + path: AppRoutes.locateDevice, + name: 'locate_device', + pageBuilder: LocateDeviceBuilder().buildPage, + ), GoRoute( path: AppRoutes.login, diff --git a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart index dffa0475..4db51388 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource.dart @@ -1,3 +1,4 @@ +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; @@ -7,4 +8,6 @@ abstract class FunctionsRemoteDatasource { Future> getPictures({required String userId}); Future takePicture({required String userId}); + + Future locateDevice({required LocateDeviceRequestEntity request}); } diff --git a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart index 37a434ca..ee555d94 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/datasources/functions_remote_datasource_impl.dart @@ -3,6 +3,8 @@ import 'dart:convert'; import 'package:dio/dio.dart'; // import 'package:flutter/material.dart'; import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart'; +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; +import 'package:functions/src/core/data/models/send_command_request_model.dart'; import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; import 'package:sf_infrastructure/sf_infrastructure.dart'; @@ -92,6 +94,22 @@ class FunctionsRemoteDatasourceImpl implements FunctionsRemoteDatasource { }*/ return PictureEntity(id: '1', userId: '1111', createdAt: 1111); } + + @override + Future locateDevice({required LocateDeviceRequestEntity request}) async { + try { + final body = request.toModel().toJson(); + await _repository.post( + '/commands', + body: body, + ); + } on DioException catch (error) { + throw _mapDioError( + error, + defaultMessage: error.response?.data ?? 'Error to locate device', + ); + } + } } Exception _mapDioError(DioException error, {required String defaultMessage}) { diff --git a/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.dart b/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.dart new file mode 100644 index 00000000..8646a2bd --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.dart @@ -0,0 +1,11 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'locate_device_request_entity.freezed.dart'; + +@freezed +abstract class LocateDeviceRequestEntity with _$LocateDeviceRequestEntity { + + const factory LocateDeviceRequestEntity({ + required String deviceName, + }) = _LocateDeviceRequestEntity; +} diff --git a/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart new file mode 100644 index 00000000..9f79acf1 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart @@ -0,0 +1,274 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'locate_device_request_entity.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$LocateDeviceRequestEntity { + + String get deviceName; dynamic get command; +/// Create a copy of LocateDeviceRequestEntity +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LocateDeviceRequestEntityCopyWith get copyWith => _$LocateDeviceRequestEntityCopyWithImpl(this as LocateDeviceRequestEntity, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LocateDeviceRequestEntity&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)&&const DeepCollectionEquality().equals(other.command, command)); +} + + +@override +int get hashCode => Object.hash(runtimeType,deviceName,const DeepCollectionEquality().hash(command)); + +@override +String toString() { + return 'LocateDeviceRequestEntity(deviceName: $deviceName, command: $command)'; +} + + +} + +/// @nodoc +abstract mixin class $LocateDeviceRequestEntityCopyWith<$Res> { + factory $LocateDeviceRequestEntityCopyWith(LocateDeviceRequestEntity value, $Res Function(LocateDeviceRequestEntity) _then) = _$LocateDeviceRequestEntityCopyWithImpl; +@useResult +$Res call({ + String deviceName, dynamic command +}); + + + + +} +/// @nodoc +class _$LocateDeviceRequestEntityCopyWithImpl<$Res> + implements $LocateDeviceRequestEntityCopyWith<$Res> { + _$LocateDeviceRequestEntityCopyWithImpl(this._self, this._then); + + final LocateDeviceRequestEntity _self; + final $Res Function(LocateDeviceRequestEntity) _then; + +/// Create a copy of LocateDeviceRequestEntity +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? deviceName = null,Object? command = freezed,}) { + return _then(_self.copyWith( +deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable +as String,command: freezed == command ? _self.command : command // ignore: cast_nullable_to_non_nullable +as dynamic, + )); +} + +} + + +/// Adds pattern-matching-related methods to [LocateDeviceRequestEntity]. +extension LocateDeviceRequestEntityPatterns on LocateDeviceRequestEntity { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _LocateDeviceRequestEntity value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _LocateDeviceRequestEntity() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _LocateDeviceRequestEntity value) $default,){ +final _that = this; +switch (_that) { +case _LocateDeviceRequestEntity(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _LocateDeviceRequestEntity value)? $default,){ +final _that = this; +switch (_that) { +case _LocateDeviceRequestEntity() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String deviceName, dynamic command)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LocateDeviceRequestEntity() when $default != null: +return $default(_that.deviceName,_that.command);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String deviceName, dynamic command) $default,) {final _that = this; +switch (_that) { +case _LocateDeviceRequestEntity(): +return $default(_that.deviceName,_that.command);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String deviceName, dynamic command)? $default,) {final _that = this; +switch (_that) { +case _LocateDeviceRequestEntity() when $default != null: +return $default(_that.deviceName,_that.command);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _LocateDeviceRequestEntity implements LocateDeviceRequestEntity { + const _LocateDeviceRequestEntity({required this.deviceName, this.command}); + + +@override final String deviceName; +@override final dynamic command; + +/// Create a copy of LocateDeviceRequestEntity +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LocateDeviceRequestEntityCopyWith<_LocateDeviceRequestEntity> get copyWith => __$LocateDeviceRequestEntityCopyWithImpl<_LocateDeviceRequestEntity>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocateDeviceRequestEntity&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)&&const DeepCollectionEquality().equals(other.command, command)); +} + + +@override +int get hashCode => Object.hash(runtimeType,deviceName,const DeepCollectionEquality().hash(command)); + +@override +String toString() { + return 'LocateDeviceRequestEntity(deviceName: $deviceName, command: $command)'; +} + + +} + +/// @nodoc +abstract mixin class _$LocateDeviceRequestEntityCopyWith<$Res> implements $LocateDeviceRequestEntityCopyWith<$Res> { + factory _$LocateDeviceRequestEntityCopyWith(_LocateDeviceRequestEntity value, $Res Function(_LocateDeviceRequestEntity) _then) = __$LocateDeviceRequestEntityCopyWithImpl; +@override @useResult +$Res call({ + String deviceName, dynamic command +}); + + + + +} +/// @nodoc +class __$LocateDeviceRequestEntityCopyWithImpl<$Res> + implements _$LocateDeviceRequestEntityCopyWith<$Res> { + __$LocateDeviceRequestEntityCopyWithImpl(this._self, this._then); + + final _LocateDeviceRequestEntity _self; + final $Res Function(_LocateDeviceRequestEntity) _then; + +/// Create a copy of LocateDeviceRequestEntity +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? deviceName = null,Object? command = freezed,}) { + return _then(_LocateDeviceRequestEntity( +deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable +as String,command: freezed == command ? _self.command : command // ignore: cast_nullable_to_non_nullable +as dynamic, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.dart b/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.dart new file mode 100644 index 00000000..296155ec --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.dart @@ -0,0 +1,24 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; + +part 'send_command_request_model.freezed.dart'; +part 'send_command_request_model.g.dart'; + +@freezed +abstract class SendCommandRequestModel with _$SendCommandRequestModel { + const factory SendCommandRequestModel({ + required String deviceName, + required String command, + }) = _SendCommandRequestModel; + + factory SendCommandRequestModel.fromJson(Map json) => + _$SendCommandRequestModelFromJson(json); + +} + +extension SendCommandRequestModelMapper on LocateDeviceRequestEntity { + SendCommandRequestModel toModel() => SendCommandRequestModel( + deviceName: deviceName, + command: 'FIND_DEVICE', + ); +} diff --git a/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.freezed.dart b/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.freezed.dart new file mode 100644 index 00000000..229b6834 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.freezed.dart @@ -0,0 +1,280 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'send_command_request_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$SendCommandRequestModel { + + String get deviceName; String get command; +/// Create a copy of SendCommandRequestModel +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$SendCommandRequestModelCopyWith get copyWith => _$SendCommandRequestModelCopyWithImpl(this as SendCommandRequestModel, _$identity); + + /// Serializes this SendCommandRequestModel to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SendCommandRequestModel&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)&&(identical(other.command, command) || other.command == command)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,deviceName,command); + +@override +String toString() { + return 'SendCommandRequestModel(deviceName: $deviceName, command: $command)'; +} + + +} + +/// @nodoc +abstract mixin class $SendCommandRequestModelCopyWith<$Res> { + factory $SendCommandRequestModelCopyWith(SendCommandRequestModel value, $Res Function(SendCommandRequestModel) _then) = _$SendCommandRequestModelCopyWithImpl; +@useResult +$Res call({ + String deviceName, String command +}); + + + + +} +/// @nodoc +class _$SendCommandRequestModelCopyWithImpl<$Res> + implements $SendCommandRequestModelCopyWith<$Res> { + _$SendCommandRequestModelCopyWithImpl(this._self, this._then); + + final SendCommandRequestModel _self; + final $Res Function(SendCommandRequestModel) _then; + +/// Create a copy of SendCommandRequestModel +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? deviceName = null,Object? command = null,}) { + return _then(_self.copyWith( +deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable +as String,command: null == command ? _self.command : command // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [SendCommandRequestModel]. +extension SendCommandRequestModelPatterns on SendCommandRequestModel { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _SendCommandRequestModel value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _SendCommandRequestModel() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _SendCommandRequestModel value) $default,){ +final _that = this; +switch (_that) { +case _SendCommandRequestModel(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _SendCommandRequestModel value)? $default,){ +final _that = this; +switch (_that) { +case _SendCommandRequestModel() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String deviceName, String command)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _SendCommandRequestModel() when $default != null: +return $default(_that.deviceName,_that.command);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String deviceName, String command) $default,) {final _that = this; +switch (_that) { +case _SendCommandRequestModel(): +return $default(_that.deviceName,_that.command);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String deviceName, String command)? $default,) {final _that = this; +switch (_that) { +case _SendCommandRequestModel() when $default != null: +return $default(_that.deviceName,_that.command);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _SendCommandRequestModel implements SendCommandRequestModel { + const _SendCommandRequestModel({required this.deviceName, required this.command}); + factory _SendCommandRequestModel.fromJson(Map json) => _$SendCommandRequestModelFromJson(json); + +@override final String deviceName; +@override final String command; + +/// Create a copy of SendCommandRequestModel +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SendCommandRequestModelCopyWith<_SendCommandRequestModel> get copyWith => __$SendCommandRequestModelCopyWithImpl<_SendCommandRequestModel>(this, _$identity); + +@override +Map toJson() { + return _$SendCommandRequestModelToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SendCommandRequestModel&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)&&(identical(other.command, command) || other.command == command)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,deviceName,command); + +@override +String toString() { + return 'SendCommandRequestModel(deviceName: $deviceName, command: $command)'; +} + + +} + +/// @nodoc +abstract mixin class _$SendCommandRequestModelCopyWith<$Res> implements $SendCommandRequestModelCopyWith<$Res> { + factory _$SendCommandRequestModelCopyWith(_SendCommandRequestModel value, $Res Function(_SendCommandRequestModel) _then) = __$SendCommandRequestModelCopyWithImpl; +@override @useResult +$Res call({ + String deviceName, String command +}); + + + + +} +/// @nodoc +class __$SendCommandRequestModelCopyWithImpl<$Res> + implements _$SendCommandRequestModelCopyWith<$Res> { + __$SendCommandRequestModelCopyWithImpl(this._self, this._then); + + final _SendCommandRequestModel _self; + final $Res Function(_SendCommandRequestModel) _then; + +/// Create a copy of SendCommandRequestModel +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? deviceName = null,Object? command = null,}) { + return _then(_SendCommandRequestModel( +deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable +as String,command: null == command ? _self.command : command // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.g.dart b/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.g.dart new file mode 100644 index 00000000..eae14744 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/core/data/models/send_command_request_model.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'send_command_request_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_SendCommandRequestModel _$SendCommandRequestModelFromJson( + Map json, +) => _SendCommandRequestModel( + deviceName: json['deviceName'] as String, + command: json['command'] as String, +); + +Map _$SendCommandRequestModelToJson( + _SendCommandRequestModel instance, +) => { + 'deviceName': instance.deviceName, + 'command': instance.command, +}; diff --git a/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart index bd6969d5..59cf7ac5 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/repositories/functions_repository_impl.dart @@ -1,4 +1,5 @@ import 'package:functions/src/core/data/datasources/functions_remote_datasource.dart'; +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; import 'package:functions/src/core/domain/repositories/functions_repository.dart'; import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; @@ -24,4 +25,10 @@ class FunctionsRepositoryImpl implements FunctionsRepository { await Future.delayed(const Duration(milliseconds: 2000)); return _remote.takePicture(userId: userId); } + + @override + Future locateDevice({required LocateDeviceRequestEntity request}) async { + await Future.delayed(const Duration(milliseconds: 2000)); + return _remote.locateDevice(request: request); + } } diff --git a/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart b/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart index 567342ca..44813f87 100644 --- a/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart +++ b/modules/legacy/modules/functions/lib/src/core/domain/repositories/functions_repository.dart @@ -1,3 +1,4 @@ +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart'; import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart'; @@ -7,4 +8,6 @@ abstract class FunctionsRepository { Future> getPictures({required String userId}); Future takePicture({required String userId}); + + Future locateDevice({required LocateDeviceRequestEntity request}); } diff --git a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart index d2a65176..7f2d1a9c 100644 --- a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart @@ -70,12 +70,6 @@ class FunctionsScreen extends ConsumerWidget { text: 'Do not disturb' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), - AppSectionButton( - onPressed: (){}, - icon: SFIcons.locationAreaCircle, - text: 'Safety zone' - ), - SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, icon: SFIcons.videoCallCircle, @@ -84,19 +78,13 @@ class FunctionsScreen extends ConsumerWidget { SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: SFIcons.fallCircle, - text: 'Fall notice' + icon: SFIcons.healthCircle, + text: 'Health' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, - icon: SFIcons.medicationCircle, - text: 'Medication reminder' - ), - SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), - AppSectionButton( - onPressed: (){}, - icon: SFIcons.activityCircle, + icon: SFIcons.healthCircle, text: 'Activity meter' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), @@ -108,6 +96,30 @@ class FunctionsScreen extends ConsumerWidget { SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( onPressed: (){}, + icon: Icons.call_outlined, + text: 'Call watch' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: SFIcons.screenTime, + text: 'Apps use' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: Icons.app_registration_sharp, + text: 'Apps supervision' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){}, + icon: SFIcons.friendsCircle, + text: 'Make friends' + ), + SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), + AppSectionButton( + onPressed: (){navigationContract.pushTo(AppRoutes.locateDevice);}, icon: SFIcons.locateSfCircle, text: 'Locate your SaveFamily' ), diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case.dart new file mode 100644 index 00000000..e6fc5bfd --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case.dart @@ -0,0 +1,5 @@ +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; + +abstract class LocateDeviceUseCase { + Future locateDevice({required LocateDeviceRequestEntity request}); +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case_impl.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case_impl.dart new file mode 100644 index 00000000..0acc44d2 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/domain/locate_device_use_case_impl.dart @@ -0,0 +1,14 @@ +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; +import 'package:functions/src/core/domain/repositories/functions_repository.dart'; +import 'package:functions/src/features/locate_device/domain/locate_device_use_case.dart'; + +class LocateDeviceUseCaseImpl implements LocateDeviceUseCase { + LocateDeviceUseCaseImpl(this._repository); + + final FunctionsRepository _repository; + + @override + Future locateDevice({required LocateDeviceRequestEntity request}) async { + return _repository.locateDevice(request: request); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/locate_device_builder.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/locate_device_builder.dart new file mode 100644 index 00000000..8120c702 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/locate_device_builder.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:functions/src/features/locate_device/presentation/locate_device_screen.dart'; +import 'package:go_router/go_router.dart'; +import 'package:get_it/get_it.dart'; +import 'package:navigation/navigation.dart'; + +class LocateDeviceBuilder { + const LocateDeviceBuilder(); + + Page buildPage(BuildContext context, GoRouterState state) { + final NavigationContract navigationContract = GetIt.I(); + + return MaterialPage( + key: state.pageKey, + child: LocateDeviceScreen(navigationContract: navigationContract), + ); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/locate_device_screen.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/locate_device_screen.dart new file mode 100644 index 00000000..7d367592 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/locate_device_screen.dart @@ -0,0 +1,148 @@ +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/locate_device/presentation/state/locate_device_view_model.dart'; +import 'package:navigation/navigation.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:utils/utils.dart'; +import 'package:legacy_shared/legacy_shared.dart'; + +class LocateDeviceScreen extends ConsumerWidget { + final NavigationContract navigationContract; + + const LocateDeviceScreen({super.key, required this.navigationContract}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + + return PageLayout( + title: context.translate('Find your device'), + body: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 16), + big: EdgeInsets.symmetric(horizontal: 15) + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.translate('Locate your SaveFamily in nearby locations'), + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 18, big: 17), + fontWeight: FontWeight.w500, + ) + ), + SizedBox(height: SizeUtils.getByScreen(small: 10, big: 8)), + Text('This function allows you to find the device indoors or in places close to you. When you press the button, the smartwatch will start beeping and you will be able to hear it.', + style: TextStyle( + fontSize: 16 + )) + ], + ), + ), + footer: Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(vertical: 12, horizontal: 26), + big: EdgeInsets.symmetric(vertical: 10, horizontal: 25) + ), + child: PrimaryButton( + onPressed: () { + showDialog(context: context, builder: (context)=>Dialog( + child: LocateDialog(), + )); + }, + text: context.translate('Locate my SaveFamily'), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 36, big: 35), + ), + ) + ); + } +} + +class LocateDialog extends ConsumerWidget { + + @override + Widget build(BuildContext context, WidgetRef ref) { + + final viewModel = ref.read(locateDeviceViewModelProvider.notifier); + final viewState = ref.watch(locateDeviceViewModelProvider); + + return Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 32, vertical: 30), + big: EdgeInsets.symmetric(horizontal: 30, vertical: 28) + ), + width: SizeUtils.getByScreen(small: 360, big: 350), + height: SizeUtils.getByScreen(small: 210, big: 205), + child: Column( + children: [ + if (viewState.isLoading) + Expanded(child: Center(child: Text(context.translate('Sending...'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 25, big: 24), + ), + ))), + if (viewState.isComplete) + Expanded(child: Center(child: Text(context.translate('Sent successfully'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 25, big: 24), + ), + ))), + if (viewState.errorMessage.isNotEmpty) ...[ + Expanded(child: Center(child: Text(context.translate('The device is not connected to the Internet'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 20, big: 19), + ), + ))), + SizedBox(height: SizeUtils.getByScreen(small: 24, big: 23)), + Expanded(child: PrimaryButton( + onPressed: (){ + Navigator.pop(context); + viewModel.endLocation(); + }, + text: context.translate('OK'), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 38, big: 36), + radius: SizeUtils.getByScreen(small: 32, big: 34), + )), + ], + if (!viewState.isComplete && !viewState.isLoading && viewState.errorMessage.isEmpty) ...[ + Text(context.translate('You are going to activate the remote location of your device. It will start ringing.'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: SizeUtils.getByScreen(small: 19, big: 18), + ), + ), + SizedBox(height: SizeUtils.getByScreen(small: 24, big: 23)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: PrimaryButton( + onPressed: (){Navigator.pop(context);}, + text: context.translate(I18n.legacyCancel), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 38, big: 36), + radius: SizeUtils.getByScreen(small: 32, big: 34), + )), + SizedBox(width: SizeUtils.getByScreen(small: 4, big: 16)), + Expanded(child: PrimaryButton( + onPressed: () { + viewModel.locateDevice(); + }, + text: context.translate(I18n.accept), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 38, big: 36), + radius: SizeUtils.getByScreen(small: 32, big: 34), + )) + ], + ) + ] + ], + ), + ); + } + +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/providers/locate_device_use_case_provider.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/providers/locate_device_use_case_provider.dart new file mode 100644 index 00000000..05e7ac49 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/providers/locate_device_use_case_provider.dart @@ -0,0 +1,9 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/core/providers/functions_repository_provider.dart'; +import 'package:functions/src/features/locate_device/domain/locate_device_use_case.dart'; +import 'package:functions/src/features/locate_device/domain/locate_device_use_case_impl.dart'; + +final locateDeviceUseCaseProvider = Provider.autoDispose((ref) { + final functionsRepository = ref.read(functionsRepositoryProvider); + return LocateDeviceUseCaseImpl(functionsRepository); +}); diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_model.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_model.dart new file mode 100644 index 00000000..779431ce --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_model.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart'; +import 'package:functions/src/features/locate_device/domain/locate_device_use_case.dart'; +import 'package:functions/src/features/locate_device/presentation/providers/locate_device_use_case_provider.dart'; +import 'package:functions/src/features/locate_device/presentation/state/locate_device_view_state.dart'; +// import 'package:legacy_shared/src/providers/logged_user_provider.dart'; +// import 'package:sf_localizations/sf_localizations.dart'; + +final locateDeviceViewModelProvider = + NotifierProvider.autoDispose( + LocateDeviceViewModel.new, + ); + +class LocateDeviceViewModel extends Notifier { + late final LocateDeviceUseCase _locateDeviceUseCase; + + late final TextEditingController nameController; + late final TextEditingController phoneController; + + // late final UserEntity loggedUser; + + @override + LocateDeviceViewState build() { + _locateDeviceUseCase = ref.read(locateDeviceUseCaseProvider); + + // loggedUser = ref.read(loggedUserProvider); + + return const LocateDeviceViewState(); + } + + Future locateDevice() async { + try { + state = state.copyWith( + isLoading: true, + isComplete: false, + errorMessage: '', + ); + + LocateDeviceRequestEntity request = LocateDeviceRequestEntity(deviceName: ''); + await _locateDeviceUseCase.locateDevice(request: request); + + state = state.copyWith( + isLoading: false, + isComplete: true, + ); + } catch (e) { + state = state.copyWith( + isLoading: false, + isComplete: false, + errorMessage: e.toString(), + ); + } + } + + void endLocation() { + state = state.copyWith( + errorMessage: '', + + ); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.dart new file mode 100644 index 00000000..467e8f54 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.dart @@ -0,0 +1,11 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +part 'locate_device_view_state.freezed.dart'; + +@freezed +abstract class LocateDeviceViewState with _$LocateDeviceViewState { + const factory LocateDeviceViewState({ + @Default(false) bool isLoading, + @Default(false) bool isComplete, + @Default('') String errorMessage, + }) = _LocateDeviceViewState; +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.freezed.dart b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.freezed.dart new file mode 100644 index 00000000..0fce616f --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/locate_device/presentation/state/locate_device_view_state.freezed.dart @@ -0,0 +1,277 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'locate_device_view_state.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$LocateDeviceViewState { + + bool get isLoading; bool get isComplete; String get errorMessage; +/// Create a copy of LocateDeviceViewState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LocateDeviceViewStateCopyWith get copyWith => _$LocateDeviceViewStateCopyWithImpl(this as LocateDeviceViewState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LocateDeviceViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,isLoading,isComplete,errorMessage); + +@override +String toString() { + return 'LocateDeviceViewState(isLoading: $isLoading, isComplete: $isComplete, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class $LocateDeviceViewStateCopyWith<$Res> { + factory $LocateDeviceViewStateCopyWith(LocateDeviceViewState value, $Res Function(LocateDeviceViewState) _then) = _$LocateDeviceViewStateCopyWithImpl; +@useResult +$Res call({ + bool isLoading, bool isComplete, String errorMessage +}); + + + + +} +/// @nodoc +class _$LocateDeviceViewStateCopyWithImpl<$Res> + implements $LocateDeviceViewStateCopyWith<$Res> { + _$LocateDeviceViewStateCopyWithImpl(this._self, this._then); + + final LocateDeviceViewState _self; + final $Res Function(LocateDeviceViewState) _then; + +/// Create a copy of LocateDeviceViewState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? isComplete = null,Object? errorMessage = null,}) { + return _then(_self.copyWith( +isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable +as bool,isComplete: null == isComplete ? _self.isComplete : isComplete // ignore: cast_nullable_to_non_nullable +as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [LocateDeviceViewState]. +extension LocateDeviceViewStatePatterns on LocateDeviceViewState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _LocateDeviceViewState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _LocateDeviceViewState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _LocateDeviceViewState value) $default,){ +final _that = this; +switch (_that) { +case _LocateDeviceViewState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _LocateDeviceViewState value)? $default,){ +final _that = this; +switch (_that) { +case _LocateDeviceViewState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( bool isLoading, bool isComplete, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LocateDeviceViewState() when $default != null: +return $default(_that.isLoading,_that.isComplete,_that.errorMessage);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( bool isLoading, bool isComplete, String errorMessage) $default,) {final _that = this; +switch (_that) { +case _LocateDeviceViewState(): +return $default(_that.isLoading,_that.isComplete,_that.errorMessage);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool isLoading, bool isComplete, String errorMessage)? $default,) {final _that = this; +switch (_that) { +case _LocateDeviceViewState() when $default != null: +return $default(_that.isLoading,_that.isComplete,_that.errorMessage);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _LocateDeviceViewState implements LocateDeviceViewState { + const _LocateDeviceViewState({this.isLoading = false, this.isComplete = false, this.errorMessage = ''}); + + +@override@JsonKey() final bool isLoading; +@override@JsonKey() final bool isComplete; +@override@JsonKey() final String errorMessage; + +/// Create a copy of LocateDeviceViewState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LocateDeviceViewStateCopyWith<_LocateDeviceViewState> get copyWith => __$LocateDeviceViewStateCopyWithImpl<_LocateDeviceViewState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocateDeviceViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,isLoading,isComplete,errorMessage); + +@override +String toString() { + return 'LocateDeviceViewState(isLoading: $isLoading, isComplete: $isComplete, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class _$LocateDeviceViewStateCopyWith<$Res> implements $LocateDeviceViewStateCopyWith<$Res> { + factory _$LocateDeviceViewStateCopyWith(_LocateDeviceViewState value, $Res Function(_LocateDeviceViewState) _then) = __$LocateDeviceViewStateCopyWithImpl; +@override @useResult +$Res call({ + bool isLoading, bool isComplete, String errorMessage +}); + + + + +} +/// @nodoc +class __$LocateDeviceViewStateCopyWithImpl<$Res> + implements _$LocateDeviceViewStateCopyWith<$Res> { + __$LocateDeviceViewStateCopyWithImpl(this._self, this._then); + + final _LocateDeviceViewState _self; + final $Res Function(_LocateDeviceViewState) _then; + +/// Create a copy of LocateDeviceViewState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? isComplete = null,Object? errorMessage = null,}) { + return _then(_LocateDeviceViewState( +isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable +as bool,isComplete: null == isComplete ? _self.isComplete : isComplete // ignore: cast_nullable_to_non_nullable +as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart b/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart index 7c49bca7..0b051380 100644 --- a/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart +++ b/modules/legacy/modules/legacy_dashboard_shell/lib/src/presentation/legacy_main_shell_screen.dart @@ -47,7 +47,7 @@ class LegacyDashboardScreen extends ConsumerWidget { label: context.translate(I18n.functions), ), NavigationDestination( - icon: Icon(Icons.location_on_outlined), + icon: Icon(SFIcons.locationOutlined), label: context.translate(I18n.location), ), NavigationDestination( diff --git a/modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart b/modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart index beeee9cf..860a1c8c 100644 --- a/modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart +++ b/modules/legacy/packages/legacy_shared/lib/src/widgets/layouts/page_layout.dart @@ -41,7 +41,7 @@ class PageLayout extends StatelessWidget{ ), ), SizedBox(height: SizeUtils.getByScreen(small: 30, big: 28)), - body, + Expanded(child: body), ?footer ], ) diff --git a/packages/design_system/fonts/SFIcons.ttf b/packages/design_system/fonts/SFIcons.ttf index caf8ca272821a0f1e693e7068a3de0d958822c3e..ef3076f16e34e88849f8e40dddacc78198cfe69d 100644 GIT binary patch delta 2049 zcmY*aO>7(25uVv4x#aRcB$p;-@mE^PBA1kwBI%e4MMjEj%Tn!F5+x=^99g1F$)x_w zxK1O3iDEad5d=or7Djrg0~Bt6qD32_KvVRPLk=yFL(rc?6SOf<2Us`-0u*x41TEEB zZFA@@zWLtFyq$eBZ{F^QAK~5uyd7@!PQ(E4bpR+YHWoHM|KO9)0oWpd;mXDOi_3k- zUo-;nHGt>u)T#?hsjCkiH1|FsTO)(|CZ2GYc#LUruO$J-UGt9`ugI6w0ryu z0MoC@|BJ@L)eZb3bBcV2NDr+oG^(x5sW}1Q66ws|#`@*vOYw_c01XPFy9P*0IlI3K zpbzhVwf}G3m#XFeuDJsXSp$DryL;X~{0PjfqR#kqclzkpOwU$zU$SM=jlif@y3|N> zOgo4h_>cB&Jc&Qt{RnMnWJP-Ewf(Q!_nF0o=d>5%Jg^6&1TjxbeGYV(pa6%#K^BW5 zDYBALO3Iirt(29DazUvno60Ta?frcK1(Xzdk135_c-NJd>TSQG>*_*^a|O2P zz6Gztcj^A#!F>mQ-u?so6Z168z%0=6(LnP%?e|dMZt3;BPA#K)m3QCJf5x<)rgsrw zg!rrmC=yR=fD$o9Q2|d9&uf5D;)(_sBfg*ko+755R{`V1>l)xV@rDLCLADd6%&`Swt ziN&1A*{~ba87hgy$4yHIT&-MnC2PIh&*Qx1#Ubk;m7UM7d)+ZtUH3)yko7|8FZSx;qGB~z>q$Y zmBiFw(67%+!@UB-*rSR5sMo-iq@78QXH48luE~s9oV1O3R6nVpr+wRD1MFF_LxPS^ z85RM0smrLwF|mMYIly?`HYOU0C0VuXR8&R|w5ag{$PJ0HBvQ*I$xk)+INb&!cK~U3 zwZ_zX(5tqg+NY|@G^B|$hr4(#INIkQ6y3i}Ro07^L-MmHQzqN^gg;#xFUegaQ$a_!zh9h6xWz$#VXKm4 zxcGQQuKYOtFiP>d~KRBKB|;l0xO^^H<#eRp>XGoM&d*%qgmr5A8!GTj#75r&owNO~yR>jBtC(0+{aT5K@ z%jM~T!NGy)^771E#m)nt%jLtv#kcUKzS!9K%=nF5=ToZ{yK*;38H@Gp{(W?!7w6i^ zm3u~<#WK#}{O+GtE-_jD^5Rytx;C@Ys9Kk|R;p`Dmq%B&7VA}Wv)b6GZY?xl*s40z hpKo(zeeLuM&HBn(b*Vj4|2=1+KX$!YYdaew{{^-_(-Z&z delta 746 zcmY+BUr19?9LK-s-aFY=m=7Tp>Ky1?b5>LeL7*#JbLv_SR#6nUHQUPlvlSY`w7<(F z2Irxkih9sJi7@b`9!3e35cSf_dWkT&LZ>qOK42&c~YDxR`4lqS%J|9!ZlI)|@PjfryxjC-J!kN_Isd`|T z0;!x#TuVRf&(q@QRzPuq(NTsfR{(>xvRT6?G1y-{UD4$`v`lAco2D+MHOVM+Fr=U5+mTqvK!~PEWKBZNJv3xwKx*&$DtPpObAn8O^3~lX@1@)Mu(ahgtqZo}+R#{JHXn7ny-S zGZ@U`uvBuWFmG6uGN%EJKsWh}06pZ30=UTZe{^t!oDhI6NlOaQOHK)JjGPg`O`a6s zIC)9{5BZiLgFYJE7QjosBLLl+c2|G_@;w0t$@c~Dk+TAvAU_bmPo5UwBsnj@5PgK+ zoOpy~W@AB#zcr1v9c+Bkw7qHG(qJhzms%!T&)X*2dhBld`tC`G)A6F+@AP#n>`@94 m^XEf_4<1h|3-J2*Y+)&WRpQ~)dsD3%N=I)*)8o8zwEHh1E61(? diff --git a/packages/design_system/lib/fonts/config.json b/packages/design_system/lib/fonts/config.json index 8e472872..560b854f 100755 --- a/packages/design_system/lib/fonts/config.json +++ b/packages/design_system/lib/fonts/config.json @@ -1076,20 +1076,6 @@ "icon" ] }, - { - "uid": "d9ab0ada4a6bda3f4f974dd8d154b5bf", - "css": "activityCircle", - "code": 59527, - "src": "custom_icons", - "selected": true, - "svg": { - "path": "M672.8 298.3C624.2 285.8 582.8 302.2 550.3 339.4 532.9 359.4 517.4 381.4 500 404.1 479.6 378.4 462.6 353.5 442.2 331.8 398.2 285.1 325.6 281.9 279.9 322.3 231.3 365.6 226.3 433.3 269.7 484.6 334.8 562.1 400.1 639 465.5 716.2 475.7 728.3 486.2 740.5 497 753.6 577.9 660.3 657 569.6 735.2 478.3 757.2 452.4 764.1 420.2 756.9 386.7 747 340.7 718.5 310.1 672.8 298.3ZM500 0C224 0 0 223.7 0 500 0 776.3 224 1000 500 1000 776.3 1000 1000 776 1000 500 1000.3 223.7 776.3 0 500 0ZM776.6 522C693.8 618.6 610.1 714.2 526.6 810.1 503.6 836.4 489.8 836.1 467.8 810.1 385.7 713.2 303.5 616 221.4 518.7 176.4 465.5 169.5 388.6 203 326.2 235.2 265.8 302.6 230.3 371.2 236.5 423.8 241.5 465.5 265.4 500.7 306.5 535.1 265.8 576.5 241.8 628.5 236.9 698.8 230.3 765.8 265.4 798 326.5 831.5 391.3 824.2 466.5 776.6 522Z", - "width": 1000 - }, - "search": [ - "icon" - ] - }, { "uid": "05dd5a74c484decee45995f6ee723ea2", "css": "rewardsCircle", @@ -1145,6 +1131,76 @@ "search": [ "icon" ] + }, + { + "uid": "623cc2ff909ec2281a19d64b238c18a1", + "css": "screenTime", + "code": 59473, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M696.6 468.8C799.4 468.8 882.8 552.1 882.8 654.9 882.8 757.8 799.4 841.1 696.6 841.1 593.8 841.1 510.4 757.8 510.4 654.9 510.4 552.1 593.8 468.8 696.6 468.8ZM569.7 130.2C611.7 130.2 645.8 164.3 645.8 206.4L645.8 440.8C548.8 463.7 476.6 550.9 476.6 654.9 476.6 660.6 476.8 666.3 477.2 671.9L400.4 671.9C386.4 671.9 375 683.2 375 697.3 375 710.1 384.6 720.7 396.9 722.4L400.4 722.7H485L487.1 722.5C497.5 754.7 515 783.5 537.9 807.3L315.8 807.3C273.7 807.3 239.6 773.2 239.6 731.1V206.4C239.6 164.3 273.7 130.2 315.8 130.2H569.7ZM662.8 536.5C653.4 536.5 645.8 544 645.8 553.4V688.8C645.8 698.1 653.4 705.7 662.8 705.7H764.4C773.7 705.7 781.3 698.1 781.3 688.8 781.3 679.5 773.7 671.9 764.4 671.9H679.7V553.4C679.7 544 672.1 536.5 662.8 536.5Z", + "width": 1000 + }, + "search": [ + "icon" + ] + }, + { + "uid": "f91b4ca494bb312e01f6e0981e7a05dc", + "css": "friendsCircle", + "code": 59474, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M632.1 435C674.4 435.3 709.6 400.5 709.6 358.1 709.6 316 675.1 281.2 633 280.9 590.7 280.6 555.8 315 555.5 357.1 555.2 399.8 589.7 434.6 632.1 435ZM292.4 542.7C294.3 527.9 286.5 513.1 272.7 510.2 260.2 507.6 246.7 508.5 233.9 507.6 233.9 528.3 233.9 547.3 233.9 567.3 244.4 567.3 254.6 567.7 264.5 567.3 278.3 567 290.4 556.2 292.4 542.7ZM386 435C428.1 435.3 463.2 400.5 463.5 358.4 463.9 315.7 429.4 280.9 387 280.9 344.6 280.9 309.5 315.4 309.5 357.8 309.1 400.1 343.6 434.6 386 435ZM534.5 470.8C531.9 470.8 530.6 470.4 528.9 470.4 475.4 470.4 422.1 470.4 368.6 470.4 359.7 470.4 350.9 471.4 342.3 473.1 329.2 475.7 317 480.6 305.5 488.2 325.9 507.9 333.4 531.5 324.2 557.8 312.7 591.3 286.8 604.1 252.3 602.8 252.3 641.9 252.3 680 252.3 718.8 265.8 718.8 278.6 718.8 292 718.8 292 715.8 292 713.9 292 711.6 292 689.9 292 667.9 292 646.2 292 643.9 292 641.6 292.4 639.3 294 630.1 302.2 623.9 310.8 624.5 320 625.2 327.2 632.4 327.2 641.9 327.5 665.2 327.2 688.6 327.2 712.2 327.2 714.5 327.2 716.8 327.2 719.1 379.1 719.1 430 719.1 481.3 719.1 481.3 716.5 481.3 714.2 481.3 711.9 481.3 669.8 480.9 627.8 481.3 585.7 481.6 542 498 505.3 529.6 475 531.9 473.7 532.8 472.4 534.5 470.8ZM500 0C223.7 0 0 224 0 500 0 776.3 224 1000 500 1000 776.3 1000 1000 776 1000 500 1000 223.7 776.3 0 500 0ZM801.6 589.7C798 597.6 792 602.8 782.5 603.2 782.5 605.8 782.5 608.1 782.5 610.1 782.5 651.1 782.5 692.2 782.5 733.2 782.5 747.7 775.6 754.6 761.2 754.6 586.7 754.6 412.3 754.6 237.8 754.6 223.4 754.6 216.5 747.7 216.5 733.2 216.5 692.2 216.5 651.1 216.5 610.1 216.5 607.8 216.5 605.5 216.5 602.8 206.6 602.8 201.4 597.2 197.4 589.7 197.4 555.2 197.4 520.4 197.4 485.9 201.7 475.7 209.6 472.1 220.4 472.7 234.6 473.4 248.7 473.1 262.8 472.7 264.5 472.7 266.8 472.7 267.7 471.7 281.2 460.2 296.3 451.1 313.1 444.5 256.2 394.9 266.8 317.7 304.9 279.2 345.3 238.8 408 233.9 453.7 268.4 475.7 285.2 489.8 307.5 495.4 334.8 503 372.2 493.1 405.1 467.8 434.3 495.4 434.3 521.7 434.3 549.3 434.3 527.3 409.3 517.1 381.1 519.7 348.9 522.3 316.4 536.8 289.4 562.4 269.4 607.1 234.2 670.2 237.8 710.2 277.6 730.9 298 742.4 322.9 743.8 352.2 745.4 392.6 729 424.8 698.1 448.8 708.9 456.3 719.1 463.9 729.6 471.1 731.3 472.1 733.6 472.7 735.5 472.7 749.7 472.7 763.8 473.4 777.9 472.7 788.8 472.4 796.6 476 800.9 485.9 801.6 520.7 801.6 555.2 801.6 589.7ZM678.1 565C664.9 536.5 671.8 510.5 694.2 488.2 670.2 473.4 644.9 467.5 617.6 471.4 557.5 480.3 517.7 527.6 517.7 588 517.7 629.4 517.7 670.8 517.7 712.2 517.7 714.2 517.7 716.5 517.7 718.5 569.3 718.5 620.6 718.5 671.8 718.5 671.8 715.8 671.8 713.9 671.8 711.6 671.8 688.2 671.8 664.9 671.8 641.6 671.8 632.1 679 624.8 688.6 624.2 697.4 623.5 705.3 630.1 707 639.3 707.3 641.6 707.3 643.9 707.3 646.2 707.3 668.2 707.3 690.2 707.3 712.2 707.3 714.2 707.6 716.5 707.6 718.8 721.1 718.8 733.9 718.8 747 718.8 747 679.7 747 641.3 747 602.8 715.8 604.5 691.2 594 678.1 565ZM707.3 537.1C707 552.6 718.5 566.4 733.6 567.3 744.4 568 754.9 567.3 766.1 567.3 766.1 547.3 766.1 527.9 766.1 508.5 755.3 508.5 745.1 508.2 734.6 508.5 719.4 508.9 707.6 521.7 707.3 537.1Z", + "width": 1000 + }, + "search": [ + "icon" + ] + }, + { + "uid": "d9ab0ada4a6bda3f4f974dd8d154b5bf", + "css": "healthCircle", + "code": 59527, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M672.8 298.3C624.2 285.8 582.8 302.2 550.3 339.4 532.9 359.4 517.4 381.4 500 404.1 479.6 378.4 462.6 353.5 442.2 331.8 398.2 285.1 325.6 281.9 279.9 322.3 231.3 365.6 226.3 433.3 269.7 484.6 334.8 562.1 400.1 639 465.5 716.2 475.7 728.3 486.2 740.5 497 753.6 577.9 660.3 657 569.6 735.2 478.3 757.2 452.4 764.1 420.2 756.9 386.7 747 340.7 718.5 310.1 672.8 298.3ZM500 0C224 0 0 223.7 0 500 0 776.3 224 1000 500 1000 776.3 1000 1000 776 1000 500 1000.3 223.7 776.3 0 500 0ZM776.6 522C693.8 618.6 610.1 714.2 526.6 810.1 503.6 836.4 489.8 836.1 467.8 810.1 385.7 713.2 303.5 616 221.4 518.7 176.4 465.5 169.5 388.6 203 326.2 235.2 265.8 302.6 230.3 371.2 236.5 423.8 241.5 465.5 265.4 500.7 306.5 535.1 265.8 576.5 241.8 628.5 236.9 698.8 230.3 765.8 265.4 798 326.5 831.5 391.3 824.2 466.5 776.6 522Z", + "width": 1000 + }, + "search": [ + "icon" + ] + }, + { + "uid": "505c0f357adb29dfe5230da603bd2b07", + "css": "temperature", + "code": 59475, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M621 665.3C621 691.6 613.2 717.4 598.5 739.2 583.9 761.1 563.1 778.2 538.8 788.3 514.5 798.3 487.8 801 461.9 795.8 436.1 790.7 412.4 778 393.8 759.4 375.2 740.8 362.5 717.1 357.4 691.3 352.3 665.5 354.9 638.7 365 614.4 375 590.1 392.1 569.3 414 554.7 435.9 540.1 461.6 532.3 487.9 532.3 523.2 532.3 557 546.3 582 571.2 606.9 596.2 621 630 621 665.3ZM798.4 665.3C798.4 706.2 790.3 746.6 774.7 784.3 759 822 736.1 856.3 707.2 885.1 678.3 914 644 936.8 606.2 952.4 568.5 967.9 528 975.9 487.2 975.8 474.9 975.8 462.7 975.1 450.5 973.6 383.8 965.1 321.6 935.3 273.1 888.7 224.7 842.1 192.5 781.1 181.3 714.8 171.9 657.1 179.1 597.9 202 544.1 224.8 490.3 262.5 444.1 310.5 410.8V177.4C310.5 130.4 329.2 85.2 362.4 52 395.7 18.7 440.8 0 487.9 0 535 0 580.1 18.7 613.4 52 646.6 85.2 665.3 130.4 665.3 177.4V410.8C706.3 439.4 739.8 477.5 762.9 521.8 786.1 566.1 798.3 615.3 798.4 665.3ZM709.7 665.3C709.6 626.4 699.3 588.3 679.8 554.6 660.4 521 632.4 493 598.8 473.5 592.1 469.6 586.5 464 582.6 457.3 578.7 450.5 576.6 442.9 576.6 435.1V177.4C576.6 153.9 567.3 131.3 550.6 114.7 534 98.1 511.4 88.7 487.9 88.7 464.4 88.7 441.8 98.1 425.2 114.7 408.5 131.3 399.2 153.9 399.2 177.4V435.1C399.2 442.9 397.1 450.5 393.2 457.3 389.3 464 383.8 469.6 377 473.5 343.3 493 315.3 521 295.8 554.7 276.4 588.4 266.1 626.7 266.1 665.6 266.1 704.5 276.4 742.8 295.9 776.5 315.4 810.2 343.4 838.2 377.1 857.7 410.8 877.1 449.1 887.3 488 887.3 527 887.3 565.2 877 598.9 857.5 632.6 838 660.6 810 680.1 776.3 699.5 742.5 709.7 704.3 709.7 665.3ZM221.8 88.7H44.4C32.6 88.7 21.3 93.4 13 101.7 4.7 110 0 121.3 0 133.1 0 144.8 4.7 156.1 13 164.4 21.3 172.7 32.6 177.4 44.4 177.4H221.8C233.5 177.4 244.8 172.7 253.1 164.4 261.5 156.1 266.1 144.8 266.1 133.1 266.1 121.3 261.5 110 253.1 101.7 244.8 93.4 233.5 88.7 221.8 88.7ZM266.1 310.5C266.1 298.7 261.5 287.4 253.1 279.1 244.8 270.8 233.5 266.1 221.8 266.1H133.1C121.3 266.1 110 270.8 101.7 279.1 93.4 287.4 88.7 298.7 88.7 310.5 88.7 322.2 93.4 333.5 101.7 341.8 110 350.2 121.3 354.8 133.1 354.8H221.8C233.5 354.8 244.8 350.2 253.1 341.8 261.5 333.5 266.1 322.2 266.1 310.5Z", + "width": 806 + }, + "search": [ + "icon" + ] + }, + { + "uid": "415b9dee17fa463032aa6f9d83a6df07", + "css": "locationOutlined", + "code": 59478, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M191.8 423.4C191.8 296.4 300.4 193.5 434.4 193.5 568.4 193.5 677 296.4 677 423.4 677 550.3 568.4 653.2 434.4 653.2 300.4 653.2 191.8 550.3 191.8 423.4ZM434.4 266.1C342.8 266.1 268.4 336.5 268.4 423.4 268.4 510.2 342.8 580.6 434.4 580.6 526.1 580.6 600.4 510.2 600.4 423.4 600.4 336.5 526.1 266.1 434.4 266.1ZM1.5 368.1C19.6 160.1 203.1 0 423.4 0H445.5C665.8 0 849.2 160.1 867.3 368.1 877 479.8 840.6 590.7 765.7 677.5L520.9 961.2C476.2 1012.9 392.7 1012.9 348 961.2L103.2 677.5C28.3 590.7-8.2 479.8 1.5 368.1ZM423.4 72.6C243 72.6 92.7 203.7 77.9 374 69.8 467 100.1 559.4 162.5 631.6L407.3 915.2C421.3 931.5 447.6 931.5 461.6 915.2L706.4 631.6C768.7 559.4 799.1 467 791 374 776.1 203.7 625.9 72.6 445.5 72.6H423.4Z", + "width": 893 + }, + "search": [ + "icon" + ] } ] } \ No newline at end of file diff --git a/packages/design_system/lib/src/icons/sf_icons.dart b/packages/design_system/lib/src/icons/sf_icons.dart index 7447078f..62b691ef 100644 --- a/packages/design_system/lib/src/icons/sf_icons.dart +++ b/packages/design_system/lib/src/icons/sf_icons.dart @@ -87,6 +87,10 @@ class SFIcons { static const IconData watch = IconData(0xe843, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData handshake = IconData(0xe844, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData listen = IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData screenTime = IconData(0xe851, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData friendsCircle = IconData(0xe852, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData temperature = IconData(0xe853, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData locationOutlined = IconData(0xe856, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData share = IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData favoriteOutlined = IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData renovationSelected = IconData(0xe862, fontFamily: _kFontFam, fontPackage: _kFontPkg); @@ -102,7 +106,7 @@ class SFIcons { static const IconData videoCallCircle = IconData(0xe884, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData fallCircle = IconData(0xe885, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData medicationCircle = IconData(0xe886, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData activityCircle = IconData(0xe887, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData healthCircle = IconData(0xe887, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData rewardsCircle = IconData(0xe888, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData locateSfCircle = IconData(0xe889, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData chat = IconData(0xe88a, fontFamily: _kFontFam, fontPackage: _kFontPkg); diff --git a/packages/navigation/lib/app_routes.dart b/packages/navigation/lib/app_routes.dart index c5f5de4d..aff2367a 100644 --- a/packages/navigation/lib/app_routes.dart +++ b/packages/navigation/lib/app_routes.dart @@ -24,4 +24,5 @@ class AppRoutes { static const contacts = '$dashboardFunctions/contacts'; static const remoteConnection = '$dashboardFunctions/remote_connection'; + static const locateDevice = '$dashboardFunctions/locateDevice'; } From e4c0a23ded0a8a0b8559c8d9fcd6ea853674ef4f Mon Sep 17 00:00:00 2001 From: aitorarana Date: Thu, 12 Feb 2026 17:27:55 +0100 Subject: [PATCH 8/8] Added call watch dialog --- .../flutter/generated_plugin_registrant.cc | 4 + .../linux/flutter/generated_plugins.cmake | 1 + .../locate_device_request_entity.freezed.dart | 43 ++- .../features/functions/functions_screen.dart | 11 +- .../state/call_watch_view_model.dart | 61 ++++ .../state/call_watch_view_state.dart | 11 + .../state/call_watch_view_state.freezed.dart | 274 ++++++++++++++++++ .../functions/widgets/call_watch_dialog.dart | 71 +++++ modules/legacy/modules/functions/pubspec.yaml | 1 + 9 files changed, 450 insertions(+), 27 deletions(-) create mode 100644 modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_model.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.freezed.dart create mode 100644 modules/legacy/modules/functions/lib/src/features/functions/widgets/call_watch_dialog.dart diff --git a/apps/mobile_app/linux/flutter/generated_plugin_registrant.cc b/apps/mobile_app/linux/flutter/generated_plugin_registrant.cc index e71a16d2..f6f23bfe 100644 --- a/apps/mobile_app/linux/flutter/generated_plugin_registrant.cc +++ b/apps/mobile_app/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include void fl_register_plugins(FlPluginRegistry* registry) { + 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/apps/mobile_app/linux/flutter/generated_plugins.cmake b/apps/mobile_app/linux/flutter/generated_plugins.cmake index 2e1de87a..f16b4c34 100644 --- a/apps/mobile_app/linux/flutter/generated_plugins.cmake +++ b/apps/mobile_app/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart b/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart index 9f79acf1..5cf32e85 100644 --- a/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart +++ b/modules/legacy/modules/functions/lib/src/core/data/models/entities/locate_device_request_entity.freezed.dart @@ -14,7 +14,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$LocateDeviceRequestEntity { - String get deviceName; dynamic get command; + String get deviceName; /// Create a copy of LocateDeviceRequestEntity /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -25,16 +25,16 @@ $LocateDeviceRequestEntityCopyWith get copyWith => _$ @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is LocateDeviceRequestEntity&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)&&const DeepCollectionEquality().equals(other.command, command)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is LocateDeviceRequestEntity&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)); } @override -int get hashCode => Object.hash(runtimeType,deviceName,const DeepCollectionEquality().hash(command)); +int get hashCode => Object.hash(runtimeType,deviceName); @override String toString() { - return 'LocateDeviceRequestEntity(deviceName: $deviceName, command: $command)'; + return 'LocateDeviceRequestEntity(deviceName: $deviceName)'; } @@ -45,7 +45,7 @@ abstract mixin class $LocateDeviceRequestEntityCopyWith<$Res> { factory $LocateDeviceRequestEntityCopyWith(LocateDeviceRequestEntity value, $Res Function(LocateDeviceRequestEntity) _then) = _$LocateDeviceRequestEntityCopyWithImpl; @useResult $Res call({ - String deviceName, dynamic command + String deviceName }); @@ -62,11 +62,10 @@ class _$LocateDeviceRequestEntityCopyWithImpl<$Res> /// Create a copy of LocateDeviceRequestEntity /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? deviceName = null,Object? command = freezed,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? deviceName = null,}) { return _then(_self.copyWith( deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable -as String,command: freezed == command ? _self.command : command // ignore: cast_nullable_to_non_nullable -as dynamic, +as String, )); } @@ -151,10 +150,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( String deviceName, dynamic command)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( String deviceName)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _LocateDeviceRequestEntity() when $default != null: -return $default(_that.deviceName,_that.command);case _: +return $default(_that.deviceName);case _: return orElse(); } @@ -172,10 +171,10 @@ return $default(_that.deviceName,_that.command);case _: /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( String deviceName, dynamic command) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( String deviceName) $default,) {final _that = this; switch (_that) { case _LocateDeviceRequestEntity(): -return $default(_that.deviceName,_that.command);case _: +return $default(_that.deviceName);case _: throw StateError('Unexpected subclass'); } @@ -192,10 +191,10 @@ return $default(_that.deviceName,_that.command);case _: /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String deviceName, dynamic command)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String deviceName)? $default,) {final _that = this; switch (_that) { case _LocateDeviceRequestEntity() when $default != null: -return $default(_that.deviceName,_that.command);case _: +return $default(_that.deviceName);case _: return null; } @@ -207,11 +206,10 @@ return $default(_that.deviceName,_that.command);case _: class _LocateDeviceRequestEntity implements LocateDeviceRequestEntity { - const _LocateDeviceRequestEntity({required this.deviceName, this.command}); + const _LocateDeviceRequestEntity({required this.deviceName}); @override final String deviceName; -@override final dynamic command; /// Create a copy of LocateDeviceRequestEntity /// with the given fields replaced by the non-null parameter values. @@ -223,16 +221,16 @@ _$LocateDeviceRequestEntityCopyWith<_LocateDeviceRequestEntity> get copyWith => @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocateDeviceRequestEntity&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)&&const DeepCollectionEquality().equals(other.command, command)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocateDeviceRequestEntity&&(identical(other.deviceName, deviceName) || other.deviceName == deviceName)); } @override -int get hashCode => Object.hash(runtimeType,deviceName,const DeepCollectionEquality().hash(command)); +int get hashCode => Object.hash(runtimeType,deviceName); @override String toString() { - return 'LocateDeviceRequestEntity(deviceName: $deviceName, command: $command)'; + return 'LocateDeviceRequestEntity(deviceName: $deviceName)'; } @@ -243,7 +241,7 @@ abstract mixin class _$LocateDeviceRequestEntityCopyWith<$Res> implements $Locat factory _$LocateDeviceRequestEntityCopyWith(_LocateDeviceRequestEntity value, $Res Function(_LocateDeviceRequestEntity) _then) = __$LocateDeviceRequestEntityCopyWithImpl; @override @useResult $Res call({ - String deviceName, dynamic command + String deviceName }); @@ -260,11 +258,10 @@ class __$LocateDeviceRequestEntityCopyWithImpl<$Res> /// Create a copy of LocateDeviceRequestEntity /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? deviceName = null,Object? command = freezed,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? deviceName = null,}) { return _then(_LocateDeviceRequestEntity( deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable -as String,command: freezed == command ? _self.command : command // ignore: cast_nullable_to_non_nullable -as dynamic, +as String, )); } diff --git a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart index 7f2d1a9c..6a58eece 100644 --- a/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart +++ b/modules/legacy/modules/functions/lib/src/features/functions/functions_screen.dart @@ -1,6 +1,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/functions/widgets/call_watch_dialog.dart'; import 'package:navigation/navigation.dart'; import 'package:sf_localizations/sf_localizations.dart'; import 'package:utils/utils.dart'; @@ -95,9 +96,11 @@ class FunctionsScreen extends ConsumerWidget { ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( - onPressed: (){}, - icon: Icons.call_outlined, - text: 'Call watch' + onPressed: (){showDialog(context: context, builder: (context)=>Dialog( + child: CallWatchDialog() + ));}, + icon: Icons.call_outlined, + text: 'Call watch' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( @@ -109,7 +112,7 @@ class FunctionsScreen extends ConsumerWidget { AppSectionButton( onPressed: (){}, icon: Icons.app_registration_sharp, - text: 'Apps supervision' + text: 'Apps surveillance' ), SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)), AppSectionButton( diff --git a/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_model.dart b/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_model.dart new file mode 100644 index 00000000..cc749ff4 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_model.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/functions/state/call_watch_view_state.dart'; +import 'package:url_launcher/url_launcher.dart'; + +final callWatchViewModelProvider = +NotifierProvider.autoDispose( + CallWatchViewModel.new, +); + +class CallWatchViewModel extends Notifier { + + late final TextEditingController phoneController; + + static final RegExp _phoneRegex = RegExp(r'^\+?\d{6,15}$'); + + @override + CallWatchViewState build() { + + phoneController = TextEditingController(); + + phoneController.addListener(_onPhoneChanged); + + ref.onDispose(disposeControllers); + + return const CallWatchViewState(); + } + + void _onPhoneChanged() { + final text = phoneController.text; + if (text == state.phone) return; + + state = state.copyWith(phone: text, errorMessage: ''); + } + + void call() async { + final phone = state.phone; + if (phone.isEmpty){ + state = state.copyWith(errorMessage: 'errorMessagePhoneIsEmpty'); + return; + } + if (!_phoneRegex.hasMatch(phone)) { + state = state.copyWith(errorMessage: 'errorMessagePhoneIsInvalid'); + return; + } + + final url = Uri(scheme: 'tel', path: phone); + + if (await canLaunchUrl(url)) { + launchUrl(url); + } else { + throw 'Could not launch $url'; + } + } + + void disposeControllers() { + phoneController.removeListener(_onPhoneChanged); + + phoneController.dispose(); + } +} diff --git a/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.dart b/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.dart new file mode 100644 index 00000000..1b6d38b4 --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.dart @@ -0,0 +1,11 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'call_watch_view_state.freezed.dart'; + +@freezed +abstract class CallWatchViewState with _$CallWatchViewState { + const factory CallWatchViewState({ + @Default('') String phone, + @Default('') String errorMessage, + }) = _CallWatchViewState; +} diff --git a/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.freezed.dart b/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.freezed.dart new file mode 100644 index 00000000..09f3d35a --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/functions/state/call_watch_view_state.freezed.dart @@ -0,0 +1,274 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'call_watch_view_state.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$CallWatchViewState { + + String get phone; String get errorMessage; +/// Create a copy of CallWatchViewState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$CallWatchViewStateCopyWith get copyWith => _$CallWatchViewStateCopyWithImpl(this as CallWatchViewState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is CallWatchViewState&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phone,errorMessage); + +@override +String toString() { + return 'CallWatchViewState(phone: $phone, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class $CallWatchViewStateCopyWith<$Res> { + factory $CallWatchViewStateCopyWith(CallWatchViewState value, $Res Function(CallWatchViewState) _then) = _$CallWatchViewStateCopyWithImpl; +@useResult +$Res call({ + String phone, String errorMessage +}); + + + + +} +/// @nodoc +class _$CallWatchViewStateCopyWithImpl<$Res> + implements $CallWatchViewStateCopyWith<$Res> { + _$CallWatchViewStateCopyWithImpl(this._self, this._then); + + final CallWatchViewState _self; + final $Res Function(CallWatchViewState) _then; + +/// Create a copy of CallWatchViewState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? phone = null,Object? errorMessage = null,}) { + return _then(_self.copyWith( +phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [CallWatchViewState]. +extension CallWatchViewStatePatterns on CallWatchViewState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _CallWatchViewState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _CallWatchViewState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _CallWatchViewState value) $default,){ +final _that = this; +switch (_that) { +case _CallWatchViewState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _CallWatchViewState value)? $default,){ +final _that = this; +switch (_that) { +case _CallWatchViewState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String phone, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _CallWatchViewState() when $default != null: +return $default(_that.phone,_that.errorMessage);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String phone, String errorMessage) $default,) {final _that = this; +switch (_that) { +case _CallWatchViewState(): +return $default(_that.phone,_that.errorMessage);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String phone, String errorMessage)? $default,) {final _that = this; +switch (_that) { +case _CallWatchViewState() when $default != null: +return $default(_that.phone,_that.errorMessage);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _CallWatchViewState implements CallWatchViewState { + const _CallWatchViewState({this.phone = '', this.errorMessage = ''}); + + +@override@JsonKey() final String phone; +@override@JsonKey() final String errorMessage; + +/// Create a copy of CallWatchViewState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$CallWatchViewStateCopyWith<_CallWatchViewState> get copyWith => __$CallWatchViewStateCopyWithImpl<_CallWatchViewState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _CallWatchViewState&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phone,errorMessage); + +@override +String toString() { + return 'CallWatchViewState(phone: $phone, errorMessage: $errorMessage)'; +} + + +} + +/// @nodoc +abstract mixin class _$CallWatchViewStateCopyWith<$Res> implements $CallWatchViewStateCopyWith<$Res> { + factory _$CallWatchViewStateCopyWith(_CallWatchViewState value, $Res Function(_CallWatchViewState) _then) = __$CallWatchViewStateCopyWithImpl; +@override @useResult +$Res call({ + String phone, String errorMessage +}); + + + + +} +/// @nodoc +class __$CallWatchViewStateCopyWithImpl<$Res> + implements _$CallWatchViewStateCopyWith<$Res> { + __$CallWatchViewStateCopyWithImpl(this._self, this._then); + + final _CallWatchViewState _self; + final $Res Function(_CallWatchViewState) _then; + +/// Create a copy of CallWatchViewState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? phone = null,Object? errorMessage = null,}) { + return _then(_CallWatchViewState( +phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +// dart format on diff --git a/modules/legacy/modules/functions/lib/src/features/functions/widgets/call_watch_dialog.dart b/modules/legacy/modules/functions/lib/src/features/functions/widgets/call_watch_dialog.dart new file mode 100644 index 00000000..5276a08d --- /dev/null +++ b/modules/legacy/modules/functions/lib/src/features/functions/widgets/call_watch_dialog.dart @@ -0,0 +1,71 @@ +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:functions/src/features/functions/state/call_watch_view_model.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:utils/utils.dart'; + +class CallWatchDialog extends ConsumerWidget { + + @override + Widget build(BuildContext context, WidgetRef ref) { + + final viewModel = ref.read(callWatchViewModelProvider.notifier); + final viewState = ref.watch(callWatchViewModelProvider); + + return Container( + padding: SizeUtils.getByScreen( + small: EdgeInsets.symmetric(horizontal: 26, vertical: 20), + big: EdgeInsets.symmetric(horizontal: 24, vertical: 18) + ), + width: SizeUtils.getByScreen(small: 390, big: 380), + height: SizeUtils.getByScreen(small: 250, big: 243), + child: Column( + children: [ + Stack( + children: [ + Center(child: Text(context.translate('Call watch'), + textAlign: TextAlign.center, + style: TextStyle(fontSize: SizeUtils.getByScreen(small: 19, big: 18)), + )), + Align( + alignment: Alignment.centerRight, + child: IconButton( + onPressed: (){Navigator.pop(context);}, + icon: Icon(Icons.close, color: Color(0xFF588EA5)), + ) + ) + ], + ), + SizedBox(height: SizeUtils.getByScreen(small: 8, big: 7)), + CustomTextField( + controller: viewModel.phoneController, + hint: context.translate('Main contact phone number'), + keyboardType: TextInputType.number, + ), + if (viewState.errorMessage.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 12), + child: Text( + viewState.errorMessage, + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).colorScheme.error, + fontSize: 13, + ), + ), + ), + SizedBox(height: SizeUtils.getByScreen(small: 28, big: 27)), + PrimaryButton( + onPressed: viewModel.call, + text: context.translate('Call me'), + color: Color(0xFF588EA5), + height: SizeUtils.getByScreen(small: 38, big: 36), + radius: SizeUtils.getByScreen(small: 32, big: 34), + ), + ], + ), + ); + } + +} \ No newline at end of file diff --git a/modules/legacy/modules/functions/pubspec.yaml b/modules/legacy/modules/functions/pubspec.yaml index d6fedac9..3f784c19 100644 --- a/modules/legacy/modules/functions/pubspec.yaml +++ b/modules/legacy/modules/functions/pubspec.yaml @@ -50,6 +50,7 @@ dependencies: dio: ^5.9.0 json_annotation: ^4.9.0 json_serializable: ^6.11.2 + url_launcher: ^6.3.2 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons.