Merge branch 'functions' into legacy

# Conflicts:
#	apps/mobile_app/lib/navigation/app_router.dart
#	apps/mobile_app/pubspec.yaml
#	modules/legacy/melos_legacy.iml
#	packages/design_system/fonts/config.json
This commit is contained in:
2026-02-13 09:20:45 +01:00
79 changed files with 5960 additions and 304 deletions

2
.idea/modules.xml generated
View File

@@ -8,10 +8,12 @@
<module fileurl="file://$PROJECT_DIR$/modules/dashboard_shell/melos_dashboard_shell.iml" filepath="$PROJECT_DIR$/modules/dashboard_shell/melos_dashboard_shell.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/design_system/melos_design_system.iml" filepath="$PROJECT_DIR$/packages/design_system/melos_design_system.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/fonts/melos_fonts.iml" filepath="$PROJECT_DIR$/packages/fonts/melos_fonts.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/functions/melos_functions.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/functions/melos_functions.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/home/melos_home.iml" filepath="$PROJECT_DIR$/modules/home/melos_home.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/hub/melos_hub.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/hub/melos_hub.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/legacy/melos_legacy.iml" filepath="$PROJECT_DIR$/modules/legacy/melos_legacy.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/legacy/modules/legacy_dashboard_shell/melos_legacy_dashboard_shell.iml" filepath="$PROJECT_DIR$/modules/legacy/modules/legacy_dashboard_shell/melos_legacy_dashboard_shell.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/legacy/packages/legacy_shared/melos_legacy_shared.iml" filepath="$PROJECT_DIR$/modules/legacy/packages/legacy_shared/melos_legacy_shared.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/navigation/melos_navigation.iml" filepath="$PROJECT_DIR$/packages/navigation/melos_navigation.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/notifications/melos_notifications.iml" filepath="$PROJECT_DIR$/modules/notifications/melos_notifications.iml" />
<module fileurl="file://$PROJECT_DIR$/modules/profile/melos_profile.iml" filepath="$PROJECT_DIR$/modules/profile/melos_profile.iml" />

View File

@@ -1,5 +1,6 @@
import 'package:account/account.dart';
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';
@@ -41,8 +42,32 @@ 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.remoteConnection,
name: 'remote_connection',
pageBuilder: RemoteConnectionBuilder().buildPage,
),
GoRoute(
path: AppRoutes.locateDevice,
name: 'locate_device',
pageBuilder: LocateDeviceBuilder().buildPage,
),
GoRoute(
path: AppRoutes.accountSettings,
name: 'account_settings',

View File

@@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h"
#include <url_launcher_linux/url_launcher_plugin.h>
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);
}

View File

@@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@@ -55,6 +55,8 @@ dependencies:
path: ../../modules/splash
account:
path: ../../modules/legacy/modules/account
functions:
path: ../../modules/legacy/modules/functions
#packages dependencies go here
navigation:
path: ../../packages/navigation

View File

@@ -20,10 +20,16 @@
<excludeFolder url="file://$MODULE_DIR$/modules/account/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/modules/account/.pub" />
<excludeFolder url="file://$MODULE_DIR$/modules/account/build" />
<excludeFolder url="file://$MODULE_DIR$/modules/functions/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/modules/functions/.pub" />
<excludeFolder url="file://$MODULE_DIR$/modules/functions/build" />
<excludeFolder url="file://$MODULE_DIR$/packages/legacy_shared/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/packages/legacy_shared/.pub" />
<excludeFolder url="file://$MODULE_DIR$/packages/legacy_shared/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>
</module>

View File

@@ -0,0 +1,13 @@
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';
abstract class FunctionsRemoteDatasource {
Future<List<ContactEntity>> getContacts({required String userId});
Future<List<PictureEntity>> getPictures({required String userId});
Future<PictureEntity> takePicture({required String userId});
Future<void> locateDevice({required LocateDeviceRequestEntity request});
}

View File

@@ -0,0 +1,148 @@
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';
class FunctionsRemoteDatasourceImpl implements FunctionsRemoteDatasource {
FunctionsRemoteDatasourceImpl(this._repository);
final QuestiaRepository _repository;
@override
Future<List<ContactEntity>> getContacts({required String userId}) async {
/*try {
final response = await _repository.get<Map<String, dynamic>>(
'/users/$userId/contacts',
);
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 [
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<List<PictureEntity>> getPictures({required String userId}) async {
/*try {
final response = await _repository.get<Map<String, dynamic>>(
'',
);
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<PictureEntity> takePicture({required String userId}) async {
/*try {
final response = await _repository.get<Map<String, dynamic>>(
'',
);
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);
}
@override
Future<void> locateDevice({required LocateDeviceRequestEntity request}) async {
try {
final body = request.toModel().toJson();
await _repository.post<void>(
'/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}) {
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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,271 @@
// 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>(T value) => value;
/// @nodoc
mixin _$LocateDeviceRequestEntity {
String get deviceName;
/// 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<LocateDeviceRequestEntity> get copyWith => _$LocateDeviceRequestEntityCopyWithImpl<LocateDeviceRequestEntity>(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));
}
@override
int get hashCode => Object.hash(runtimeType,deviceName);
@override
String toString() {
return 'LocateDeviceRequestEntity(deviceName: $deviceName)';
}
}
/// @nodoc
abstract mixin class $LocateDeviceRequestEntityCopyWith<$Res> {
factory $LocateDeviceRequestEntityCopyWith(LocateDeviceRequestEntity value, $Res Function(LocateDeviceRequestEntity) _then) = _$LocateDeviceRequestEntityCopyWithImpl;
@useResult
$Res call({
String deviceName
});
}
/// @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,}) {
return _then(_self.copyWith(
deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// 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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(TResult Function( String deviceName)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _LocateDeviceRequestEntity() when $default != null:
return $default(_that.deviceName);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 extends Object?>(TResult Function( String deviceName) $default,) {final _that = this;
switch (_that) {
case _LocateDeviceRequestEntity():
return $default(_that.deviceName);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 extends Object?>(TResult? Function( String deviceName)? $default,) {final _that = this;
switch (_that) {
case _LocateDeviceRequestEntity() when $default != null:
return $default(_that.deviceName);case _:
return null;
}
}
}
/// @nodoc
class _LocateDeviceRequestEntity implements LocateDeviceRequestEntity {
const _LocateDeviceRequestEntity({required this.deviceName});
@override final String deviceName;
/// 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));
}
@override
int get hashCode => Object.hash(runtimeType,deviceName);
@override
String toString() {
return 'LocateDeviceRequestEntity(deviceName: $deviceName)';
}
}
/// @nodoc
abstract mixin class _$LocateDeviceRequestEntityCopyWith<$Res> implements $LocateDeviceRequestEntityCopyWith<$Res> {
factory _$LocateDeviceRequestEntityCopyWith(_LocateDeviceRequestEntity value, $Res Function(_LocateDeviceRequestEntity) _then) = __$LocateDeviceRequestEntityCopyWithImpl;
@override @useResult
$Res call({
String deviceName
});
}
/// @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,}) {
return _then(_LocateDeviceRequestEntity(
deviceName: null == deviceName ? _self.deviceName : deviceName // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on

View File

@@ -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<String, dynamic> json) =>
_$SendCommandRequestModelFromJson(json);
}
extension SendCommandRequestModelMapper on LocateDeviceRequestEntity {
SendCommandRequestModel toModel() => SendCommandRequestModel(
deviceName: deviceName,
command: 'FIND_DEVICE',
);
}

View File

@@ -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>(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<SendCommandRequestModel> get copyWith => _$SendCommandRequestModelCopyWithImpl<SendCommandRequestModel>(this as SendCommandRequestModel, _$identity);
/// Serializes this SendCommandRequestModel to a JSON map.
Map<String, dynamic> 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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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<String, dynamic> 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<String, dynamic> 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

View File

@@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'send_command_request_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_SendCommandRequestModel _$SendCommandRequestModelFromJson(
Map<String, dynamic> json,
) => _SendCommandRequestModel(
deviceName: json['deviceName'] as String,
command: json['command'] as String,
);
Map<String, dynamic> _$SendCommandRequestModelToJson(
_SendCommandRequestModel instance,
) => <String, dynamic>{
'deviceName': instance.deviceName,
'command': instance.command,
};

View File

@@ -0,0 +1,34 @@
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';
class FunctionsRepositoryImpl implements FunctionsRepository {
const FunctionsRepositoryImpl(this._remote);
final FunctionsRemoteDatasource _remote;
@override
Future<List<ContactEntity>> getContacts({required String userId}) {
return _remote.getContacts(userId: userId);
}
@override
Future<List<PictureEntity>> getPictures({required String userId}) async {
await Future<void>.delayed(const Duration(milliseconds: 2000));
return _remote.getPictures(userId: userId);
}
@override
Future<PictureEntity> takePicture({required String userId}) async {
await Future<void>.delayed(const Duration(milliseconds: 2000));
return _remote.takePicture(userId: userId);
}
@override
Future<void> locateDevice({required LocateDeviceRequestEntity request}) async {
await Future<void>.delayed(const Duration(milliseconds: 2000));
return _remote.locateDevice(request: request);
}
}

View File

@@ -0,0 +1,13 @@
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';
abstract class FunctionsRepository {
Future<List<ContactEntity>> getContacts({required String userId});
Future<List<PictureEntity>> getPictures({required String userId});
Future<PictureEntity> takePicture({required String userId});
Future<void> locateDevice({required LocateDeviceRequestEntity request});
}

View File

@@ -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<FunctionsRemoteDatasource>((ref) {
final questiaRepository = getIt<QuestiaRepository>();
return FunctionsRemoteDatasourceImpl(questiaRepository);
});

View File

@@ -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<FunctionsRepository>((ref) {
final remote = ref.read(functionsRemoteDatasourceProvider);
return FunctionsRepositoryImpl(remote);
});

View File

@@ -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<void> buildPage(BuildContext context, GoRouterState state) {
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
return MaterialPage<void>(
key: state.pageKey,
child: ContactsScreen(navigationContract: navigationContract),
);
}
}

View File

@@ -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;
}

View File

@@ -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>(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<ContactEntity> get copyWith => _$ContactEntityCopyWithImpl<ContactEntity>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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

View File

@@ -0,0 +1,5 @@
import 'package:functions/src/features/contacts/domain/entities/contact_entity.dart';
abstract class GetContactsUseCase {
Future<List<ContactEntity>> getContacts({required String userId});
}

View File

@@ -0,0 +1,14 @@
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/contacts/domain/get_contacts_use_case.dart';
class GetContactsUseCaseImpl implements GetContactsUseCase {
GetContactsUseCaseImpl(this._repository);
final FunctionsRepository _repository;
@override
Future<List<ContactEntity>> getContacts({required String userId}) {
return _repository.getContacts(userId: userId);
}
}

View File

@@ -0,0 +1,247 @@
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/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';
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.contacts[index],
isEditing: state.isEditing,
),
separatorBuilder: (BuildContext context, int index)=>SizedBox(
height: SizeUtils.getByScreen(small: 18, big: 17)
),
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)
),
),
],
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),
),
),
],
)
),
);
}
}
class ContactCard extends ConsumerWidget {
final ContactEntity 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,
),
),
),
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,
),
),
),
]
],
),
);
}
}

View File

@@ -0,0 +1,140 @@
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/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 ContactEntity 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'),
),
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),
)
)
),
),
),
],
)
],
),
PrimaryButton(
onPressed: (){vm.updateContact(contact);},
text: context.translate(I18n.legacySave),
color: Color(0xFF588EA5)
)
],
))
),
],
)
),
);
}
}

View File

@@ -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<GetContactsUseCase>((ref) {
final functionsRepository = ref.read(functionsRepositoryProvider);
return GetContactsUseCaseImpl(functionsRepository);
});

View File

@@ -0,0 +1,78 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.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_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 =
NotifierProvider.autoDispose<ContactsViewModel, ContactsViewState>(
ContactsViewModel.new,
);
class ContactsViewModel extends Notifier<ContactsViewState> {
late final GetContactsUseCase _getContactsUseCase;
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(userId: '').then(setContacts);
ref.onDispose(disposeControllers);
return const ContactsViewState();
}
void setContacts(List<ContactEntity> contacts) {
state = state.copyWith(
contacts: contacts
);
}
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 _onPhoneChanged() {
final text = phoneController.text;
if (text == state.phone) return;
state = state.copyWith(phone: text, errorMessage: '');
}
void updateContact(ContactEntity contact) {
}
void disposeControllers() {
nameController.removeListener(_onNameChanged);
phoneController.removeListener(_onPhoneChanged);
nameController.dispose();
phoneController.dispose();
}
}

View File

@@ -0,0 +1,16 @@
import 'package:freezed_annotation/freezed_annotation.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([]) List<ContactEntity> contacts,
@Default(false) bool isLoading,
@Default(false) bool isEditing,
@Default('') String name,
@Default('') String phone,
@Default('') String errorMessage,
}) = _ContactsViewState;
}

View File

@@ -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 'contacts_view_state.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$ContactsViewState {
List<ContactEntity> 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)
@pragma('vm:prefer-inline')
$ContactsViewStateCopyWith<ContactsViewState> get copyWith => _$ContactsViewStateCopyWithImpl<ContactsViewState>(this as ContactsViewState, _$identity);
@override
bool operator ==(Object other) {
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,const DeepCollectionEquality().hash(contacts),isLoading,isEditing,name,phone,errorMessage);
@override
String toString() {
return 'ContactsViewState(contacts: $contacts, 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({
List<ContactEntity> contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage
});
}
/// @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? contacts = null,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) {
return _then(_self.copyWith(
contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable
as List<ContactEntity>,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,
));
}
}
/// 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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(TResult Function( List<ContactEntity> 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.contacts,_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 extends Object?>(TResult Function( List<ContactEntity> contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage) $default,) {final _that = this;
switch (_that) {
case _ContactsViewState():
return $default(_that.contacts,_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 extends Object?>(TResult? Function( List<ContactEntity> 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.contacts,_that.isLoading,_that.isEditing,_that.name,_that.phone,_that.errorMessage);case _:
return null;
}
}
}
/// @nodoc
class _ContactsViewState implements ContactsViewState {
const _ContactsViewState({final List<ContactEntity> contacts = const [], this.isLoading = false, this.isEditing = false, this.name = '', this.phone = '', this.errorMessage = ''}): _contacts = contacts;
final List<ContactEntity> _contacts;
@override@JsonKey() List<ContactEntity> 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;
@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&&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,const DeepCollectionEquality().hash(_contacts),isLoading,isEditing,name,phone,errorMessage);
@override
String toString() {
return 'ContactsViewState(contacts: $contacts, 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({
List<ContactEntity> contacts, bool isLoading, bool isEditing, String name, String phone, String errorMessage
});
}
/// @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? contacts = null,Object? isLoading = null,Object? isEditing = null,Object? name = null,Object? phone = null,Object? errorMessage = null,}) {
return _then(_ContactsViewState(
contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable
as List<ContactEntity>,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,
));
}
}
// dart format on

View File

@@ -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<void> buildPage(BuildContext context, GoRouterState state) {
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
return MaterialPage<void>(
key: state.pageKey,
child: FunctionsScreen(navigationContract: navigationContract),
);
}
}

View File

@@ -0,0 +1,194 @@
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';
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: (){navigationContract.pushTo(AppRoutes.remoteConnection);},
icon: SFIcons.connection,
text: 'Remote connection'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
icon: SFIcons.calendarCircle,
text: 'Calendar'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){navigationContract.pushTo(AppRoutes.contacts);},
icon: SFIcons.contactsCircle,
text: 'Contacts'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
icon: SFIcons.doNotDisturbCircle,
text: 'Do not disturb'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
icon: SFIcons.videoCallCircle,
text: 'Video call'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
icon: SFIcons.healthCircle,
text: 'Health'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
icon: SFIcons.healthCircle,
text: 'Activity meter'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
icon: SFIcons.rewardsCircle,
text: 'Rewards'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
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(
onPressed: (){},
icon: SFIcons.screenTime,
text: 'Apps use'
),
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
AppSectionButton(
onPressed: (){},
icon: Icons.app_registration_sharp,
text: 'Apps surveillance'
),
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'
),
],
),
))),
],
)
),
);
}
}
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: 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,
),
),
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
)
)
)
],
),
)
);
}
}

View File

@@ -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, CallWatchViewState>(
CallWatchViewModel.new,
);
class CallWatchViewModel extends Notifier<CallWatchViewState> {
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();
}
}

View File

@@ -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;
}

View File

@@ -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>(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<CallWatchViewState> get copyWith => _$CallWatchViewStateCopyWithImpl<CallWatchViewState>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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

View File

@@ -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),
),
],
),
);
}
}

View File

@@ -0,0 +1,5 @@
import 'package:functions/src/core/data/models/entities/locate_device_request_entity.dart';
abstract class LocateDeviceUseCase {
Future<void> locateDevice({required LocateDeviceRequestEntity request});
}

View File

@@ -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<void> locateDevice({required LocateDeviceRequestEntity request}) async {
return _repository.locateDevice(request: request);
}
}

View File

@@ -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<void> buildPage(BuildContext context, GoRouterState state) {
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
return MaterialPage<void>(
key: state.pageKey,
child: LocateDeviceScreen(navigationContract: navigationContract),
);
}
}

View File

@@ -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),
))
],
)
]
],
),
);
}
}

View File

@@ -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<LocateDeviceUseCase>((ref) {
final functionsRepository = ref.read(functionsRepositoryProvider);
return LocateDeviceUseCaseImpl(functionsRepository);
});

View File

@@ -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, LocateDeviceViewState>(
LocateDeviceViewModel.new,
);
class LocateDeviceViewModel extends Notifier<LocateDeviceViewState> {
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<void> 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: '',
);
}
}

View File

@@ -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;
}

View File

@@ -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>(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<LocateDeviceViewState> get copyWith => _$LocateDeviceViewStateCopyWithImpl<LocateDeviceViewState>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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

View File

@@ -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;
}

View File

@@ -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>(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<PictureEntity> get copyWith => _$PictureEntityCopyWithImpl<PictureEntity>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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

View File

@@ -0,0 +1,5 @@
import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart';
abstract class GetPicturesUseCase {
Future<List<PictureEntity>> getPictures({required String userId});
}

View File

@@ -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<List<PictureEntity>> getPictures({required String userId}) {
return _repository.getPictures(userId: userId);
}
}

View File

@@ -0,0 +1,5 @@
import 'package:functions/src/features/remote_connection/domain/entities/picture_entity.dart';
abstract class TakePictureUseCase {
Future<PictureEntity> takePicture({required String userId});
}

View File

@@ -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<PictureEntity> takePicture({required String userId}) {
return _repository.takePicture(userId: userId);
}
}

View File

@@ -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<GetPicturesUseCase>((ref) {
final functionsRepository = ref.read(functionsRepositoryProvider);
return GetPicturesUseCaseImpl(functionsRepository);
});

View File

@@ -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<TakePictureUseCase>((ref) {
final functionsRepository = ref.read(functionsRepositoryProvider);
return TakePictureUseCaseImpl(functionsRepository);
});

View File

@@ -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<Widget>.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: () 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)
),
width: SizeUtils.getByScreen(small: 360, big: 350),
height: SizeUtils.getByScreen(small: 195, big: 185),
child: Center(child: Text(context.translate('Loading photo...'),
textAlign: TextAlign.center,
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 26, big: 25)),
)),
),
));
await viewModel.takePicture();
Navigator.pop(context);
},
text: context.translate('Take a picture'),
color: Color(0xFF588EA5),
height: SizeUtils.getByScreen(small: 36, big: 35),
),
)
);
}
}

View File

@@ -0,0 +1,180 @@
// 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: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';
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);
final viewModel = ref.read(remoteConnectionViewModelProvider.notifier);
final viewState = ref.watch(remoteConnectionViewModelProvider);
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: (){showDialog(context: context, builder: (context)=>Dialog(
child: CallDialog(
)
));},
icon: SFIcons.listen,
text: 'Remote listening'
),
],
),
)),
);
}
}
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;
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
)
)
)
],
),
)
);
}
}

View File

@@ -0,0 +1,97 @@
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, RemoteConnectionViewState>(
RemoteConnectionViewModel.new,
);
class RemoteConnectionViewModel extends Notifier<RemoteConnectionViewState> {
late final GetPicturesUseCase _getPicturesUseCase;
late final TakePictureUseCase _takePictureUseCase;
late final TextEditingController phoneController;
// late final UserEntity loggedUser;
static final RegExp _phoneRegex = RegExp(r'^\+?\d{6,15}$');
@override
RemoteConnectionViewState build() {
_getPicturesUseCase = ref.read(getPicturesUseCaseProvider);
_takePictureUseCase = ref.read(takePictureUseCaseProvider);
// loggedUser = ref.read(loggedUserProvider);
phoneController = TextEditingController();
phoneController.addListener(_onPhoneChanged);
_getPicturesUseCase.getPictures(userId: '').then(setImages);
ref.onDispose(disposeControllers);
return const RemoteConnectionViewState();
}
void setImages(List<PictureEntity> pictures) {
state = state.copyWith(
pictures: pictures
);
}
void _onPhoneChanged() {
final text = phoneController.text;
if (text == state.phone) return;
state = state.copyWith(phone: text, errorMessage: '');
}
Future<void> takePicture() async {
try {
state = state.copyWith(isTakingPicture: true);
await _takePictureUseCase.takePicture(userId: '')
.then((picture) {
List<PictureEntity> pictures = state.pictures;
//pictures.add(picture);
state = state.copyWith(
isTakingPicture: true,
);
});
} catch (e){
state = state.copyWith(
isTakingPicture: false,
errorMessage: e.toString(),
);
}
}
Future<void> 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);
phoneController.dispose();
}
}

View File

@@ -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<PictureEntity> pictures,
@Default(true) bool isLoadingImages,
@Default(false) bool isTakingPicture,
@Default(false) bool isCalling,
@Default('') String errorMessage
}) = _RemoteConnectionViewState;
}

View File

@@ -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>(T value) => value;
/// @nodoc
mixin _$RemoteConnectionViewState {
String get phone; List<PictureEntity> 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<RemoteConnectionViewState> get copyWith => _$RemoteConnectionViewStateCopyWithImpl<RemoteConnectionViewState>(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<PictureEntity> 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<PictureEntity>,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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(TResult Function( String phone, List<PictureEntity> 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 extends Object?>(TResult Function( String phone, List<PictureEntity> 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 extends Object?>(TResult? Function( String phone, List<PictureEntity> 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<PictureEntity> pictures = const [], this.isLoadingImages = true, this.isTakingPicture = false, this.isCalling = false, this.errorMessage = ''}): _pictures = pictures;
@override@JsonKey() final String phone;
final List<PictureEntity> _pictures;
@override@JsonKey() List<PictureEntity> 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<PictureEntity> 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<PictureEntity>,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

View File

@@ -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<void> buildPage(BuildContext context, GoRouterState state) {
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
return MaterialPage<void>(
key: state.pageKey,
child: RemoteConnectionScreen(navigationContract: navigationContract),
);
}
}

View File

@@ -0,0 +1,115 @@
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
url_launcher: ^6.3.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

View File

@@ -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)),

View File

@@ -47,11 +47,11 @@ 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(
icon: Icon(Icons.chat_outlined),
icon: Icon(SFIcons.chat),
label: context.translate(I18n.chat),
),
],

View File

@@ -0,0 +1,5 @@
import 'package:legacy_shared/src/data/models/entities/user_entity.dart';
abstract class LegacySharedRemoteDatasource {
Future<UserEntity> getLoggedUser({required String token});
}

View File

@@ -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<UserEntity> getLoggedUser({required String token}) async {
try {
final response = await _repository.get<Map<String, dynamic>>(
'/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;
}

View File

@@ -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;
}

View File

@@ -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>(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<UserEntity> get copyWith => _$UserEntityCopyWithImpl<UserEntity>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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

View File

@@ -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<String, dynamic> 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<String, dynamic> 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 ?? ''
);
}
}

View File

@@ -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>(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<GetLoggedUserResponseModel> get copyWith => _$GetLoggedUserResponseModelCopyWithImpl<GetLoggedUserResponseModel>(this as GetLoggedUserResponseModel, _$identity);
/// Serializes this GetLoggedUserResponseModel to a JSON map.
Map<String, dynamic> 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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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<String, dynamic> 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<String, dynamic> 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<GetLoggedUserItemResponseModel> get copyWith => _$GetLoggedUserItemResponseModelCopyWithImpl<GetLoggedUserItemResponseModel>(this as GetLoggedUserItemResponseModel, _$identity);
/// Serializes this GetLoggedUserItemResponseModel to a JSON map.
Map<String, dynamic> 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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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 extends Object?>(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<String, dynamic> 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<String, dynamic> 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

View File

@@ -0,0 +1,57 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'get_logged_user_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_GetLoggedUserResponseModel _$GetLoggedUserResponseModelFromJson(
Map<String, dynamic> json,
) => _GetLoggedUserResponseModel(
item: GetLoggedUserItemResponseModel.fromJson(
json['item'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$GetLoggedUserResponseModelToJson(
_GetLoggedUserResponseModel instance,
) => <String, dynamic>{'item': instance.item};
_GetLoggedUserItemResponseModel _$GetLoggedUserItemResponseModelFromJson(
Map<String, dynamic> 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<String, dynamic> _$GetLoggedUserItemResponseModelToJson(
_GetLoggedUserItemResponseModel instance,
) => <String, dynamic>{
'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,
};

View File

@@ -0,0 +1,6 @@
import 'package:legacy_shared/src/data/models/entities/user_entity.dart';
abstract class LegacySharedRepository {
Future<UserEntity> getLoggedUser({required String token});
}

View File

@@ -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<UserEntity> getLoggedUser({required String token}) {
return _remote.getLoggedUser(token: token);
}
}

View File

@@ -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<LegacySharedRemoteDatasource>((ref) {
final questiaRepository = getIt<QuestiaRepository>();
return LegacySharedRemoteDatasourceImpl(questiaRepository);
});

View File

@@ -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<LegacySharedRepository>((ref) {
final remote = ref.read(legacySharedRemoteDatasourceProvider);
return LegacySharedRepositoryImpl(remote);
});

View File

@@ -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, UserEntity>(
LoggedUserNotifier.new,
);
class LoggedUserNotifier extends AsyncNotifier<UserEntity> {
late final legacySharedRepository;
@override
FutureOr<UserEntity> build() {
legacySharedRepository = ref.read(legacySharedRepositoryProvider);
return legacySharedRepository.getLoggedUser(token: '');
}
}

View File

@@ -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)),
Expanded(child: body),
?footer
],
)
),
);
}
}

View File

@@ -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

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/// Flutter icons SFIcons
/// Copyright (C) 2025 by original authors @ fluttericon.com, fontello.com
/// Copyright (C) 2026 by original authors @ fluttericon.com, fontello.com
/// This font was generated by FlutterIcon.com, which is derived from Fontello.
///
/// To use this font, place it in your fonts/ directory and include the
@@ -17,310 +17,98 @@
/// License: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
/// Homepage: https://design.google.com/icons/
///
library;
import 'package:flutter/widgets.dart';
import 'package:utils/utils.dart';
class SFIcons {
SFIcons._();
static const _kFontFam = 'SFIcons';
static const _kFontPkg = isTest ? null : 'sf_components_package';
static const String? _kFontPkg = 'design_system';
static const IconData back = IconData(
0xe800,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData euro = IconData(
0xe801,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData location = IconData(
0xe802,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData alert = IconData(
0xe803,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData close = IconData(
0xe804,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData immoSelected = IconData(
0xe805,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData forward = IconData(
0xe806,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData favorite = IconData(
0xe807,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData search = IconData(
0xe808,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData filter = IconData(
0xe809,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData filterList = IconData(
0xe80a,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData finance = IconData(
0xe80b,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData infoOutlined = IconData(
0xe80c,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData arrowLeftAlt = IconData(
0xe80d,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData edit = IconData(
0xe80e,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData cookie = IconData(
0xe80f,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData email = IconData(
0xe810,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData video = IconData(
0xe811,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData phone = IconData(
0xe812,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData chevronRight = IconData(
0xe813,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData checkCircle = IconData(
0xe814,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData lightbulbOn = IconData(
0xe815,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData externalLink = IconData(
0xe816,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData preferences = IconData(
0xe817,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData bank = IconData(
0xe818,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData arrowRightAlt = IconData(
0xe819,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData offline = IconData(
0xe81a,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData cursorClick = IconData(
0xe81b,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData wand = IconData(
0xe81c,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData help = IconData(
0xe81d,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData notifications = IconData(
0xe81e,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData helpOutlined = IconData(
0xe81f,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData contentCopy = IconData(
0xe820,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData apartmentScene = IconData(
0xe821,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData walletAddMoney = IconData(
0xe822,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData walletSubtractMoney = IconData(
0xe823,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData start = IconData(
0xe828,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData immo = IconData(
0xe829,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData star = IconData(
0xe82a,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData startSelected = IconData(
0xe82b,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData infoCircle = IconData(
0xe82c,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData financeSelected = IconData(
0xe82d,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData loginOutlined = IconData(
0xe82f,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData bank1 = IconData(
0xe830,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData gavel = IconData(
0xe831,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData timer = IconData(
0xe832,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData home = IconData(
0xe83a,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData apartment = IconData(
0xe83b,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData radioButtonUncheckedRounded = IconData(
0xe83c,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData radioButtonCheckedRounded = IconData(
0xe83d,
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,
);
static const IconData renovation = IconData(
0xe868,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData rotateLeft = IconData(
0xe835,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData options = IconData(
0xe86f,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData service = IconData(
0xe870,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData question = IconData(
0xe871,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData lightbulbOutline = IconData(
0xe8a8,
fontFamily: _kFontFam,
fontPackage: _kFontPkg,
);
static const IconData back = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData euro = IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData location = IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData alert = IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData close = IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData immoSelected = IconData(0xe805, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData forward = IconData(0xe806, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData favorite = IconData(0xe807, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData search = IconData(0xe808, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData filter = IconData(0xe809, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData filterList = IconData(0xe80a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData finance = IconData(0xe80b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData infoOutlined = IconData(0xe80c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData arrowLeftAlt = IconData(0xe80d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData edit = IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData cookie = IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData email = IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData video = IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData phone = IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData chevronRight = IconData(0xe813, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData checkCircle = IconData(0xe814, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData lightbulbOn = IconData(0xe815, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData externalLink = IconData(0xe816, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData preferences = IconData(0xe817, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData bank = IconData(0xe818, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData arrowRightAlt = IconData(0xe819, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData offline = IconData(0xe81a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData cursorClick = IconData(0xe81b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData wand = IconData(0xe81c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData help = IconData(0xe81d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData notifications = IconData(0xe81e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData helpOutlined = IconData(0xe81f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData contentCopy = IconData(0xe820, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData apartmentScene = IconData(0xe821, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData walletAddMoney = IconData(0xe822, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData walletSubtractMoney = IconData(0xe823, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData google = IconData(0xe824, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData premium = IconData(0xe825, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData savings = IconData(0xe826, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData functions = IconData(0xe827, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData start = IconData(0xe828, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData immo = IconData(0xe829, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData star = IconData(0xe82a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData startSelected = IconData(0xe82b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData infoCircle = IconData(0xe82c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData financeSelected = IconData(0xe82d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData loginOutlined = IconData(0xe82f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData bank1 = IconData(0xe830, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData gavel = IconData(0xe831, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData timer = IconData(0xe832, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData rotateLeft = IconData(0xe835, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData home = IconData(0xe83a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData apartment = IconData(0xe83b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData radioButtonUncheckedRounded = IconData(0xe83c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData radioButtonCheckedRounded = IconData(0xe83d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData payments = IconData(0xe83e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData customerService = IconData(0xe83f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData account = IconData(0xe840, fontFamily: _kFontFam, fontPackage: _kFontPkg);
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 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);
static const IconData renovation = IconData(0xe868, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData options = IconData(0xe86f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData service = IconData(0xe870, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData question = IconData(0xe871, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData connection = IconData(0xe87f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData calendarCircle = IconData(0xe880, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData contactsCircle = IconData(0xe881, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData doNotDisturbCircle = IconData(0xe882, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData locationAreaCircle = IconData(0xe883, fontFamily: _kFontFam, fontPackage: _kFontPkg);
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 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);
static const IconData lightbulbOutline = IconData(0xe8a8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}

View File

@@ -32,6 +32,10 @@ dev_dependencies:
# The following section is specific to Flutter packages.
flutter:
uses-material-design: true
fonts:
- family: SFIcons
fonts:
- asset: fonts/SFIcons.ttf
# To add assets to your package, add an assets section, like this:
# assets:

View File

@@ -25,4 +25,9 @@ class AppRoutes {
static const legacyDashboard = '$legacy/dashboard';
static const dashboardHub = '$legacyDashboard/hub';
static const dashboardFunctions = '$legacyDashboard/functions';
static const contacts = '$dashboardFunctions/contacts';
static const remoteConnection = '$dashboardFunctions/remote_connection';
static const locateDevice = '$dashboardFunctions/locateDevice';
}