diff --git a/apps/mobile_app/lib/navigation/app_router.dart b/apps/mobile_app/lib/navigation/app_router.dart index ef76d5b8..6a3c303e 100644 --- a/apps/mobile_app/lib/navigation/app_router.dart +++ b/apps/mobile_app/lib/navigation/app_router.dart @@ -26,7 +26,7 @@ late final GoRouter appRouter; void configureAppRouter() { appRouter = GoRouter( navigatorKey: rootNavigatorKey, - initialLocation: AppRoutes.splash, + initialLocation: AppRoutes.controlPanel, debugLogDiagnostics: true, routes: [ GoRoute( diff --git a/modules/legacy/modules/device_management/lib/src/core/data/datasources/background_image_remote_datasource.dart b/modules/legacy/modules/device_management/lib/src/core/data/datasources/background_image_remote_datasource.dart new file mode 100644 index 00000000..7a1c6d32 --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/data/datasources/background_image_remote_datasource.dart @@ -0,0 +1,17 @@ +import '../models/get_background_image_response_model.dart'; + +abstract class BackgroundImageRemoteDatasource { + Future getBackgroundImage({ + required String deviceId, + }); + + Future uploadImage({ + required String deviceId, + required String path + }); + + Future setBackgroundImage({ + required String deviceId, + required String fileId + }); +} diff --git a/modules/legacy/modules/device_management/lib/src/core/data/datasources/background_image_remote_datasource_impl.dart b/modules/legacy/modules/device_management/lib/src/core/data/datasources/background_image_remote_datasource_impl.dart new file mode 100644 index 00000000..e4dcee17 --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/data/datasources/background_image_remote_datasource_impl.dart @@ -0,0 +1,61 @@ +import 'package:dio/dio.dart'; +import 'package:legacy_shared/legacy_shared.dart'; +import 'package:sf_infrastructure/configure_dependencies.dart'; + +import '../models/get_background_image_response_model.dart'; +import 'background_image_remote_datasource.dart'; + +class BackgroundImageRemoteDatasourceImpl implements BackgroundImageRemoteDatasource { + BackgroundImageRemoteDatasourceImpl(this._repository); + + final QuestiaRepository _repository; + + @override + Future getBackgroundImage({required String deviceId}) async { + + final response = await safeCall( + () => _repository.get( + '/devices/$deviceId/background-image', + ), + 'Error getting background image', + ); + + final data = response.data; + if (data == null || data.isEmpty) { + throw Exception('Empty response from /auth/totp/secret'); + } + + final model = GetBackgroundImageResponseModel.fromJson(data); + return model; + } + + @override + Future uploadImage({required String deviceId, required String path}) async { + + final formData = FormData.fromMap({ + 'file': await MultipartFile.fromFile(path), + }); + + await safeCall( + () => _repository.post( + '/photos', + body: formData + ), + 'Error creating image', + ); + } + + @override + Future setBackgroundImage({required String deviceId, required String fileId}) async { + + await safeCall( + () => _repository.put( + '/devices/$deviceId/background-image', + body: { + 'photoId': fileId + } + ), + 'Error creating image', + ); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.dart b/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.dart new file mode 100644 index 00000000..2b0ca432 --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.dart @@ -0,0 +1,32 @@ +import 'package:device_management/src/features/remote_connection/domain/entities/picture_entity.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +import 'get_pictures_response_model.dart'; + +part 'get_background_image_response_model.freezed.dart'; +part 'get_background_image_response_model.g.dart'; + +@freezed +abstract class GetBackgroundImageResponseModel with _$GetBackgroundImageResponseModel { + const factory GetBackgroundImageResponseModel({ + required GetPicturesItemResponseModel item, + }) = _GetBackgroundImageResponseModel; + + factory GetBackgroundImageResponseModel.fromJson(Map json) => + _$GetBackgroundImageResponseModelFromJson(json); +} + +extension GetBackgroundImageResponseModelMapper on GetBackgroundImageResponseModel { + PictureEntity toEntity() { + return PictureEntity( + id: item.id, + deviceIdentificator: item.deviceIdentificator, + imgType: item.imgType, + timestamp: item.timestamp, + fileId: item.fileId, + fileName: item.fileName, + contentType: item.contentType, + createdAt: item.createdAt, + ); + } +} diff --git a/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.freezed.dart b/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.freezed.dart new file mode 100644 index 00000000..be65749e --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.freezed.dart @@ -0,0 +1,295 @@ +// 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_background_image_response_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$GetBackgroundImageResponseModel { + + GetPicturesItemResponseModel get item; +/// Create a copy of GetBackgroundImageResponseModel +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$GetBackgroundImageResponseModelCopyWith get copyWith => _$GetBackgroundImageResponseModelCopyWithImpl(this as GetBackgroundImageResponseModel, _$identity); + + /// Serializes this GetBackgroundImageResponseModel to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is GetBackgroundImageResponseModel&&(identical(other.item, item) || other.item == item)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,item); + +@override +String toString() { + return 'GetBackgroundImageResponseModel(item: $item)'; +} + + +} + +/// @nodoc +abstract mixin class $GetBackgroundImageResponseModelCopyWith<$Res> { + factory $GetBackgroundImageResponseModelCopyWith(GetBackgroundImageResponseModel value, $Res Function(GetBackgroundImageResponseModel) _then) = _$GetBackgroundImageResponseModelCopyWithImpl; +@useResult +$Res call({ + GetPicturesItemResponseModel item +}); + + +$GetPicturesItemResponseModelCopyWith<$Res> get item; + +} +/// @nodoc +class _$GetBackgroundImageResponseModelCopyWithImpl<$Res> + implements $GetBackgroundImageResponseModelCopyWith<$Res> { + _$GetBackgroundImageResponseModelCopyWithImpl(this._self, this._then); + + final GetBackgroundImageResponseModel _self; + final $Res Function(GetBackgroundImageResponseModel) _then; + +/// Create a copy of GetBackgroundImageResponseModel +/// 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 GetPicturesItemResponseModel, + )); +} +/// Create a copy of GetBackgroundImageResponseModel +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$GetPicturesItemResponseModelCopyWith<$Res> get item { + + return $GetPicturesItemResponseModelCopyWith<$Res>(_self.item, (value) { + return _then(_self.copyWith(item: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [GetBackgroundImageResponseModel]. +extension GetBackgroundImageResponseModelPatterns on GetBackgroundImageResponseModel { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _GetBackgroundImageResponseModel value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _GetBackgroundImageResponseModel() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _GetBackgroundImageResponseModel value) $default,){ +final _that = this; +switch (_that) { +case _GetBackgroundImageResponseModel(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _GetBackgroundImageResponseModel value)? $default,){ +final _that = this; +switch (_that) { +case _GetBackgroundImageResponseModel() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( GetPicturesItemResponseModel item)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _GetBackgroundImageResponseModel() when $default != null: +return $default(_that.item);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( GetPicturesItemResponseModel item) $default,) {final _that = this; +switch (_that) { +case _GetBackgroundImageResponseModel(): +return $default(_that.item);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( GetPicturesItemResponseModel item)? $default,) {final _that = this; +switch (_that) { +case _GetBackgroundImageResponseModel() when $default != null: +return $default(_that.item);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _GetBackgroundImageResponseModel implements GetBackgroundImageResponseModel { + const _GetBackgroundImageResponseModel({required this.item}); + factory _GetBackgroundImageResponseModel.fromJson(Map json) => _$GetBackgroundImageResponseModelFromJson(json); + +@override final GetPicturesItemResponseModel item; + +/// Create a copy of GetBackgroundImageResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$GetBackgroundImageResponseModelCopyWith<_GetBackgroundImageResponseModel> get copyWith => __$GetBackgroundImageResponseModelCopyWithImpl<_GetBackgroundImageResponseModel>(this, _$identity); + +@override +Map toJson() { + return _$GetBackgroundImageResponseModelToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetBackgroundImageResponseModel&&(identical(other.item, item) || other.item == item)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,item); + +@override +String toString() { + return 'GetBackgroundImageResponseModel(item: $item)'; +} + + +} + +/// @nodoc +abstract mixin class _$GetBackgroundImageResponseModelCopyWith<$Res> implements $GetBackgroundImageResponseModelCopyWith<$Res> { + factory _$GetBackgroundImageResponseModelCopyWith(_GetBackgroundImageResponseModel value, $Res Function(_GetBackgroundImageResponseModel) _then) = __$GetBackgroundImageResponseModelCopyWithImpl; +@override @useResult +$Res call({ + GetPicturesItemResponseModel item +}); + + +@override $GetPicturesItemResponseModelCopyWith<$Res> get item; + +} +/// @nodoc +class __$GetBackgroundImageResponseModelCopyWithImpl<$Res> + implements _$GetBackgroundImageResponseModelCopyWith<$Res> { + __$GetBackgroundImageResponseModelCopyWithImpl(this._self, this._then); + + final _GetBackgroundImageResponseModel _self; + final $Res Function(_GetBackgroundImageResponseModel) _then; + +/// Create a copy of GetBackgroundImageResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? item = null,}) { + return _then(_GetBackgroundImageResponseModel( +item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable +as GetPicturesItemResponseModel, + )); +} + +/// Create a copy of GetBackgroundImageResponseModel +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$GetPicturesItemResponseModelCopyWith<$Res> get item { + + return $GetPicturesItemResponseModelCopyWith<$Res>(_self.item, (value) { + return _then(_self.copyWith(item: value)); + }); +} +} + +// dart format on diff --git a/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.g.dart b/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.g.dart new file mode 100644 index 00000000..9dcef45f --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/data/models/get_background_image_response_model.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'get_background_image_response_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_GetBackgroundImageResponseModel _$GetBackgroundImageResponseModelFromJson( + Map json, +) => _GetBackgroundImageResponseModel( + item: GetPicturesItemResponseModel.fromJson( + json['item'] as Map, + ), +); + +Map _$GetBackgroundImageResponseModelToJson( + _GetBackgroundImageResponseModel instance, +) => {'item': instance.item}; diff --git a/modules/legacy/modules/device_management/lib/src/core/data/repositories/background_image_repository_impl.dart b/modules/legacy/modules/device_management/lib/src/core/data/repositories/background_image_repository_impl.dart new file mode 100644 index 00000000..21f8b8da --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/data/repositories/background_image_repository_impl.dart @@ -0,0 +1,28 @@ + +import 'package:device_management/src/core/data/models/get_background_image_response_model.dart'; + +import '../../../features/remote_connection/domain/entities/picture_entity.dart'; +import '../../domain/repositories/background_image_repository.dart'; +import '../datasources/background_image_remote_datasource.dart'; + +class BackgroundImageRepositoryImpl implements BackgroundImageRepository { + const BackgroundImageRepositoryImpl(this._remote); + + final BackgroundImageRemoteDatasource _remote; + + @override + Future getBackgroundImage({required String deviceId}) async { + final model = await _remote.getBackgroundImage(deviceId: deviceId); + return model.toEntity(); + } + + @override + Future uploadImage({required String deviceId, required String path}) { + return _remote.uploadImage(deviceId: deviceId, path: path); + } + + @override + Future setBackgroundImage({required String deviceId, required String fileId}) { + return _remote.setBackgroundImage(deviceId: deviceId, fileId: fileId); + } +} \ No newline at end of file diff --git a/modules/legacy/modules/device_management/lib/src/core/domain/repositories/background_image_repository.dart b/modules/legacy/modules/device_management/lib/src/core/domain/repositories/background_image_repository.dart new file mode 100644 index 00000000..8ae0e6ac --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/domain/repositories/background_image_repository.dart @@ -0,0 +1,8 @@ + +import 'package:device_management/src/features/remote_connection/domain/entities/picture_entity.dart'; + +abstract class BackgroundImageRepository { + Future getBackgroundImage({required String deviceId}); + Future uploadImage({required String deviceId, required String path}); + Future setBackgroundImage({required String deviceId, required String fileId}); +} diff --git a/modules/legacy/modules/device_management/lib/src/core/providers/background_image_remote_datasource_provider.dart b/modules/legacy/modules/device_management/lib/src/core/providers/background_image_remote_datasource_provider.dart new file mode 100644 index 00000000..ec96e057 --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/providers/background_image_remote_datasource_provider.dart @@ -0,0 +1,11 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:sf_infrastructure/sf_infrastructure.dart'; + +import '../data/datasources/background_image_remote_datasource.dart'; +import '../data/datasources/background_image_remote_datasource_impl.dart'; + +final backgroundImageRemoteDatasourceProvider = +Provider((ref) { + final questiaRepository = getIt(); + return BackgroundImageRemoteDatasourceImpl(questiaRepository); +}); diff --git a/modules/legacy/modules/device_management/lib/src/core/providers/background_image_repository_provider.dart b/modules/legacy/modules/device_management/lib/src/core/providers/background_image_repository_provider.dart new file mode 100644 index 00000000..017606d5 --- /dev/null +++ b/modules/legacy/modules/device_management/lib/src/core/providers/background_image_repository_provider.dart @@ -0,0 +1,11 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../data/repositories/background_image_repository_impl.dart'; +import '../domain/repositories/background_image_repository.dart'; +import 'background_image_remote_datasource_provider.dart'; + +final backgroundImageRepositoryProvider = +Provider((ref) { + final remote = ref.read(backgroundImageRemoteDatasourceProvider); + return BackgroundImageRepositoryImpl(remote); +}); diff --git a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/background_image_screen.dart b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/background_image_screen.dart index 4e2b629f..4ed87bde 100644 --- a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/background_image_screen.dart +++ b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/background_image_screen.dart @@ -121,8 +121,8 @@ class BackgroundImageScreen extends ConsumerWidget { const Icon(Icons.add_photo_alternate_outlined, size: 140, color: Colors.grey), const SizedBox(height: 28), state.isSaving - ? const Text('Pulsa para seleccionar una foto') - : const CircularProgressIndicator() + ? const CircularProgressIndicator() + : const Text('Pulsa para seleccionar una foto') ], ); }, diff --git a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_model.dart b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_model.dart index 122eb7e4..e2d2ad7c 100644 --- a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_model.dart +++ b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_model.dart @@ -3,6 +3,8 @@ import 'package:image_picker/image_picker.dart'; import 'package:legacy_shared/legacy_shared.dart'; import 'package:sf_localizations/sf_localizations.dart'; +import '../../../../core/domain/repositories/background_image_repository.dart'; +import '../../../../core/providers/background_image_repository_provider.dart'; import 'background_image_view_state.dart'; final backgroundImageViewModelProvider = @@ -11,11 +13,11 @@ NotifierProvider.autoDispose ); class BackgroundImageViewModel extends Notifier { - late final CommandsRepository _commandsRepository; + late final BackgroundImageRepository _repository; @override BackgroundImageViewState build() { - _commandsRepository = ref.read(commandsRepositoryProvider); + _repository = ref.read(backgroundImageRepositoryProvider); Future.microtask(_load); return const BackgroundImageViewState(); } @@ -25,8 +27,9 @@ class BackgroundImageViewModel extends Notifier { final device = ref.read(selectedDeviceProvider); if (device == null) return; - // final image = await _repository.getBackgroundImage(deviceId: device.id); - state = state.copyWith(image: '', isLoading: false); + final image = await _repository.getBackgroundImage(deviceId: device.identificator); + + state = state.copyWith(image: image.fileId, isLoading: false); } catch (e) { state = state.copyWith( isLoading: false, @@ -53,13 +56,12 @@ class BackgroundImageViewModel extends Notifier { if (device == null) return; try { - final request = SendCommandRequestModel( - device: device.identificator, - command: DeviceCommand.setBackgroundImage, - data: {}, - ); - await _commandsRepository.send(request: request); + await _repository.uploadImage(deviceId: device.identificator, path: image.path); + + final fileId = ''; + + await _repository.setBackgroundImage(deviceId: device.identificator, fileId: fileId); state = state.copyWith( image: image.path, @@ -67,6 +69,7 @@ class BackgroundImageViewModel extends Notifier { successMessage: I18n.alarmUpdated, ); } catch (e) { + print(e); state = state.copyWith( isSaving: false, errorMessage: formatErrorMessage(e), diff --git a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.dart b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.dart index 95f21244..d9739081 100644 --- a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.dart +++ b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.dart @@ -7,7 +7,7 @@ abstract class BackgroundImageViewState with _$BackgroundImageViewState { const factory BackgroundImageViewState({ @Default('') String image, @Default(true) bool isLoading, - @Default(true) bool isSaving, + @Default(false) bool isSaving, @Default('') String successMessage, @Default('') String errorMessage, }) = _BackgroundImageViewState; diff --git a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.freezed.dart b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.freezed.dart index cced6d94..10296ffb 100644 --- a/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.freezed.dart +++ b/modules/legacy/modules/device_management/lib/src/features/background_image/presentation/state/background_image_view_state.freezed.dart @@ -210,7 +210,7 @@ return $default(_that.image,_that.isLoading,_that.isSaving,_that.successMessage, class _BackgroundImageViewState implements BackgroundImageViewState { - const _BackgroundImageViewState({this.image = '', this.isLoading = false, this.isSaving = true, this.successMessage = '', this.errorMessage = ''}); + const _BackgroundImageViewState({this.image = '', this.isLoading = true, this.isSaving = false, this.successMessage = '', this.errorMessage = ''}); @override@JsonKey() final String image;