diff --git a/README.md b/README.md index d2d55073b..3a3b7f1d7 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ To *update* docker-compose with newest image (if you have started the docker-com docker-compose -f ./docker/docker-compose.yml pull && docker-compose -f ./docker/docker-compose.yml up ``` -The server will be running at `http://your-ip:2283/api` through `Nginx` +The server will be running at `http://your-ip:2283/api` ## Step 3: Register User @@ -225,6 +225,15 @@ make dev # required Makefile installed on the system. All servers and web container are hot reload for quick feedback loop. +## Note for developers +### 1 - OpenAPI +OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). When you add a new or modify an existing endpoint, you must run the generate command below to update the client SDK. + +```bash +npm run api:generate # Run from server directory +``` +You can find the generated client SDK in the [`web/src/api`](web/src/api) for Typescript SDK and [`mobile/openapi`](mobile/openapi) for Dart SDK. + # Support If you like the app, find it helpful, and want to support me to offset the cost of publishing to AppStores, you can sponsor the project with [**Github Sponsor**](https://github.com/sponsors/alextran1502), or a one time donation with the Buy Me a coffee link below. diff --git a/mobile/analysis_options.yaml b/mobile/analysis_options.yaml index ecf2f65ca..b570c2b2e 100644 --- a/mobile/analysis_options.yaml +++ b/mobile/analysis_options.yaml @@ -21,10 +21,18 @@ linter: # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. + rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule use_build_context_synchronously: false + require_trailing_commas: true + unrelated_type_equality_checks: true # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options +analyzer: + exclude: + - openapi/ + - openapi/test/ + - lib/generated_plugin_registrant.dart diff --git a/mobile/assets/i18n/en-US.json b/mobile/assets/i18n/en-US.json index 7d568f60f..4a239b09f 100644 --- a/mobile/assets/i18n/en-US.json +++ b/mobile/assets/i18n/en-US.json @@ -71,6 +71,7 @@ "login_form_label_password": "Password", "login_form_password_hint": "password", "login_form_save_login": "Stay logged in", + "login_form_failed_login": "Error logging you in, check server url, email and password", "monthly_title_text_date_format": "MMMM y", "profile_drawer_client_server_up_to_date": "Client and Server are up-to-date", "profile_drawer_sign_out": "Sign Out", @@ -81,6 +82,7 @@ "search_result_page_new_search_hint": "New Search", "select_additional_user_for_sharing_page_suggestions": "Suggestions", "select_user_for_sharing_page_err_album": "Failed to create album", + "select_user_for_sharing_page_share_suggestions": "Suggestions", "share_add": "Add", "share_add_photos": "Add photos", "share_add_title": "Add a title", @@ -100,4 +102,4 @@ "version_announcement_overlay_text_2": "please take your time to visit the ", "version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.", "version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89" -} \ No newline at end of file +} diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 5e0e51a77..c14f2f39f 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -46,12 +46,15 @@ void main() async { Locale('de', 'DE') ]; - runApp(EasyLocalization( + runApp( + EasyLocalization( supportedLocales: locales, path: 'assets/i18n', useFallbackTranslations: true, fallbackLocale: locales.first, - child: const ProviderScope(child: ImmichApp()))); + child: const ProviderScope(child: ImmichApp()), + ), + ); } class ImmichApp extends ConsumerStatefulWidget { @@ -111,6 +114,7 @@ class ImmichAppState extends ConsumerState @override initState() { super.initState(); + initApp().then((_) => debugPrint("App Init Completed")); } @@ -120,10 +124,9 @@ class ImmichAppState extends ConsumerState super.dispose(); } - final _immichRouter = AppRouter(); - @override Widget build(BuildContext context) { + var router = ref.watch(appRouterProvider); ref.watch(releaseInfoProvider.notifier).checkGithubReleaseInfo(); return MaterialApp( @@ -142,7 +145,8 @@ class ImmichAppState extends ConsumerState primarySwatch: Colors.indigo, fontFamily: 'WorkSans', snackBarTheme: const SnackBarThemeData( - contentTextStyle: TextStyle(fontFamily: 'WorkSans')), + contentTextStyle: TextStyle(fontFamily: 'WorkSans'), + ), scaffoldBackgroundColor: immichBackgroundColor, appBarTheme: const AppBarTheme( backgroundColor: immichBackgroundColor, @@ -152,9 +156,10 @@ class ImmichAppState extends ConsumerState systemOverlayStyle: SystemUiOverlayStyle.dark, ), ), - routeInformationParser: _immichRouter.defaultRouteParser(), - routerDelegate: _immichRouter.delegate( - navigatorObservers: () => [TabNavigationObserver(ref: ref)]), + routeInformationParser: router.defaultRouteParser(), + routerDelegate: router.delegate( + navigatorObservers: () => [TabNavigationObserver(ref: ref)], + ), ), const ImmichLoadingOverlay(), const VersionAnnouncementOverlay(), diff --git a/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart b/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart index a9e12b848..4bed6eb5f 100644 --- a/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart +++ b/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart @@ -3,17 +3,20 @@ import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/asset_viewer/models/image_viewer_page_state.model.dart'; import 'package:immich_mobile/modules/asset_viewer/services/image_viewer.service.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart'; +import 'package:openapi/api.dart'; class ImageViewerStateNotifier extends StateNotifier { - final ImageViewerService _imageViewerService = ImageViewerService(); + final ImageViewerService _imageViewerService; - ImageViewerStateNotifier() - : super(ImageViewerPageState( - downloadAssetStatus: DownloadAssetStatus.idle)); + ImageViewerStateNotifier(this._imageViewerService) + : super( + ImageViewerPageState( + downloadAssetStatus: DownloadAssetStatus.idle, + ), + ); - void downloadAsset(ImmichAsset asset, BuildContext context) async { + void downloadAsset(AssetResponseDto asset, BuildContext context) async { state = state.copyWith(downloadAssetStatus: DownloadAssetStatus.loading); bool isSuccess = await _imageViewerService.downloadAssetToDevice(asset); @@ -43,4 +46,5 @@ class ImageViewerStateNotifier extends StateNotifier { final imageViewerStateProvider = StateNotifierProvider( - ((ref) => ImageViewerStateNotifier())); + ((ref) => ImageViewerStateNotifier(ref.watch(imageViewerServiceProvider))), +); diff --git a/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart b/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart index 9ee9e8a67..771b0873d 100644 --- a/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart +++ b/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart @@ -1,33 +1,35 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; -import 'package:hive_flutter/hive_flutter.dart'; -import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; +import 'package:openapi/api.dart'; import 'package:path/path.dart' as p; -import 'package:http/http.dart' as http; import 'package:photo_manager/photo_manager.dart'; import 'package:path_provider/path_provider.dart'; +final imageViewerServiceProvider = + Provider((ref) => ImageViewerService(ref.watch(apiServiceProvider))); + class ImageViewerService { - Future downloadAssetToDevice(ImmichAsset asset) async { + final ApiService _apiService; + ImageViewerService(this._apiService); + + Future downloadAssetToDevice(AssetResponseDto asset) async { try { String fileName = p.basename(asset.originalPath); - var savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey); - Uri filePath = Uri.parse( - "$savedEndpoint/asset/download?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=false"); - var res = await http.get( - filePath, - headers: { - "Authorization": "Bearer ${Hive.box(userInfoBox).get(accessTokenKey)}" - }, + var res = await _apiService.assetApi.downloadFileWithHttpInfo( + asset.deviceAssetId, + asset.deviceId, + isThumb: false, + isWeb: false, ); final AssetEntity? entity; - if (asset.type == 'IMAGE') { + if (asset.type == AssetTypeEnum.IMAGE) { entity = await PhotoManager.editor.saveImage( res.bodyBytes, title: p.basename(asset.originalPath), diff --git a/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart b/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart index 892ef04c8..952be9448 100644 --- a/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart +++ b/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart @@ -2,13 +2,12 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/shared/models/immich_asset_with_exif.model.dart'; -import 'package:intl/intl.dart'; +import 'package:openapi/api.dart'; import 'package:path/path.dart' as p; import 'package:latlong2/latlong.dart'; class ExifBottomSheet extends ConsumerWidget { - final ImmichAssetWithExif assetDetail; + final AssetResponseDto assetDetail; const ExifBottomSheet({Key? key, required this.assetDetail}) : super(key: key); @@ -26,8 +25,10 @@ class ExifBottomSheet extends ConsumerWidget { ), child: FlutterMap( options: MapOptions( - center: LatLng(assetDetail.exifInfo!.latitude!, - assetDetail.exifInfo!.longitude!), + center: LatLng( + assetDetail.exifInfo?.latitude?.toDouble() ?? 0, + assetDetail.exifInfo?.longitude?.toDouble() ?? 0, + ), zoom: 16.0, ), layers: [ @@ -46,10 +47,13 @@ class ExifBottomSheet extends ConsumerWidget { markers: [ Marker( anchorPos: AnchorPos.align(AnchorAlign.top), - point: LatLng(assetDetail.exifInfo!.latitude!, - assetDetail.exifInfo!.longitude!), + point: LatLng( + assetDetail.exifInfo?.latitude?.toDouble() ?? 0, + assetDetail.exifInfo?.longitude?.toDouble() ?? 0, + ), builder: (ctx) => const Image( - image: AssetImage('assets/location-pin.png')), + image: AssetImage('assets/location-pin.png'), + ), ), ], ), @@ -63,7 +67,10 @@ class ExifBottomSheet extends ConsumerWidget { return Text( "${assetDetail.exifInfo!.city}, ${assetDetail.exifInfo!.state}", style: TextStyle( - fontSize: 12, color: Colors.grey[200], fontWeight: FontWeight.bold), + fontSize: 12, + color: Colors.grey[200], + fontWeight: FontWeight.bold, + ), ); } @@ -74,7 +81,7 @@ class ExifBottomSheet extends ConsumerWidget { if (assetDetail.exifInfo?.dateTimeOriginal != null) Text( DateFormat('date_format'.tr()).format( - DateTime.parse(assetDetail.exifInfo!.dateTimeOriginal!), + assetDetail.exifInfo!.dateTimeOriginal!, ), style: TextStyle( color: Colors.grey[400], @@ -151,7 +158,8 @@ class ExifBottomSheet extends ConsumerWidget { ), subtitle: assetDetail.exifInfo?.exifImageHeight != null ? Text( - "${assetDetail.exifInfo?.exifImageHeight} x ${assetDetail.exifInfo?.exifImageWidth} ${assetDetail.exifInfo?.fileSizeInByte!}B ") + "${assetDetail.exifInfo?.exifImageHeight} x ${assetDetail.exifInfo?.exifImageWidth} ${assetDetail.exifInfo?.fileSizeInByte!}B ", + ) : null, ), if (assetDetail.exifInfo?.make != null) @@ -166,7 +174,8 @@ class ExifBottomSheet extends ConsumerWidget { style: const TextStyle(fontWeight: FontWeight.bold), ), subtitle: Text( - "ƒ/${assetDetail.exifInfo?.fNumber} 1/${(1 / (assetDetail.exifInfo?.exposureTime ?? 1)).toStringAsFixed(0)} ${assetDetail.exifInfo?.focalLength}mm ISO${assetDetail.exifInfo?.iso} "), + "ƒ/${assetDetail.exifInfo?.fNumber} 1/${(1 / (assetDetail.exifInfo?.exposureTime ?? 1)).toStringAsFixed(0)} ${assetDetail.exifInfo?.focalLength}mm ISO${assetDetail.exifInfo?.iso} ", + ), ), ], ), diff --git a/mobile/lib/modules/asset_viewer/ui/remote_photo_view.dart b/mobile/lib/modules/asset_viewer/ui/remote_photo_view.dart index 3a9bce99b..384eae20c 100644 --- a/mobile/lib/modules/asset_viewer/ui/remote_photo_view.dart +++ b/mobile/lib/modules/asset_viewer/ui/remote_photo_view.dart @@ -17,16 +17,20 @@ class _RemotePhotoViewState extends State { bool allowMoving = _status == _RemoteImageStatus.full; return PhotoView( - imageProvider: _imageProvider, - minScale: PhotoViewComputedScale.contained, - maxScale: allowMoving ? 1.0 : PhotoViewComputedScale.contained, - enablePanAlways: true, - scaleStateChangedCallback: _scaleStateChanged, - onScaleEnd: _onScaleListener); + imageProvider: _imageProvider, + minScale: PhotoViewComputedScale.contained, + maxScale: allowMoving ? 1.0 : PhotoViewComputedScale.contained, + enablePanAlways: true, + scaleStateChangedCallback: _scaleStateChanged, + onScaleEnd: _onScaleListener, + ); } - void _onScaleListener(BuildContext context, ScaleEndDetails details, - PhotoViewControllerValue controllerValue) { + void _onScaleListener( + BuildContext context, + ScaleEndDetails details, + PhotoViewControllerValue controllerValue, + ) { // Disable swipe events when zoomed in if (_zoomedIn) return; @@ -42,12 +46,17 @@ class _RemotePhotoViewState extends State { } CachedNetworkImageProvider _authorizedImageProvider(String url) { - return CachedNetworkImageProvider(url, - headers: {"Authorization": widget.authToken}, cacheKey: url); + return CachedNetworkImageProvider( + url, + headers: {"Authorization": widget.authToken}, + cacheKey: url, + ); } void _performStateTransition( - _RemoteImageStatus newStatus, CachedNetworkImageProvider provider) { + _RemoteImageStatus newStatus, + CachedNetworkImageProvider provider, + ) { // Transition to same status is forbidden if (_status == newStatus) return; // Transition full -> thumbnail is forbidden @@ -67,19 +76,22 @@ class _RemotePhotoViewState extends State { _authorizedImageProvider(widget.thumbnailUrl); _imageProvider = thumbnailProvider; - thumbnailProvider - .resolve(const ImageConfiguration()) - .addListener(ImageStreamListener((ImageInfo imageInfo, _) { - _performStateTransition(_RemoteImageStatus.thumbnail, thumbnailProvider); - })); + thumbnailProvider.resolve(const ImageConfiguration()).addListener( + ImageStreamListener((ImageInfo imageInfo, _) { + _performStateTransition( + _RemoteImageStatus.thumbnail, + thumbnailProvider, + ); + }), + ); CachedNetworkImageProvider fullProvider = _authorizedImageProvider(widget.imageUrl); - fullProvider - .resolve(const ImageConfiguration()) - .addListener(ImageStreamListener((ImageInfo imageInfo, _) { - _performStateTransition(_RemoteImageStatus.full, fullProvider); - })); + fullProvider.resolve(const ImageConfiguration()).addListener( + ImageStreamListener((ImageInfo imageInfo, _) { + _performStateTransition(_RemoteImageStatus.full, fullProvider); + }), + ); } @override @@ -90,14 +102,14 @@ class _RemotePhotoViewState extends State { } class RemotePhotoView extends StatefulWidget { - const RemotePhotoView( - {Key? key, - required this.thumbnailUrl, - required this.imageUrl, - required this.authToken, - required this.onSwipeDown, - required this.onSwipeUp}) - : super(key: key); + const RemotePhotoView({ + Key? key, + required this.thumbnailUrl, + required this.imageUrl, + required this.authToken, + required this.onSwipeDown, + required this.onSwipeUp, + }) : super(key: key); final String thumbnailUrl; final String imageUrl; diff --git a/mobile/lib/modules/asset_viewer/ui/top_control_app_bar.dart b/mobile/lib/modules/asset_viewer/ui/top_control_app_bar.dart index 39e8ecf6a..eba66a269 100644 --- a/mobile/lib/modules/asset_viewer/ui/top_control_app_bar.dart +++ b/mobile/lib/modules/asset_viewer/ui/top_control_app_bar.dart @@ -3,17 +3,17 @@ import 'dart:developer'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class TopControlAppBar extends ConsumerWidget with PreferredSizeWidget { - const TopControlAppBar( - {Key? key, - required this.asset, - required this.onMoreInfoPressed, - required this.onDownloadPressed}) - : super(key: key); + const TopControlAppBar({ + Key? key, + required this.asset, + required this.onMoreInfoPressed, + required this.onDownloadPressed, + }) : super(key: key); - final ImmichAsset asset; + final AssetResponseDto asset; final Function onMoreInfoPressed; final Function onDownloadPressed; @@ -54,12 +54,13 @@ class TopControlAppBar extends ConsumerWidget with PreferredSizeWidget { : const Icon(Icons.favorite_border_rounded), ), IconButton( - iconSize: iconSize, - splashRadius: iconSize, - onPressed: () { - onMoreInfoPressed(); - }, - icon: const Icon(Icons.more_horiz_rounded)) + iconSize: iconSize, + splashRadius: iconSize, + onPressed: () { + onMoreInfoPressed(); + }, + icon: const Icon(Icons.more_horiz_rounded), + ) ], ); } diff --git a/mobile/lib/modules/asset_viewer/views/image_viewer_page.dart b/mobile/lib/modules/asset_viewer/views/image_viewer_page.dart index a59fc825c..d88b8a9dc 100644 --- a/mobile/lib/modules/asset_viewer/views/image_viewer_page.dart +++ b/mobile/lib/modules/asset_viewer/views/image_viewer_page.dart @@ -11,17 +11,16 @@ import 'package:immich_mobile/modules/asset_viewer/ui/exif_bottom_sheet.dart'; import 'package:immich_mobile/modules/asset_viewer/ui/remote_photo_view.dart'; import 'package:immich_mobile/modules/asset_viewer/ui/top_control_app_bar.dart'; import 'package:immich_mobile/modules/home/services/asset.service.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset_with_exif.model.dart'; +import 'package:openapi/api.dart'; // ignore: must_be_immutable class ImageViewerPage extends HookConsumerWidget { final String imageUrl; final String heroTag; final String thumbnailUrl; - final ImmichAsset asset; + final AssetResponseDto asset; - ImmichAssetWithExif? assetDetail; + AssetResponseDto? assetDetail; ImageViewerPage({ Key? key, @@ -54,10 +53,13 @@ class ImageViewerPage extends HookConsumerWidget { ); } - useEffect(() { - getAssetExif(); - return null; - }, []); + useEffect( + () { + getAssetExif(); + return null; + }, + [], + ); return Scaffold( backgroundColor: Colors.black, @@ -75,14 +77,15 @@ class ImageViewerPage extends HookConsumerWidget { children: [ Center( child: Hero( - tag: heroTag, - child: RemotePhotoView( - thumbnailUrl: thumbnailUrl, - imageUrl: imageUrl, - authToken: "Bearer ${box.get(accessTokenKey)}", - onSwipeDown: () => AutoRouter.of(context).pop(), - onSwipeUp: () => showInfo(), - )), + tag: heroTag, + child: RemotePhotoView( + thumbnailUrl: thumbnailUrl, + imageUrl: imageUrl, + authToken: "Bearer ${box.get(accessTokenKey)}", + onSwipeDown: () => AutoRouter.of(context).pop(), + onSwipeUp: () => showInfo(), + ), + ), ), if (downloadAssetStatus == DownloadAssetStatus.loading) const Center( diff --git a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart index 99be903dc..4a2e4908e 100644 --- a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart +++ b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart @@ -12,15 +12,14 @@ import 'package:immich_mobile/modules/asset_viewer/ui/download_loading_indicator import 'package:immich_mobile/modules/asset_viewer/ui/exif_bottom_sheet.dart'; import 'package:immich_mobile/modules/asset_viewer/ui/top_control_app_bar.dart'; import 'package:immich_mobile/modules/home/services/asset.service.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset_with_exif.model.dart'; +import 'package:openapi/api.dart'; import 'package:video_player/video_player.dart'; // ignore: must_be_immutable class VideoViewerPage extends HookConsumerWidget { final String videoUrl; - final ImmichAsset asset; - ImmichAssetWithExif? assetDetail; + final AssetResponseDto asset; + AssetResponseDto? assetDetail; VideoViewerPage({Key? key, required this.videoUrl, required this.asset}) : super(key: key); @@ -49,10 +48,13 @@ class VideoViewerPage extends HookConsumerWidget { await ref.watch(assetServiceProvider).getAssetById(asset.id); } - useEffect(() { - getAssetExif(); - return null; - }, []); + useEffect( + () { + getAssetExif(); + return null; + }, + [], + ); return Scaffold( backgroundColor: Colors.black, @@ -116,8 +118,10 @@ class _VideoThumbnailPlayerState extends State { Future initializePlayer() async { try { - videoPlayerController = VideoPlayerController.network(widget.url, - httpHeaders: {"Authorization": "Bearer ${widget.jwtToken}"}); + videoPlayerController = VideoPlayerController.network( + widget.url, + httpHeaders: {"Authorization": "Bearer ${widget.jwtToken}"}, + ); await videoPlayerController.initialize(); _createChewieController(); diff --git a/mobile/lib/modules/backup/models/backup_state.model.dart b/mobile/lib/modules/backup/models/backup_state.model.dart index c3c66f08c..8f41b0200 100644 --- a/mobile/lib/modules/backup/models/backup_state.model.dart +++ b/mobile/lib/modules/backup/models/backup_state.model.dart @@ -1,10 +1,10 @@ import 'package:cancellation_token_http/http.dart'; import 'package:collection/collection.dart'; +import 'package:openapi/api.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:immich_mobile/modules/backup/models/available_album.model.dart'; import 'package:immich_mobile/modules/backup/models/current_upload_asset.model.dart'; -import 'package:immich_mobile/shared/models/server_info.model.dart'; enum BackUpProgressEnum { idle, inProgress, done } @@ -14,7 +14,7 @@ class BackUpState { final List allAssetsInDatabase; final double progressInPercentage; final CancellationToken cancelToken; - final ServerInfo serverInfo; + final ServerInfoResponseDto serverInfo; /// All available albums on the device final List availableAlbums; @@ -49,7 +49,7 @@ class BackUpState { List? allAssetsInDatabase, double? progressInPercentage, CancellationToken? cancelToken, - ServerInfo? serverInfo, + ServerInfoResponseDto? serverInfo, List? availableAlbums, Set? selectedBackupAlbums, Set? excludedBackupAlbums, @@ -93,8 +93,10 @@ class BackUpState { collectionEquals(other.selectedBackupAlbums, selectedBackupAlbums) && collectionEquals(other.excludedBackupAlbums, excludedBackupAlbums) && collectionEquals(other.allUniqueAssets, allUniqueAssets) && - collectionEquals(other.selectedAlbumsBackupAssetsIds, - selectedAlbumsBackupAssetsIds) && + collectionEquals( + other.selectedAlbumsBackupAssetsIds, + selectedAlbumsBackupAssetsIds, + ) && other.currentUploadAsset == currentUploadAsset; } diff --git a/mobile/lib/modules/backup/models/check_duplicate_asset_response.model.dart b/mobile/lib/modules/backup/models/check_duplicate_asset_response.model.dart deleted file mode 100644 index 2fc30ea61..000000000 --- a/mobile/lib/modules/backup/models/check_duplicate_asset_response.model.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'dart:convert'; - -class CheckDuplicateAssetResponse { - final bool isExist; - CheckDuplicateAssetResponse({ - required this.isExist, - }); - - CheckDuplicateAssetResponse copyWith({ - bool? isExist, - }) { - return CheckDuplicateAssetResponse( - isExist: isExist ?? this.isExist, - ); - } - - Map toMap() { - final result = {}; - - result.addAll({'isExist': isExist}); - - return result; - } - - factory CheckDuplicateAssetResponse.fromMap(Map map) { - return CheckDuplicateAssetResponse( - isExist: map['isExist'] ?? false, - ); - } - - String toJson() => json.encode(toMap()); - - factory CheckDuplicateAssetResponse.fromJson(String source) => - CheckDuplicateAssetResponse.fromMap(json.decode(source)); - - @override - String toString() => 'CheckDuplicateAssetResponse(isExist: $isExist)'; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is CheckDuplicateAssetResponse && other.isExist == isExist; - } - - @override - int get hashCode => isExist.hashCode; -} diff --git a/mobile/lib/modules/backup/providers/backup.provider.dart b/mobile/lib/modules/backup/providers/backup.provider.dart index 2f6970f55..e71a8dbfd 100644 --- a/mobile/lib/modules/backup/providers/backup.provider.dart +++ b/mobile/lib/modules/backup/providers/backup.provider.dart @@ -12,8 +12,8 @@ import 'package:immich_mobile/modules/backup/providers/error_backup_list.provide import 'package:immich_mobile/modules/backup/services/backup.service.dart'; import 'package:immich_mobile/modules/login/models/authentication_state.model.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; -import 'package:immich_mobile/shared/models/server_info.model.dart'; import 'package:immich_mobile/shared/services/server_info.service.dart'; +import 'package:openapi/api.dart'; import 'package:photo_manager/photo_manager.dart'; class BackupNotifier extends StateNotifier { @@ -28,12 +28,12 @@ class BackupNotifier extends StateNotifier { allAssetsInDatabase: const [], progressInPercentage: 0, cancelToken: CancellationToken(), - serverInfo: ServerInfo( + serverInfo: ServerInfoResponseDto( diskAvailable: "0", diskAvailableRaw: 0, diskSize: "0", diskSizeRaw: 0, - diskUsagePercentage: 0.0, + diskUsagePercentage: 0, diskUse: "0", diskUseRaw: 0, ), @@ -113,7 +113,9 @@ class BackupNotifier extends StateNotifier { // Get all albums on the device List availableAlbums = []; List albums = await PhotoManager.getAssetPathList( - hasAll: true, type: RequestType.common); + hasAll: true, + type: RequestType.common, + ); for (AssetPathEntity album in albums) { AvailableAlbum availableAlbum = AvailableAlbum(albumEntity: album); @@ -156,7 +158,10 @@ class BackupNotifier extends StateNotifier { // Get album that contains all assets var list = await PhotoManager.getAssetPathList( - hasAll: true, onlyAll: true, type: RequestType.common); + hasAll: true, + onlyAll: true, + type: RequestType.common, + ); AssetPathEntity albumHasAllAssets = list.first; backupAlbumInfoBox.put( @@ -175,13 +180,15 @@ class BackupNotifier extends StateNotifier { for (var selectedAlbumId in backupAlbumInfo!.selectedAlbumIds) { var albumAsset = await AssetPathEntity.fromId(selectedAlbumId); state = state.copyWith( - selectedBackupAlbums: {...state.selectedBackupAlbums, albumAsset}); + selectedBackupAlbums: {...state.selectedBackupAlbums, albumAsset}, + ); } for (var excludedAlbumId in backupAlbumInfo.excludedAlbumsIds) { var albumAsset = await AssetPathEntity.fromId(excludedAlbumId); state = state.copyWith( - excludedBackupAlbums: {...state.excludedBackupAlbums, albumAsset}); + excludedBackupAlbums: {...state.excludedBackupAlbums, albumAsset}, + ); } } catch (e) { debugPrint("[ERROR] Failed to generate album from id $e"); @@ -211,8 +218,11 @@ class BackupNotifier extends StateNotifier { Set allUniqueAssets = assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums); - List allAssetsInDatabase = - await _backupService.getDeviceBackupAsset(); + var allAssetsInDatabase = await _backupService.getDeviceBackupAsset(); + + if (allAssetsInDatabase == null) { + return; + } // Find asset that were backup from selected albums Set selectedAlbumsBackupAssets = @@ -328,23 +338,27 @@ class BackupNotifier extends StateNotifier { void cancelBackup() { state.cancelToken.cancel(); state = state.copyWith( - backupProgress: BackUpProgressEnum.idle, progressInPercentage: 0.0); + backupProgress: BackUpProgressEnum.idle, + progressInPercentage: 0.0, + ); } void _onAssetUploaded(String deviceAssetId, String deviceId) { - state = state.copyWith(selectedAlbumsBackupAssetsIds: { - ...state.selectedAlbumsBackupAssetsIds, - deviceAssetId - }, allAssetsInDatabase: [ - ...state.allAssetsInDatabase, - deviceAssetId - ]); + state = state.copyWith( + selectedAlbumsBackupAssetsIds: { + ...state.selectedAlbumsBackupAssetsIds, + deviceAssetId + }, + allAssetsInDatabase: [...state.allAssetsInDatabase, deviceAssetId], + ); if (state.allUniqueAssets.length - state.selectedAlbumsBackupAssetsIds.length == 0) { state = state.copyWith( - backupProgress: BackUpProgressEnum.done, progressInPercentage: 0.0); + backupProgress: BackUpProgressEnum.done, + progressInPercentage: 0.0, + ); } _updateServerInfo(); @@ -352,24 +366,19 @@ class BackupNotifier extends StateNotifier { void _onUploadProgress(int sent, int total) { state = state.copyWith( - progressInPercentage: (sent.toDouble() / total.toDouble() * 100)); + progressInPercentage: (sent.toDouble() / total.toDouble() * 100), + ); } Future _updateServerInfo() async { var serverInfo = await _serverInfoService.getServerInfo(); // Update server info - state = state.copyWith( - serverInfo: ServerInfo( - diskSize: serverInfo.diskSize, - diskUse: serverInfo.diskUse, - diskAvailable: serverInfo.diskAvailable, - diskSizeRaw: serverInfo.diskSizeRaw, - diskUseRaw: serverInfo.diskUseRaw, - diskAvailableRaw: serverInfo.diskAvailableRaw, - diskUsagePercentage: serverInfo.diskUsagePercentage, - ), - ); + if (serverInfo != null) { + state = state.copyWith( + serverInfo: serverInfo, + ); + } } void resumeBackup() { diff --git a/mobile/lib/modules/backup/services/backup.service.dart b/mobile/lib/modules/backup/services/backup.service.dart index c1b1576ab..59696028f 100644 --- a/mobile/lib/modules/backup/services/backup.service.dart +++ b/mobile/lib/modules/backup/services/backup.service.dart @@ -2,59 +2,38 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/modules/backup/models/check_duplicate_asset_response.model.dart'; import 'package:immich_mobile/modules/backup/models/current_upload_asset.model.dart'; import 'package:immich_mobile/modules/backup/models/error_upload_asset.model.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; -import 'package:immich_mobile/shared/models/device_info.model.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; import 'package:immich_mobile/utils/files_helper.dart'; +import 'package:openapi/api.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:http_parser/http_parser.dart'; import 'package:path/path.dart' as p; import 'package:cancellation_token_http/http.dart' as http; -final backupServiceProvider = - Provider((ref) => BackupService(ref.watch(networkServiceProvider))); +final backupServiceProvider = Provider( + (ref) => BackupService( + ref.watch(apiServiceProvider), + ), +); class BackupService { - final NetworkService _networkService; + final ApiService _apiService; + BackupService(this._apiService); - BackupService(this._networkService); - - Future> getDeviceBackupAsset() async { - String deviceId = Hive.box(userInfoBox).get(deviceIdKey); - - Response response = - await _networkService.getRequest(url: "asset/$deviceId"); - List result = jsonDecode(response.toString()); - - return result.cast(); - } - - Future checkDuplicateAsset(String deviceAssetId) async { + Future?> getDeviceBackupAsset() async { String deviceId = Hive.box(userInfoBox).get(deviceIdKey); try { - Response response = - await _networkService.postRequest(url: "asset/check", data: { - "deviceId": deviceId, - "deviceAssetId": deviceAssetId, - }); - - if (response.statusCode == 200) { - var result = CheckDuplicateAssetResponse.fromJson(response.toString()); - - return result.isExist; - } else { - return false; - } + return await _apiService.assetApi.getUserAssetsByDeviceId(deviceId); } catch (e) { - return false; + debugPrint('Error [getDeviceBackupAsset] ${e.toString()}'); + return null; } } @@ -99,9 +78,11 @@ class BackupService { var box = Hive.box(userInfoBox); var req = MultipartRequest( - 'POST', Uri.parse('$savedEndpoint/asset/upload'), - onProgress: ((bytes, totalBytes) => - uploadProgressCb(bytes, totalBytes))); + 'POST', + Uri.parse('$savedEndpoint/asset/upload'), + onProgress: ((bytes, totalBytes) => + uploadProgressCb(bytes, totalBytes)), + ); req.headers["Authorization"] = "Bearer ${box.get(accessTokenKey)}"; req.fields['deviceAssetId'] = entity.id; @@ -133,16 +114,19 @@ class BackupService { var error = jsonDecode(data); debugPrint( - "Error(${error['statusCode']}) uploading ${entity.id} | $originalFileName | Created on ${entity.createDateTime} | ${error['error']}"); + "Error(${error['statusCode']}) uploading ${entity.id} | $originalFileName | Created on ${entity.createDateTime} | ${error['error']}", + ); - errorCb(ErrorUploadAsset( - asset: entity, - id: entity.id, - createdAt: entity.createDateTime, - fileName: originalFileName, - fileType: _getAssetType(entity.type), - errorMessage: error['error'], - )); + errorCb( + ErrorUploadAsset( + asset: entity, + id: entity.id, + createdAt: entity.createDateTime, + fileName: originalFileName, + fileType: _getAssetType(entity.type), + errorMessage: error['error'], + ), + ); continue; } } @@ -160,8 +144,6 @@ class BackupService { } } - void sendBackupRequest(AssetEntity entity) {} - String _getAssetType(AssetType assetType) { switch (assetType) { case AssetType.audio: @@ -175,15 +157,29 @@ class BackupService { } } - Future setAutoBackup( - bool status, String deviceId, String deviceType) async { - var res = await _networkService.patchRequest(url: 'device-info', data: { - "isAutoBackup": status, - "deviceId": deviceId, - "deviceType": deviceType, - }); + Future setAutoBackup( + bool status, + String deviceId, + DeviceTypeEnum deviceType, + ) async { + try { + var updatedDeviceInfo = await _apiService.deviceInfoApi.updateDeviceInfo( + UpdateDeviceInfoDto( + deviceId: deviceId, + deviceType: deviceType, + isAutoBackup: status, + ), + ); - return DeviceInfoRemote.fromJson(res.toString()); + if (updatedDeviceInfo == null) { + throw Exception("Error updating device info"); + } + + return updatedDeviceInfo; + } catch (e) { + debugPrint("Error setAutoBackup: ${e.toString()}"); + throw Error(); + } } } diff --git a/mobile/lib/modules/backup/ui/album_info_card.dart b/mobile/lib/modules/backup/ui/album_info_card.dart index 90a1e8976..370db0c3b 100644 --- a/mobile/lib/modules/backup/ui/album_info_card.dart +++ b/mobile/lib/modules/backup/ui/album_info_card.dart @@ -26,7 +26,9 @@ class AlbumInfoCard extends HookConsumerWidget { ref.watch(backupProvider).excludedBackupAlbums.contains(albumInfo); ColorFilter selectedFilter = ColorFilter.mode( - Theme.of(context).primaryColor.withAlpha(100), BlendMode.darken); + Theme.of(context).primaryColor.withAlpha(100), + BlendMode.darken, + ); ColorFilter excludedFilter = ColorFilter.mode(Colors.red.withAlpha(75), BlendMode.darken); ColorFilter unselectedFilter = @@ -40,7 +42,10 @@ class AlbumInfoCard extends HookConsumerWidget { label: const Text( "album_info_card_backup_album_included", style: TextStyle( - fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.bold, + ), ).tr(), backgroundColor: Theme.of(context).primaryColor, ); @@ -51,7 +56,10 @@ class AlbumInfoCard extends HookConsumerWidget { label: const Text( "album_info_card_backup_album_excluded", style: TextStyle( - fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.bold, + ), ).tr(), backgroundColor: Colors.red[300], ); @@ -138,15 +146,16 @@ class AlbumInfoCard extends HookConsumerWidget { height: 200, decoration: BoxDecoration( borderRadius: const BorderRadius.only( - topLeft: Radius.circular(12), - topRight: Radius.circular(12)), + topLeft: Radius.circular(12), + topRight: Radius.circular(12), + ), image: DecorationImage( colorFilter: _buildImageFilter(), image: imageData != null ? MemoryImage(imageData!) : const AssetImage( - 'assets/immich-logo-no-outline.png') - as ImageProvider, + 'assets/immich-logo-no-outline.png', + ) as ImageProvider, fit: BoxFit.cover, ), ), @@ -174,9 +183,10 @@ class AlbumInfoCard extends HookConsumerWidget { Text( albumInfo.name, style: TextStyle( - fontSize: 14, - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.bold), + fontSize: 14, + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, + ), ), Padding( padding: const EdgeInsets.only(top: 2.0), @@ -186,7 +196,9 @@ class AlbumInfoCard extends HookConsumerWidget { ? " (${'backup_all'.tr()})" : ""), style: TextStyle( - fontSize: 12, color: Colors.grey[600]), + fontSize: 12, + color: Colors.grey[600], + ), ), ) ], diff --git a/mobile/lib/modules/backup/ui/backup_info_card.dart b/mobile/lib/modules/backup/ui/backup_info_card.dart index 300fa1feb..6bc832a5d 100644 --- a/mobile/lib/modules/backup/ui/backup_info_card.dart +++ b/mobile/lib/modules/backup/ui/backup_info_card.dart @@ -5,12 +5,12 @@ class BackupInfoCard extends StatelessWidget { final String title; final String subtitle; final String info; - const BackupInfoCard( - {Key? key, - required this.title, - required this.subtitle, - required this.info}) - : super(key: key); + const BackupInfoCard({ + Key? key, + required this.title, + required this.subtitle, + required this.info, + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/mobile/lib/modules/backup/views/album_preview_page.dart b/mobile/lib/modules/backup/views/album_preview_page.dart index 561d177b7..2266fe8bc 100644 --- a/mobile/lib/modules/backup/views/album_preview_page.dart +++ b/mobile/lib/modules/backup/views/album_preview_page.dart @@ -20,10 +20,13 @@ class AlbumPreviewPage extends HookConsumerWidget { await album.getAssetListRange(start: 0, end: album.assetCount); } - useEffect(() { - _getAssetsInAlbum(); - return null; - }, []); + useEffect( + () { + _getAssetsInAlbum(); + return null; + }, + [], + ); return Scaffold( appBar: AppBar( @@ -39,9 +42,10 @@ class AlbumPreviewPage extends HookConsumerWidget { child: Text( "ID ${album.id}", style: TextStyle( - fontSize: 10, - color: Colors.grey[600], - fontWeight: FontWeight.bold), + fontSize: 10, + color: Colors.grey[600], + fontWeight: FontWeight.bold, + ), ), ), ], @@ -59,9 +63,11 @@ class AlbumPreviewPage extends HookConsumerWidget { ), itemCount: assets.value.length, itemBuilder: (context, index) { - Future thumbData = assets.value[index] - .thumbnailDataWithSize(const ThumbnailSize(200, 200), - quality: 50); + Future thumbData = + assets.value[index].thumbnailDataWithSize( + const ThumbnailSize(200, 200), + quality: 50, + ); return FutureBuilder( future: thumbData, diff --git a/mobile/lib/modules/backup/views/backup_album_selection_page.dart b/mobile/lib/modules/backup/views/backup_album_selection_page.dart index 27cf55684..50a5be853 100644 --- a/mobile/lib/modules/backup/views/backup_album_selection_page.dart +++ b/mobile/lib/modules/backup/views/backup_album_selection_page.dart @@ -17,10 +17,13 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { final selectedBackupAlbums = ref.watch(backupProvider).selectedBackupAlbums; final excludedBackupAlbums = ref.watch(backupProvider).excludedBackupAlbums; - useEffect(() { - ref.read(backupProvider.notifier).getBackupInfo(); - return null; - }, []); + useEffect( + () { + ref.read(backupProvider.notifier).getBackupInfo(); + return null; + }, + [], + ); _buildAlbumSelectionList() { if (availableAlbums.isEmpty) { @@ -42,8 +45,9 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { ? const EdgeInsets.only(left: 16.00) : const EdgeInsets.all(0), child: AlbumInfoCard( - imageData: thumbnailData, - albumInfo: availableAlbums[index].albumEntity), + imageData: thumbnailData, + albumInfo: availableAlbums[index].albumEntity, + ), ); }), ), @@ -73,13 +77,15 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { child: Chip( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5)), + borderRadius: BorderRadius.circular(5), + ), label: Text( album.name, style: const TextStyle( - fontSize: 10, - color: Colors.white, - fontWeight: FontWeight.bold), + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.bold, + ), ), backgroundColor: Theme.of(context).primaryColor, deleteIconColor: Colors.white, @@ -109,13 +115,15 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { child: Chip( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5)), + borderRadius: BorderRadius.circular(5), + ), label: Text( album.name, style: const TextStyle( - fontSize: 10, - color: Colors.white, - fontWeight: FontWeight.bold), + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.bold, + ), ), backgroundColor: Colors.red[300], deleteIconColor: Colors.white, @@ -185,9 +193,10 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { title: Text( "backup_album_selection_page_total_assets", style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: Colors.grey[700]), + fontWeight: FontWeight.bold, + fontSize: 14, + color: Colors.grey[700], + ), ).tr(), trailing: Text( ref @@ -234,7 +243,8 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { builder: (BuildContext context) { return AlertDialog( shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12)), + borderRadius: BorderRadius.circular(12), + ), elevation: 5, title: Text( 'backup_album_selection_page_selection_info', @@ -250,7 +260,9 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { Text( 'backup_album_selection_page_assets_scatter', style: TextStyle( - fontSize: 14, color: Colors.grey[700]), + fontSize: 14, + color: Colors.grey[700], + ), ).tr(), ], ), diff --git a/mobile/lib/modules/backup/views/backup_controller_page.dart b/mobile/lib/modules/backup/views/backup_controller_page.dart index a778e986d..65377b853 100644 --- a/mobile/lib/modules/backup/views/backup_controller_page.dart +++ b/mobile/lib/modules/backup/views/backup_controller_page.dart @@ -11,7 +11,6 @@ import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/providers/websocket.provider.dart'; import 'package:immich_mobile/modules/backup/ui/backup_info_card.dart'; -import 'package:intl/intl.dart'; import 'package:percent_indicator/linear_percent_indicator.dart'; class BackupControllerPage extends HookConsumerWidget { @@ -27,16 +26,19 @@ class BackupControllerPage extends HookConsumerWidget { ? false : true; - useEffect(() { - if (backupState.backupProgress != BackUpProgressEnum.inProgress) { - ref.watch(backupProvider.notifier).getBackupInfo(); - } + useEffect( + () { + if (backupState.backupProgress != BackUpProgressEnum.inProgress) { + ref.watch(backupProvider.notifier).getBackupInfo(); + } - ref - .watch(websocketProvider.notifier) - .stopListenToEvent('on_upload_success'); - return null; - }, []); + ref + .watch(websocketProvider.notifier) + .stopListenToEvent('on_upload_success'); + return null; + }, + [], + ); Widget _buildStorageInformation() { return ListTile( @@ -68,10 +70,11 @@ class BackupControllerPage extends HookConsumerWidget { Padding( padding: const EdgeInsets.only(top: 12.0), child: const Text('backup_controller_page_storage_format').tr( - args: [ - backupState.serverInfo.diskUse, - backupState.serverInfo.diskSize - ]), + args: [ + backupState.serverInfo.diskUse, + backupState.serverInfo.diskSize + ], + ), ), ], ), @@ -129,8 +132,10 @@ class BackupControllerPage extends HookConsumerWidget { .setAutoBackup(true); } }, - child: Text(backupBtnText, - style: const TextStyle(fontWeight: FontWeight.bold)), + child: Text( + backupBtnText, + style: const TextStyle(fontWeight: FontWeight.bold), + ), ), ) ], @@ -157,9 +162,10 @@ class BackupControllerPage extends HookConsumerWidget { child: Text( text.trim().substring(0, text.length - 2), style: TextStyle( - color: Theme.of(context).primaryColor, - fontSize: 12, - fontWeight: FontWeight.bold), + color: Theme.of(context).primaryColor, + fontSize: 12, + fontWeight: FontWeight.bold, + ), ), ); } else { @@ -168,9 +174,10 @@ class BackupControllerPage extends HookConsumerWidget { child: Text( "backup_controller_page_none_selected".tr(), style: TextStyle( - color: Theme.of(context).primaryColor, - fontSize: 12, - fontWeight: FontWeight.bold), + color: Theme.of(context).primaryColor, + fontSize: 12, + fontWeight: FontWeight.bold, + ), ), ); } @@ -190,9 +197,10 @@ class BackupControllerPage extends HookConsumerWidget { child: Text( text.trim().substring(0, text.length - 2), style: TextStyle( - color: Colors.red[300], - fontSize: 12, - fontWeight: FontWeight.bold), + color: Colors.red[300], + fontSize: 12, + fontWeight: FontWeight.bold, + ), ), ); } else { @@ -213,9 +221,10 @@ class BackupControllerPage extends HookConsumerWidget { borderOnForeground: false, child: ListTile( minVerticalPadding: 15, - title: const Text("backup_controller_page_albums", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)) - .tr(), + title: const Text( + "backup_controller_page_albums", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20), + ).tr(), subtitle: Padding( padding: const EdgeInsets.only(top: 8.0), child: Column( @@ -284,9 +293,9 @@ class BackupControllerPage extends HookConsumerWidget { fontWeight: FontWeight.bold, fontSize: 11, ), - ).tr(args: [ - ref.watch(errorBackupListProvider).length.toString() - ]), + ).tr( + args: [ref.watch(errorBackupListProvider).length.toString()], + ), backgroundColor: Colors.white, onPressed: () { AutoRouter.of(context).push(const FailedBackupStatusRoute()); @@ -331,12 +340,16 @@ class BackupControllerPage extends HookConsumerWidget { child: const Text( 'backup_controller_page_filename', style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 10.0), - ).tr(args: [ - backupState.currentUploadAsset.fileName, - backupState.currentUploadAsset.fileType - .toLowerCase() - ]), + fontWeight: FontWeight.bold, + fontSize: 10.0, + ), + ).tr( + args: [ + backupState.currentUploadAsset.fileName, + backupState.currentUploadAsset.fileType + .toLowerCase() + ], + ), ), ), ], @@ -352,16 +365,20 @@ class BackupControllerPage extends HookConsumerWidget { padding: const EdgeInsets.all(6.0), child: const Text( "backup_controller_page_created", - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 10.0), - ).tr(args: [ - DateFormat.yMMMMd('en_US').format( - DateTime.parse( - backupState.currentUploadAsset.createdAt - .toString(), - ), - ) - ]), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 10.0, + ), + ).tr( + args: [ + DateFormat.yMMMMd('en_US').format( + DateTime.parse( + backupState.currentUploadAsset.createdAt + .toString(), + ), + ) + ], + ), ), ), ], @@ -406,14 +423,15 @@ class BackupControllerPage extends HookConsumerWidget { style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ).tr(), leading: IconButton( - onPressed: () { - ref.watch(websocketProvider.notifier).listenUploadEvent(); - AutoRouter.of(context).pop(true); - }, - splashRadius: 24, - icon: const Icon( - Icons.arrow_back_ios_rounded, - )), + onPressed: () { + ref.watch(websocketProvider.notifier).listenUploadEvent(); + AutoRouter.of(context).pop(true); + }, + splashRadius: 24, + icon: const Icon( + Icons.arrow_back_ios_rounded, + ), + ), ), body: Padding( padding: const EdgeInsets.only(left: 16.0, right: 16, bottom: 32), diff --git a/mobile/lib/modules/backup/views/failed_backup_status_page.dart b/mobile/lib/modules/backup/views/failed_backup_status_page.dart index 203ea0fad..c78592fa2 100644 --- a/mobile/lib/modules/backup/views/failed_backup_status_page.dart +++ b/mobile/lib/modules/backup/views/failed_backup_status_page.dart @@ -19,13 +19,14 @@ class FailedBackupStatusPage extends HookConsumerWidget { style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), leading: IconButton( - onPressed: () { - AutoRouter.of(context).pop(true); - }, - splashRadius: 24, - icon: const Icon( - Icons.arrow_back_ios_rounded, - )), + onPressed: () { + AutoRouter.of(context).pop(true); + }, + splashRadius: 24, + icon: const Icon( + Icons.arrow_back_ios_rounded, + ), + ), ), body: ListView.builder( shrinkWrap: true, @@ -92,9 +93,10 @@ class FailedBackupStatusPage extends HookConsumerWidget { ), ), style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Colors.grey[700]), + fontSize: 12, + fontWeight: FontWeight.w600, + color: Colors.grey[700], + ), ), Icon( Icons.error, diff --git a/mobile/lib/modules/home/models/delete_asset_response.model.dart b/mobile/lib/modules/home/models/delete_asset_response.model.dart deleted file mode 100644 index 6e9105941..000000000 --- a/mobile/lib/modules/home/models/delete_asset_response.model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'dart:convert'; - -class DeleteAssetResponse { - final String id; - final String status; - - DeleteAssetResponse({ - required this.id, - required this.status, - }); - - DeleteAssetResponse copyWith({ - String? id, - String? status, - }) { - return DeleteAssetResponse( - id: id ?? this.id, - status: status ?? this.status, - ); - } - - Map toMap() { - return { - 'id': id, - 'status': status, - }; - } - - factory DeleteAssetResponse.fromMap(Map map) { - return DeleteAssetResponse( - id: map['id'] ?? '', - status: map['status'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory DeleteAssetResponse.fromJson(String source) => - DeleteAssetResponse.fromMap(json.decode(source)); - - @override - String toString() => 'DeleteAssetResponse(id: $id, status: $status)'; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is DeleteAssetResponse && - other.id == id && - other.status == status; - } - - @override - int get hashCode => id.hashCode ^ status.hashCode; -} diff --git a/mobile/lib/modules/home/models/get_all_asset_response.model.dart b/mobile/lib/modules/home/models/get_all_asset_response.model.dart index 86b340ae3..f02d830b2 100644 --- a/mobile/lib/modules/home/models/get_all_asset_response.model.dart +++ b/mobile/lib/modules/home/models/get_all_asset_response.model.dart @@ -1,11 +1,9 @@ -import 'dart:convert'; - import 'package:flutter/foundation.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class ImmichAssetGroupByDate { final String date; - List assets; + List assets; ImmichAssetGroupByDate({ required this.date, required this.assets, @@ -13,7 +11,7 @@ class ImmichAssetGroupByDate { ImmichAssetGroupByDate copyWith({ String? date, - List? assets, + List? assets, }) { return ImmichAssetGroupByDate( date: date ?? this.date, @@ -21,26 +19,6 @@ class ImmichAssetGroupByDate { ); } - Map toMap() { - return { - 'date': date, - 'assets': assets.map((x) => x.toMap()).toList(), - }; - } - - factory ImmichAssetGroupByDate.fromMap(Map map) { - return ImmichAssetGroupByDate( - date: map['date'] ?? '', - assets: List.from( - map['assets']?.map((x) => ImmichAsset.fromMap(x))), - ); - } - - String toJson() => json.encode(toMap()); - - factory ImmichAssetGroupByDate.fromJson(String source) => - ImmichAssetGroupByDate.fromMap(json.decode(source)); - @override String toString() => 'ImmichAssetGroupByDate(date: $date, assets: $assets)'; @@ -79,28 +57,6 @@ class GetAllAssetResponse { ); } - Map toMap() { - return { - 'count': count, - 'data': data.map((x) => x.toMap()).toList(), - 'nextPageKey': nextPageKey, - }; - } - - factory GetAllAssetResponse.fromMap(Map map) { - return GetAllAssetResponse( - count: map['count']?.toInt() ?? 0, - data: List.from( - map['data']?.map((x) => ImmichAssetGroupByDate.fromMap(x))), - nextPageKey: map['nextPageKey'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory GetAllAssetResponse.fromJson(String source) => - GetAllAssetResponse.fromMap(json.decode(source)); - @override String toString() => 'GetAllAssetResponse(count: $count, data: $data, nextPageKey: $nextPageKey)'; diff --git a/mobile/lib/modules/home/models/home_page_state.model.dart b/mobile/lib/modules/home/models/home_page_state.model.dart index 95621fc99..1701ac3ff 100644 --- a/mobile/lib/modules/home/models/home_page_state.model.dart +++ b/mobile/lib/modules/home/models/home_page_state.model.dart @@ -1,12 +1,10 @@ -import 'dart:convert'; - import 'package:collection/collection.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class HomePageState { final bool isMultiSelectEnable; - final Set selectedItems; + final Set selectedItems; final Set selectedDateGroup; HomePageState({ required this.isMultiSelectEnable, @@ -16,7 +14,7 @@ class HomePageState { HomePageState copyWith({ bool? isMultiSelectEnable, - Set? selectedItems, + Set? selectedItems, Set? selectedDateGroup, }) { return HomePageState( @@ -26,28 +24,6 @@ class HomePageState { ); } - Map toMap() { - return { - 'isMultiSelectEnable': isMultiSelectEnable, - 'selectedItems': selectedItems.map((x) => x.toMap()).toList(), - 'selectedDateGroup': selectedDateGroup.toList(), - }; - } - - factory HomePageState.fromMap(Map map) { - return HomePageState( - isMultiSelectEnable: map['isMultiSelectEnable'] ?? false, - selectedItems: Set.from( - map['selectedItems']?.map((x) => ImmichAsset.fromMap(x))), - selectedDateGroup: Set.from(map['selectedDateGroup']), - ); - } - - String toJson() => json.encode(toMap()); - - factory HomePageState.fromJson(String source) => - HomePageState.fromMap(json.decode(source)); - @override String toString() => 'HomePageState(isMultiSelectEnable: $isMultiSelectEnable, selectedItems: $selectedItems, selectedDateGroup: $selectedDateGroup)'; diff --git a/mobile/lib/modules/home/providers/home_page_state.provider.dart b/mobile/lib/modules/home/providers/home_page_state.provider.dart index 6a9fb7176..f81c7199a 100644 --- a/mobile/lib/modules/home/providers/home_page_state.provider.dart +++ b/mobile/lib/modules/home/providers/home_page_state.provider.dart @@ -1,6 +1,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/home/models/home_page_state.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class HomePageStateNotifier extends StateNotifier { HomePageStateNotifier() @@ -14,7 +14,8 @@ class HomePageStateNotifier extends StateNotifier { void addSelectedDateGroup(String dateGroupTitle) { state = state.copyWith( - selectedDateGroup: {...state.selectedDateGroup, dateGroupTitle}); + selectedDateGroup: {...state.selectedDateGroup, dateGroupTitle}, + ); } void removeSelectedDateGroup(String dateGroupTitle) { @@ -25,36 +26,39 @@ class HomePageStateNotifier extends StateNotifier { state = state.copyWith(selectedDateGroup: currentDateGroup); } - void enableMultiSelect(Set selectedItems) { + void enableMultiSelect(Set selectedItems) { state = state.copyWith(isMultiSelectEnable: true, selectedItems: selectedItems); } void disableMultiSelect() { state = state.copyWith( - isMultiSelectEnable: false, selectedItems: {}, selectedDateGroup: {}); + isMultiSelectEnable: false, + selectedItems: {}, + selectedDateGroup: {}, + ); } - void addSingleSelectedItem(ImmichAsset asset) { + void addSingleSelectedItem(AssetResponseDto asset) { state = state.copyWith(selectedItems: {...state.selectedItems, asset}); } - void addMultipleSelectedItems(List assets) { + void addMultipleSelectedItems(List assets) { state = state.copyWith(selectedItems: {...state.selectedItems, ...assets}); } - void removeSingleSelectedItem(ImmichAsset asset) { - Set currentList = state.selectedItems; + void removeSingleSelectedItem(AssetResponseDto asset) { + Set currentList = state.selectedItems; currentList.removeWhere((e) => e.id == asset.id); state = state.copyWith(selectedItems: currentList); } - void removeMultipleSelectedItem(List assets) { - Set currentList = state.selectedItems; + void removeMultipleSelectedItem(List assets) { + Set currentList = state.selectedItems; - for (ImmichAsset asset in assets) { + for (AssetResponseDto asset in assets) { currentList.removeWhere((e) => e.id == asset.id); } @@ -64,4 +68,5 @@ class HomePageStateNotifier extends StateNotifier { final homePageStateProvider = StateNotifierProvider( - ((ref) => HomePageStateNotifier())); + ((ref) => HomePageStateNotifier()), +); diff --git a/mobile/lib/modules/home/providers/upload_profile_image.provider.dart b/mobile/lib/modules/home/providers/upload_profile_image.provider.dart index f8d21d782..66060da38 100644 --- a/mobile/lib/modules/home/providers/upload_profile_image.provider.dart +++ b/mobile/lib/modules/home/providers/upload_profile_image.provider.dart @@ -73,10 +73,12 @@ class UploadProfileImageState { class UploadProfileImageNotifier extends StateNotifier { UploadProfileImageNotifier(this._userSErvice) - : super(UploadProfileImageState( - profileImagePath: '', - status: UploadProfileStatus.idle, - )); + : super( + UploadProfileImageState( + profileImagePath: '', + status: UploadProfileStatus.idle, + ), + ); final UserService _userSErvice; @@ -88,8 +90,9 @@ class UploadProfileImageNotifier if (res != null) { debugPrint("Succesfully upload profile image"); state = state.copyWith( - status: UploadProfileStatus.success, - profileImagePath: res.profileImagePath); + status: UploadProfileStatus.success, + profileImagePath: res.profileImagePath, + ); return true; } @@ -100,4 +103,5 @@ class UploadProfileImageNotifier final uploadProfileImageProvider = StateNotifierProvider( - ((ref) => UploadProfileImageNotifier(ref.watch(userServiceProvider)))); + ((ref) => UploadProfileImageNotifier(ref.watch(userServiceProvider))), +); diff --git a/mobile/lib/modules/home/services/asset.service.dart b/mobile/lib/modules/home/services/asset.service.dart index 16546f1dc..3e44d8b16 100644 --- a/mobile/lib/modules/home/services/asset.service.dart +++ b/mobile/lib/modules/home/services/asset.service.dart @@ -1,120 +1,51 @@ -import 'dart:convert'; +import 'dart:async'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/home/models/delete_asset_response.model.dart'; -import 'package:immich_mobile/modules/home/models/get_all_asset_response.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset_with_exif.model.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; +import 'package:openapi/api.dart'; -final assetServiceProvider = - Provider((ref) => AssetService(ref.watch(networkServiceProvider))); +final assetServiceProvider = Provider( + (ref) => AssetService( + ref.watch(apiServiceProvider), + ), +); class AssetService { - final NetworkService _networkService; - AssetService(this._networkService); + final ApiService _apiService; - Future?> getAllAsset() async { - var res = await _networkService.getRequest(url: "asset/"); + AssetService(this._apiService); + + Future?> getAllAsset() async { try { - List decodedData = jsonDecode(res.toString()); - - List result = - List.from(decodedData.map((a) => ImmichAsset.fromMap(a))); - return result; + return await _apiService.assetApi.getAllAssets(); } catch (e) { - debugPrint("Error getAllAsset ${e.toString()}"); - } - return null; - } - - Future getAllAssetWithPagination() async { - var res = await _networkService.getRequest(url: "asset/all"); - try { - Map decodedData = jsonDecode(res.toString()); - - GetAllAssetResponse result = GetAllAssetResponse.fromMap(decodedData); - return result; - } catch (e) { - debugPrint("Error getAllAsset ${e.toString()}"); - } - return null; - } - - Future getOlderAsset(String? nextPageKey) async { - try { - var res = await _networkService.getRequest( - url: "asset/all?nextPageKey=$nextPageKey", - ); - - Map decodedData = jsonDecode(res.toString()); - - GetAllAssetResponse result = GetAllAssetResponse.fromMap(decodedData); - if (result.count != 0) { - return result; - } - } catch (e) { - debugPrint("Error getAllAsset ${e.toString()}"); - } - return null; - } - - Future> getNewAsset(String latestDate) async { - try { - var res = await _networkService.getRequest( - url: "asset/new?latestDate=$latestDate", - ); - - List decodedData = jsonDecode(res.toString()); - - List result = - List.from(decodedData.map((a) => ImmichAsset.fromMap(a))); - if (result.isNotEmpty) { - return result; - } - - return []; - } catch (e) { - debugPrint("Error getAllAsset ${e.toString()}"); - return []; - } - } - - Future getAssetById(String assetId) async { - try { - var res = await _networkService.getRequest( - url: "asset/assetById/$assetId", - ); - - Map decodedData = jsonDecode(res.toString()); - - ImmichAssetWithExif result = ImmichAssetWithExif.fromMap(decodedData); - return result; - } catch (e) { - debugPrint("Error getAllAsset ${e.toString()}"); + debugPrint("Error [getAllAsset] ${e.toString()}"); return null; } } - Future?> deleteAssets( - Set deleteAssets) async { + Future getAssetById(String assetId) async { try { - var payload = []; + return await _apiService.assetApi.getAssetById(assetId); + } catch (e) { + debugPrint("Error [getAssetById] ${e.toString()}"); + return null; + } + } + + Future?> deleteAssets( + Set deleteAssets, + ) async { + try { + List payload = []; for (var asset in deleteAssets) { payload.add(asset.id); } - var res = await _networkService - .deleteRequest(url: "asset/", data: {"ids": payload}); - - List decodedData = jsonDecode(res.toString()); - - List result = - List.from(decodedData.map((a) => DeleteAssetResponse.fromMap(a))); - - return result; + return await _apiService.assetApi + .deleteAsset(DeleteAssetDto(ids: payload)); } catch (e) { debugPrint("Error getAllAsset ${e.toString()}"); return null; diff --git a/mobile/lib/modules/home/ui/control_bottom_app_bar.dart b/mobile/lib/modules/home/ui/control_bottom_app_bar.dart index 2ff56fb99..87b08e231 100644 --- a/mobile/lib/modules/home/ui/control_bottom_app_bar.dart +++ b/mobile/lib/modules/home/ui/control_bottom_app_bar.dart @@ -15,7 +15,9 @@ class ControlBottomAppBar extends StatelessWidget { height: MediaQuery.of(context).size.height * 0.15, decoration: BoxDecoration( borderRadius: const BorderRadius.only( - topLeft: Radius.circular(15), topRight: Radius.circular(15)), + topLeft: Radius.circular(15), + topRight: Radius.circular(15), + ), color: Colors.grey[300]?.withOpacity(0.98), ), child: Column( @@ -48,12 +50,12 @@ class ControlBottomAppBar extends StatelessWidget { } class ControlBoxButton extends StatelessWidget { - const ControlBoxButton( - {Key? key, - required this.label, - required this.iconData, - required this.onPressed}) - : super(key: key); + const ControlBoxButton({ + Key? key, + required this.label, + required this.iconData, + required this.onPressed, + }) : super(key: key); final String label; final IconData iconData; diff --git a/mobile/lib/modules/home/ui/daily_title_text.dart b/mobile/lib/modules/home/ui/daily_title_text.dart index 15e941f9a..ad2532b41 100644 --- a/mobile/lib/modules/home/ui/daily_title_text.dart +++ b/mobile/lib/modules/home/ui/daily_title_text.dart @@ -2,8 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; -import 'package:intl/intl.dart'; +import 'package:openapi/api.dart'; class DailyTitleText extends ConsumerWidget { const DailyTitleText({ @@ -13,14 +12,15 @@ class DailyTitleText extends ConsumerWidget { }) : super(key: key); final String isoDate; - final List assetGroup; + final List assetGroup; @override Widget build(BuildContext context, WidgetRef ref) { var currentYear = DateTime.now().year; var groupYear = DateTime.parse(isoDate).year; - var formatDateTemplate = - currentYear == groupYear ? "daily_title_text_date".tr() : "daily_title_text_date_year".tr(); + var formatDateTemplate = currentYear == groupYear + ? "daily_title_text_date".tr() + : "daily_title_text_date_year".tr(); var dateText = DateFormat(formatDateTemplate).format(DateTime.parse(isoDate)); var isMultiSelectEnable = @@ -74,7 +74,11 @@ class DailyTitleText extends ConsumerWidget { return SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.only( - top: 29.0, bottom: 29.0, left: 12.0, right: 12.0), + top: 29.0, + bottom: 29.0, + left: 12.0, + right: 12.0, + ), child: Row( children: [ Text( diff --git a/mobile/lib/modules/home/ui/disable_multi_select_button.dart b/mobile/lib/modules/home/ui/disable_multi_select_button.dart index 3a28d7fe8..9a75bd637 100644 --- a/mobile/lib/modules/home/ui/disable_multi_select_button.dart +++ b/mobile/lib/modules/home/ui/disable_multi_select_button.dart @@ -29,15 +29,18 @@ class DisableMultiSelectButton extends ConsumerWidget { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 4.0), child: TextButton.icon( - onPressed: () { - onPressed(); - }, - icon: const Icon(Icons.close_rounded), - label: Text( - '$selectedItemCount', - style: const TextStyle( - fontWeight: FontWeight.w600, fontSize: 18), - )), + onPressed: () { + onPressed(); + }, + icon: const Icon(Icons.close_rounded), + label: Text( + '$selectedItemCount', + style: const TextStyle( + fontWeight: FontWeight.w600, + fontSize: 18, + ), + ), + ), ), ), ), diff --git a/mobile/lib/modules/home/ui/draggable_scrollbar.dart b/mobile/lib/modules/home/ui/draggable_scrollbar.dart index b7e075492..90e7d85e5 100644 --- a/mobile/lib/modules/home/ui/draggable_scrollbar.dart +++ b/mobile/lib/modules/home/ui/draggable_scrollbar.dart @@ -118,20 +118,24 @@ class DraggableScrollbar extends StatefulWidget { this.labelConstraints, }) : assert(child.scrollDirection == Axis.vertical), scrollThumbBuilder = _thumbSemicircleBuilder( - heightScrollThumb * 0.6, scrollThumbKey, alwaysVisibleScrollThumb), + heightScrollThumb * 0.6, + scrollThumbKey, + alwaysVisibleScrollThumb, + ), super(key: key); @override DraggableScrollbarState createState() => DraggableScrollbarState(); - static buildScrollThumbAndLabel( - {required Widget scrollThumb, - required Color backgroundColor, - required Animation? thumbAnimation, - required Animation? labelAnimation, - required Text? labelText, - required BoxConstraints? labelConstraints, - required bool alwaysVisibleScrollThumb}) { + static buildScrollThumbAndLabel({ + required Widget scrollThumb, + required Color backgroundColor, + required Animation? thumbAnimation, + required Animation? labelAnimation, + required Text? labelText, + required BoxConstraints? labelConstraints, + required bool alwaysVisibleScrollThumb, + }) { var scrollThumbAndLabel = labelText == null ? scrollThumb : Row( @@ -158,7 +162,10 @@ class DraggableScrollbar extends StatefulWidget { } static ScrollThumbBuilder _thumbSemicircleBuilder( - double width, Key? scrollThumbKey, bool alwaysVisibleScrollThumb) { + double width, + Key? scrollThumbKey, + bool alwaysVisibleScrollThumb, + ) { return ( Color backgroundColor, Animation thumbAnimation, @@ -198,7 +205,9 @@ class DraggableScrollbar extends StatefulWidget { } static ScrollThumbBuilder _thumbArrowBuilder( - Key? scrollThumbKey, bool alwaysVisibleScrollThumb) { + Key? scrollThumbKey, + bool alwaysVisibleScrollThumb, + ) { return ( Color backgroundColor, Animation thumbAnimation, @@ -234,7 +243,9 @@ class DraggableScrollbar extends StatefulWidget { } static ScrollThumbBuilder _thumbRRectBuilder( - Key? scrollThumbKey, bool alwaysVisibleScrollThumb) { + Key? scrollThumbKey, + bool alwaysVisibleScrollThumb, + ) { return ( Color backgroundColor, Animation thumbAnimation, @@ -372,42 +383,44 @@ class DraggableScrollbarState extends State } return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - //print("LayoutBuilder constraints=$constraints"); + builder: (BuildContext context, BoxConstraints constraints) { + //print("LayoutBuilder constraints=$constraints"); - return NotificationListener( - onNotification: (ScrollNotification notification) { - changePosition(notification); - return false; - }, - child: Stack( - children: [ - RepaintBoundary( - child: widget.child, - ), - RepaintBoundary( + return NotificationListener( + onNotification: (ScrollNotification notification) { + changePosition(notification); + return false; + }, + child: Stack( + children: [ + RepaintBoundary( + child: widget.child, + ), + RepaintBoundary( child: GestureDetector( - onVerticalDragStart: _onVerticalDragStart, - onVerticalDragUpdate: _onVerticalDragUpdate, - onVerticalDragEnd: _onVerticalDragEnd, - child: Container( - alignment: Alignment.topRight, - margin: EdgeInsets.only(top: _barOffset), - padding: widget.padding, - child: widget.scrollThumbBuilder( - widget.backgroundColor, - _thumbAnimation, - _labelAnimation, - widget.heightScrollThumb, - labelText: labelText, - labelConstraints: widget.labelConstraints, + onVerticalDragStart: _onVerticalDragStart, + onVerticalDragUpdate: _onVerticalDragUpdate, + onVerticalDragEnd: _onVerticalDragEnd, + child: Container( + alignment: Alignment.topRight, + margin: EdgeInsets.only(top: _barOffset), + padding: widget.padding, + child: widget.scrollThumbBuilder( + widget.backgroundColor, + _thumbAnimation, + _labelAnimation, + widget.heightScrollThumb, + labelText: labelText, + labelConstraints: widget.labelConstraints, + ), + ), ), ), - )), - ], - ), - ); - }); + ], + ), + ); + }, + ); } //scroll bar has received notification that it's view was scrolled @@ -498,7 +511,10 @@ class DraggableScrollbarState extends State } double viewDelta = getScrollViewDelta( - details.delta.dy, barMaxScrollExtent, viewMaxScrollExtent); + details.delta.dy, + barMaxScrollExtent, + viewMaxScrollExtent, + ); _viewOffset = widget.controller.position.pixels + viewDelta; if (_viewOffset < widget.controller.position.minScrollExtent) { @@ -579,7 +595,9 @@ class ArrowClipper extends CustomClipper { path.lineTo(startPointX + arrowWidth, startPointY); path.lineTo(startPointX + arrowWidth, startPointY + 1.0); path.lineTo( - startPointX + arrowWidth / 2, startPointY - arrowWidth / 2 + 1.0); + startPointX + arrowWidth / 2, + startPointY - arrowWidth / 2 + 1.0, + ); path.lineTo(startPointX, startPointY + 1.0); path.close(); @@ -589,7 +607,9 @@ class ArrowClipper extends CustomClipper { path.lineTo(startPointX, startPointY); path.lineTo(startPointX, startPointY - 1.0); path.lineTo( - startPointX + arrowWidth / 2, startPointY + arrowWidth / 2 - 1.0); + startPointX + arrowWidth / 2, + startPointY + arrowWidth / 2 - 1.0, + ); path.lineTo(startPointX + arrowWidth, startPointY - 1.0); path.close(); diff --git a/mobile/lib/modules/home/ui/image_grid.dart b/mobile/lib/modules/home/ui/image_grid.dart index 3b8e11adb..1a7f1b2d7 100644 --- a/mobile/lib/modules/home/ui/image_grid.dart +++ b/mobile/lib/modules/home/ui/image_grid.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/home/ui/thumbnail_image.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class ImageGrid extends ConsumerWidget { - final List assetGroup; + final List assetGroup; const ImageGrid({Key? key, required this.assetGroup}) : super(key: key); @@ -25,7 +25,7 @@ class ImageGrid extends ConsumerWidget { child: Stack( children: [ ThumbnailImage(asset: assetGroup[index]), - if (assetType != 'IMAGE') + if (assetType != AssetTypeEnum.IMAGE) Positioned( top: 5, right: 5, diff --git a/mobile/lib/modules/home/ui/immich_sliver_appbar.dart b/mobile/lib/modules/home/ui/immich_sliver_appbar.dart index 1f46def56..7e71cf93f 100644 --- a/mobile/lib/modules/home/ui/immich_sliver_appbar.dart +++ b/mobile/lib/modules/home/ui/immich_sliver_appbar.dart @@ -31,7 +31,8 @@ class ImmichSliverAppBar extends ConsumerWidget { pinned: false, snap: false, shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(5))), + borderRadius: BorderRadius.all(Radius.circular(5)), + ), leading: Builder( builder: (BuildContext context) { return Stack( @@ -99,7 +100,8 @@ class ImmichSliverAppBar extends ConsumerWidget { child: CircularProgressIndicator( strokeWidth: 1, valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), + Theme.of(context).primaryColor, + ), ), ), ), @@ -117,7 +119,8 @@ class ImmichSliverAppBar extends ConsumerWidget { Icons.cloud_off_rounded, size: 8, ), - child: const Icon(Icons.backup_rounded)), + child: const Icon(Icons.backup_rounded), + ), onPressed: () async { var onPop = await AutoRouter.of(context) .push(const BackupControllerRoute()); diff --git a/mobile/lib/modules/home/ui/monthly_title_text.dart b/mobile/lib/modules/home/ui/monthly_title_text.dart index ad9998c8f..f31962460 100644 --- a/mobile/lib/modules/home/ui/monthly_title_text.dart +++ b/mobile/lib/modules/home/ui/monthly_title_text.dart @@ -1,6 +1,5 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; class MonthlyTitleText extends StatelessWidget { const MonthlyTitleText({ @@ -12,7 +11,8 @@ class MonthlyTitleText extends StatelessWidget { @override Widget build(BuildContext context) { - var monthTitleText = DateFormat("monthly_title_text_date_format".tr()).format(DateTime.parse(isoDate)); + var monthTitleText = DateFormat("monthly_title_text_date_format".tr()) + .format(DateTime.parse(isoDate)); return SliverToBoxAdapter( child: Padding( diff --git a/mobile/lib/modules/home/ui/profile_drawer.dart b/mobile/lib/modules/home/ui/profile_drawer.dart index 20ef4d139..6154fdc31 100644 --- a/mobile/lib/modules/home/ui/profile_drawer.dart +++ b/mobile/lib/modules/home/ui/profile_drawer.dart @@ -55,7 +55,8 @@ class ProfileDrawer extends HookConsumerWidget { return CircleAvatar( radius: 35, backgroundImage: NetworkImage( - '$endpoint/user/profile-image/${authState.userId}?d=${dummmy++}'), + '$endpoint/user/profile-image/${authState.userId}?d=${dummmy++}', + ), backgroundColor: Colors.transparent, ); } else { @@ -71,7 +72,8 @@ class ProfileDrawer extends HookConsumerWidget { return CircleAvatar( radius: 35, backgroundImage: NetworkImage( - '$endpoint/user/profile-image/${authState.userId}?d=${dummmy++}'), + '$endpoint/user/profile-image/${authState.userId}?d=${dummmy++}', + ), backgroundColor: Colors.transparent, ); } @@ -93,7 +95,10 @@ class ProfileDrawer extends HookConsumerWidget { _pickUserProfileImage() async { final XFile? image = await ImagePicker().pickImage( - source: ImageSource.gallery, maxHeight: 1024, maxWidth: 1024); + source: ImageSource.gallery, + maxHeight: 1024, + maxWidth: 1024, + ); if (image != null) { var success = @@ -101,16 +106,20 @@ class ProfileDrawer extends HookConsumerWidget { if (success) { ref.watch(authenticationProvider.notifier).updateUserProfileImagePath( - ref.read(uploadProfileImageProvider).profileImagePath); + ref.read(uploadProfileImageProvider).profileImagePath, + ); } } } - useEffect(() { - _getPackageInfo(); - _buildUserProfileImage(); - return null; - }, []); + useEffect( + () { + _getPackageInfo(); + _buildUserProfileImage(); + return null; + }, + [], + ); return Drawer( child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -186,9 +195,10 @@ class ProfileDrawer extends HookConsumerWidget { title: const Text( "profile_drawer_sign_out", style: TextStyle( - color: Colors.black54, - fontSize: 14, - fontWeight: FontWeight.bold), + color: Colors.black54, + fontSize: 14, + fontWeight: FontWeight.bold, + ), ).tr(), onTap: () async { bool res = @@ -231,9 +241,10 @@ class ProfileDrawer extends HookConsumerWidget { : "profile_drawer_client_server_up_to_date".tr(), textAlign: TextAlign.center, style: TextStyle( - fontSize: 11, - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.w600), + fontSize: 11, + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.w600, + ), ), ), const Divider(), @@ -271,7 +282,7 @@ class ProfileDrawer extends HookConsumerWidget { ), ), Text( - "${serverInfoState.serverVersion.major}.${serverInfoState.serverVersion.minor}.${serverInfoState.serverVersion.patch}", + "${serverInfoState.serverVersion.major}.${serverInfoState.serverVersion.minor}.${serverInfoState.serverVersion.patch_}", style: TextStyle( fontSize: 11, color: Colors.grey[500], diff --git a/mobile/lib/modules/home/ui/thumbnail_image.dart b/mobile/lib/modules/home/ui/thumbnail_image.dart index ff5af246d..f86e76505 100644 --- a/mobile/lib/modules/home/ui/thumbnail_image.dart +++ b/mobile/lib/modules/home/ui/thumbnail_image.dart @@ -8,11 +8,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/routing/router.dart'; +import 'package:openapi/api.dart'; class ThumbnailImage extends HookConsumerWidget { - final ImmichAsset asset; + final AssetResponseDto asset; const ThumbnailImage({Key? key, required this.asset}) : super(key: key); @@ -22,14 +22,13 @@ class ThumbnailImage extends HookConsumerWidget { var box = Hive.box(userInfoBox); var thumbnailRequestUrl = - '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true'; - + '${box.get(serverEndpointKey)}/asset/thumbnail/${asset.id}'; var selectedAsset = ref.watch(homePageStateProvider).selectedItems; var isMultiSelectEnable = ref.watch(homePageStateProvider).isMultiSelectEnable; var deviceId = ref.watch(authenticationProvider).deviceId; - Widget _buildSelectionIcon(ImmichAsset asset) { + Widget _buildSelectionIcon(AssetResponseDto asset) { if (selectedAsset.contains(asset)) { return Icon( Icons.check_circle, @@ -61,7 +60,7 @@ class ThumbnailImage extends HookConsumerWidget { .watch(homePageStateProvider.notifier) .addSingleSelectedItem(asset); } else { - if (asset.type == 'IMAGE') { + if (asset.type == AssetTypeEnum.IMAGE) { AutoRouter.of(context).push( ImageViewerRoute( imageUrl: @@ -74,9 +73,10 @@ class ThumbnailImage extends HookConsumerWidget { } else { AutoRouter.of(context).push( VideoViewerRoute( - videoUrl: - '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', - asset: asset), + videoUrl: + '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', + asset: asset, + ), ); } } @@ -94,14 +94,16 @@ class ThumbnailImage extends HookConsumerWidget { decoration: BoxDecoration( border: isMultiSelectEnable && selectedAsset.contains(asset) ? Border.all( - color: Theme.of(context).primaryColorLight, width: 10) + color: Theme.of(context).primaryColorLight, + width: 10, + ) : const Border(), ), child: CachedNetworkImage( cacheKey: "${asset.id}-${cacheKey.value}", width: 300, height: 300, - memCacheHeight: asset.type == 'IMAGE' ? 250 : 400, + memCacheHeight: asset.type == AssetTypeEnum.IMAGE ? 250 : 400, fit: BoxFit.cover, imageUrl: thumbnailRequestUrl, httpHeaders: { @@ -112,9 +114,11 @@ class ThumbnailImage extends HookConsumerWidget { Transform.scale( scale: 0.2, child: CircularProgressIndicator( - value: downloadProgress.progress), + value: downloadProgress.progress, + ), ), errorWidget: (context, url, error) { + debugPrint("Error getting thumbnail $url = $error"); return Icon( Icons.image_not_supported_outlined, color: Theme.of(context).primaryColor, diff --git a/mobile/lib/modules/home/views/home_page.dart b/mobile/lib/modules/home/views/home_page.dart index 00c1aa893..66a4834b7 100644 --- a/mobile/lib/modules/home/views/home_page.dart +++ b/mobile/lib/modules/home/views/home_page.dart @@ -26,12 +26,15 @@ class HomePage extends HookConsumerWidget { ref.watch(homePageStateProvider).isMultiSelectEnable; var homePageState = ref.watch(homePageStateProvider); - useEffect(() { - ref.read(websocketProvider.notifier).connect(); - ref.read(assetProvider.notifier).getAllAsset(); - ref.watch(serverInfoProvider.notifier).getServerVersion(); - return null; - }, []); + useEffect( + () { + ref.read(websocketProvider.notifier).connect(); + ref.read(assetProvider.notifier).getAllAsset(); + ref.watch(serverInfoProvider.notifier).getServerVersion(); + return null; + }, + [], + ); void reloadAllAsset() { ref.read(assetProvider.notifier).getAllAsset(); diff --git a/mobile/lib/modules/login/models/authentication_state.model.dart b/mobile/lib/modules/login/models/authentication_state.model.dart index 6603021bb..4805d499b 100644 --- a/mobile/lib/modules/login/models/authentication_state.model.dart +++ b/mobile/lib/modules/login/models/authentication_state.model.dart @@ -1,10 +1,8 @@ -import 'dart:convert'; - -import 'package:immich_mobile/shared/models/device_info.model.dart'; +import 'package:openapi/api.dart'; class AuthenticationState { final String deviceId; - final String deviceType; + final DeviceTypeEnum deviceType; final String userId; final String userEmail; final bool isAuthenticated; @@ -13,8 +11,7 @@ class AuthenticationState { final bool isAdmin; final bool shouldChangePassword; final String profileImagePath; - final DeviceInfoRemote deviceInfo; - + final DeviceInfoResponseDto deviceInfo; AuthenticationState({ required this.deviceId, required this.deviceType, @@ -31,7 +28,7 @@ class AuthenticationState { AuthenticationState copyWith({ String? deviceId, - String? deviceType, + DeviceTypeEnum? deviceType, String? userId, String? userEmail, bool? isAuthenticated, @@ -40,7 +37,7 @@ class AuthenticationState { bool? isAdmin, bool? shouldChangePassword, String? profileImagePath, - DeviceInfoRemote? deviceInfo, + DeviceInfoResponseDto? deviceInfo, }) { return AuthenticationState( deviceId: deviceId ?? this.deviceId, @@ -57,45 +54,6 @@ class AuthenticationState { ); } - Map toMap() { - final result = {}; - - result.addAll({'deviceId': deviceId}); - result.addAll({'deviceType': deviceType}); - result.addAll({'userId': userId}); - result.addAll({'userEmail': userEmail}); - result.addAll({'isAuthenticated': isAuthenticated}); - result.addAll({'firstName': firstName}); - result.addAll({'lastName': lastName}); - result.addAll({'isAdmin': isAdmin}); - result.addAll({'shouldChangePassword': shouldChangePassword}); - result.addAll({'profileImagePath': profileImagePath}); - result.addAll({'deviceInfo': deviceInfo.toMap()}); - - return result; - } - - factory AuthenticationState.fromMap(Map map) { - return AuthenticationState( - deviceId: map['deviceId'] ?? '', - deviceType: map['deviceType'] ?? '', - userId: map['userId'] ?? '', - userEmail: map['userEmail'] ?? '', - isAuthenticated: map['isAuthenticated'] ?? false, - firstName: map['firstName'] ?? '', - lastName: map['lastName'] ?? '', - isAdmin: map['isAdmin'] ?? false, - shouldChangePassword: map['shouldChangePassword'] ?? false, - profileImagePath: map['profileImagePath'] ?? '', - deviceInfo: DeviceInfoRemote.fromMap(map['deviceInfo']), - ); - } - - String toJson() => json.encode(toMap()); - - factory AuthenticationState.fromJson(String source) => - AuthenticationState.fromMap(json.decode(source)); - @override String toString() { return 'AuthenticationState(deviceId: $deviceId, deviceType: $deviceType, userId: $userId, userEmail: $userEmail, isAuthenticated: $isAuthenticated, firstName: $firstName, lastName: $lastName, isAdmin: $isAdmin, shouldChangePassword: $shouldChangePassword, profileImagePath: $profileImagePath, deviceInfo: $deviceInfo)'; diff --git a/mobile/lib/modules/login/models/hive_saved_login_info.model.dart b/mobile/lib/modules/login/models/hive_saved_login_info.model.dart index 471e5df66..6d367d597 100644 --- a/mobile/lib/modules/login/models/hive_saved_login_info.model.dart +++ b/mobile/lib/modules/login/models/hive_saved_login_info.model.dart @@ -16,9 +16,10 @@ class HiveSavedLoginInfo { @HiveField(3) bool isSaveLogin; - HiveSavedLoginInfo( - {required this.email, - required this.password, - required this.serverUrl, - required this.isSaveLogin}); + HiveSavedLoginInfo({ + required this.email, + required this.password, + required this.serverUrl, + required this.isSaveLogin, + }); } diff --git a/mobile/lib/modules/login/providers/authentication.provider.dart b/mobile/lib/modules/login/providers/authentication.provider.dart index 0634e5731..885066e22 100644 --- a/mobile/lib/modules/login/providers/authentication.provider.dart +++ b/mobile/lib/modules/login/providers/authentication.provider.dart @@ -1,23 +1,23 @@ -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/modules/login/models/authentication_state.model.dart'; import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart'; -import 'package:immich_mobile/modules/login/models/login_response.model.dart'; import 'package:immich_mobile/modules/backup/services/backup.service.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; import 'package:immich_mobile/shared/services/device_info.service.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; -import 'package:immich_mobile/shared/models/device_info.model.dart'; +import 'package:openapi/api.dart'; class AuthenticationNotifier extends StateNotifier { AuthenticationNotifier( - this._deviceInfoService, this._backupService, this._networkService) - : super( + this._deviceInfoService, + this._backupService, + this._apiService, + ) : super( AuthenticationState( deviceId: "", - deviceType: "", + deviceType: DeviceTypeEnum.ANDROID, userId: "", userEmail: "", firstName: '', @@ -26,12 +26,11 @@ class AuthenticationNotifier extends StateNotifier { isAdmin: false, shouldChangePassword: false, isAuthenticated: false, - deviceInfo: DeviceInfoRemote( + deviceInfo: DeviceInfoResponseDto( id: 0, userId: "", deviceId: "", - deviceType: "", - notificationToken: "", + deviceType: DeviceTypeEnum.ANDROID, createdAt: "", isAutoBackup: false, ), @@ -40,10 +39,14 @@ class AuthenticationNotifier extends StateNotifier { final DeviceInfoService _deviceInfoService; final BackupService _backupService; - final NetworkService _networkService; + final ApiService _apiService; - Future login(String email, String password, String serverEndpoint, - bool isSavedLoginInfo) async { + Future login( + String email, + String password, + String serverEndpoint, + bool isSavedLoginInfo, + ) async { // Store server endpoint to Hive and test endpoint if (serverEndpoint[serverEndpoint.length - 1] == "/") { var validUrl = serverEndpoint.substring(0, serverEndpoint.length - 1); @@ -52,12 +55,12 @@ class AuthenticationNotifier extends StateNotifier { Hive.box(userInfoBox).put(serverEndpointKey, serverEndpoint); } + // Check Server URL validity try { - bool isServerEndpointVerified = await _networkService.pingServer(); - if (!isServerEndpointVerified) { - return false; - } + _apiService.setEndpoint(Hive.box(userInfoBox).get(serverEndpointKey)); + await _apiService.serverInfoApi.pingServer(); } catch (e) { + debugPrint('Invalid Server Endpoint Url $e'); return false; } @@ -72,56 +75,73 @@ class AuthenticationNotifier extends StateNotifier { // Make sign-in request try { - Response res = await _networkService.postRequest( - url: 'auth/login', data: {'email': email, 'password': password}); + var loginResponse = await _apiService.authenticationApi.login( + LoginCredentialDto( + email: email, + password: password, + ), + ); - var payload = LogInReponse.fromJson(res.toString()); + if (loginResponse == null) { + debugPrint('Login Response is null'); + return false; + } - Hive.box(userInfoBox).put(accessTokenKey, payload.accessToken); + Hive.box(userInfoBox).put(accessTokenKey, loginResponse.accessToken); state = state.copyWith( isAuthenticated: true, - userId: payload.userId, - userEmail: payload.userEmail, - firstName: payload.firstName, - lastName: payload.lastName, - profileImagePath: payload.profileImagePath, - isAdmin: payload.isAdmin, - shouldChangePassword: payload.shouldChangePassword, + userId: loginResponse.userId, + userEmail: loginResponse.userEmail, + firstName: loginResponse.firstName, + lastName: loginResponse.lastName, + profileImagePath: loginResponse.profileImagePath, + isAdmin: loginResponse.isAdmin, + shouldChangePassword: loginResponse.shouldChangePassword, ); + // Login Success - Set Access Token to API Client + _apiService.setAccessToken(loginResponse.accessToken); + if (isSavedLoginInfo) { // Save login info to local storage Hive.box(hiveLoginInfoBox).put( savedLoginInfoKey, HiveSavedLoginInfo( - email: email, - password: password, - isSaveLogin: true, - serverUrl: Hive.box(userInfoBox).get(serverEndpointKey)), + email: email, + password: password, + isSaveLogin: true, + serverUrl: Hive.box(userInfoBox).get(serverEndpointKey), + ), ); } else { Hive.box(hiveLoginInfoBox) .delete(savedLoginInfoKey); } } catch (e) { + debugPrint("Error logging in $e"); return false; } // Register device info try { - Response res = await _networkService.postRequest( - url: 'device-info', - data: { - 'deviceId': state.deviceId, - 'deviceType': state.deviceType, - }, + DeviceInfoResponseDto? deviceInfo = + await _apiService.deviceInfoApi.createDeviceInfo( + CreateDeviceInfoDto( + deviceId: state.deviceId, + deviceType: state.deviceType, + ), ); - DeviceInfoRemote deviceInfo = DeviceInfoRemote.fromJson(res.toString()); + if (deviceInfo == null) { + debugPrint('Device Info Response is null'); + return false; + } + state = state.copyWith(deviceInfo: deviceInfo); } catch (e) { debugPrint("ERROR Register Device Info: $e"); + return false; } return true; @@ -129,27 +149,7 @@ class AuthenticationNotifier extends StateNotifier { Future logout() async { Hive.box(userInfoBox).delete(accessTokenKey); - state = AuthenticationState( - deviceId: "", - deviceType: "", - userId: "", - userEmail: "", - firstName: '', - lastName: '', - profileImagePath: '', - shouldChangePassword: false, - isAuthenticated: false, - isAdmin: false, - deviceInfo: DeviceInfoRemote( - id: 0, - userId: "", - deviceId: "", - deviceType: "", - notificationToken: "", - createdAt: "", - isAutoBackup: false, - ), - ); + state = state.copyWith(isAuthenticated: false); return true; } @@ -157,11 +157,13 @@ class AuthenticationNotifier extends StateNotifier { setAutoBackup(bool backupState) async { var deviceInfo = await _deviceInfoService.getDeviceInfo(); var deviceId = deviceInfo["deviceId"]; - var deviceType = deviceInfo["deviceType"]; - DeviceInfoRemote deviceInfoRemote = + DeviceTypeEnum deviceType = deviceInfo["deviceType"]; + + DeviceInfoResponseDto updatedDeviceInfo = await _backupService.setAutoBackup(backupState, deviceId, deviceType); - state = state.copyWith(deviceInfo: deviceInfoRemote); + + state = state.copyWith(deviceInfo: updatedDeviceInfo); } updateUserProfileImagePath(String path) { @@ -169,19 +171,20 @@ class AuthenticationNotifier extends StateNotifier { } Future changePassword(String newPassword) async { - Response res = await _networkService.putRequest( - url: 'user', - data: { - 'id': state.userId, - 'password': newPassword, - 'shouldChangePassword': false, - }, - ); + try { + await _apiService.userApi.updateUser( + UpdateUserDto( + id: state.userId, + password: newPassword, + shouldChangePassword: false, + ), + ); - if (res.statusCode == 200) { state = state.copyWith(shouldChangePassword: false); + return true; - } else { + } catch (e) { + debugPrint("Error changing password $e"); return false; } } @@ -192,6 +195,6 @@ final authenticationProvider = return AuthenticationNotifier( ref.watch(deviceInfoServiceProvider), ref.watch(backupServiceProvider), - ref.watch(networkServiceProvider), + ref.watch(apiServiceProvider), ); }); diff --git a/mobile/lib/modules/login/ui/change_password_form.dart b/mobile/lib/modules/login/ui/change_password_form.dart index 4e3632e74..0351803d4 100644 --- a/mobile/lib/modules/login/ui/change_password_form.dart +++ b/mobile/lib/modules/login/ui/change_password_form.dart @@ -140,35 +140,36 @@ class ChangePasswordButton extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return ElevatedButton( - style: ElevatedButton.styleFrom( - visualDensity: VisualDensity.standard, - primary: Theme.of(context).primaryColor, - onPrimary: Colors.grey[50], - elevation: 2, - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 25), - ), - onPressed: () async { - if (formKey.currentState!.validate()) { - var isSuccess = await ref - .watch(authenticationProvider.notifier) - .changePassword(passwordController.value.text); + style: ElevatedButton.styleFrom( + visualDensity: VisualDensity.standard, + primary: Theme.of(context).primaryColor, + onPrimary: Colors.grey[50], + elevation: 2, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 25), + ), + onPressed: () async { + if (formKey.currentState!.validate()) { + var isSuccess = await ref + .watch(authenticationProvider.notifier) + .changePassword(passwordController.value.text); - if (isSuccess) { - bool res = - await ref.watch(authenticationProvider.notifier).logout(); + if (isSuccess) { + bool res = + await ref.watch(authenticationProvider.notifier).logout(); - if (res) { - ref.watch(backupProvider.notifier).cancelBackup(); - ref.watch(assetProvider.notifier).clearAllAsset(); - ref.watch(websocketProvider.notifier).disconnect(); - AutoRouter.of(context).replace(const LoginRoute()); - } + if (res) { + ref.watch(backupProvider.notifier).cancelBackup(); + ref.watch(assetProvider.notifier).clearAllAsset(); + ref.watch(websocketProvider.notifier).disconnect(); + AutoRouter.of(context).replace(const LoginRoute()); } } - }, - child: const Text( - "Change Password", - style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), - )); + } + }, + child: const Text( + "Change Password", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + ), + ); } } diff --git a/mobile/lib/modules/login/ui/login_form.dart b/mobile/lib/modules/login/ui/login_form.dart index b109254a7..dad98505d 100644 --- a/mobile/lib/modules/login/ui/login_form.dart +++ b/mobile/lib/modules/login/ui/login_form.dart @@ -22,22 +22,25 @@ class LoginForm extends HookConsumerWidget { final passwordController = useTextEditingController.fromValue(TextEditingValue.empty); final serverEndpointController = - useTextEditingController(text: 'login_endpoint_hint'.tr()); + useTextEditingController(text: 'login_form_endpoint_hint'.tr()); final isSaveLoginInfo = useState(false); - useEffect(() { - var loginInfo = - Hive.box(hiveLoginInfoBox).get(savedLoginInfoKey); + useEffect( + () { + var loginInfo = Hive.box(hiveLoginInfoBox) + .get(savedLoginInfoKey); - if (loginInfo != null) { - usernameController.text = loginInfo.email; - passwordController.text = loginInfo.password; - serverEndpointController.text = loginInfo.serverUrl; - isSaveLoginInfo.value = loginInfo.isSaveLogin; - } + if (loginInfo != null) { + usernameController.text = loginInfo.email; + passwordController.text = loginInfo.password; + serverEndpointController.text = loginInfo.serverUrl; + isSaveLoginInfo.value = loginInfo.isSaveLogin; + } - return null; - }, []); + return null; + }, + [], + ); return Center( child: ConstrainedBox( @@ -71,14 +74,16 @@ class LoginForm extends HookConsumerWidget { dense: true, side: const BorderSide(color: Colors.grey, width: 1.5), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5)), + borderRadius: BorderRadius.circular(5), + ), enableFeedback: true, title: const Text( "login_form_save_login", style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.grey), + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), ).tr(), value: isSaveLoginInfo.value, onChanged: (switchValue) { @@ -108,7 +113,6 @@ class ServerEndpointInput extends StatelessWidget { : super(key: key); String? _validateInput(String? url) { - if (url?.startsWith(RegExp(r'https?://')) == true) { return null; } else { @@ -122,7 +126,7 @@ class ServerEndpointInput extends StatelessWidget { controller: controller, decoration: InputDecoration( labelText: 'login_form_endpoint_url'.tr(), - border: OutlineInputBorder(), + border: const OutlineInputBorder(), hintText: 'login_form_endpoint_hint'.tr(), ), validator: _validateInput, @@ -140,8 +144,9 @@ class EmailInput extends StatelessWidget { if (email == null || email == '') return null; if (email.endsWith(' ')) return 'login_form_err_trailing_whitespace'.tr(); if (email.startsWith(' ')) return 'login_form_err_leading_whitespace'.tr(); - if (email.contains(' ') || !email.contains('@')) + if (email.contains(' ') || !email.contains('@')) { return 'login_form_err_invalid_email'.tr(); + } return null; } @@ -151,7 +156,7 @@ class EmailInput extends StatelessWidget { controller: controller, decoration: InputDecoration( labelText: 'login_form_label_email'.tr(), - border: OutlineInputBorder(), + border: const OutlineInputBorder(), hintText: 'login_form_email_hint'.tr(), ), validator: _validateInput, @@ -171,9 +176,10 @@ class PasswordInput extends StatelessWidget { obscureText: true, controller: controller, decoration: InputDecoration( - labelText: 'login_form_label_password'.tr(), - border: OutlineInputBorder(), - hintText: 'login_form_password_hint'.tr()), + labelText: 'login_form_label_password'.tr(), + border: const OutlineInputBorder(), + hintText: 'login_form_password_hint'.tr(), + ), ); } } @@ -195,43 +201,47 @@ class LoginButton extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return ElevatedButton( - style: ElevatedButton.styleFrom( - visualDensity: VisualDensity.standard, - primary: Theme.of(context).primaryColor, - onPrimary: Colors.grey[50], - elevation: 2, - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 25), - ), - onPressed: () async { - // This will remove current cache asset state of previous user login. - ref.watch(assetProvider.notifier).clearAllAsset(); + style: ElevatedButton.styleFrom( + visualDensity: VisualDensity.standard, + primary: Theme.of(context).primaryColor, + onPrimary: Colors.grey[50], + elevation: 2, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 25), + ), + onPressed: () async { + // This will remove current cache asset state of previous user login. + ref.watch(assetProvider.notifier).clearAllAsset(); - var isAuthenticated = await ref - .watch(authenticationProvider.notifier) - .login(emailController.text, passwordController.text, - serverEndpointController.text, isSavedLoginInfo); + var isAuthenticated = + await ref.watch(authenticationProvider.notifier).login( + emailController.text, + passwordController.text, + serverEndpointController.text, + isSavedLoginInfo, + ); - if (isAuthenticated) { - // Resume backup (if enable) then navigate + if (isAuthenticated) { + // Resume backup (if enable) then navigate - if (ref.watch(authenticationProvider).shouldChangePassword && - !ref.watch(authenticationProvider).isAdmin) { - AutoRouter.of(context).push(const ChangePasswordRoute()); - } else { - ref.watch(backupProvider.notifier).resumeBackup(); - AutoRouter.of(context).pushNamed("/tab-controller-page"); - } + if (ref.watch(authenticationProvider).shouldChangePassword && + !ref.watch(authenticationProvider).isAdmin) { + AutoRouter.of(context).push(const ChangePasswordRoute()); } else { - ImmichToast.show( - context: context, - msg: "login_failed".tr(), - toastType: ToastType.error, - ); + ref.watch(backupProvider.notifier).resumeBackup(); + AutoRouter.of(context).pushNamed("/tab-controller-page"); } - }, - child: const Text( - "login_form_button_text", - style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), - ).tr()); + } else { + ImmichToast.show( + context: context, + msg: "login_form_failed_login".tr(), + toastType: ToastType.error, + ); + } + }, + child: const Text( + "login_form_button_text", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + ).tr(), + ); } } diff --git a/mobile/lib/modules/search/models/curated_location.model.dart b/mobile/lib/modules/search/models/curated_location.model.dart deleted file mode 100644 index a3baebbdf..000000000 --- a/mobile/lib/modules/search/models/curated_location.model.dart +++ /dev/null @@ -1,84 +0,0 @@ -import 'dart:convert'; - -class CuratedLocation { - final String id; - final String city; - final String resizePath; - final String deviceAssetId; - final String deviceId; - - CuratedLocation({ - required this.id, - required this.city, - required this.resizePath, - required this.deviceAssetId, - required this.deviceId, - }); - - CuratedLocation copyWith({ - String? id, - String? city, - String? resizePath, - String? deviceAssetId, - String? deviceId, - }) { - return CuratedLocation( - id: id ?? this.id, - city: city ?? this.city, - resizePath: resizePath ?? this.resizePath, - deviceAssetId: deviceAssetId ?? this.deviceAssetId, - deviceId: deviceId ?? this.deviceId, - ); - } - - Map toMap() { - return { - 'id': id, - 'city': city, - 'resizePath': resizePath, - 'deviceAssetId': deviceAssetId, - 'deviceId': deviceId, - }; - } - - factory CuratedLocation.fromMap(Map map) { - return CuratedLocation( - id: map['id'] ?? '', - city: map['city'] ?? '', - resizePath: map['resizePath'] ?? '', - deviceAssetId: map['deviceAssetId'] ?? '', - deviceId: map['deviceId'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory CuratedLocation.fromJson(String source) => - CuratedLocation.fromMap(json.decode(source)); - - @override - String toString() { - return 'CuratedLocation(id: $id, city: $city, resizePath: $resizePath, deviceAssetId: $deviceAssetId, deviceId: $deviceId)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is CuratedLocation && - other.id == id && - other.city == city && - other.resizePath == resizePath && - other.deviceAssetId == deviceAssetId && - other.deviceId == deviceId; - } - - @override - int get hashCode { - return id.hashCode ^ - city.hashCode ^ - resizePath.hashCode ^ - deviceAssetId.hashCode ^ - deviceId.hashCode; - } -} diff --git a/mobile/lib/modules/search/models/curated_object.model.dart b/mobile/lib/modules/search/models/curated_object.model.dart deleted file mode 100644 index c389aaf92..000000000 --- a/mobile/lib/modules/search/models/curated_object.model.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'dart:convert'; - -class CuratedObject { - final String id; - final String object; - final String resizePath; - final String deviceAssetId; - final String deviceId; - CuratedObject({ - required this.id, - required this.object, - required this.resizePath, - required this.deviceAssetId, - required this.deviceId, - }); - - CuratedObject copyWith({ - String? id, - String? object, - String? resizePath, - String? deviceAssetId, - String? deviceId, - }) { - return CuratedObject( - id: id ?? this.id, - object: object ?? this.object, - resizePath: resizePath ?? this.resizePath, - deviceAssetId: deviceAssetId ?? this.deviceAssetId, - deviceId: deviceId ?? this.deviceId, - ); - } - - Map toMap() { - final result = {}; - - result.addAll({'id': id}); - result.addAll({'object': object}); - result.addAll({'resizePath': resizePath}); - result.addAll({'deviceAssetId': deviceAssetId}); - result.addAll({'deviceId': deviceId}); - - return result; - } - - factory CuratedObject.fromMap(Map map) { - return CuratedObject( - id: map['id'] ?? '', - object: map['object'] ?? '', - resizePath: map['resizePath'] ?? '', - deviceAssetId: map['deviceAssetId'] ?? '', - deviceId: map['deviceId'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory CuratedObject.fromJson(String source) => - CuratedObject.fromMap(json.decode(source)); - - @override - String toString() { - return 'CuratedObject(id: $id, object: $object, resizePath: $resizePath, deviceAssetId: $deviceAssetId, deviceId: $deviceId)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is CuratedObject && - other.id == id && - other.object == object && - other.resizePath == resizePath && - other.deviceAssetId == deviceAssetId && - other.deviceId == deviceId; - } - - @override - int get hashCode { - return id.hashCode ^ - object.hashCode ^ - resizePath.hashCode ^ - deviceAssetId.hashCode ^ - deviceId.hashCode; - } -} diff --git a/mobile/lib/modules/search/models/search_result_page_state.model.dart b/mobile/lib/modules/search/models/search_result_page_state.model.dart index 4911bb0e6..1d79dff4b 100644 --- a/mobile/lib/modules/search/models/search_result_page_state.model.dart +++ b/mobile/lib/modules/search/models/search_result_page_state.model.dart @@ -1,13 +1,13 @@ import 'dart:convert'; import 'package:collection/collection.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class SearchResultPageState { final bool isLoading; final bool isSuccess; final bool isError; - final List searchResult; + final List searchResult; SearchResultPageState({ required this.isLoading, @@ -20,7 +20,7 @@ class SearchResultPageState { bool? isLoading, bool? isSuccess, bool? isError, - List? searchResult, + List? searchResult, }) { return SearchResultPageState( isLoading: isLoading ?? this.isLoading, @@ -35,7 +35,7 @@ class SearchResultPageState { 'isLoading': isLoading, 'isSuccess': isSuccess, 'isError': isError, - 'searchResult': searchResult.map((x) => x.toMap()).toList(), + 'searchResult': searchResult.map((x) => x.toJson()).toList(), }; } @@ -44,8 +44,9 @@ class SearchResultPageState { isLoading: map['isLoading'] ?? false, isSuccess: map['isSuccess'] ?? false, isError: map['isError'] ?? false, - searchResult: List.from( - map['searchResult']?.map((x) => ImmichAsset.fromMap(x))), + searchResult: List.from( + map['searchResult']?.map((x) => AssetResponseDto.mapFromJson(x)), + ), ); } diff --git a/mobile/lib/modules/search/providers/search_page_state.provider.dart b/mobile/lib/modules/search/providers/search_page_state.provider.dart index dc61aad1a..d66b6b280 100644 --- a/mobile/lib/modules/search/providers/search_page_state.provider.dart +++ b/mobile/lib/modules/search/providers/search_page_state.provider.dart @@ -1,9 +1,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/search/models/curated_location.model.dart'; -import 'package:immich_mobile/modules/search/models/curated_object.model.dart'; import 'package:immich_mobile/modules/search/models/search_page_state.model.dart'; import 'package:immich_mobile/modules/search/services/search.service.dart'; +import 'package:openapi/api.dart'; class SearchPageStateNotifier extends StateNotifier { SearchPageStateNotifier(this._searchService) @@ -58,7 +57,7 @@ final searchPageStateProvider = }); final getCuratedLocationProvider = - FutureProvider.autoDispose>((ref) async { + FutureProvider.autoDispose>((ref) async { final SearchService searchService = ref.watch(searchServiceProvider); var curatedLocation = await searchService.getCuratedLocation(); @@ -66,7 +65,7 @@ final getCuratedLocationProvider = }); final getCuratedObjectProvider = - FutureProvider.autoDispose>((ref) async { + FutureProvider.autoDispose>((ref) async { final SearchService searchService = ref.watch(searchServiceProvider); var curatedObject = await searchService.getCuratedObjects(); diff --git a/mobile/lib/modules/search/providers/search_result_page.provider.dart b/mobile/lib/modules/search/providers/search_result_page.provider.dart index eb9f9c3da..d6984a4b8 100644 --- a/mobile/lib/modules/search/providers/search_result_page.provider.dart +++ b/mobile/lib/modules/search/providers/search_result_page.provider.dart @@ -3,8 +3,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/search/models/search_result_page_state.model.dart'; import 'package:immich_mobile/modules/search/services/search.service.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:intl/intl.dart'; +import 'package:openapi/api.dart'; class SearchResultPageNotifier extends StateNotifier { SearchResultPageNotifier(this._searchService) @@ -21,19 +21,29 @@ class SearchResultPageNotifier extends StateNotifier { void search(String searchTerm) async { state = state.copyWith( - searchResult: [], isError: false, isLoading: true, isSuccess: false); + searchResult: [], + isError: false, + isLoading: true, + isSuccess: false, + ); - List? assets = await _searchService.searchAsset(searchTerm); + List? assets = + await _searchService.searchAsset(searchTerm); if (assets != null) { state = state.copyWith( - searchResult: assets, - isError: false, - isLoading: false, - isSuccess: true); + searchResult: assets, + isError: false, + isLoading: false, + isSuccess: true, + ); } else { state = state.copyWith( - searchResult: [], isError: true, isLoading: false, isSuccess: false); + searchResult: [], + isError: true, + isLoading: false, + isSuccess: false, + ); } } } @@ -48,7 +58,11 @@ final searchResultGroupByDateTimeProvider = StateProvider((ref) { var assets = ref.watch(searchResultPageProvider).searchResult; assets.sortByCompare( - (e) => DateTime.parse(e.createdAt), (a, b) => b.compareTo(a)); - return assets.groupListsBy((element) => - DateFormat('y-MM-dd').format(DateTime.parse(element.createdAt))); + (e) => DateTime.parse(e.createdAt), + (a, b) => b.compareTo(a), + ); + return assets.groupListsBy( + (element) => + DateFormat('y-MM-dd').format(DateTime.parse(element.createdAt)), + ); }); diff --git a/mobile/lib/modules/search/services/search.service.dart b/mobile/lib/modules/search/services/search.service.dart index 06e6bab6f..83e6122a8 100644 --- a/mobile/lib/modules/search/services/search.service.dart +++ b/mobile/lib/modules/search/services/search.service.dart @@ -1,79 +1,54 @@ -import 'dart:convert'; - import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/search/models/curated_location.model.dart'; -import 'package:immich_mobile/modules/search/models/curated_object.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; +import 'package:openapi/api.dart'; -final searchServiceProvider = - Provider((ref) => SearchService(ref.watch(networkServiceProvider))); +final searchServiceProvider = Provider( + (ref) => SearchService( + ref.watch(apiServiceProvider), + ), +); class SearchService { - final NetworkService _networkService; - SearchService(this._networkService); + final ApiService _apiService; + SearchService(this._apiService); Future?> getUserSuggestedSearchTerms() async { try { - var res = await _networkService.getRequest(url: "asset/searchTerm"); - List decodedData = jsonDecode(res.toString()); - - return List.from(decodedData); + return await _apiService.assetApi.getAssetSearchTerms(); } catch (e) { debugPrint("[ERROR] [getUserSuggestedSearchTerms] ${e.toString()}"); return []; } } - Future?> searchAsset(String searchTerm) async { + Future?> searchAsset(String searchTerm) async { try { - var res = await _networkService.postRequest( - url: "asset/search", - data: {"searchTerm": searchTerm}, - ); - - List decodedData = jsonDecode(res.toString()); - - List result = - List.from(decodedData.map((a) => ImmichAsset.fromMap(a))); - - return result; + return await _apiService.assetApi + .searchAsset(SearchAssetDto(searchTerm: searchTerm)); } catch (e) { debugPrint("[ERROR] [searchAsset] ${e.toString()}"); return null; } } - Future?> getCuratedLocation() async { + Future?> getCuratedLocation() async { try { - var res = await _networkService.getRequest(url: "asset/allLocation"); + var locations = await _apiService.assetApi.getCuratedLocations(); - List decodedData = jsonDecode(res.toString()); - - List result = - List.from(decodedData.map((a) => CuratedLocation.fromMap(a))); - - return result; + return locations; } catch (e) { - debugPrint("[ERROR] [getCuratedLocation] ${e.toString()}"); - throw Error(); + debugPrint("Error [getCuratedLocation] ${e.toString()}"); + return []; } } - Future?> getCuratedObjects() async { + Future?> getCuratedObjects() async { try { - var res = await _networkService.getRequest(url: "asset/allObjects"); - - List decodedData = jsonDecode(res.toString()); - - List result = - List.from(decodedData.map((a) => CuratedObject.fromMap(a))); - - return result; + return await _apiService.assetApi.getCuratedObjects(); } catch (e) { - debugPrint("[ERROR] [CuratedObject] ${e.toString()}"); - throw Error(); + debugPrint("Error [getCuratedObjects] ${e.toString()}"); + throw []; } } } diff --git a/mobile/lib/modules/search/ui/search_bar.dart b/mobile/lib/modules/search/ui/search_bar.dart index f1b67749a..f9883f65e 100644 --- a/mobile/lib/modules/search/ui/search_bar.dart +++ b/mobile/lib/modules/search/ui/search_bar.dart @@ -5,9 +5,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart'; class SearchBar extends HookConsumerWidget with PreferredSizeWidget { - SearchBar( - {Key? key, required this.searchFocusNode, required this.onSubmitted}) - : super(key: key); + SearchBar({ + Key? key, + required this.searchFocusNode, + required this.onSubmitted, + }) : super(key: key); final FocusNode searchFocusNode; final Function(String) onSubmitted; @@ -26,7 +28,8 @@ class SearchBar extends HookConsumerWidget with PreferredSizeWidget { ref.watch(searchPageStateProvider.notifier).disableSearch(); searchTermController.clear(); }, - icon: const Icon(Icons.arrow_back_ios_rounded)) + icon: const Icon(Icons.arrow_back_ios_rounded), + ) : const Icon(Icons.search_rounded), title: TextField( controller: searchTermController, @@ -50,10 +53,10 @@ class SearchBar extends HookConsumerWidget with PreferredSizeWidget { }, decoration: InputDecoration( hintText: 'search_bar_hint'.tr(), - enabledBorder: UnderlineInputBorder( + enabledBorder: const UnderlineInputBorder( borderSide: BorderSide(color: Colors.transparent), ), - focusedBorder: UnderlineInputBorder( + focusedBorder: const UnderlineInputBorder( borderSide: BorderSide(color: Colors.transparent), ), ), diff --git a/mobile/lib/modules/search/ui/thumbnail_with_info.dart b/mobile/lib/modules/search/ui/thumbnail_with_info.dart index 36956b9a7..d65db0224 100644 --- a/mobile/lib/modules/search/ui/thumbnail_with_info.dart +++ b/mobile/lib/modules/search/ui/thumbnail_with_info.dart @@ -2,15 +2,14 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/utils/capitalize_first_letter.dart'; class ThumbnailWithInfo extends StatelessWidget { - const ThumbnailWithInfo( - {Key? key, - required this.textInfo, - required this.imageUrl, - required this.onTap}) - : super(key: key); + const ThumbnailWithInfo({ + Key? key, + required this.textInfo, + required this.imageUrl, + required this.onTap, + }) : super(key: key); final String textInfo; final String imageUrl; diff --git a/mobile/lib/modules/search/views/search_page.dart b/mobile/lib/modules/search/views/search_page.dart index 9a2a5fb54..832c64178 100644 --- a/mobile/lib/modules/search/views/search_page.dart +++ b/mobile/lib/modules/search/views/search_page.dart @@ -5,8 +5,6 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/modules/search/models/curated_location.model.dart'; -import 'package:immich_mobile/modules/search/models/curated_object.model.dart'; import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart'; import 'package:immich_mobile/modules/search/ui/search_bar.dart'; import 'package:immich_mobile/modules/search/ui/search_suggestion_list.dart'; @@ -14,6 +12,7 @@ import 'package:immich_mobile/modules/search/ui/thumbnail_with_info.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; import 'package:immich_mobile/utils/capitalize_first_letter.dart'; +import 'package:openapi/api.dart'; // ignore: must_be_immutable class SearchPage extends HookConsumerWidget { @@ -25,15 +24,18 @@ class SearchPage extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { var box = Hive.box(userInfoBox); final isSearchEnabled = ref.watch(searchPageStateProvider).isSearchEnabled; - AsyncValue> curatedLocation = + AsyncValue> curatedLocation = ref.watch(getCuratedLocationProvider); - AsyncValue> curatedObjects = + AsyncValue> curatedObjects = ref.watch(getCuratedObjectProvider); - useEffect(() { - searchFocusNode = FocusNode(); - return () => searchFocusNode.dispose(); - }, []); + useEffect( + () { + searchFocusNode = FocusNode(); + return () => searchFocusNode.dispose(); + }, + [], + ); _onSearchSubmitted(String searchTerm) async { searchFocusNode.unfocus(); @@ -58,16 +60,16 @@ class SearchPage extends HookConsumerWidget { scrollDirection: Axis.horizontal, itemCount: curatedLocation.value?.length, itemBuilder: ((context, index) { - CuratedLocation locationInfo = curatedLocations[index]; + var locationInfo = curatedLocations[index]; var thumbnailRequestUrl = - '${box.get(serverEndpointKey)}/asset/file?aid=${locationInfo.deviceAssetId}&did=${locationInfo.deviceId}&isThumb=true'; - + '${box.get(serverEndpointKey)}/asset/thumbnail/${locationInfo.id}'; return ThumbnailWithInfo( imageUrl: thumbnailRequestUrl, textInfo: locationInfo.city, onTap: () { AutoRouter.of(context).push( - SearchResultRoute(searchTerm: locationInfo.city)); + SearchResultRoute(searchTerm: locationInfo.city), + ); }, ); }), @@ -109,7 +111,7 @@ class SearchPage extends HookConsumerWidget { scrollDirection: Axis.horizontal, itemCount: curatedObjects.value?.length, itemBuilder: ((context, index) { - CuratedObject curatedObjectInfo = objects[index]; + var curatedObjectInfo = objects[index]; var thumbnailRequestUrl = '${box.get(serverEndpointKey)}/asset/file?aid=${curatedObjectInfo.deviceAssetId}&did=${curatedObjectInfo.deviceId}&isThumb=true'; @@ -117,9 +119,12 @@ class SearchPage extends HookConsumerWidget { imageUrl: thumbnailRequestUrl, textInfo: curatedObjectInfo.object, onTap: () { - AutoRouter.of(context).push(SearchResultRoute( + AutoRouter.of(context).push( + SearchResultRoute( searchTerm: curatedObjectInfo.object - .capitalizeFirstLetter())); + .capitalizeFirstLetter(), + ), + ); }, ); }), @@ -160,7 +165,7 @@ class SearchPage extends HookConsumerWidget { ListView( children: [ Padding( - padding: EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16.0), child: const Text( "search_page_places", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), @@ -168,8 +173,8 @@ class SearchPage extends HookConsumerWidget { ), _buildPlaces(), Padding( - padding: EdgeInsets.all(16.0), - child: const Text( + padding: const EdgeInsets.all(16.0), + child: const Text( "search_page_things", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ).tr(), diff --git a/mobile/lib/modules/search/views/search_result_page.dart b/mobile/lib/modules/search/views/search_result_page.dart index 7fd14abfa..ffcd7c80b 100644 --- a/mobile/lib/modules/search/views/search_result_page.dart +++ b/mobile/lib/modules/search/views/search_result_page.dart @@ -29,13 +29,18 @@ class SearchResultPage extends HookConsumerWidget { late FocusNode searchFocusNode; - useEffect(() { - searchFocusNode = FocusNode(); + useEffect( + () { + searchFocusNode = FocusNode(); - Future.delayed(Duration.zero, - () => ref.read(searchResultPageProvider.notifier).search(searchTerm)); - return () => searchFocusNode.dispose(); - }, []); + Future.delayed( + Duration.zero, + () => ref.read(searchResultPageProvider.notifier).search(searchTerm), + ); + return () => searchFocusNode.dispose(); + }, + [], + ); _onSearchSubmitted(String newSearchTerm) { debugPrint("Re-Search with $newSearchTerm"); @@ -69,10 +74,10 @@ class SearchResultPage extends HookConsumerWidget { }, decoration: InputDecoration( hintText: 'search_result_page_new_search_hint'.tr(), - enabledBorder: UnderlineInputBorder( + enabledBorder: const UnderlineInputBorder( borderSide: BorderSide(color: Colors.transparent), ), - focusedBorder: UnderlineInputBorder( + focusedBorder: const UnderlineInputBorder( borderSide: BorderSide(color: Colors.transparent), ), ), @@ -90,9 +95,10 @@ class SearchResultPage extends HookConsumerWidget { Text( currentSearchTerm.value, style: TextStyle( - color: Theme.of(context).primaryColor, - fontSize: 13, - fontWeight: FontWeight.bold), + color: Theme.of(context).primaryColor, + fontSize: 13, + fontWeight: FontWeight.bold, + ), maxLines: 1, ), Icon( @@ -116,9 +122,10 @@ class SearchResultPage extends HookConsumerWidget { if (searchResultPageState.isLoading) { return Center( - child: SpinKitDancingSquare( - color: Theme.of(context).primaryColor, - )); + child: SpinKitDancingSquare( + color: Theme.of(context).primaryColor, + ), + ); } if (searchResultPageState.isSuccess) { @@ -184,11 +191,12 @@ class SearchResultPage extends HookConsumerWidget { icon: const Icon(Icons.arrow_back_ios_rounded), ), title: GestureDetector( - onTap: () { - isNewSearch.value = true; - searchFocusNode.requestFocus(); - }, - child: isNewSearch.value ? _buildTextField() : _buildChip()), + onTap: () { + isNewSearch.value = true; + searchFocusNode.requestFocus(); + }, + child: isNewSearch.value ? _buildTextField() : _buildChip(), + ), centerTitle: false, ), body: GestureDetector( diff --git a/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart b/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart index faea8d0ec..e2fd8e3d1 100644 --- a/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart +++ b/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart @@ -1,12 +1,10 @@ -import 'dart:convert'; - import 'package:collection/collection.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class AssetSelectionPageResult { - final Set selectedNewAsset; - final Set selectedAdditionalAsset; + final Set selectedNewAsset; + final Set selectedAdditionalAsset; final bool isAlbumExist; AssetSelectionPageResult({ @@ -16,8 +14,8 @@ class AssetSelectionPageResult { }); AssetSelectionPageResult copyWith({ - Set? selectedNewAsset, - Set? selectedAdditionalAsset, + Set? selectedNewAsset, + Set? selectedAdditionalAsset, bool? isAlbumExist, }) { return AssetSelectionPageResult( @@ -28,35 +26,6 @@ class AssetSelectionPageResult { ); } - Map toMap() { - final result = {}; - - result.addAll( - {'selectedNewAsset': selectedNewAsset.map((x) => x.toMap()).toList()}); - result.addAll({ - 'selectedAdditionalAsset': - selectedAdditionalAsset.map((x) => x.toMap()).toList() - }); - result.addAll({'isAlbumExist': isAlbumExist}); - - return result; - } - - factory AssetSelectionPageResult.fromMap(Map map) { - return AssetSelectionPageResult( - selectedNewAsset: Set.from( - map['selectedNewAsset']?.map((x) => ImmichAsset.fromMap(x))), - selectedAdditionalAsset: Set.from( - map['selectedAdditionalAsset']?.map((x) => ImmichAsset.fromMap(x))), - isAlbumExist: map['isAlbumExist'] ?? false, - ); - } - - String toJson() => json.encode(toMap()); - - factory AssetSelectionPageResult.fromJson(String source) => - AssetSelectionPageResult.fromMap(json.decode(source)); - @override String toString() => 'AssetSelectionPageResult(selectedNewAsset: $selectedNewAsset, selectedAdditionalAsset: $selectedAdditionalAsset, isAlbumExist: $isAlbumExist)'; diff --git a/mobile/lib/modules/sharing/models/asset_selection_state.model.dart b/mobile/lib/modules/sharing/models/asset_selection_state.model.dart index 7520bc2a5..6a0a9160a 100644 --- a/mobile/lib/modules/sharing/models/asset_selection_state.model.dart +++ b/mobile/lib/modules/sharing/models/asset_selection_state.model.dart @@ -1,14 +1,12 @@ -import 'dart:convert'; - import 'package:collection/collection.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class AssetSelectionState { final Set selectedMonths; - final Set selectedNewAssetsForAlbum; - final Set selectedAdditionalAssetsForAlbum; - final Set selectedAssetsInAlbumViewer; + final Set selectedNewAssetsForAlbum; + final Set selectedAdditionalAssetsForAlbum; + final Set selectedAssetsInAlbumViewer; final bool isMultiselectEnable; /// Indicate the asset selection page is navigated from existing album @@ -24,9 +22,9 @@ class AssetSelectionState { AssetSelectionState copyWith({ Set? selectedMonths, - Set? selectedNewAssetsForAlbum, - Set? selectedAdditionalAssetsForAlbum, - Set? selectedAssetsInAlbumViewer, + Set? selectedNewAssetsForAlbum, + Set? selectedAdditionalAssetsForAlbum, + Set? selectedAssetsInAlbumViewer, bool? isMultiselectEnable, bool? isAlbumExist, }) { @@ -43,49 +41,6 @@ class AssetSelectionState { ); } - Map toMap() { - final result = {}; - - result.addAll({'selectedMonths': selectedMonths.toList()}); - result.addAll({ - 'selectedNewAssetsForAlbum': - selectedNewAssetsForAlbum.map((x) => x.toMap()).toList() - }); - result.addAll({ - 'selectedAdditionalAssetsForAlbum': - selectedAdditionalAssetsForAlbum.map((x) => x.toMap()).toList() - }); - result.addAll({ - 'selectedAssetsInAlbumViewer': - selectedAssetsInAlbumViewer.map((x) => x.toMap()).toList() - }); - result.addAll({'isMultiselectEnable': isMultiselectEnable}); - result.addAll({'isAlbumExist': isAlbumExist}); - - return result; - } - - factory AssetSelectionState.fromMap(Map map) { - return AssetSelectionState( - selectedMonths: Set.from(map['selectedMonths']), - selectedNewAssetsForAlbum: Set.from( - map['selectedNewAssetsForAlbum']?.map((x) => ImmichAsset.fromMap(x))), - selectedAdditionalAssetsForAlbum: Set.from( - map['selectedAdditionalAssetsForAlbum'] - ?.map((x) => ImmichAsset.fromMap(x))), - selectedAssetsInAlbumViewer: Set.from( - map['selectedAssetsInAlbumViewer'] - ?.map((x) => ImmichAsset.fromMap(x))), - isMultiselectEnable: map['isMultiselectEnable'] ?? false, - isAlbumExist: map['isAlbumExist'] ?? false, - ); - } - - String toJson() => json.encode(toMap()); - - factory AssetSelectionState.fromJson(String source) => - AssetSelectionState.fromMap(json.decode(source)); - @override String toString() { return 'AssetSelectionState(selectedMonths: $selectedMonths, selectedNewAssetsForAlbum: $selectedNewAssetsForAlbum, selectedAdditionalAssetsForAlbum: $selectedAdditionalAssetsForAlbum, selectedAssetsInAlbumViewer: $selectedAssetsInAlbumViewer, isMultiselectEnable: $isMultiselectEnable, isAlbumExist: $isAlbumExist)'; @@ -99,10 +54,14 @@ class AssetSelectionState { return other is AssetSelectionState && setEquals(other.selectedMonths, selectedMonths) && setEquals(other.selectedNewAssetsForAlbum, selectedNewAssetsForAlbum) && - setEquals(other.selectedAdditionalAssetsForAlbum, - selectedAdditionalAssetsForAlbum) && setEquals( - other.selectedAssetsInAlbumViewer, selectedAssetsInAlbumViewer) && + other.selectedAdditionalAssetsForAlbum, + selectedAdditionalAssetsForAlbum, + ) && + setEquals( + other.selectedAssetsInAlbumViewer, + selectedAssetsInAlbumViewer, + ) && other.isMultiselectEnable == isMultiselectEnable && other.isAlbumExist == isAlbumExist; } diff --git a/mobile/lib/modules/sharing/models/shared_album.model.dart b/mobile/lib/modules/sharing/models/shared_album.model.dart deleted file mode 100644 index d8f146892..000000000 --- a/mobile/lib/modules/sharing/models/shared_album.model.dart +++ /dev/null @@ -1,117 +0,0 @@ -import 'dart:convert'; - -import 'package:collection/collection.dart'; - -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; -import 'package:immich_mobile/shared/models/user.model.dart'; - -class SharedAlbum { - final String id; - final String ownerId; - final String albumName; - final String createdAt; - final String? albumThumbnailAssetId; - final List sharedUsers; - final List? assets; - - SharedAlbum({ - required this.id, - required this.ownerId, - required this.albumName, - required this.createdAt, - required this.albumThumbnailAssetId, - required this.sharedUsers, - this.assets, - }); - - SharedAlbum copyWith({ - String? id, - String? ownerId, - String? albumName, - String? createdAt, - String? albumThumbnailAssetId, - List? sharedUsers, - List? assets, - }) { - return SharedAlbum( - id: id ?? this.id, - ownerId: ownerId ?? this.ownerId, - albumName: albumName ?? this.albumName, - createdAt: createdAt ?? this.createdAt, - albumThumbnailAssetId: - albumThumbnailAssetId ?? this.albumThumbnailAssetId, - sharedUsers: sharedUsers ?? this.sharedUsers, - assets: assets ?? this.assets, - ); - } - - Map toMap() { - final result = {}; - - result.addAll({'id': id}); - result.addAll({'ownerId': ownerId}); - result.addAll({'albumName': albumName}); - result.addAll({'createdAt': createdAt}); - if (albumThumbnailAssetId != null) { - result.addAll({'albumThumbnailAssetId': albumThumbnailAssetId}); - } - result.addAll({'sharedUsers': sharedUsers.map((x) => x.toMap()).toList()}); - if (assets != null) { - result.addAll({'assets': assets!.map((x) => x.toMap()).toList()}); - } - - return result; - } - - factory SharedAlbum.fromMap(Map map) { - return SharedAlbum( - id: map['id'] ?? '', - ownerId: map['ownerId'] ?? '', - albumName: map['albumName'] ?? '', - createdAt: map['createdAt'] ?? '', - albumThumbnailAssetId: map['albumThumbnailAssetId'], - sharedUsers: - List.from(map['sharedUsers']?.map((x) => User.fromMap(x))), - assets: map['assets'] != null - ? List.from( - map['assets']?.map((x) => ImmichAsset.fromMap(x))) - : null, - ); - } - - String toJson() => json.encode(toMap()); - - factory SharedAlbum.fromJson(String source) => - SharedAlbum.fromMap(json.decode(source)); - - @override - String toString() { - return 'SharedAlbum(id: $id, ownerId: $ownerId, albumName: $albumName, createdAt: $createdAt, albumThumbnailAssetId: $albumThumbnailAssetId, sharedUsers: $sharedUsers, assets: $assets)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - final listEquals = const DeepCollectionEquality().equals; - - return other is SharedAlbum && - other.id == id && - other.ownerId == ownerId && - other.albumName == albumName && - other.createdAt == createdAt && - other.albumThumbnailAssetId == albumThumbnailAssetId && - listEquals(other.sharedUsers, sharedUsers) && - listEquals(other.assets, assets); - } - - @override - int get hashCode { - return id.hashCode ^ - ownerId.hashCode ^ - albumName.hashCode ^ - createdAt.hashCode ^ - albumThumbnailAssetId.hashCode ^ - sharedUsers.hashCode ^ - assets.hashCode; - } -} diff --git a/mobile/lib/modules/sharing/providers/album_title.provider.dart b/mobile/lib/modules/sharing/providers/album_title.provider.dart index 5ccc82d40..126b3499a 100644 --- a/mobile/lib/modules/sharing/providers/album_title.provider.dart +++ b/mobile/lib/modules/sharing/providers/album_title.provider.dart @@ -13,4 +13,5 @@ class AlbumTitleNotifier extends StateNotifier { } final albumTitleProvider = StateNotifierProvider( - (ref) => AlbumTitleNotifier()); + (ref) => AlbumTitleNotifier(), +); diff --git a/mobile/lib/modules/sharing/providers/album_viewer.provider.dart b/mobile/lib/modules/sharing/providers/album_viewer.provider.dart index 4e64b8eb5..561f93710 100644 --- a/mobile/lib/modules/sharing/providers/album_viewer.provider.dart +++ b/mobile/lib/modules/sharing/providers/album_viewer.provider.dart @@ -30,7 +30,10 @@ class AlbumViewerNotifier extends StateNotifier { } Future changeAlbumTitle( - String albumId, String ownerId, String newAlbumTitle) async { + String albumId, + String ownerId, + String newAlbumTitle, + ) async { SharedAlbumService service = ref.watch(sharedAlbumServiceProvider); bool isSuccess = diff --git a/mobile/lib/modules/sharing/providers/asset_selection.provider.dart b/mobile/lib/modules/sharing/providers/asset_selection.provider.dart index c87a59aa2..809e3d18c 100644 --- a/mobile/lib/modules/sharing/providers/asset_selection.provider.dart +++ b/mobile/lib/modules/sharing/providers/asset_selection.provider.dart @@ -1,41 +1,46 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/sharing/models/asset_selection_state.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class AssetSelectionNotifier extends StateNotifier { AssetSelectionNotifier() - : super(AssetSelectionState( - selectedNewAssetsForAlbum: {}, - selectedMonths: {}, - selectedAdditionalAssetsForAlbum: {}, - selectedAssetsInAlbumViewer: {}, - isAlbumExist: false, - isMultiselectEnable: false, - )); + : super( + AssetSelectionState( + selectedNewAssetsForAlbum: {}, + selectedMonths: {}, + selectedAdditionalAssetsForAlbum: {}, + selectedAssetsInAlbumViewer: {}, + isAlbumExist: false, + isMultiselectEnable: false, + ), + ); void setIsAlbumExist(bool isAlbumExist) { state = state.copyWith(isAlbumExist: isAlbumExist); } void removeAssetsInMonth( - String removedMonth, List assetsInMonth) { - Set currentAssetList = state.selectedNewAssetsForAlbum; + String removedMonth, + List assetsInMonth, + ) { + Set currentAssetList = state.selectedNewAssetsForAlbum; Set currentMonthList = state.selectedMonths; currentMonthList .removeWhere((selectedMonth) => selectedMonth == removedMonth); - for (ImmichAsset asset in assetsInMonth) { + for (AssetResponseDto asset in assetsInMonth) { currentAssetList.removeWhere((e) => e.id == asset.id); } state = state.copyWith( - selectedNewAssetsForAlbum: currentAssetList, - selectedMonths: currentMonthList); + selectedNewAssetsForAlbum: currentAssetList, + selectedMonths: currentMonthList, + ); } - void addAdditionalAssets(List assets) { + void addAdditionalAssets(List assets) { state = state.copyWith( selectedAdditionalAssetsForAlbum: { ...state.selectedAdditionalAssetsForAlbum, @@ -44,7 +49,7 @@ class AssetSelectionNotifier extends StateNotifier { ); } - void addAllAssetsInMonth(String month, List assetsInMonth) { + void addAllAssetsInMonth(String month, List assetsInMonth) { state = state.copyWith( selectedMonths: {...state.selectedMonths, month}, selectedNewAssetsForAlbum: { @@ -54,7 +59,7 @@ class AssetSelectionNotifier extends StateNotifier { ); } - void addNewAssets(List assets) { + void addNewAssets(List assets) { state = state.copyWith( selectedNewAssetsForAlbum: { ...state.selectedNewAssetsForAlbum, @@ -63,20 +68,20 @@ class AssetSelectionNotifier extends StateNotifier { ); } - void removeSelectedNewAssets(List assets) { - Set currentList = state.selectedNewAssetsForAlbum; + void removeSelectedNewAssets(List assets) { + Set currentList = state.selectedNewAssetsForAlbum; - for (ImmichAsset asset in assets) { + for (AssetResponseDto asset in assets) { currentList.removeWhere((e) => e.id == asset.id); } state = state.copyWith(selectedNewAssetsForAlbum: currentList); } - void removeSelectedAdditionalAssets(List assets) { - Set currentList = state.selectedAdditionalAssetsForAlbum; + void removeSelectedAdditionalAssets(List assets) { + Set currentList = state.selectedAdditionalAssetsForAlbum; - for (ImmichAsset asset in assets) { + for (AssetResponseDto asset in assets) { currentList.removeWhere((e) => e.id == asset.id); } @@ -104,7 +109,7 @@ class AssetSelectionNotifier extends StateNotifier { ); } - void addAssetsInAlbumViewer(List assets) { + void addAssetsInAlbumViewer(List assets) { state = state.copyWith( selectedAssetsInAlbumViewer: { ...state.selectedAssetsInAlbumViewer, @@ -113,10 +118,10 @@ class AssetSelectionNotifier extends StateNotifier { ); } - void removeAssetsInAlbumViewer(List assets) { - Set currentList = state.selectedAssetsInAlbumViewer; + void removeAssetsInAlbumViewer(List assets) { + Set currentList = state.selectedAssetsInAlbumViewer; - for (ImmichAsset asset in assets) { + for (AssetResponseDto asset in assets) { currentList.removeWhere((e) => e.id == asset.id); } diff --git a/mobile/lib/modules/sharing/providers/shared_album.provider.dart b/mobile/lib/modules/sharing/providers/shared_album.provider.dart index efb3c090a..792db47aa 100644 --- a/mobile/lib/modules/sharing/providers/shared_album.provider.dart +++ b/mobile/lib/modules/sharing/providers/shared_album.provider.dart @@ -1,17 +1,19 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart'; +import 'package:openapi/api.dart'; -class SharedAlbumNotifier extends StateNotifier> { +class SharedAlbumNotifier extends StateNotifier> { SharedAlbumNotifier(this._sharedAlbumService) : super([]); final SharedAlbumService _sharedAlbumService; getAllSharedAlbums() async { - List sharedAlbums = + List? sharedAlbums = await _sharedAlbumService.getAllSharedAlbum(); - state = sharedAlbums; + if (sharedAlbums != null) { + state = sharedAlbums; + } } Future deleteAlbum(String albumId) async { @@ -37,7 +39,9 @@ class SharedAlbumNotifier extends StateNotifier> { } Future removeAssetFromAlbum( - String albumId, List assetIds) async { + String albumId, + List assetIds, + ) async { var res = await _sharedAlbumService.removeAssetFromAlbum(albumId, assetIds); if (res) { @@ -49,12 +53,12 @@ class SharedAlbumNotifier extends StateNotifier> { } final sharedAlbumProvider = - StateNotifierProvider>((ref) { + StateNotifierProvider>((ref) { return SharedAlbumNotifier(ref.watch(sharedAlbumServiceProvider)); }); final sharedAlbumDetailProvider = FutureProvider.autoDispose - .family((ref, albumId) async { + .family((ref, albumId) async { final SharedAlbumService sharedAlbumService = ref.watch(sharedAlbumServiceProvider); diff --git a/mobile/lib/modules/sharing/providers/suggested_shared_users.provider.dart b/mobile/lib/modules/sharing/providers/suggested_shared_users.provider.dart index 8ddc122b2..0c4a2a350 100644 --- a/mobile/lib/modules/sharing/providers/suggested_shared_users.provider.dart +++ b/mobile/lib/modules/sharing/providers/suggested_shared_users.provider.dart @@ -1,10 +1,10 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/shared/models/user.model.dart'; import 'package:immich_mobile/shared/services/user.service.dart'; +import 'package:openapi/api.dart'; final suggestedSharedUsersProvider = - FutureProvider.autoDispose>((ref) async { + FutureProvider.autoDispose>((ref) async { UserService userService = ref.watch(userServiceProvider); - return await userService.getAllUsersInfo(); + return await userService.getAllUsersInfo(isAll: false) ?? []; }); diff --git a/mobile/lib/modules/sharing/services/shared_album.service.dart b/mobile/lib/modules/sharing/services/shared_album.service.dart index 9183dcb8d..92a995fb9 100644 --- a/mobile/lib/modules/sharing/services/shared_album.service.dart +++ b/mobile/lib/modules/sharing/services/shared_album.service.dart @@ -1,73 +1,69 @@ import 'dart:async'; -import 'dart:convert'; -import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; +import 'package:openapi/api.dart'; -final sharedAlbumServiceProvider = - Provider((ref) => SharedAlbumService(ref.watch(networkServiceProvider))); +final sharedAlbumServiceProvider = Provider( + (ref) => SharedAlbumService( + ref.watch(apiServiceProvider), + ), +); class SharedAlbumService { - final NetworkService _networkService; - SharedAlbumService(this._networkService); + final ApiService _apiService; + SharedAlbumService(this._apiService); - Future> getAllSharedAlbum() async { + Future?> getAllSharedAlbum() async { try { - var res = await _networkService.getRequest(url: 'album?shared=true'); - List decodedData = jsonDecode(res.toString()); - List result = - List.from(decodedData.map((e) => SharedAlbum.fromMap(e))); - - return result; + return await _apiService.albumApi.getAllAlbums(shared: true); } catch (e) { debugPrint("Error getAllSharedAlbum ${e.toString()}"); + return null; } - - return []; } - Future createSharedAlbum(String albumName, Set assets, - List sharedUserIds) async { + Future createSharedAlbum( + String albumName, + Set assets, + List sharedUserIds, + ) async { try { - var res = await _networkService.postRequest(url: 'album', data: { - "albumName": albumName, - "sharedWithUserIds": sharedUserIds, - "assetIds": assets.map((asset) => asset.id).toList(), - }); + _apiService.albumApi.createAlbum( + CreateAlbumDto( + albumName: albumName, + assetIds: assets.map((asset) => asset.id).toList(), + sharedWithUserIds: sharedUserIds, + ), + ); - return res != null; + return true; } catch (e) { debugPrint("Error createSharedAlbum ${e.toString()}"); return false; } } - Future getAlbumDetail(String albumId) async { + Future getAlbumDetail(String albumId) async { try { - var res = await _networkService.getRequest(url: 'album/$albumId'); - dynamic decodedData = jsonDecode(res.toString()); - SharedAlbum result = SharedAlbum.fromMap(decodedData); - - return result; + return await _apiService.albumApi.getAlbumInfo(albumId); } catch (e) { - throw Exception('Error getAllSharedAlbum ${e.toString()}'); + debugPrint('Error [getAlbumDetail] ${e.toString()}'); + return null; } } Future addAdditionalAssetToAlbum( - Set assets, String albumId) async { + Set assets, + String albumId, + ) async { try { - var res = - await _networkService.putRequest(url: 'album/$albumId/assets', data: { - "albumId": albumId, - "assetIds": assets.map((asset) => asset.id).toList(), - }); - - return res != null; + var result = await _apiService.albumApi.addAssetsToAlbum( + albumId, + AddAssetsDto(assetIds: assets.map((asset) => asset.id).toList()), + ); + return result != null; } catch (e) { debugPrint("Error addAdditionalAssetToAlbum ${e.toString()}"); return false; @@ -75,14 +71,16 @@ class SharedAlbumService { } Future addAdditionalUserToAlbum( - List sharedUserIds, String albumId) async { + List sharedUserIds, + String albumId, + ) async { try { - var res = - await _networkService.putRequest(url: 'album/$albumId/users', data: { - "sharedUserIds": sharedUserIds, - }); + var result = await _apiService.albumApi.addUsersToAlbum( + albumId, + AddUsersDto(sharedUserIds: sharedUserIds), + ); - return res != null; + return result != null; } catch (e) { debugPrint("Error addAdditionalUserToAlbum ${e.toString()}"); return false; @@ -91,12 +89,7 @@ class SharedAlbumService { Future deleteAlbum(String albumId) async { try { - Response res = await _networkService.deleteRequest(url: 'album/$albumId'); - - if (res.statusCode != 200) { - return false; - } - + await _apiService.albumApi.deleteAlbum(albumId); return true; } catch (e) { debugPrint("Error deleteAlbum ${e.toString()}"); @@ -106,12 +99,7 @@ class SharedAlbumService { Future leaveAlbum(String albumId) async { try { - Response res = - await _networkService.deleteRequest(url: 'album/$albumId/user/me'); - - if (res.statusCode != 200) { - return false; - } + await _apiService.albumApi.removeUserFromAlbum(albumId, "me"); return true; } catch (e) { @@ -121,16 +109,14 @@ class SharedAlbumService { } Future removeAssetFromAlbum( - String albumId, List assetIds) async { + String albumId, + List assetIds, + ) async { try { - Response res = await _networkService - .deleteRequest(url: 'album/$albumId/assets', data: { - "assetIds": assetIds, - }); - - if (res.statusCode != 200) { - return false; - } + await _apiService.albumApi.removeAssetFromAlbum( + albumId, + RemoveAssetsDto(assetIds: assetIds), + ); return true; } catch (e) { @@ -140,17 +126,18 @@ class SharedAlbumService { } Future changeTitleAlbum( - String albumId, String ownerId, String newAlbumTitle) async { + String albumId, + String ownerId, + String newAlbumTitle, + ) async { try { - Response res = - await _networkService.patchRequest(url: 'album/$albumId/', data: { - "ownerId": ownerId, - "albumName": newAlbumTitle, - }); - - if (res.statusCode != 200) { - return false; - } + await _apiService.albumApi.updateAlbumInfo( + albumId, + UpdateAlbumDto( + ownerId: ownerId, + albumName: newAlbumTitle, + ), + ); return true; } catch (e) { diff --git a/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart b/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart index 3a4a351cf..fdfab5976 100644 --- a/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart +++ b/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart @@ -5,12 +5,12 @@ class AlbumActionOutlinedButton extends StatelessWidget { final String labelText; final IconData iconData; - const AlbumActionOutlinedButton( - {Key? key, - this.onPressed, - required this.labelText, - required this.iconData}) - : super(key: key); + const AlbumActionOutlinedButton({ + Key? key, + this.onPressed, + required this.labelText, + required this.iconData, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -31,7 +31,10 @@ class AlbumActionOutlinedButton extends StatelessWidget { label: Text( labelText, style: const TextStyle( - fontSize: 12, fontWeight: FontWeight.bold, color: Colors.black87), + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), ), onPressed: onPressed, ), diff --git a/mobile/lib/modules/sharing/ui/album_title_text_field.dart b/mobile/lib/modules/sharing/ui/album_title_text_field.dart index 1556c87fa..61dbad01a 100644 --- a/mobile/lib/modules/sharing/ui/album_title_text_field.dart +++ b/mobile/lib/modules/sharing/ui/album_title_text_field.dart @@ -31,7 +31,10 @@ class AlbumTitleTextField extends ConsumerWidget { }, focusNode: albumTitleTextFieldFocusNode, style: TextStyle( - fontSize: 28, color: Colors.grey[700], fontWeight: FontWeight.bold), + fontSize: 28, + color: Colors.grey[700], + fontWeight: FontWeight.bold, + ), controller: albumTitleController, onTap: () { isAlbumTitleTextFieldFocus.value = true; diff --git a/mobile/lib/modules/sharing/ui/album_viewer_appbar.dart b/mobile/lib/modules/sharing/ui/album_viewer_appbar.dart index bcb0690a2..dd85021e5 100644 --- a/mobile/lib/modules/sharing/ui/album_viewer_appbar.dart +++ b/mobile/lib/modules/sharing/ui/album_viewer_appbar.dart @@ -4,24 +4,24 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/immich_colors.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/providers/album_viewer.provider.dart'; import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart'; import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart'; import 'package:immich_mobile/shared/views/immich_loading_overlay.dart'; +import 'package:openapi/api.dart'; class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget { const AlbumViewerAppbar({ Key? key, - required AsyncValue albumInfo, + required AsyncValue albumInfo, required this.userId, required this.albumId, }) : _albumInfo = albumInfo, super(key: key); - final AsyncValue _albumInfo; + final AsyncValue _albumInfo; final String userId; final String albumId; @@ -105,7 +105,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget { _buildBottomSheetActionButton() { if (isMultiSelectionEnable) { - if (_albumInfo.asData?.value.ownerId == userId) { + if (_albumInfo.asData?.value?.ownerId == userId) { return ListTile( leading: const Icon(Icons.delete_sweep_rounded), title: const Text( @@ -118,7 +118,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget { return const SizedBox(); } } else { - if (_albumInfo.asData?.value.ownerId == userId) { + if (_albumInfo.asData?.value?.ownerId == userId) { return ListTile( leading: const Icon(Icons.delete_forever_rounded), title: const Text( diff --git a/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart b/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart index 52d093868..79f87d5b2 100644 --- a/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart +++ b/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart @@ -2,15 +2,17 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/providers/album_viewer.provider.dart'; +import 'package:openapi/api.dart'; class AlbumViewerEditableTitle extends HookConsumerWidget { - final SharedAlbum albumInfo; + final AlbumResponseDto albumInfo; final FocusNode titleFocusNode; - const AlbumViewerEditableTitle( - {Key? key, required this.albumInfo, required this.titleFocusNode}) - : super(key: key); + const AlbumViewerEditableTitle({ + Key? key, + required this.albumInfo, + required this.titleFocusNode, + }) : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { @@ -24,12 +26,15 @@ class AlbumViewerEditableTitle extends HookConsumerWidget { } } - useEffect(() { - titleFocusNode.addListener(onFocusModeChange); - return () { - titleFocusNode.removeListener(onFocusModeChange); - }; - }, []); + useEffect( + () { + titleFocusNode.addListener(onFocusModeChange); + return () { + titleFocusNode.removeListener(onFocusModeChange); + }; + }, + [], + ); return TextField( onChanged: (value) { diff --git a/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart b/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart index 95a2b1bf7..c5f3a6bd9 100644 --- a/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart +++ b/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart @@ -7,11 +7,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/routing/router.dart'; +import 'package:openapi/api.dart'; class AlbumViewerThumbnail extends HookConsumerWidget { - final ImmichAsset asset; + final AssetResponseDto asset; const AlbumViewerThumbnail({Key? key, required this.asset}) : super(key: key); @@ -20,7 +20,7 @@ class AlbumViewerThumbnail extends HookConsumerWidget { final cacheKey = useState(1); var box = Hive.box(userInfoBox); var thumbnailRequestUrl = - '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true'; + '${box.get(serverEndpointKey)}/asset/thumbnail/${asset.id}'; var deviceId = ref.watch(authenticationProvider).deviceId; final selectedAssetsInAlbumViewer = ref.watch(assetSelectionProvider).selectedAssetsInAlbumViewer; @@ -28,7 +28,7 @@ class AlbumViewerThumbnail extends HookConsumerWidget { ref.watch(assetSelectionProvider).isMultiselectEnable; _viewAsset() { - if (asset.type == 'IMAGE') { + if (asset.type == AssetTypeEnum.IMAGE) { AutoRouter.of(context).push( ImageViewerRoute( imageUrl: @@ -41,9 +41,10 @@ class AlbumViewerThumbnail extends HookConsumerWidget { } else { AutoRouter.of(context).push( VideoViewerRoute( - videoUrl: - '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', - asset: asset), + videoUrl: + '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', + asset: asset, + ), ); } } @@ -170,16 +171,13 @@ class AlbumViewerThumbnail extends HookConsumerWidget { return GestureDetector( onTap: isMultiSelectionEnable ? _handleSelectionGesture : _viewAsset, onLongPress: _enableMultiSelection, - child: Hero( - tag: asset.id, - child: Stack( - children: [ - _buildThumbnailImage(), - _buildAssetStoreLocationIcon(), - if (asset.type != 'IMAGE') _buildVideoLabel(), - if (isMultiSelectionEnable) _buildAssetSelectionIcon(), - ], - ), + child: Stack( + children: [ + _buildThumbnailImage(), + _buildAssetStoreLocationIcon(), + if (asset.type != AssetTypeEnum.IMAGE) _buildVideoLabel(), + if (isMultiSelectionEnable) _buildAssetSelectionIcon(), + ], ), ); } diff --git a/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart b/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart index 8d719bac5..358648762 100644 --- a/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart +++ b/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/sharing/ui/selection_thumbnail_image.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class AssetGridByMonth extends HookConsumerWidget { - final List assetGroup; + final List assetGroup; const AssetGridByMonth({Key? key, required this.assetGroup}) : super(key: key); @override diff --git a/mobile/lib/modules/sharing/ui/month_group_title.dart b/mobile/lib/modules/sharing/ui/month_group_title.dart index 71e160664..ba766721a 100644 --- a/mobile/lib/modules/sharing/ui/month_group_title.dart +++ b/mobile/lib/modules/sharing/ui/month_group_title.dart @@ -2,15 +2,17 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class MonthGroupTitle extends HookConsumerWidget { final String month; - final List assetGroup; + final List assetGroup; - const MonthGroupTitle( - {Key? key, required this.month, required this.assetGroup}) - : super(key: key); + const MonthGroupTitle({ + Key? key, + required this.month, + required this.assetGroup, + }) : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { @@ -75,7 +77,11 @@ class MonthGroupTitle extends HookConsumerWidget { return SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.only( - top: 29.0, bottom: 29.0, left: 14.0, right: 8.0), + top: 29.0, + bottom: 29.0, + left: 14.0, + right: 8.0, + ), child: Row( children: [ GestureDetector( diff --git a/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart b/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart index 13e6ce203..24be82106 100644 --- a/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart +++ b/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart @@ -5,10 +5,10 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class SelectionThumbnailImage extends HookConsumerWidget { - final ImmichAsset asset; + final AssetResponseDto asset; const SelectionThumbnailImage({Key? key, required this.asset}) : super(key: key); @@ -18,14 +18,14 @@ class SelectionThumbnailImage extends HookConsumerWidget { final cacheKey = useState(1); var box = Hive.box(userInfoBox); var thumbnailRequestUrl = - '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true'; + '${box.get(serverEndpointKey)}/asset/thumbnail/${asset.id}'; var selectedAsset = ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum; var newAssetsForAlbum = ref.watch(assetSelectionProvider).selectedAdditionalAssetsForAlbum; var isAlbumExist = ref.watch(assetSelectionProvider).isAlbumExist; - Widget _buildSelectionIcon(ImmichAsset asset) { + Widget _buildSelectionIcon(AssetResponseDto asset) { if (selectedAsset.contains(asset) && !isAlbumExist) { return Icon( Icons.check_circle, @@ -103,7 +103,7 @@ class SelectionThumbnailImage extends HookConsumerWidget { cacheKey: "${asset.id}-${cacheKey.value}", width: 150, height: 150, - memCacheHeight: asset.type == 'IMAGE' ? 150 : 150, + memCacheHeight: asset.type == AssetTypeEnum.IMAGE ? 150 : 150, fit: BoxFit.cover, imageUrl: thumbnailRequestUrl, httpHeaders: { @@ -131,14 +131,14 @@ class SelectionThumbnailImage extends HookConsumerWidget { child: _buildSelectionIcon(asset), ), ), - if (asset.type != 'IMAGE') + if (asset.type != AssetTypeEnum.IMAGE) Positioned( bottom: 5, right: 5, child: Row( children: [ Text( - '${asset.duration?.substring(0, 7)}', + asset.duration.substring(0, 7), style: const TextStyle( color: Colors.white, fontSize: 10, diff --git a/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart b/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart index b6b75d65a..d62f1e097 100644 --- a/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart +++ b/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart @@ -4,10 +4,10 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; +import 'package:openapi/api.dart'; class SharedAlbumThumbnailImage extends HookConsumerWidget { - final ImmichAsset asset; + final AssetResponseDto asset; const SharedAlbumThumbnailImage({Key? key, required this.asset}) : super(key: key); @@ -18,7 +18,7 @@ class SharedAlbumThumbnailImage extends HookConsumerWidget { var box = Hive.box(userInfoBox); var thumbnailRequestUrl = - '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true'; + '${box.get(serverEndpointKey)}/asset/thumbnail/${asset.id}'; return GestureDetector( onTap: () { @@ -30,7 +30,7 @@ class SharedAlbumThumbnailImage extends HookConsumerWidget { cacheKey: "${asset.id}-${cacheKey.value}", width: 500, height: 500, - memCacheHeight: asset.type == 'IMAGE' ? 500 : 500, + memCacheHeight: 500, fit: BoxFit.cover, imageUrl: thumbnailRequestUrl, httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"}, diff --git a/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart b/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart index 32adf2138..e39bcf115 100644 --- a/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart +++ b/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart @@ -40,7 +40,8 @@ class SharingSliverAppBar extends StatelessWidget { child: TextButton.icon( style: ButtonStyle( backgroundColor: MaterialStateProperty.all( - Theme.of(context).primaryColor.withAlpha(20)), + Theme.of(context).primaryColor.withAlpha(20), + ), // foregroundColor: MaterialStateProperty.all(Colors.white), ), onPressed: () { @@ -65,7 +66,8 @@ class SharingSliverAppBar extends StatelessWidget { child: TextButton.icon( style: ButtonStyle( backgroundColor: MaterialStateProperty.all( - Theme.of(context).primaryColor.withAlpha(20)), + Theme.of(context).primaryColor.withAlpha(20), + ), // foregroundColor: MaterialStateProperty.all(Colors.white), ), onPressed: null, diff --git a/mobile/lib/modules/sharing/views/album_viewer_page.dart b/mobile/lib/modules/sharing/views/album_viewer_page.dart index 1f26a643e..c10268d67 100644 --- a/mobile/lib/modules/sharing/views/album_viewer_page.dart +++ b/mobile/lib/modules/sharing/views/album_viewer_page.dart @@ -7,7 +7,6 @@ import 'package:immich_mobile/constants/immich_colors.dart'; import 'package:immich_mobile/modules/home/ui/draggable_scrollbar.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/modules/sharing/models/asset_selection_page_result.model.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart'; import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.dart'; import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart'; @@ -19,7 +18,7 @@ import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; import 'package:immich_mobile/shared/ui/immich_sliver_persistent_app_bar_delegate.dart'; import 'package:immich_mobile/shared/views/immich_loading_overlay.dart'; -import 'package:intl/intl.dart'; +import 'package:openapi/api.dart'; class AlbumViewerPage extends HookConsumerWidget { final String albumId; @@ -30,18 +29,18 @@ class AlbumViewerPage extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { FocusNode titleFocusNode = useFocusNode(); ScrollController scrollController = useScrollController(); - AsyncValue albumInfo = + AsyncValue albumInfo = ref.watch(sharedAlbumDetailProvider(albumId)); final userId = ref.watch(authenticationProvider).userId; /// Find out if the assets in album exist on the device /// If they exist, add to selected asset state to show they are already selected. - void _onAddPhotosPressed(SharedAlbum albumInfo) async { - if (albumInfo.assets?.isNotEmpty == true) { + void _onAddPhotosPressed(AlbumResponseDto albumInfo) async { + if (albumInfo.assets.isNotEmpty == true) { ref .watch(assetSelectionProvider.notifier) - .addNewAssets(albumInfo.assets!.toList()); + .addNewAssets(albumInfo.assets.toList()); } ref.watch(assetSelectionProvider.notifier).setIsAlbumExist(true); @@ -57,7 +56,9 @@ class AlbumViewerPage extends HookConsumerWidget { var isSuccess = await ref .watch(sharedAlbumServiceProvider) .addAdditionalAssetToAlbum( - returnPayload.selectedAdditionalAsset, albumId); + returnPayload.selectedAdditionalAsset, + albumId, + ); if (isSuccess) { ref.refresh(sharedAlbumDetailProvider(albumId)); @@ -72,10 +73,11 @@ class AlbumViewerPage extends HookConsumerWidget { } } - void _onAddUsersPressed(SharedAlbum albumInfo) async { - List? sharedUserIds = await AutoRouter.of(context) - .push?>( - SelectAdditionalUserForSharingRoute(albumInfo: albumInfo)); + void _onAddUsersPressed(AlbumResponseDto albumInfo) async { + List? sharedUserIds = + await AutoRouter.of(context).push?>( + SelectAdditionalUserForSharingRoute(albumInfo: albumInfo), + ); if (sharedUserIds != null) { ImmichLoadingOverlayController.appLoader.show(); @@ -92,7 +94,7 @@ class AlbumViewerPage extends HookConsumerWidget { } } - Widget _buildTitle(SharedAlbum albumInfo) { + Widget _buildTitle(AlbumResponseDto albumInfo) { return Padding( padding: const EdgeInsets.only(left: 8, right: 8, top: 16), child: userId == albumInfo.ownerId @@ -102,19 +104,24 @@ class AlbumViewerPage extends HookConsumerWidget { ) : Padding( padding: const EdgeInsets.only(left: 8.0), - child: Text(albumInfo.albumName, - style: const TextStyle( - fontSize: 24, fontWeight: FontWeight.bold)), + child: Text( + albumInfo.albumName, + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), ), ); } - Widget _buildAlbumDateRange(SharedAlbum albumInfo) { + Widget _buildAlbumDateRange(AlbumResponseDto albumInfo) { String startDate = ""; DateTime parsedStartDate = - DateTime.parse(albumInfo.assets!.first.createdAt); + DateTime.parse(albumInfo.assets.first.createdAt); DateTime parsedEndDate = DateTime.parse( - albumInfo.assets?.last.createdAt ?? '11111111'); //Need default. + albumInfo.assets.last.createdAt, + ); //Need default. if (parsedStartDate.year == parsedEndDate.year) { startDate = DateFormat('LLL d').format(parsedStartDate); @@ -129,18 +136,21 @@ class AlbumViewerPage extends HookConsumerWidget { child: Text( "$startDate-$endDate", style: const TextStyle( - fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey), + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), ), ); } - Widget _buildHeader(SharedAlbum albumInfo) { + Widget _buildHeader(AlbumResponseDto albumInfo) { return SliverToBoxAdapter( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildTitle(albumInfo), - if (albumInfo.assets?.isNotEmpty == true) + if (albumInfo.assets.isNotEmpty == true) _buildAlbumDateRange(albumInfo), SizedBox( height: 60, @@ -172,8 +182,8 @@ class AlbumViewerPage extends HookConsumerWidget { ); } - Widget _buildImageGrid(SharedAlbum albumInfo) { - if (albumInfo.assets?.isNotEmpty == true) { + Widget _buildImageGrid(AlbumResponseDto albumInfo) { + if (albumInfo.assets.isNotEmpty) { return SliverPadding( padding: const EdgeInsets.only(top: 10.0), sliver: SliverGrid( @@ -184,9 +194,9 @@ class AlbumViewerPage extends HookConsumerWidget { ), delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { - return AlbumViewerThumbnail(asset: albumInfo.assets![index]); + return AlbumViewerThumbnail(asset: albumInfo.assets[index]); }, - childCount: albumInfo.assets?.length, + childCount: albumInfo.assets.length, ), ), ); @@ -194,7 +204,7 @@ class AlbumViewerPage extends HookConsumerWidget { return const SliverToBoxAdapter(); } - Widget _buildControlButton(SharedAlbum albumInfo) { + Widget _buildControlButton(AlbumResponseDto albumInfo) { return Padding( padding: const EdgeInsets.only(left: 16.0, top: 8, bottom: 8), child: SizedBox( @@ -219,7 +229,7 @@ class AlbumViewerPage extends HookConsumerWidget { ); } - Widget _buildBody(SharedAlbum albumInfo) { + Widget _buildBody(AlbumResponseDto albumInfo) { return GestureDetector( onTap: () { titleFocusNode.unfocus(); @@ -252,9 +262,16 @@ class AlbumViewerPage extends HookConsumerWidget { return Scaffold( appBar: AlbumViewerAppbar( - albumInfo: albumInfo, userId: userId, albumId: albumId), + albumInfo: albumInfo, + userId: userId, + albumId: albumId, + ), body: albumInfo.when( - data: (albumInfo) => _buildBody(albumInfo), + data: (albumInfo) => albumInfo != null + ? _buildBody(albumInfo) + : const Center( + child: CircularProgressIndicator(), + ), error: (e, _) => Center(child: Text("Error loading album info $e")), loading: () => const Center( child: ImmichLoadingIndicator(), diff --git a/mobile/lib/modules/sharing/views/create_shared_album_page.dart b/mobile/lib/modules/sharing/views/create_shared_album_page.dart index 2da6eae0a..6cc6b1faa 100644 --- a/mobile/lib/modules/sharing/views/create_shared_album_page.dart +++ b/mobile/lib/modules/sharing/views/create_shared_album_page.dart @@ -56,10 +56,11 @@ class CreateSharedAlbumPage extends HookConsumerWidget { left: 10, ), child: AlbumTitleTextField( - isAlbumTitleEmpty: isAlbumTitleEmpty, - albumTitleTextFieldFocusNode: albumTitleTextFieldFocusNode, - albumTitleController: albumTitleController, - isAlbumTitleTextFieldFocus: isAlbumTitleTextFieldFocus), + isAlbumTitleEmpty: isAlbumTitleEmpty, + albumTitleTextFieldFocusNode: albumTitleTextFieldFocusNode, + albumTitleController: albumTitleController, + isAlbumTitleTextFieldFocus: isAlbumTitleTextFieldFocus, + ), ); } @@ -67,8 +68,8 @@ class CreateSharedAlbumPage extends HookConsumerWidget { if (selectedAssets.isEmpty) { return SliverToBoxAdapter( child: Padding( - padding: EdgeInsets.only(top: 200, left: 18), - child: Text( + padding: const EdgeInsets.only(top: 200, left: 18), + child: const Text( 'create_shared_album_page_share_add_assets', style: TextStyle(fontSize: 12), ).tr(), @@ -86,13 +87,16 @@ class CreateSharedAlbumPage extends HookConsumerWidget { padding: const EdgeInsets.only(top: 16, left: 18, right: 18), child: OutlinedButton.icon( style: OutlinedButton.styleFrom( - alignment: Alignment.centerLeft, - padding: - const EdgeInsets.symmetric(vertical: 22, horizontal: 16), - side: const BorderSide( - color: Color.fromARGB(255, 206, 206, 206)), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5))), + alignment: Alignment.centerLeft, + padding: + const EdgeInsets.symmetric(vertical: 22, horizontal: 16), + side: const BorderSide( + color: Color.fromARGB(255, 206, 206, 206), + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + ), onPressed: _onSelectPhotosButtonPressed, icon: const Icon(Icons.add_rounded), label: Padding( @@ -100,9 +104,10 @@ class CreateSharedAlbumPage extends HookConsumerWidget { child: Text( 'create_shared_album_page_share_select_photos', style: TextStyle( - fontSize: 16, - color: Colors.grey[700], - fontWeight: FontWeight.bold), + fontSize: 16, + color: Colors.grey[700], + fontWeight: FontWeight.bold, + ), ).tr(), ), ), @@ -147,7 +152,8 @@ class CreateSharedAlbumPage extends HookConsumerWidget { return GestureDetector( onTap: _onBackgroundTapped, child: SharedAlbumThumbnailImage( - asset: selectedAssets.toList()[index]), + asset: selectedAssets.toList()[index], + ), ); }, childCount: selectedAssets.length, @@ -160,58 +166,60 @@ class CreateSharedAlbumPage extends HookConsumerWidget { } return Scaffold( - appBar: AppBar( - elevation: 0, - centerTitle: false, - leading: IconButton( - onPressed: () { - ref.watch(assetSelectionProvider.notifier).removeAll(); - AutoRouter.of(context).pop(); - }, - icon: const Icon(Icons.close_rounded)), - title: const Text( - 'share_create_album', - style: TextStyle(color: Colors.black), - ).tr(), - actions: [ - TextButton( - onPressed: albumTitleController.text.isNotEmpty - ? _showSelectUserPage - : null, - child: Text( - 'create_shared_album_page_share'.tr(), - style: TextStyle( - fontWeight: FontWeight.bold, + appBar: AppBar( + elevation: 0, + centerTitle: false, + leading: IconButton( + onPressed: () { + ref.watch(assetSelectionProvider.notifier).removeAll(); + AutoRouter.of(context).pop(); + }, + icon: const Icon(Icons.close_rounded), + ), + title: const Text( + 'share_create_album', + style: TextStyle(color: Colors.black), + ).tr(), + actions: [ + TextButton( + onPressed: albumTitleController.text.isNotEmpty + ? _showSelectUserPage + : null, + child: Text( + 'create_shared_album_page_share'.tr(), + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + body: GestureDetector( + onTap: _onBackgroundTapped, + child: CustomScrollView( + slivers: [ + SliverAppBar( + elevation: 5, + automaticallyImplyLeading: false, + // leading: Container(), + pinned: true, + floating: false, + bottom: PreferredSize( + preferredSize: const Size.fromHeight(66.0), + child: Column( + children: [ + _buildTitleInputField(), + if (selectedAssets.isNotEmpty) _buildControlButton(), + ], ), ), ), + _buildTitle(), + _buildSelectPhotosButton(), + _buildSelectedImageGrid(), ], ), - body: GestureDetector( - onTap: _onBackgroundTapped, - child: CustomScrollView( - slivers: [ - SliverAppBar( - elevation: 5, - automaticallyImplyLeading: false, - // leading: Container(), - pinned: true, - floating: false, - bottom: PreferredSize( - preferredSize: const Size.fromHeight(66.0), - child: Column( - children: [ - _buildTitleInputField(), - if (selectedAssets.isNotEmpty) _buildControlButton(), - ], - ), - ), - ), - _buildTitle(), - _buildSelectPhotosButton(), - _buildSelectedImageGrid(), - ], - ), - )); + ), + ); } } diff --git a/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart b/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart index 59ebc7e00..21fd7acb7 100644 --- a/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart +++ b/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart @@ -3,29 +3,28 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/providers/suggested_shared_users.provider.dart'; -import 'package:immich_mobile/shared/models/user.model.dart'; import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; +import 'package:openapi/api.dart'; class SelectAdditionalUserForSharingPage extends HookConsumerWidget { - final SharedAlbum albumInfo; + final AlbumResponseDto albumInfo; const SelectAdditionalUserForSharingPage({Key? key, required this.albumInfo}) : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { - AsyncValue> suggestedShareUsers = + AsyncValue> suggestedShareUsers = ref.watch(suggestedSharedUsersProvider); - final sharedUsersList = useState>({}); + final sharedUsersList = useState>({}); _addNewUsersHandler() { AutoRouter.of(context) .pop(sharedUsersList.value.map((e) => e.id).toList()); } - _buildTileIcon(User user) { + _buildTileIcon(UserResponseDto user) { if (sharedUsersList.value.contains(user)) { return CircleAvatar( backgroundColor: Theme.of(context).primaryColor, @@ -43,7 +42,7 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { } } - _buildUserList(List users) { + _buildUserList(List users) { List usersChip = []; for (var user in sharedUsersList.value) { @@ -55,9 +54,10 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { label: Text( user.email, style: const TextStyle( - fontSize: 12, - color: Colors.black87, - fontWeight: FontWeight.bold), + fontSize: 12, + color: Colors.black87, + fontWeight: FontWeight.bold, + ), ), ), ), @@ -70,13 +70,14 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { children: [...usersChip], ), Padding( - padding: EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16.0), child: Text( 'select_additional_user_for_sharing_page_suggestions'.tr(), - style: TextStyle( - fontSize: 14, - color: Colors.grey, - fontWeight: FontWeight.bold), + style: const TextStyle( + fontSize: 14, + color: Colors.grey, + fontWeight: FontWeight.bold, + ), ), ), ListView.builder( @@ -87,13 +88,16 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { title: Text( users[index].email, style: const TextStyle( - fontSize: 14, fontWeight: FontWeight.bold), + fontSize: 14, + fontWeight: FontWeight.bold, + ), ), onTap: () { if (sharedUsersList.value.contains(users[index])) { sharedUsersList.value = sharedUsersList.value - .where((selectedUser) => - selectedUser.id != users[index].id) + .where( + (selectedUser) => selectedUser.id != users[index].id, + ) .toSet(); } else { sharedUsersList.value = { @@ -139,7 +143,8 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { data: (users) { for (var sharedUsers in albumInfo.sharedUsers) { users.removeWhere( - (u) => u.id == sharedUsers.id || u.id == albumInfo.ownerId); + (u) => u.id == sharedUsers.id || u.id == albumInfo.ownerId, + ); } return _buildUserList(users); diff --git a/mobile/lib/modules/sharing/views/select_user_for_sharing_page.dart b/mobile/lib/modules/sharing/views/select_user_for_sharing_page.dart index 0e0efc487..74c5c59df 100644 --- a/mobile/lib/modules/sharing/views/select_user_for_sharing_page.dart +++ b/mobile/lib/modules/sharing/views/select_user_for_sharing_page.dart @@ -9,15 +9,16 @@ import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.da import 'package:immich_mobile/modules/sharing/providers/suggested_shared_users.provider.dart'; import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart'; import 'package:immich_mobile/routing/router.dart'; -import 'package:immich_mobile/shared/models/user.model.dart'; import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; +import 'package:openapi/api.dart'; class SelectUserForSharingPage extends HookConsumerWidget { const SelectUserForSharingPage({Key? key}) : super(key: key); + @override Widget build(BuildContext context, WidgetRef ref) { - final sharedUsersList = useState>({}); - AsyncValue> suggestedShareUsers = + final sharedUsersList = useState>({}); + AsyncValue> suggestedShareUsers = ref.watch(suggestedSharedUsersProvider); _createSharedAlbum() async { @@ -37,10 +38,14 @@ class SelectUserForSharingPage extends HookConsumerWidget { .navigate(const TabControllerRoute(children: [SharingRoute()])); } - ScaffoldMessenger(child: SnackBar(content: Text('select_user_for_sharing_page_err_album').tr())); + ScaffoldMessenger( + child: SnackBar( + content: const Text('select_user_for_sharing_page_err_album').tr(), + ), + ); } - _buildTileIcon(User user) { + _buildTileIcon(UserResponseDto user) { if (sharedUsersList.value.contains(user)) { return CircleAvatar( backgroundColor: Theme.of(context).primaryColor, @@ -58,7 +63,7 @@ class SelectUserForSharingPage extends HookConsumerWidget { } } - _buildUserList(List users) { + _buildUserList(List users) { List usersChip = []; for (var user in sharedUsersList.value) { @@ -70,9 +75,10 @@ class SelectUserForSharingPage extends HookConsumerWidget { label: Text( user.email, style: const TextStyle( - fontSize: 12, - color: Colors.black87, - fontWeight: FontWeight.bold), + fontSize: 12, + color: Colors.black87, + fontWeight: FontWeight.bold, + ), ), ), ), @@ -85,13 +91,14 @@ class SelectUserForSharingPage extends HookConsumerWidget { children: [...usersChip], ), Padding( - padding: EdgeInsets.all(16.0), - child: Text( - 'share_suggestions', + padding: const EdgeInsets.all(16.0), + child: const Text( + 'select_user_for_sharing_page_share_suggestions', style: TextStyle( - fontSize: 14, - color: Colors.grey, - fontWeight: FontWeight.bold), + fontSize: 14, + color: Colors.grey, + fontWeight: FontWeight.bold, + ), ).tr(), ), ListView.builder( @@ -102,13 +109,16 @@ class SelectUserForSharingPage extends HookConsumerWidget { title: Text( users[index].email, style: const TextStyle( - fontSize: 14, fontWeight: FontWeight.bold), + fontSize: 14, + fontWeight: FontWeight.bold, + ), ), onTap: () { if (sharedUsersList.value.contains(users[index])) { sharedUsersList.value = sharedUsersList.value - .where((selectedUser) => - selectedUser.id != users[index].id) + .where( + (selectedUser) => selectedUser.id != users[index].id, + ) .toSet(); } else { sharedUsersList.value = { @@ -141,12 +151,13 @@ class SelectUserForSharingPage extends HookConsumerWidget { ), actions: [ TextButton( - onPressed: - sharedUsersList.value.isEmpty ? null : _createSharedAlbum, - child: const Text( - "share_create_album", - style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), - ).tr()) + onPressed: + sharedUsersList.value.isEmpty ? null : _createSharedAlbum, + child: const Text( + "share_create_album", + style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + ).tr(), + ) ], ), body: suggestedShareUsers.when( diff --git a/mobile/lib/modules/sharing/views/sharing_page.dart b/mobile/lib/modules/sharing/views/sharing_page.dart index 616b55b4b..728d52673 100644 --- a/mobile/lib/modules/sharing/views/sharing_page.dart +++ b/mobile/lib/modules/sharing/views/sharing_page.dart @@ -5,10 +5,10 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hive/hive.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.dart'; import 'package:immich_mobile/modules/sharing/ui/sharing_sliver_appbar.dart'; import 'package:immich_mobile/routing/router.dart'; +import 'package:openapi/api.dart'; import 'package:transparent_image/transparent_image.dart'; class SharingPage extends HookConsumerWidget { @@ -18,13 +18,16 @@ class SharingPage extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { var box = Hive.box(userInfoBox); var thumbnailRequestUrl = '${box.get(serverEndpointKey)}/asset/thumbnail'; - final List sharedAlbums = ref.watch(sharedAlbumProvider); + final List sharedAlbums = ref.watch(sharedAlbumProvider); - useEffect(() { - ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums(); + useEffect( + () { + ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums(); - return null; - }, []); + return null; + }, + [], + ); _buildAlbumList() { return SliverList( @@ -60,9 +63,10 @@ class SharingPage extends HookConsumerWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.grey.shade800), + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.grey.shade800, + ), ), onTap: () { AutoRouter.of(context) @@ -133,9 +137,9 @@ class SharingPage extends HookConsumerWidget { slivers: [ const SharingSliverAppBar(), SliverPadding( - padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), sliver: SliverToBoxAdapter( - child: Text( + child: const Text( "sharing_page_album", style: TextStyle( fontWeight: FontWeight.bold, diff --git a/mobile/lib/routing/auth_guard.dart b/mobile/lib/routing/auth_guard.dart index 3677a4f63..692cd4e38 100644 --- a/mobile/lib/routing/auth_guard.dart +++ b/mobile/lib/routing/auth_guard.dart @@ -1,21 +1,25 @@ -import 'dart:convert'; - import 'package:auto_route/auto_route.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; +import 'package:flutter/foundation.dart'; +import 'package:immich_mobile/routing/router.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; class AuthGuard extends AutoRouteGuard { - final NetworkService _networkService = NetworkService(); - + final ApiService _apiService; + AuthGuard(this._apiService); @override void onNavigation(NavigationResolver resolver, StackRouter router) async { try { - var res = await _networkService.postRequest(url: 'auth/validateToken'); - var jsonReponse = jsonDecode(res.toString()); - if (jsonReponse['authStatus']) { + var res = await _apiService.authenticationApi.validateAccessToken(); + + if (res != null && res.authStatus) { resolver.next(true); + } else { + router.replaceAll([const LoginRoute()]); } } catch (e) { - router.removeUntil((route) => route.name == "LoginRoute"); + debugPrint("Error [onNavigation] ${e.toString()}"); + router.replaceAll([const LoginRoute()]); + return; } } } diff --git a/mobile/lib/routing/router.dart b/mobile/lib/routing/router.dart index 6bce788af..a964b4695 100644 --- a/mobile/lib/routing/router.dart +++ b/mobile/lib/routing/router.dart @@ -1,5 +1,6 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/backup/views/album_preview_page.dart'; import 'package:immich_mobile/modules/backup/views/backup_album_selection_page.dart'; import 'package:immich_mobile/modules/backup/views/failed_backup_status_page.dart'; @@ -9,7 +10,6 @@ import 'package:immich_mobile/modules/home/views/home_page.dart'; import 'package:immich_mobile/modules/search/views/search_page.dart'; import 'package:immich_mobile/modules/search/views/search_result_page.dart'; import 'package:immich_mobile/modules/sharing/models/asset_selection_page_result.model.dart'; -import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/views/album_viewer_page.dart'; import 'package:immich_mobile/modules/sharing/views/asset_selection_page.dart'; import 'package:immich_mobile/modules/sharing/views/create_shared_album_page.dart'; @@ -17,12 +17,13 @@ import 'package:immich_mobile/modules/sharing/views/select_additional_user_for_s import 'package:immich_mobile/modules/sharing/views/select_user_for_sharing_page.dart'; import 'package:immich_mobile/modules/sharing/views/sharing_page.dart'; import 'package:immich_mobile/routing/auth_guard.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/modules/backup/views/backup_controller_page.dart'; import 'package:immich_mobile/modules/asset_viewer/views/image_viewer_page.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; import 'package:immich_mobile/shared/views/splash_screen.dart'; import 'package:immich_mobile/shared/views/tab_controller_page.dart'; import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart'; +import 'package:openapi/api.dart'; import 'package:photo_manager/photo_manager.dart'; part 'router.gr.dart'; @@ -74,5 +75,9 @@ part 'router.gr.dart'; ], ) class AppRouter extends _$AppRouter { - AppRouter() : super(authGuard: AuthGuard()); + final ApiService _apiService; + AppRouter(this._apiService) : super(authGuard: AuthGuard(_apiService)); } + +final appRouterProvider = + Provider((ref) => AppRouter(ref.watch(apiServiceProvider))); diff --git a/mobile/lib/routing/router.gr.dart b/mobile/lib/routing/router.gr.dart index 16042b45a..79ce762d0 100644 --- a/mobile/lib/routing/router.gr.dart +++ b/mobile/lib/routing/router.gr.dart @@ -234,7 +234,7 @@ class ImageViewerRoute extends PageRouteInfo { required String imageUrl, required String heroTag, required String thumbnailUrl, - required ImmichAsset asset}) + required AssetResponseDto asset}) : super(ImageViewerRoute.name, path: '/image-viewer-page', args: ImageViewerRouteArgs( @@ -263,7 +263,7 @@ class ImageViewerRouteArgs { final String thumbnailUrl; - final ImmichAsset asset; + final AssetResponseDto asset; @override String toString() { @@ -275,7 +275,7 @@ class ImageViewerRouteArgs { /// [VideoViewerPage] class VideoViewerRoute extends PageRouteInfo { VideoViewerRoute( - {Key? key, required String videoUrl, required ImmichAsset asset}) + {Key? key, required String videoUrl, required AssetResponseDto asset}) : super(VideoViewerRoute.name, path: '/video-viewer-page', args: VideoViewerRouteArgs( @@ -292,7 +292,7 @@ class VideoViewerRouteArgs { final String videoUrl; - final ImmichAsset asset; + final AssetResponseDto asset; @override String toString() { @@ -390,7 +390,7 @@ class AlbumViewerRouteArgs { class SelectAdditionalUserForSharingRoute extends PageRouteInfo { SelectAdditionalUserForSharingRoute( - {Key? key, required SharedAlbum albumInfo}) + {Key? key, required AlbumResponseDto albumInfo}) : super(SelectAdditionalUserForSharingRoute.name, path: '/select-additional-user-for-sharing-page', args: SelectAdditionalUserForSharingRouteArgs( @@ -405,7 +405,7 @@ class SelectAdditionalUserForSharingRouteArgs { final Key? key; - final SharedAlbum albumInfo; + final AlbumResponseDto albumInfo; @override String toString() { diff --git a/mobile/lib/routing/tab_navigation_observer.dart b/mobile/lib/routing/tab_navigation_observer.dart index 5eecc7ec3..bac868cf3 100644 --- a/mobile/lib/routing/tab_navigation_observer.dart +++ b/mobile/lib/routing/tab_navigation_observer.dart @@ -23,7 +23,9 @@ class TabNavigationObserver extends AutoRouterObserver { @override Future didChangeTabRoute( - TabPageRoute route, TabPageRoute previousRoute) async { + TabPageRoute route, + TabPageRoute previousRoute, + ) async { // Perform tasks on re-visit to SearchRoute if (route.name == 'SearchRoute') { // Refresh Location State diff --git a/mobile/lib/shared/models/device_info.model.dart b/mobile/lib/shared/models/device_info.model.dart deleted file mode 100644 index 0792e9109..000000000 --- a/mobile/lib/shared/models/device_info.model.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:convert'; - -class DeviceInfoRemote { - final int id; - final String userId; - final String deviceId; - final String deviceType; - final String notificationToken; - final String createdAt; - final bool isAutoBackup; - - DeviceInfoRemote({ - required this.id, - required this.userId, - required this.deviceId, - required this.deviceType, - required this.notificationToken, - required this.createdAt, - required this.isAutoBackup, - }); - - DeviceInfoRemote copyWith({ - int? id, - String? userId, - String? deviceId, - String? deviceType, - String? notificationToken, - String? createdAt, - bool? isAutoBackup, - }) { - return DeviceInfoRemote( - id: id ?? this.id, - userId: userId ?? this.userId, - deviceId: deviceId ?? this.deviceId, - deviceType: deviceType ?? this.deviceType, - notificationToken: notificationToken ?? this.notificationToken, - createdAt: createdAt ?? this.createdAt, - isAutoBackup: isAutoBackup ?? this.isAutoBackup, - ); - } - - Map toMap() { - return { - 'id': id, - 'userId': userId, - 'deviceId': deviceId, - 'deviceType': deviceType, - 'notificationToken': notificationToken, - 'createdAt': createdAt, - 'isAutoBackup': isAutoBackup, - }; - } - - factory DeviceInfoRemote.fromMap(Map map) { - return DeviceInfoRemote( - id: map['id']?.toInt() ?? 0, - userId: map['userId'] ?? '', - deviceId: map['deviceId'] ?? '', - deviceType: map['deviceType'] ?? '', - notificationToken: map['notificationToken'] ?? '', - createdAt: map['createdAt'] ?? '', - isAutoBackup: map['isAutoBackup'] ?? false, - ); - } - - String toJson() => json.encode(toMap()); - - factory DeviceInfoRemote.fromJson(String source) => - DeviceInfoRemote.fromMap(json.decode(source)); - - @override - String toString() { - return 'DeviceInfo(id: $id, userId: $userId, deviceId: $deviceId, deviceType: $deviceType, notificationToken: $notificationToken, createdAt: $createdAt, isAutoBackup: $isAutoBackup)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is DeviceInfoRemote && - other.id == id && - other.userId == userId && - other.deviceId == deviceId && - other.deviceType == deviceType && - other.notificationToken == notificationToken && - other.createdAt == createdAt && - other.isAutoBackup == isAutoBackup; - } - - @override - int get hashCode { - return id.hashCode ^ - userId.hashCode ^ - deviceId.hashCode ^ - deviceType.hashCode ^ - notificationToken.hashCode ^ - createdAt.hashCode ^ - isAutoBackup.hashCode; - } -} diff --git a/mobile/lib/shared/models/exif.model.dart b/mobile/lib/shared/models/exif.model.dart deleted file mode 100644 index 7d8528b36..000000000 --- a/mobile/lib/shared/models/exif.model.dart +++ /dev/null @@ -1,212 +0,0 @@ -import 'dart:convert'; - -class ImmichExif { - final int? id; - final String? assetId; - final String? make; - final String? model; - final String? imageName; - final int? exifImageWidth; - final int? exifImageHeight; - final int? fileSizeInByte; - final String? orientation; - final String? dateTimeOriginal; - final String? modifyDate; - final String? lensModel; - final double? fNumber; - final double? focalLength; - final int? iso; - final double? exposureTime; - final double? latitude; - final double? longitude; - final String? city; - final String? state; - final String? country; - - ImmichExif({ - this.id, - this.assetId, - this.make, - this.model, - this.imageName, - this.exifImageWidth, - this.exifImageHeight, - this.fileSizeInByte, - this.orientation, - this.dateTimeOriginal, - this.modifyDate, - this.lensModel, - this.fNumber, - this.focalLength, - this.iso, - this.exposureTime, - this.latitude, - this.longitude, - this.city, - this.state, - this.country, - }); - - ImmichExif copyWith({ - int? id, - String? assetId, - String? make, - String? model, - String? imageName, - int? exifImageWidth, - int? exifImageHeight, - int? fileSizeInByte, - String? orientation, - String? dateTimeOriginal, - String? modifyDate, - String? lensModel, - double? fNumber, - double? focalLength, - int? iso, - double? exposureTime, - double? latitude, - double? longitude, - String? city, - String? state, - String? country, - }) { - return ImmichExif( - id: id ?? this.id, - assetId: assetId ?? this.assetId, - make: make ?? this.make, - model: model ?? this.model, - imageName: imageName ?? this.imageName, - exifImageWidth: exifImageWidth ?? this.exifImageWidth, - exifImageHeight: exifImageHeight ?? this.exifImageHeight, - fileSizeInByte: fileSizeInByte ?? this.fileSizeInByte, - orientation: orientation ?? this.orientation, - dateTimeOriginal: dateTimeOriginal ?? this.dateTimeOriginal, - modifyDate: modifyDate ?? this.modifyDate, - lensModel: lensModel ?? this.lensModel, - fNumber: fNumber ?? this.fNumber, - focalLength: focalLength ?? this.focalLength, - iso: iso ?? this.iso, - exposureTime: exposureTime ?? this.exposureTime, - latitude: latitude ?? this.latitude, - longitude: longitude ?? this.longitude, - city: city ?? this.city, - state: state ?? this.state, - country: country ?? this.country, - ); - } - - Map toMap() { - return { - 'id': id, - 'assetId': assetId, - 'make': make, - 'model': model, - 'imageName': imageName, - 'exifImageWidth': exifImageWidth, - 'exifImageHeight': exifImageHeight, - 'fileSizeInByte': fileSizeInByte, - 'orientation': orientation, - 'dateTimeOriginal': dateTimeOriginal, - 'modifyDate': modifyDate, - 'lensModel': lensModel, - 'fNumber': fNumber, - 'focalLength': focalLength, - 'iso': iso, - 'exposureTime': exposureTime, - 'latitude': latitude, - 'longitude': longitude, - 'city': city, - 'state': state, - 'country': country, - }; - } - - factory ImmichExif.fromMap(Map map) { - return ImmichExif( - id: map['id']?.toInt(), - assetId: map['assetId'], - make: map['make'], - model: map['model'], - imageName: map['imageName'], - exifImageWidth: map['exifImageWidth']?.toInt(), - exifImageHeight: map['exifImageHeight']?.toInt(), - fileSizeInByte: map['fileSizeInByte']?.toInt(), - orientation: map['orientation'], - dateTimeOriginal: map['dateTimeOriginal'], - modifyDate: map['modifyDate'], - lensModel: map['lensModel'], - fNumber: map['fNumber']?.toDouble(), - focalLength: map['focalLength']?.toDouble(), - iso: map['iso']?.toInt(), - exposureTime: map['exposureTime']?.toDouble(), - latitude: map['latitude']?.toDouble(), - longitude: map['longitude']?.toDouble(), - city: map['city'], - state: map['state'], - country: map['country'], - ); - } - - String toJson() => json.encode(toMap()); - - factory ImmichExif.fromJson(String source) => - ImmichExif.fromMap(json.decode(source)); - - @override - String toString() { - return 'ImmichExif(id: $id, assetId: $assetId, make: $make, model: $model, imageName: $imageName, exifImageWidth: $exifImageWidth, exifImageHeight: $exifImageHeight, fileSizeInByte: $fileSizeInByte, orientation: $orientation, dateTimeOriginal: $dateTimeOriginal, modifyDate: $modifyDate, lensModel: $lensModel, fNumber: $fNumber, focalLength: $focalLength, iso: $iso, exposureTime: $exposureTime, latitude: $latitude, longitude: $longitude, city: $city, state: $state, country: $country)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is ImmichExif && - other.id == id && - other.assetId == assetId && - other.make == make && - other.model == model && - other.imageName == imageName && - other.exifImageWidth == exifImageWidth && - other.exifImageHeight == exifImageHeight && - other.fileSizeInByte == fileSizeInByte && - other.orientation == orientation && - other.dateTimeOriginal == dateTimeOriginal && - other.modifyDate == modifyDate && - other.lensModel == lensModel && - other.fNumber == fNumber && - other.focalLength == focalLength && - other.iso == iso && - other.exposureTime == exposureTime && - other.latitude == latitude && - other.longitude == longitude && - other.city == city && - other.state == state && - other.country == country; - } - - @override - int get hashCode { - return id.hashCode ^ - assetId.hashCode ^ - make.hashCode ^ - model.hashCode ^ - imageName.hashCode ^ - exifImageWidth.hashCode ^ - exifImageHeight.hashCode ^ - fileSizeInByte.hashCode ^ - orientation.hashCode ^ - dateTimeOriginal.hashCode ^ - modifyDate.hashCode ^ - lensModel.hashCode ^ - fNumber.hashCode ^ - focalLength.hashCode ^ - iso.hashCode ^ - exposureTime.hashCode ^ - latitude.hashCode ^ - longitude.hashCode ^ - city.hashCode ^ - state.hashCode ^ - country.hashCode; - } -} diff --git a/mobile/lib/shared/models/immich_asset.model.dart b/mobile/lib/shared/models/immich_asset.model.dart deleted file mode 100644 index 558c19f2b..000000000 --- a/mobile/lib/shared/models/immich_asset.model.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'dart:convert'; - -import 'package:equatable/equatable.dart'; - -class ImmichAsset extends Equatable { - final String id; - final String deviceAssetId; - final String userId; - final String deviceId; - final String type; - final String createdAt; - final String modifiedAt; - final bool isFavorite; - final String? duration; - final String originalPath; - final String resizePath; - - const ImmichAsset({ - required this.id, - required this.deviceAssetId, - required this.userId, - required this.deviceId, - required this.type, - required this.createdAt, - required this.modifiedAt, - required this.isFavorite, - this.duration, - required this.originalPath, - required this.resizePath, - }); - - ImmichAsset copyWith({ - String? id, - String? deviceAssetId, - String? userId, - String? deviceId, - String? type, - String? createdAt, - String? modifiedAt, - bool? isFavorite, - String? duration, - String? originalPath, - String? resizePath, - }) { - return ImmichAsset( - id: id ?? this.id, - deviceAssetId: deviceAssetId ?? this.deviceAssetId, - userId: userId ?? this.userId, - deviceId: deviceId ?? this.deviceId, - type: type ?? this.type, - createdAt: createdAt ?? this.createdAt, - modifiedAt: modifiedAt ?? this.modifiedAt, - isFavorite: isFavorite ?? this.isFavorite, - duration: duration ?? this.duration, - originalPath: originalPath ?? this.originalPath, - resizePath: resizePath ?? this.resizePath, - ); - } - - Map toMap() { - final result = {}; - - result.addAll({'id': id}); - result.addAll({'deviceAssetId': deviceAssetId}); - result.addAll({'userId': userId}); - result.addAll({'deviceId': deviceId}); - result.addAll({'type': type}); - result.addAll({'createdAt': createdAt}); - result.addAll({'modifiedAt': modifiedAt}); - result.addAll({'isFavorite': isFavorite}); - if (duration != null) { - result.addAll({'duration': duration}); - } - result.addAll({'originalPath': originalPath}); - result.addAll({'resizePath': resizePath}); - - return result; - } - - factory ImmichAsset.fromMap(Map map) { - return ImmichAsset( - id: map['id'] ?? '', - deviceAssetId: map['deviceAssetId'] ?? '', - userId: map['userId'] ?? '', - deviceId: map['deviceId'] ?? '', - type: map['type'] ?? '', - createdAt: map['createdAt'] ?? '', - modifiedAt: map['modifiedAt'] ?? '', - isFavorite: map['isFavorite'] ?? false, - duration: map['duration'], - originalPath: map['originalPath'] ?? '', - resizePath: map['resizePath'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory ImmichAsset.fromJson(String source) => - ImmichAsset.fromMap(json.decode(source)); - - @override - String toString() { - return 'ImmichAsset(id: $id, deviceAssetId: $deviceAssetId, userId: $userId, deviceId: $deviceId, type: $type, createdAt: $createdAt, modifiedAt: $modifiedAt, isFavorite: $isFavorite, duration: $duration, originalPath: $originalPath, resizePath: $resizePath)'; - } - - @override - List get props { - return [id]; - } -} diff --git a/mobile/lib/shared/models/immich_asset_with_exif.model.dart b/mobile/lib/shared/models/immich_asset_with_exif.model.dart deleted file mode 100644 index 88ff97437..000000000 --- a/mobile/lib/shared/models/immich_asset_with_exif.model.dart +++ /dev/null @@ -1,135 +0,0 @@ -import 'dart:convert'; - -import 'package:immich_mobile/shared/models/exif.model.dart'; - -class ImmichAssetWithExif { - final String id; - final String deviceAssetId; - final String userId; - final String deviceId; - final String type; - final String createdAt; - final String modifiedAt; - final String originalPath; - final bool isFavorite; - final String? duration; - final ImmichExif? exifInfo; - - ImmichAssetWithExif({ - required this.id, - required this.deviceAssetId, - required this.userId, - required this.deviceId, - required this.type, - required this.createdAt, - required this.modifiedAt, - required this.originalPath, - required this.isFavorite, - this.duration, - this.exifInfo, - }); - - ImmichAssetWithExif copyWith({ - String? id, - String? deviceAssetId, - String? userId, - String? deviceId, - String? type, - String? createdAt, - String? modifiedAt, - String? originalPath, - bool? isFavorite, - String? duration, - ImmichExif? exifInfo, - }) { - return ImmichAssetWithExif( - id: id ?? this.id, - deviceAssetId: deviceAssetId ?? this.deviceAssetId, - userId: userId ?? this.userId, - deviceId: deviceId ?? this.deviceId, - type: type ?? this.type, - createdAt: createdAt ?? this.createdAt, - modifiedAt: modifiedAt ?? this.modifiedAt, - originalPath: originalPath ?? this.originalPath, - isFavorite: isFavorite ?? this.isFavorite, - duration: duration ?? this.duration, - exifInfo: exifInfo ?? this.exifInfo, - ); - } - - Map toMap() { - return { - 'id': id, - 'deviceAssetId': deviceAssetId, - 'userId': userId, - 'deviceId': deviceId, - 'type': type, - 'createdAt': createdAt, - 'modifiedAt': modifiedAt, - 'originalPath': originalPath, - 'isFavorite': isFavorite, - 'duration': duration, - 'exifInfo': exifInfo?.toMap(), - }; - } - - factory ImmichAssetWithExif.fromMap(Map map) { - return ImmichAssetWithExif( - id: map['id'] ?? '', - deviceAssetId: map['deviceAssetId'] ?? '', - userId: map['userId'] ?? '', - deviceId: map['deviceId'] ?? '', - type: map['type'] ?? '', - createdAt: map['createdAt'] ?? '', - modifiedAt: map['modifiedAt'] ?? '', - originalPath: map['originalPath'] ?? '', - isFavorite: map['isFavorite'] ?? false, - duration: map['duration'], - exifInfo: - map['exifInfo'] != null ? ImmichExif.fromMap(map['exifInfo']) : null, - ); - } - - String toJson() => json.encode(toMap()); - - factory ImmichAssetWithExif.fromJson(String source) => - ImmichAssetWithExif.fromMap(json.decode(source)); - - @override - String toString() { - return 'ImmichAssetWithExif(id: $id, deviceAssetId: $deviceAssetId, userId: $userId, deviceId: $deviceId, type: $type, createdAt: $createdAt, modifiedAt: $modifiedAt, originalPath: $originalPath, isFavorite: $isFavorite, duration: $duration, exifInfo: $exifInfo)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is ImmichAssetWithExif && - other.id == id && - other.deviceAssetId == deviceAssetId && - other.userId == userId && - other.deviceId == deviceId && - other.type == type && - other.createdAt == createdAt && - other.modifiedAt == modifiedAt && - other.originalPath == originalPath && - other.isFavorite == isFavorite && - other.duration == duration && - other.exifInfo == exifInfo; - } - - @override - int get hashCode { - return id.hashCode ^ - deviceAssetId.hashCode ^ - userId.hashCode ^ - deviceId.hashCode ^ - type.hashCode ^ - createdAt.hashCode ^ - modifiedAt.hashCode ^ - originalPath.hashCode ^ - isFavorite.hashCode ^ - duration.hashCode ^ - exifInfo.hashCode; - } -} diff --git a/mobile/lib/shared/models/mapbox_info.model.dart b/mobile/lib/shared/models/mapbox_info.model.dart deleted file mode 100644 index f3407bab3..000000000 --- a/mobile/lib/shared/models/mapbox_info.model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'dart:convert'; - -class MapboxInfo { - final bool isEnable; - final String mapboxSecret; - MapboxInfo({ - required this.isEnable, - required this.mapboxSecret, - }); - - MapboxInfo copyWith({ - bool? isEnable, - String? mapboxSecret, - }) { - return MapboxInfo( - isEnable: isEnable ?? this.isEnable, - mapboxSecret: mapboxSecret ?? this.mapboxSecret, - ); - } - - Map toMap() { - return { - 'isEnable': isEnable, - 'mapboxSecret': mapboxSecret, - }; - } - - factory MapboxInfo.fromMap(Map map) { - return MapboxInfo( - isEnable: map['isEnable'] ?? false, - mapboxSecret: map['mapboxSecret'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory MapboxInfo.fromJson(String source) => - MapboxInfo.fromMap(json.decode(source)); - - @override - String toString() => - 'MapboxInfo(isEnable: $isEnable, mapboxSecret: $mapboxSecret)'; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is MapboxInfo && - other.isEnable == isEnable && - other.mapboxSecret == mapboxSecret; - } - - @override - int get hashCode => isEnable.hashCode ^ mapboxSecret.hashCode; -} diff --git a/mobile/lib/shared/models/server_info.model.dart b/mobile/lib/shared/models/server_info.model.dart deleted file mode 100644 index 7343fbe96..000000000 --- a/mobile/lib/shared/models/server_info.model.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:convert'; - -class ServerInfo { - final String diskSize; - final String diskUse; - final String diskAvailable; - final int diskSizeRaw; - final int diskUseRaw; - final int diskAvailableRaw; - final double diskUsagePercentage; - ServerInfo({ - required this.diskSize, - required this.diskUse, - required this.diskAvailable, - required this.diskSizeRaw, - required this.diskUseRaw, - required this.diskAvailableRaw, - required this.diskUsagePercentage, - }); - - ServerInfo copyWith({ - String? diskSize, - String? diskUse, - String? diskAvailable, - int? diskSizeRaw, - int? diskUseRaw, - int? diskAvailableRaw, - double? diskUsagePercentage, - }) { - return ServerInfo( - diskSize: diskSize ?? this.diskSize, - diskUse: diskUse ?? this.diskUse, - diskAvailable: diskAvailable ?? this.diskAvailable, - diskSizeRaw: diskSizeRaw ?? this.diskSizeRaw, - diskUseRaw: diskUseRaw ?? this.diskUseRaw, - diskAvailableRaw: diskAvailableRaw ?? this.diskAvailableRaw, - diskUsagePercentage: diskUsagePercentage ?? this.diskUsagePercentage, - ); - } - - Map toMap() { - return { - 'diskSize': diskSize, - 'diskUse': diskUse, - 'diskAvailable': diskAvailable, - 'diskSizeRaw': diskSizeRaw, - 'diskUseRaw': diskUseRaw, - 'diskAvailableRaw': diskAvailableRaw, - 'diskUsagePercentage': diskUsagePercentage, - }; - } - - factory ServerInfo.fromMap(Map map) { - return ServerInfo( - diskSize: map['diskSize'] ?? '', - diskUse: map['diskUse'] ?? '', - diskAvailable: map['diskAvailable'] ?? '', - diskSizeRaw: map['diskSizeRaw']?.toInt() ?? 0, - diskUseRaw: map['diskUseRaw']?.toInt() ?? 0, - diskAvailableRaw: map['diskAvailableRaw']?.toInt() ?? 0, - diskUsagePercentage: map['diskUsagePercentage']?.toDouble() ?? 0.0, - ); - } - - String toJson() => json.encode(toMap()); - - factory ServerInfo.fromJson(String source) => - ServerInfo.fromMap(json.decode(source)); - - @override - String toString() { - return 'ServerInfo(diskSize: $diskSize, diskUse: $diskUse, diskAvailable: $diskAvailable, diskSizeRaw: $diskSizeRaw, diskUseRaw: $diskUseRaw, diskAvailableRaw: $diskAvailableRaw, diskUsagePercentage: $diskUsagePercentage)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is ServerInfo && - other.diskSize == diskSize && - other.diskUse == diskUse && - other.diskAvailable == diskAvailable && - other.diskSizeRaw == diskSizeRaw && - other.diskUseRaw == diskUseRaw && - other.diskAvailableRaw == diskAvailableRaw && - other.diskUsagePercentage == diskUsagePercentage; - } - - @override - int get hashCode { - return diskSize.hashCode ^ - diskUse.hashCode ^ - diskAvailable.hashCode ^ - diskSizeRaw.hashCode ^ - diskUseRaw.hashCode ^ - diskAvailableRaw.hashCode ^ - diskUsagePercentage.hashCode; - } -} diff --git a/mobile/lib/shared/models/server_info_state.model.dart b/mobile/lib/shared/models/server_info_state.model.dart index f82beb794..7b1ea9c91 100644 --- a/mobile/lib/shared/models/server_info_state.model.dart +++ b/mobile/lib/shared/models/server_info_state.model.dart @@ -1,29 +1,22 @@ -import 'dart:convert'; - -import 'package:immich_mobile/shared/models/mapbox_info.model.dart'; -import 'package:immich_mobile/shared/models/server_version.model.dart'; +import 'package:openapi/api.dart'; class ServerInfoState { - final MapboxInfo mapboxInfo; - final ServerVersion serverVersion; + final ServerVersionReponseDto serverVersion; final bool isVersionMismatch; final String versionMismatchErrorMessage; ServerInfoState({ - required this.mapboxInfo, required this.serverVersion, required this.isVersionMismatch, required this.versionMismatchErrorMessage, }); ServerInfoState copyWith({ - MapboxInfo? mapboxInfo, - ServerVersion? serverVersion, + ServerVersionReponseDto? serverVersion, bool? isVersionMismatch, String? versionMismatchErrorMessage, }) { return ServerInfoState( - mapboxInfo: mapboxInfo ?? this.mapboxInfo, serverVersion: serverVersion ?? this.serverVersion, isVersionMismatch: isVersionMismatch ?? this.isVersionMismatch, versionMismatchErrorMessage: @@ -31,32 +24,9 @@ class ServerInfoState { ); } - Map toMap() { - return { - 'mapboxInfo': mapboxInfo.toMap(), - 'serverVersion': serverVersion.toMap(), - 'isVersionMismatch': isVersionMismatch, - 'versionMismatchErrorMessage': versionMismatchErrorMessage, - }; - } - - factory ServerInfoState.fromMap(Map map) { - return ServerInfoState( - mapboxInfo: MapboxInfo.fromMap(map['mapboxInfo']), - serverVersion: ServerVersion.fromMap(map['serverVersion']), - isVersionMismatch: map['isVersionMismatch'] ?? false, - versionMismatchErrorMessage: map['versionMismatchErrorMessage'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory ServerInfoState.fromJson(String source) => - ServerInfoState.fromMap(json.decode(source)); - @override String toString() { - return 'ServerInfoState(mapboxInfo: $mapboxInfo, serverVersion: $serverVersion, isVersionMismatch: $isVersionMismatch, versionMismatchErrorMessage: $versionMismatchErrorMessage)'; + return 'ServerInfoState( serverVersion: $serverVersion, isVersionMismatch: $isVersionMismatch, versionMismatchErrorMessage: $versionMismatchErrorMessage)'; } @override @@ -64,7 +34,6 @@ class ServerInfoState { if (identical(this, other)) return true; return other is ServerInfoState && - other.mapboxInfo == mapboxInfo && other.serverVersion == serverVersion && other.isVersionMismatch == isVersionMismatch && other.versionMismatchErrorMessage == versionMismatchErrorMessage; @@ -72,8 +41,7 @@ class ServerInfoState { @override int get hashCode { - return mapboxInfo.hashCode ^ - serverVersion.hashCode ^ + return serverVersion.hashCode ^ isVersionMismatch.hashCode ^ versionMismatchErrorMessage.hashCode; } diff --git a/mobile/lib/shared/models/server_version.model.dart b/mobile/lib/shared/models/server_version.model.dart deleted file mode 100644 index d41fb1e13..000000000 --- a/mobile/lib/shared/models/server_version.model.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'dart:convert'; - -class ServerVersion { - final int major; - final int minor; - final int patch; - final int build; - - ServerVersion({ - required this.major, - required this.minor, - required this.patch, - required this.build, - }); - - ServerVersion copyWith({ - int? major, - int? minor, - int? patch, - int? build, - }) { - return ServerVersion( - major: major ?? this.major, - minor: minor ?? this.minor, - patch: patch ?? this.patch, - build: build ?? this.build, - ); - } - - Map toMap() { - return { - 'major': major, - 'minor': minor, - 'patch': patch, - 'build': build, - }; - } - - factory ServerVersion.fromMap(Map map) { - return ServerVersion( - major: map['major']?.toInt() ?? 0, - minor: map['minor']?.toInt() ?? 0, - patch: map['patch']?.toInt() ?? 0, - build: map['build']?.toInt() ?? 0, - ); - } - - String toJson() => json.encode(toMap()); - - factory ServerVersion.fromJson(String source) => - ServerVersion.fromMap(json.decode(source)); - - @override - String toString() { - return 'ServerVersion(major: $major, minor: $minor, patch: $patch, build: $build)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is ServerVersion && - other.major == major && - other.minor == minor && - other.patch == patch && - other.build == build; - } - - @override - int get hashCode { - return major.hashCode ^ minor.hashCode ^ patch.hashCode ^ build.hashCode; - } -} diff --git a/mobile/lib/shared/models/user.model.dart b/mobile/lib/shared/models/user.model.dart deleted file mode 100644 index 99b0ce6cc..000000000 --- a/mobile/lib/shared/models/user.model.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'dart:convert'; - -class User { - final String id; - final String email; - final String createdAt; - final String firstName; - final String lastName; - - User({ - required this.id, - required this.email, - required this.createdAt, - required this.firstName, - required this.lastName, - }); - - User copyWith({ - String? id, - String? email, - String? createdAt, - String? firstName, - String? lastName, - }) { - return User( - id: id ?? this.id, - email: email ?? this.email, - createdAt: createdAt ?? this.createdAt, - firstName: firstName ?? this.firstName, - lastName: lastName ?? this.lastName, - ); - } - - Map toMap() { - final result = {}; - - result.addAll({'id': id}); - result.addAll({'email': email}); - result.addAll({'createdAt': createdAt}); - - return result; - } - - factory User.fromMap(Map map) { - return User( - id: map['id'] ?? '', - email: map['email'] ?? '', - createdAt: map['createdAt'] ?? '', - firstName: map['firstName'] ?? '', - lastName: map['lastName'] ?? '', - ); - } - - String toJson() => json.encode(toMap()); - - factory User.fromJson(String source) => User.fromMap(json.decode(source)); - - @override - String toString() => - 'UserInfo(id: $id, email: $email, createdAt: $createdAt)'; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is User && - other.id == id && - other.email == email && - other.createdAt == createdAt && - other.firstName == firstName && - other.lastName == lastName; - } - - @override - int get hashCode => id.hashCode ^ email.hashCode ^ createdAt.hashCode; -} diff --git a/mobile/lib/shared/providers/asset.provider.dart b/mobile/lib/shared/providers/asset.provider.dart index bb42fbd1e..84ddc2dc9 100644 --- a/mobile/lib/shared/providers/asset.provider.dart +++ b/mobile/lib/shared/providers/asset.provider.dart @@ -1,21 +1,20 @@ import 'package:flutter/foundation.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/home/models/delete_asset_response.model.dart'; import 'package:immich_mobile/modules/home/services/asset.service.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/shared/services/device_info.service.dart'; import 'package:collection/collection.dart'; import 'package:intl/intl.dart'; +import 'package:openapi/api.dart'; import 'package:photo_manager/photo_manager.dart'; -class AssetNotifier extends StateNotifier> { +class AssetNotifier extends StateNotifier> { final AssetService _assetService; final DeviceInfoService _deviceInfoService = DeviceInfoService(); AssetNotifier(this._assetService) : super([]); getAllAsset() async { - List? allAssets = await _assetService.getAllAsset(); + var allAssets = await _assetService.getAllAsset(); if (allAssets != null) { state = allAssets; @@ -26,11 +25,11 @@ class AssetNotifier extends StateNotifier> { state = []; } - onNewAssetUploaded(ImmichAsset newAsset) { + onNewAssetUploaded(AssetResponseDto newAsset) { state = [...state, newAsset]; } - deleteAssets(Set deleteAssets) async { + deleteAssets(Set deleteAssets) async { var deviceInfo = await _deviceInfoService.getDeviceInfo(); var deviceId = deviceInfo["deviceId"]; var deleteIdList = []; @@ -53,14 +52,15 @@ class AssetNotifier extends StateNotifier> { } // Delete asset on server - List? deleteAssetResult = + List? deleteAssetResult = await _assetService.deleteAssets(deleteAssets); + if (deleteAssetResult == null) { return; } for (var asset in deleteAssetResult) { - if (asset.status == 'success') { + if (asset.status == DeleteAssetStatus.SUCCESS) { state = state.where((immichAsset) => immichAsset.id != asset.id).toList(); } @@ -69,7 +69,7 @@ class AssetNotifier extends StateNotifier> { } final assetProvider = - StateNotifierProvider>((ref) { + StateNotifierProvider>((ref) { return AssetNotifier(ref.watch(assetServiceProvider)); }); @@ -77,17 +77,25 @@ final assetGroupByDateTimeProvider = StateProvider((ref) { var assets = ref.watch(assetProvider); assets.sortByCompare( - (e) => DateTime.parse(e.createdAt), (a, b) => b.compareTo(a)); - return assets.groupListsBy((element) => - DateFormat('y-MM-dd').format(DateTime.parse(element.createdAt))); + (e) => DateTime.parse(e.createdAt), + (a, b) => b.compareTo(a), + ); + return assets.groupListsBy( + (element) => + DateFormat('y-MM-dd').format(DateTime.parse(element.createdAt)), + ); }); final assetGroupByMonthYearProvider = StateProvider((ref) { var assets = ref.watch(assetProvider); assets.sortByCompare( - (e) => DateTime.parse(e.createdAt), (a, b) => b.compareTo(a)); + (e) => DateTime.parse(e.createdAt), + (a, b) => b.compareTo(a), + ); - return assets.groupListsBy((element) => - DateFormat('MMMM, y').format(DateTime.parse(element.createdAt))); + return assets.groupListsBy( + (element) => + DateFormat('MMMM, y').format(DateTime.parse(element.createdAt)), + ); }); diff --git a/mobile/lib/shared/providers/release_info.provider.dart b/mobile/lib/shared/providers/release_info.provider.dart index 65276dd73..c9f91ec84 100644 --- a/mobile/lib/shared/providers/release_info.provider.dart +++ b/mobile/lib/shared/providers/release_info.provider.dart @@ -56,4 +56,5 @@ class ReleaseInfoNotifier extends StateNotifier { } final releaseInfoProvider = StateNotifierProvider( - (ref) => ReleaseInfoNotifier()); + (ref) => ReleaseInfoNotifier(), +); diff --git a/mobile/lib/shared/providers/server_info.provider.dart b/mobile/lib/shared/providers/server_info.provider.dart index 2eb2eedfc..0794e73cd 100644 --- a/mobile/lib/shared/providers/server_info.provider.dart +++ b/mobile/lib/shared/providers/server_info.provider.dart @@ -1,18 +1,20 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/shared/models/mapbox_info.model.dart'; import 'package:immich_mobile/shared/models/server_info_state.model.dart'; -import 'package:immich_mobile/shared/models/server_version.model.dart'; import 'package:immich_mobile/shared/services/server_info.service.dart'; +import 'package:openapi/api.dart'; import 'package:package_info_plus/package_info_plus.dart'; class ServerInfoNotifier extends StateNotifier { ServerInfoNotifier(this._serverInfoService) : super( ServerInfoState( - mapboxInfo: MapboxInfo(isEnable: false, mapboxSecret: ""), - serverVersion: - ServerVersion(major: 0, patch: 0, minor: 0, build: 0), + serverVersion: ServerVersionReponseDto( + major: 0, + patch_: 0, + minor: 0, + build: 0, + ), isVersionMismatch: false, versionMismatchErrorMessage: "", ), @@ -21,7 +23,8 @@ class ServerInfoNotifier extends StateNotifier { final ServerInfoService _serverInfoService; getServerVersion() async { - ServerVersion? serverVersion = await _serverInfoService.getServerVersion(); + ServerVersionReponseDto? serverVersion = + await _serverInfoService.getServerVersion(); if (serverVersion == null) { state = state.copyWith( @@ -59,7 +62,9 @@ class ServerInfoNotifier extends StateNotifier { } state = state.copyWith( - isVersionMismatch: false, versionMismatchErrorMessage: ""); + isVersionMismatch: false, + versionMismatchErrorMessage: "", + ); } Map _getDetailVersion(String version) { diff --git a/mobile/lib/shared/providers/websocket.provider.dart b/mobile/lib/shared/providers/websocket.provider.dart index 60d13f76d..bc4876276 100644 --- a/mobile/lib/shared/providers/websocket.provider.dart +++ b/mobile/lib/shared/providers/websocket.provider.dart @@ -5,8 +5,8 @@ import 'package:hive/hive.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; -import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/shared/providers/asset.provider.dart'; +import 'package:openapi/api.dart'; import 'package:socket_io_client/socket_io_client.dart'; class WebscoketState { @@ -92,8 +92,11 @@ class WebsocketNotifier extends StateNotifier { socket.on('on_upload_success', (data) { var jsonString = jsonDecode(data.toString()); - ImmichAsset newAsset = ImmichAsset.fromMap(jsonString); - ref.watch(assetProvider.notifier).onNewAssetUploaded(newAsset); + AssetResponseDto? newAsset = AssetResponseDto.fromJson(jsonString); + + if (newAsset != null) { + ref.watch(assetProvider.notifier).onNewAssetUploaded(newAsset); + } }); } catch (e) { debugPrint("[WEBSOCKET] Catch Websocket Error - ${e.toString()}"); @@ -119,8 +122,11 @@ class WebsocketNotifier extends StateNotifier { debugPrint("[Websocket] Start listening to event on_upload_success"); state.socket?.on('on_upload_success', (data) { var jsonString = jsonDecode(data.toString()); - ImmichAsset newAsset = ImmichAsset.fromMap(jsonString); - ref.watch(assetProvider.notifier).onNewAssetUploaded(newAsset); + AssetResponseDto? newAsset = AssetResponseDto.fromJson(jsonString); + + if (newAsset != null) { + ref.watch(assetProvider.notifier).onNewAssetUploaded(newAsset); + } }); } } diff --git a/mobile/lib/shared/services/api.service.dart b/mobile/lib/shared/services/api.service.dart new file mode 100644 index 000000000..37630beb9 --- /dev/null +++ b/mobile/lib/shared/services/api.service.dart @@ -0,0 +1,30 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:openapi/api.dart'; + +final apiServiceProvider = Provider((ref) => ApiService()); + +class ApiService { + late ApiClient _apiClient; + + late UserApi userApi; + late AuthenticationApi authenticationApi; + late AlbumApi albumApi; + late AssetApi assetApi; + late ServerInfoApi serverInfoApi; + late DeviceInfoApi deviceInfoApi; + + setEndpoint(String endpoint) { + _apiClient = ApiClient(basePath: endpoint); + + userApi = UserApi(_apiClient); + authenticationApi = AuthenticationApi(_apiClient); + albumApi = AlbumApi(_apiClient); + assetApi = AssetApi(_apiClient); + serverInfoApi = ServerInfoApi(_apiClient); + deviceInfoApi = DeviceInfoApi(_apiClient); + } + + setAccessToken(String accessToken) { + _apiClient.addDefaultHeader('Authorization', 'bearer $accessToken'); + } +} diff --git a/mobile/lib/shared/services/device_info.service.dart b/mobile/lib/shared/services/device_info.service.dart index e1cd8a91f..429d927fc 100644 --- a/mobile/lib/shared/services/device_info.service.dart +++ b/mobile/lib/shared/services/device_info.service.dart @@ -2,6 +2,7 @@ import 'package:flutter_udid/flutter_udid.dart'; import 'dart:io' show Platform; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:openapi/api.dart'; final deviceInfoServiceProvider = Provider((_) => DeviceInfoService()); @@ -9,12 +10,12 @@ class DeviceInfoService { Future> getDeviceInfo() async { // Get device info var deviceId = await FlutterUdid.consistentUdid; - var deviceType = ""; + var deviceType = DeviceTypeEnum.ANDROID; if (Platform.isAndroid) { - deviceType = "ANDROID"; + deviceType = DeviceTypeEnum.ANDROID; } else if (Platform.isIOS) { - deviceType = "IOS"; + deviceType = DeviceTypeEnum.IOS; } return {"deviceId": deviceId, "deviceType": deviceType}; diff --git a/mobile/lib/shared/services/local_storage.service.dart b/mobile/lib/shared/services/local_storage.service.dart deleted file mode 100644 index f409b2d7c..000000000 --- a/mobile/lib/shared/services/local_storage.service.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:hive/hive.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/constants/hive_box.dart'; - -final localStorageServiceProvider = Provider((_) => LocalStorageService()); - -class LocalStorageService { - late Box _box; - - LocalStorageService() { - _box = Hive.box(userInfoBox); - } - - T get(String key) { - return _box.get(key); - } - - put(String key, T value) { - return _box.put(key, value); - } -} diff --git a/mobile/lib/shared/services/network.service.dart b/mobile/lib/shared/services/network.service.dart index 24ad7649d..f8a502d0a 100644 --- a/mobile/lib/shared/services/network.service.dart +++ b/mobile/lib/shared/services/network.service.dart @@ -33,10 +33,11 @@ class NetworkService { } } - Future getRequest( - {required String url, - bool isByteResponse = false, - bool isStreamReponse = false}) async { + Future getRequest({ + required String url, + bool isByteResponse = false, + bool isStreamReponse = false, + }) async { try { var savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey); diff --git a/mobile/lib/shared/services/server_info.service.dart b/mobile/lib/shared/services/server_info.service.dart index df25fe256..92ea9d89d 100644 --- a/mobile/lib/shared/services/server_info.service.dart +++ b/mobile/lib/shared/services/server_info.service.dart @@ -1,33 +1,33 @@ -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/shared/models/server_info.model.dart'; -import 'package:immich_mobile/shared/models/server_version.model.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; +import 'package:openapi/api.dart'; -final serverInfoServiceProvider = - Provider((ref) => ServerInfoService(ref.watch(networkServiceProvider))); +final serverInfoServiceProvider = Provider( + (ref) => ServerInfoService( + ref.watch(apiServiceProvider), + ), +); class ServerInfoService { - final NetworkService _networkService; - ServerInfoService(this._networkService); + final ApiService _apiService; + ServerInfoService(this._apiService); - Future getServerInfo() async { - Response response = await _networkService.getRequest(url: 'server-info'); - - return ServerInfo.fromJson(response.toString()); + Future getServerInfo() async { + try { + return await _apiService.serverInfoApi.getServerInfo(); + } catch (e) { + debugPrint("Error [getServerInfo] ${e.toString()}"); + return null; + } } - Future getServerVersion() async { + Future getServerVersion() async { try { - Response response = - await _networkService.getRequest(url: 'server-info/version'); - - return ServerVersion.fromJson(response.toString()); + return await _apiService.serverInfoApi.getServerVersion(); } catch (e) { debugPrint("Error getting server info"); + return null; } - - return null; } } diff --git a/mobile/lib/shared/services/user.service.dart b/mobile/lib/shared/services/user.service.dart index 737cd97fc..482f08635 100644 --- a/mobile/lib/shared/services/user.service.dart +++ b/mobile/lib/shared/services/user.service.dart @@ -1,70 +1,49 @@ -import 'dart:convert'; - -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; -import 'package:hive/hive.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:http/http.dart'; import 'package:http_parser/http_parser.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/shared/models/upload_profile_image_repsonse.model.dart'; -import 'package:immich_mobile/shared/models/user.model.dart'; -import 'package:immich_mobile/shared/services/network.service.dart'; -import 'package:immich_mobile/utils/dio_http_interceptor.dart'; +import 'package:immich_mobile/shared/services/api.service.dart'; import 'package:immich_mobile/utils/files_helper.dart'; +import 'package:openapi/api.dart'; -final userServiceProvider = - Provider((ref) => UserService(ref.watch(networkServiceProvider))); +final userServiceProvider = Provider( + (ref) => UserService( + ref.watch(apiServiceProvider), + ), +); class UserService { - final NetworkService _networkService; - UserService(this._networkService); + final ApiService _apiService; - Future> getAllUsersInfo() async { + UserService(this._apiService); + + Future?> getAllUsersInfo({required bool isAll}) async { try { - var res = await _networkService.getRequest(url: 'user'); - List decodedData = jsonDecode(res.toString()); - List result = List.from(decodedData.map((e) => User.fromMap(e))); - - return result; + return await _apiService.userApi.getAllUsers(isAll); } catch (e) { - debugPrint("Error getAllUsersInfo ${e.toString()}"); + debugPrint("Error [getAllUsersInfo] ${e.toString()}"); + return null; } - - return []; } - Future uploadProfileImage(XFile image) async { - var dio = Dio(); - dio.interceptors.add(AuthenticatedRequestInterceptor()); - String savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey); - var mimeType = FileHelper.getMimeType(image.path); - - final imageData = MultipartFile.fromBytes( - await image.readAsBytes(), - filename: image.name, - contentType: MediaType( - mimeType["type"], - mimeType["subType"], - ), - ); - - final formData = FormData.fromMap({'file': imageData}); - + Future uploadProfileImage(XFile image) async { try { - Response res = await dio.post( - '$savedEndpoint/user/profile-image', - data: formData, + var mimeType = FileHelper.getMimeType(image.path); + + return await _apiService.userApi.createProfileImage( + MultipartFile.fromBytes( + 'file', + await image.readAsBytes(), + filename: image.name, + contentType: MediaType( + mimeType["type"], + mimeType["subType"], + ), + ), ); - - var payload = UploadProfileImageResponse.fromJson(res.toString()); - - return payload; - } on DioError catch (e) { - debugPrint("Error uploading file: ${e.response}"); - return null; } catch (e) { - debugPrint("Error uploading file: $e"); + debugPrint("Error [uploadProfileImage] ${e.toString()}"); return null; } } diff --git a/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart b/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart index 85a67daa2..d9c43cd35 100644 --- a/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart +++ b/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart @@ -22,7 +22,10 @@ class ImmichSliverPersistentAppBarDelegate @override Widget build( - BuildContext context, double shrinkOffset, bool overlapsContent) { + BuildContext context, + double shrinkOffset, + bool overlapsContent, + ) { return SizedBox.expand(child: child); } diff --git a/mobile/lib/shared/views/splash_screen.dart b/mobile/lib/shared/views/splash_screen.dart index fd3828ee4..23a545602 100644 --- a/mobile/lib/shared/views/splash_screen.dart +++ b/mobile/lib/shared/views/splash_screen.dart @@ -19,10 +19,13 @@ class SplashScreenPage extends HookConsumerWidget { Hive.box(hiveLoginInfoBox).get(savedLoginInfoKey); void performLoggingIn() async { - var isAuthenticated = await ref - .read(authenticationProvider.notifier) - .login( - loginInfo!.email, loginInfo.password, loginInfo.serverUrl, true); + var isAuthenticated = + await ref.read(authenticationProvider.notifier).login( + loginInfo!.email, + loginInfo.password, + loginInfo.serverUrl, + true, + ); if (isAuthenticated) { // Resume backup (if enable) then navigate @@ -33,14 +36,17 @@ class SplashScreenPage extends HookConsumerWidget { } } - useEffect(() { - if (loginInfo?.isSaveLogin == true) { - performLoggingIn(); - } else { - AutoRouter.of(context).push(const LoginRoute()); - } - return null; - }, []); + useEffect( + () { + if (loginInfo?.isSaveLogin == true) { + performLoggingIn(); + } else { + AutoRouter.of(context).push(const LoginRoute()); + } + return null; + }, + [], + ); return Scaffold( backgroundColor: immichBackgroundColor, diff --git a/mobile/lib/shared/views/tab_controller_page.dart b/mobile/lib/shared/views/tab_controller_page.dart index b32baf33b..9da202f08 100644 --- a/mobile/lib/shared/views/tab_controller_page.dart +++ b/mobile/lib/shared/views/tab_controller_page.dart @@ -35,23 +35,30 @@ class TabControllerPage extends ConsumerWidget { ? null : BottomNavigationBar( selectedLabelStyle: const TextStyle( - fontSize: 15, fontWeight: FontWeight.w600), + fontSize: 15, + fontWeight: FontWeight.w600, + ), unselectedLabelStyle: const TextStyle( - fontSize: 15, fontWeight: FontWeight.w600), + fontSize: 15, + fontWeight: FontWeight.w600, + ), currentIndex: tabsRouter.activeIndex, onTap: (index) { tabsRouter.setActiveIndex(index); }, items: [ BottomNavigationBarItem( - label: 'tab_controller_nav_photos'.tr(), - icon: const Icon(Icons.photo)), + label: 'tab_controller_nav_photos'.tr(), + icon: const Icon(Icons.photo), + ), BottomNavigationBarItem( - label: 'tab_controller_nav_search'.tr(), - icon: const Icon(Icons.search)), + label: 'tab_controller_nav_search'.tr(), + icon: const Icon(Icons.search), + ), BottomNavigationBarItem( - label: 'tab_controller_nav_sharing'.tr(), - icon: const Icon(Icons.group_outlined)), + label: 'tab_controller_nav_sharing'.tr(), + icon: const Icon(Icons.group_outlined), + ), ], ), ), diff --git a/mobile/lib/shared/views/version_announcement_overlay.dart b/mobile/lib/shared/views/version_announcement_overlay.dart index 90095ef27..aa56bd8fb 100644 --- a/mobile/lib/shared/views/version_announcement_overlay.dart +++ b/mobile/lib/shared/views/version_announcement_overlay.dart @@ -54,13 +54,16 @@ class VersionAnnouncementOverlay extends HookConsumerWidget { child: RichText( text: TextSpan( style: const TextStyle( - fontSize: 14, - fontFamily: 'WorkSans', - color: Colors.black87, - height: 1.2), + fontSize: 14, + fontFamily: 'WorkSans', + color: Colors.black87, + height: 1.2, + ), children: [ TextSpan( - text: 'version_announcement_overlay_text_1'.tr(), + text: + 'version_announcement_overlay_text_1' + .tr(), ), const TextSpan( text: ' Immich ', @@ -71,11 +74,14 @@ class VersionAnnouncementOverlay extends HookConsumerWidget { ), ), TextSpan( - text: "version_announcement_overlay_text_2".tr(), + text: + "version_announcement_overlay_text_2" + .tr(), ), TextSpan( - text: "version_announcement_overlay_release_notes" - .tr(), + text: + "version_announcement_overlay_release_notes" + .tr(), style: const TextStyle( decoration: TextDecoration.underline, ), @@ -83,7 +89,9 @@ class VersionAnnouncementOverlay extends HookConsumerWidget { ..onTap = goToReleaseNote, ), TextSpan( - text: "version_announcement_overlay_text_3".tr(), + text: + "version_announcement_overlay_text_3" + .tr(), ) ], ), @@ -92,22 +100,25 @@ class VersionAnnouncementOverlay extends HookConsumerWidget { Padding( padding: const EdgeInsets.only(top: 16.0), child: ElevatedButton( - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - visualDensity: VisualDensity.standard, - primary: Colors.indigo, - onPrimary: Colors.grey[50], - elevation: 2, - padding: const EdgeInsets.symmetric( - vertical: 10, horizontal: 25), + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + visualDensity: VisualDensity.standard, + primary: Colors.indigo, + onPrimary: Colors.grey[50], + elevation: 2, + padding: const EdgeInsets.symmetric( + vertical: 10, + horizontal: 25, ), - onPressed: onAcknowledgeTapped, - child: const Text( - "version_announcement_overlay_ack", - style: TextStyle( - fontSize: 14, - ), - ).tr()), + ), + onPressed: onAcknowledgeTapped, + child: const Text( + "version_announcement_overlay_ack", + style: TextStyle( + fontSize: 14, + ), + ).tr(), + ), ) ], ), diff --git a/mobile/openapi/.gitignore b/mobile/openapi/.gitignore new file mode 100644 index 000000000..1be28ced0 --- /dev/null +++ b/mobile/openapi/.gitignore @@ -0,0 +1,17 @@ +# See https://dart.dev/guides/libraries/private-files + +.dart_tool/ +.packages +build/ +pubspec.lock # Except for application packages + +doc/api/ + +# IntelliJ +*.iml +*.ipr +*.iws +.idea/ + +# Mac +.DS_Store diff --git a/mobile/openapi/.openapi-generator-ignore b/mobile/openapi/.openapi-generator-ignore new file mode 100644 index 000000000..7484ee590 --- /dev/null +++ b/mobile/openapi/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/mobile/openapi/.openapi-generator/FILES b/mobile/openapi/.openapi-generator/FILES new file mode 100644 index 000000000..9818927be --- /dev/null +++ b/mobile/openapi/.openapi-generator/FILES @@ -0,0 +1,100 @@ +.gitignore +.travis.yml +README.md +analysis_options.yaml +doc/AddAssetsDto.md +doc/AddUsersDto.md +doc/AdminSignupResponseDto.md +doc/AlbumApi.md +doc/AlbumResponseDto.md +doc/AssetApi.md +doc/AssetFileUploadResponseDto.md +doc/AssetResponseDto.md +doc/AssetTypeEnum.md +doc/AuthenticationApi.md +doc/CheckDuplicateAssetDto.md +doc/CheckDuplicateAssetResponseDto.md +doc/CreateAlbumDto.md +doc/CreateDeviceInfoDto.md +doc/CreateProfileImageResponseDto.md +doc/CreateUserDto.md +doc/CuratedLocationsResponseDto.md +doc/CuratedObjectsResponseDto.md +doc/DeleteAssetDto.md +doc/DeleteAssetResponseDto.md +doc/DeleteAssetStatus.md +doc/DeviceInfoApi.md +doc/DeviceInfoResponseDto.md +doc/DeviceTypeEnum.md +doc/ExifResponseDto.md +doc/LoginCredentialDto.md +doc/LoginResponseDto.md +doc/RemoveAssetsDto.md +doc/SearchAssetDto.md +doc/ServerInfoApi.md +doc/ServerInfoResponseDto.md +doc/ServerPingResponse.md +doc/ServerVersionReponseDto.md +doc/SignUpDto.md +doc/SmartInfoResponseDto.md +doc/UpdateAlbumDto.md +doc/UpdateDeviceInfoDto.md +doc/UpdateUserDto.md +doc/UserApi.md +doc/UserCountResponseDto.md +doc/UserResponseDto.md +doc/ValidateAccessTokenResponseDto.md +git_push.sh +lib/api.dart +lib/api/album_api.dart +lib/api/asset_api.dart +lib/api/authentication_api.dart +lib/api/device_info_api.dart +lib/api/server_info_api.dart +lib/api/user_api.dart +lib/api_client.dart +lib/api_exception.dart +lib/api_helper.dart +lib/auth/api_key_auth.dart +lib/auth/authentication.dart +lib/auth/http_basic_auth.dart +lib/auth/http_bearer_auth.dart +lib/auth/oauth.dart +lib/model/add_assets_dto.dart +lib/model/add_users_dto.dart +lib/model/admin_signup_response_dto.dart +lib/model/album_response_dto.dart +lib/model/asset_file_upload_response_dto.dart +lib/model/asset_response_dto.dart +lib/model/asset_type_enum.dart +lib/model/check_duplicate_asset_dto.dart +lib/model/check_duplicate_asset_response_dto.dart +lib/model/create_album_dto.dart +lib/model/create_device_info_dto.dart +lib/model/create_profile_image_response_dto.dart +lib/model/create_user_dto.dart +lib/model/curated_locations_response_dto.dart +lib/model/curated_objects_response_dto.dart +lib/model/delete_asset_dto.dart +lib/model/delete_asset_response_dto.dart +lib/model/delete_asset_status.dart +lib/model/device_info_response_dto.dart +lib/model/device_type_enum.dart +lib/model/exif_response_dto.dart +lib/model/login_credential_dto.dart +lib/model/login_response_dto.dart +lib/model/remove_assets_dto.dart +lib/model/search_asset_dto.dart +lib/model/server_info_response_dto.dart +lib/model/server_ping_response.dart +lib/model/server_version_reponse_dto.dart +lib/model/sign_up_dto.dart +lib/model/smart_info_response_dto.dart +lib/model/update_album_dto.dart +lib/model/update_device_info_dto.dart +lib/model/update_user_dto.dart +lib/model/user_count_response_dto.dart +lib/model/user_response_dto.dart +lib/model/validate_access_token_response_dto.dart +pubspec.yaml +test/validate_access_token_response_dto_test.dart diff --git a/mobile/openapi/.openapi-generator/VERSION b/mobile/openapi/.openapi-generator/VERSION new file mode 100644 index 000000000..6d54bbd77 --- /dev/null +++ b/mobile/openapi/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.0.1 \ No newline at end of file diff --git a/mobile/openapi/.travis.yml b/mobile/openapi/.travis.yml new file mode 100644 index 000000000..2774ccbba --- /dev/null +++ b/mobile/openapi/.travis.yml @@ -0,0 +1,14 @@ +# +# AUTO-GENERATED FILE, DO NOT MODIFY! +# +# https://docs.travis-ci.com/user/languages/dart/ +# +language: dart +dart: +# Install a specific stable release +- "2.12" +install: +- pub get + +script: +- pub run test diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md new file mode 100644 index 000000000..1e9edfc0a --- /dev/null +++ b/mobile/openapi/README.md @@ -0,0 +1,158 @@ +# openapi +Immich API + +This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 1.17.0 +- Build package: org.openapitools.codegen.languages.DartClientCodegen + +## Requirements + +Dart 2.12 or later + +## Installation & Usage + +### Github +If this Dart package is published to Github, add the following dependency to your pubspec.yaml +``` +dependencies: + openapi: + git: https://github.com/GIT_USER_ID/GIT_REPO_ID.git +``` + +### Local +To use the package in your local drive, add the following dependency to your pubspec.yaml +``` +dependencies: + openapi: + path: /path/to/openapi +``` + +## Tests + +TODO + +## Getting Started + +Please follow the [installation procedure](#installation--usage) and then run the following: + +```dart +import 'package:openapi/api.dart'; + +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | +final addAssetsDto = AddAssetsDto(); // AddAssetsDto | + +try { + final result = api_instance.addAssetsToAlbum(albumId, addAssetsDto); + print(result); +} catch (e) { + print('Exception when calling AlbumApi->addAssetsToAlbum: $e\n'); +} + +``` + +## Documentation for API Endpoints + +All URIs are relative to */api* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*AlbumApi* | [**addAssetsToAlbum**](doc//AlbumApi.md#addassetstoalbum) | **PUT** /album/{albumId}/assets | +*AlbumApi* | [**addUsersToAlbum**](doc//AlbumApi.md#adduserstoalbum) | **PUT** /album/{albumId}/users | +*AlbumApi* | [**createAlbum**](doc//AlbumApi.md#createalbum) | **POST** /album | +*AlbumApi* | [**deleteAlbum**](doc//AlbumApi.md#deletealbum) | **DELETE** /album/{albumId} | +*AlbumApi* | [**getAlbumInfo**](doc//AlbumApi.md#getalbuminfo) | **GET** /album/{albumId} | +*AlbumApi* | [**getAllAlbums**](doc//AlbumApi.md#getallalbums) | **GET** /album | +*AlbumApi* | [**removeAssetFromAlbum**](doc//AlbumApi.md#removeassetfromalbum) | **DELETE** /album/{albumId}/assets | +*AlbumApi* | [**removeUserFromAlbum**](doc//AlbumApi.md#removeuserfromalbum) | **DELETE** /album/{albumId}/user/{userId} | +*AlbumApi* | [**updateAlbumInfo**](doc//AlbumApi.md#updatealbuminfo) | **PATCH** /album/{albumId} | +*AssetApi* | [**checkDuplicateAsset**](doc//AssetApi.md#checkduplicateasset) | **POST** /asset/check | +*AssetApi* | [**deleteAsset**](doc//AssetApi.md#deleteasset) | **DELETE** /asset | +*AssetApi* | [**downloadFile**](doc//AssetApi.md#downloadfile) | **GET** /asset/download | +*AssetApi* | [**getAllAssets**](doc//AssetApi.md#getallassets) | **GET** /asset | +*AssetApi* | [**getAssetById**](doc//AssetApi.md#getassetbyid) | **GET** /asset/assetById/{assetId} | +*AssetApi* | [**getAssetSearchTerms**](doc//AssetApi.md#getassetsearchterms) | **GET** /asset/searchTerm | +*AssetApi* | [**getAssetThumbnail**](doc//AssetApi.md#getassetthumbnail) | **GET** /asset/thumbnail/{assetId} | +*AssetApi* | [**getCuratedLocations**](doc//AssetApi.md#getcuratedlocations) | **GET** /asset/allLocation | +*AssetApi* | [**getCuratedObjects**](doc//AssetApi.md#getcuratedobjects) | **GET** /asset/allObjects | +*AssetApi* | [**getUserAssetsByDeviceId**](doc//AssetApi.md#getuserassetsbydeviceid) | **GET** /asset/{deviceId} | +*AssetApi* | [**searchAsset**](doc//AssetApi.md#searchasset) | **POST** /asset/search | +*AssetApi* | [**serveFile**](doc//AssetApi.md#servefile) | **GET** /asset/file | +*AssetApi* | [**uploadFile**](doc//AssetApi.md#uploadfile) | **POST** /asset/upload | +*AuthenticationApi* | [**adminSignUp**](doc//AuthenticationApi.md#adminsignup) | **POST** /auth/admin-sign-up | +*AuthenticationApi* | [**login**](doc//AuthenticationApi.md#login) | **POST** /auth/login | +*AuthenticationApi* | [**validateAccessToken**](doc//AuthenticationApi.md#validateaccesstoken) | **POST** /auth/validateToken | +*DeviceInfoApi* | [**createDeviceInfo**](doc//DeviceInfoApi.md#createdeviceinfo) | **POST** /device-info | +*DeviceInfoApi* | [**updateDeviceInfo**](doc//DeviceInfoApi.md#updatedeviceinfo) | **PATCH** /device-info | +*ServerInfoApi* | [**getServerInfo**](doc//ServerInfoApi.md#getserverinfo) | **GET** /server-info | +*ServerInfoApi* | [**getServerVersion**](doc//ServerInfoApi.md#getserverversion) | **GET** /server-info/version | +*ServerInfoApi* | [**pingServer**](doc//ServerInfoApi.md#pingserver) | **GET** /server-info/ping | +*UserApi* | [**createProfileImage**](doc//UserApi.md#createprofileimage) | **POST** /user/profile-image | +*UserApi* | [**createUser**](doc//UserApi.md#createuser) | **POST** /user | +*UserApi* | [**getAllUsers**](doc//UserApi.md#getallusers) | **GET** /user | +*UserApi* | [**getMyUserInfo**](doc//UserApi.md#getmyuserinfo) | **GET** /user/me | +*UserApi* | [**getProfileImage**](doc//UserApi.md#getprofileimage) | **GET** /user/profile-image/{userId} | +*UserApi* | [**getUserCount**](doc//UserApi.md#getusercount) | **GET** /user/count | +*UserApi* | [**updateUser**](doc//UserApi.md#updateuser) | **PUT** /user | + + +## Documentation For Models + + - [AddAssetsDto](doc//AddAssetsDto.md) + - [AddUsersDto](doc//AddUsersDto.md) + - [AdminSignupResponseDto](doc//AdminSignupResponseDto.md) + - [AlbumResponseDto](doc//AlbumResponseDto.md) + - [AssetFileUploadResponseDto](doc//AssetFileUploadResponseDto.md) + - [AssetResponseDto](doc//AssetResponseDto.md) + - [AssetTypeEnum](doc//AssetTypeEnum.md) + - [CheckDuplicateAssetDto](doc//CheckDuplicateAssetDto.md) + - [CheckDuplicateAssetResponseDto](doc//CheckDuplicateAssetResponseDto.md) + - [CreateAlbumDto](doc//CreateAlbumDto.md) + - [CreateDeviceInfoDto](doc//CreateDeviceInfoDto.md) + - [CreateProfileImageResponseDto](doc//CreateProfileImageResponseDto.md) + - [CreateUserDto](doc//CreateUserDto.md) + - [CuratedLocationsResponseDto](doc//CuratedLocationsResponseDto.md) + - [CuratedObjectsResponseDto](doc//CuratedObjectsResponseDto.md) + - [DeleteAssetDto](doc//DeleteAssetDto.md) + - [DeleteAssetResponseDto](doc//DeleteAssetResponseDto.md) + - [DeleteAssetStatus](doc//DeleteAssetStatus.md) + - [DeviceInfoResponseDto](doc//DeviceInfoResponseDto.md) + - [DeviceTypeEnum](doc//DeviceTypeEnum.md) + - [ExifResponseDto](doc//ExifResponseDto.md) + - [LoginCredentialDto](doc//LoginCredentialDto.md) + - [LoginResponseDto](doc//LoginResponseDto.md) + - [RemoveAssetsDto](doc//RemoveAssetsDto.md) + - [SearchAssetDto](doc//SearchAssetDto.md) + - [ServerInfoResponseDto](doc//ServerInfoResponseDto.md) + - [ServerPingResponse](doc//ServerPingResponse.md) + - [ServerVersionReponseDto](doc//ServerVersionReponseDto.md) + - [SignUpDto](doc//SignUpDto.md) + - [SmartInfoResponseDto](doc//SmartInfoResponseDto.md) + - [UpdateAlbumDto](doc//UpdateAlbumDto.md) + - [UpdateDeviceInfoDto](doc//UpdateDeviceInfoDto.md) + - [UpdateUserDto](doc//UpdateUserDto.md) + - [UserCountResponseDto](doc//UserCountResponseDto.md) + - [UserResponseDto](doc//UserResponseDto.md) + - [ValidateAccessTokenResponseDto](doc//ValidateAccessTokenResponseDto.md) + + +## Documentation For Authorization + + +## bearer + +- **Type**: HTTP Bearer authentication + + +## Author + + + diff --git a/mobile/openapi/analysis_options.yaml b/mobile/openapi/analysis_options.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/mobile/openapi/doc/AddAssetsDto.md b/mobile/openapi/doc/AddAssetsDto.md new file mode 100644 index 000000000..b74211d6b --- /dev/null +++ b/mobile/openapi/doc/AddAssetsDto.md @@ -0,0 +1,15 @@ +# openapi.model.AddAssetsDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**assetIds** | **List** | | [default to const []] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/AddUsersDto.md b/mobile/openapi/doc/AddUsersDto.md new file mode 100644 index 000000000..9f7770d60 --- /dev/null +++ b/mobile/openapi/doc/AddUsersDto.md @@ -0,0 +1,15 @@ +# openapi.model.AddUsersDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**sharedUserIds** | **List** | | [default to const []] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/AdminSignupResponseDto.md b/mobile/openapi/doc/AdminSignupResponseDto.md new file mode 100644 index 000000000..ff9890de5 --- /dev/null +++ b/mobile/openapi/doc/AdminSignupResponseDto.md @@ -0,0 +1,19 @@ +# openapi.model.AdminSignupResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | +**email** | **String** | | +**firstName** | **String** | | +**lastName** | **String** | | +**createdAt** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/AlbumApi.md b/mobile/openapi/doc/AlbumApi.md new file mode 100644 index 000000000..1a0fe61ed --- /dev/null +++ b/mobile/openapi/doc/AlbumApi.md @@ -0,0 +1,452 @@ +# openapi.api.AlbumApi + +## Load the API package +```dart +import 'package:openapi/api.dart'; +``` + +All URIs are relative to */api* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**addAssetsToAlbum**](AlbumApi.md#addassetstoalbum) | **PUT** /album/{albumId}/assets | +[**addUsersToAlbum**](AlbumApi.md#adduserstoalbum) | **PUT** /album/{albumId}/users | +[**createAlbum**](AlbumApi.md#createalbum) | **POST** /album | +[**deleteAlbum**](AlbumApi.md#deletealbum) | **DELETE** /album/{albumId} | +[**getAlbumInfo**](AlbumApi.md#getalbuminfo) | **GET** /album/{albumId} | +[**getAllAlbums**](AlbumApi.md#getallalbums) | **GET** /album | +[**removeAssetFromAlbum**](AlbumApi.md#removeassetfromalbum) | **DELETE** /album/{albumId}/assets | +[**removeUserFromAlbum**](AlbumApi.md#removeuserfromalbum) | **DELETE** /album/{albumId}/user/{userId} | +[**updateAlbumInfo**](AlbumApi.md#updatealbuminfo) | **PATCH** /album/{albumId} | + + +# **addAssetsToAlbum** +> AlbumResponseDto addAssetsToAlbum(albumId, addAssetsDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | +final addAssetsDto = AddAssetsDto(); // AddAssetsDto | + +try { + final result = api_instance.addAssetsToAlbum(albumId, addAssetsDto); + print(result); +} catch (e) { + print('Exception when calling AlbumApi->addAssetsToAlbum: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **albumId** | **String**| | + **addAssetsDto** | [**AddAssetsDto**](AddAssetsDto.md)| | + +### Return type + +[**AlbumResponseDto**](AlbumResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **addUsersToAlbum** +> AlbumResponseDto addUsersToAlbum(albumId, addUsersDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | +final addUsersDto = AddUsersDto(); // AddUsersDto | + +try { + final result = api_instance.addUsersToAlbum(albumId, addUsersDto); + print(result); +} catch (e) { + print('Exception when calling AlbumApi->addUsersToAlbum: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **albumId** | **String**| | + **addUsersDto** | [**AddUsersDto**](AddUsersDto.md)| | + +### Return type + +[**AlbumResponseDto**](AlbumResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **createAlbum** +> AlbumResponseDto createAlbum(createAlbumDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final createAlbumDto = CreateAlbumDto(); // CreateAlbumDto | + +try { + final result = api_instance.createAlbum(createAlbumDto); + print(result); +} catch (e) { + print('Exception when calling AlbumApi->createAlbum: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **createAlbumDto** | [**CreateAlbumDto**](CreateAlbumDto.md)| | + +### Return type + +[**AlbumResponseDto**](AlbumResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **deleteAlbum** +> deleteAlbum(albumId) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | + +try { + api_instance.deleteAlbum(albumId); +} catch (e) { + print('Exception when calling AlbumApi->deleteAlbum: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **albumId** | **String**| | + +### Return type + +void (empty response body) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getAlbumInfo** +> AlbumResponseDto getAlbumInfo(albumId) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | + +try { + final result = api_instance.getAlbumInfo(albumId); + print(result); +} catch (e) { + print('Exception when calling AlbumApi->getAlbumInfo: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **albumId** | **String**| | + +### Return type + +[**AlbumResponseDto**](AlbumResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getAllAlbums** +> List getAllAlbums(shared) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final shared = true; // bool | + +try { + final result = api_instance.getAllAlbums(shared); + print(result); +} catch (e) { + print('Exception when calling AlbumApi->getAllAlbums: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **shared** | **bool**| | [optional] + +### Return type + +[**List**](AlbumResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **removeAssetFromAlbum** +> removeAssetFromAlbum(albumId, removeAssetsDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | +final removeAssetsDto = RemoveAssetsDto(); // RemoveAssetsDto | + +try { + api_instance.removeAssetFromAlbum(albumId, removeAssetsDto); +} catch (e) { + print('Exception when calling AlbumApi->removeAssetFromAlbum: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **albumId** | **String**| | + **removeAssetsDto** | [**RemoveAssetsDto**](RemoveAssetsDto.md)| | + +### Return type + +void (empty response body) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **removeUserFromAlbum** +> removeUserFromAlbum(albumId, userId) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | +final userId = userId_example; // String | + +try { + api_instance.removeUserFromAlbum(albumId, userId); +} catch (e) { + print('Exception when calling AlbumApi->removeUserFromAlbum: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **albumId** | **String**| | + **userId** | **String**| | + +### Return type + +void (empty response body) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **updateAlbumInfo** +> AlbumResponseDto updateAlbumInfo(albumId, updateAlbumDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AlbumApi(); +final albumId = albumId_example; // String | +final updateAlbumDto = UpdateAlbumDto(); // UpdateAlbumDto | + +try { + final result = api_instance.updateAlbumInfo(albumId, updateAlbumDto); + print(result); +} catch (e) { + print('Exception when calling AlbumApi->updateAlbumInfo: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **albumId** | **String**| | + **updateAlbumDto** | [**UpdateAlbumDto**](UpdateAlbumDto.md)| | + +### Return type + +[**AlbumResponseDto**](AlbumResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/mobile/openapi/doc/AlbumResponseDto.md b/mobile/openapi/doc/AlbumResponseDto.md new file mode 100644 index 000000000..79dfd8490 --- /dev/null +++ b/mobile/openapi/doc/AlbumResponseDto.md @@ -0,0 +1,22 @@ +# openapi.model.AlbumResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | +**ownerId** | **String** | | +**albumName** | **String** | | +**createdAt** | **String** | | +**albumThumbnailAssetId** | **String** | | +**shared** | **bool** | | +**sharedUsers** | [**List**](UserResponseDto.md) | | [default to const []] +**assets** | [**List**](AssetResponseDto.md) | | [default to const []] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/AssetApi.md b/mobile/openapi/doc/AssetApi.md new file mode 100644 index 000000000..89455a9e6 --- /dev/null +++ b/mobile/openapi/doc/AssetApi.md @@ -0,0 +1,641 @@ +# openapi.api.AssetApi + +## Load the API package +```dart +import 'package:openapi/api.dart'; +``` + +All URIs are relative to */api* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**checkDuplicateAsset**](AssetApi.md#checkduplicateasset) | **POST** /asset/check | +[**deleteAsset**](AssetApi.md#deleteasset) | **DELETE** /asset | +[**downloadFile**](AssetApi.md#downloadfile) | **GET** /asset/download | +[**getAllAssets**](AssetApi.md#getallassets) | **GET** /asset | +[**getAssetById**](AssetApi.md#getassetbyid) | **GET** /asset/assetById/{assetId} | +[**getAssetSearchTerms**](AssetApi.md#getassetsearchterms) | **GET** /asset/searchTerm | +[**getAssetThumbnail**](AssetApi.md#getassetthumbnail) | **GET** /asset/thumbnail/{assetId} | +[**getCuratedLocations**](AssetApi.md#getcuratedlocations) | **GET** /asset/allLocation | +[**getCuratedObjects**](AssetApi.md#getcuratedobjects) | **GET** /asset/allObjects | +[**getUserAssetsByDeviceId**](AssetApi.md#getuserassetsbydeviceid) | **GET** /asset/{deviceId} | +[**searchAsset**](AssetApi.md#searchasset) | **POST** /asset/search | +[**serveFile**](AssetApi.md#servefile) | **GET** /asset/file | +[**uploadFile**](AssetApi.md#uploadfile) | **POST** /asset/upload | + + +# **checkDuplicateAsset** +> CheckDuplicateAssetResponseDto checkDuplicateAsset(checkDuplicateAssetDto) + + + +Check duplicated asset before uploading - for Web upload used + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final checkDuplicateAssetDto = CheckDuplicateAssetDto(); // CheckDuplicateAssetDto | + +try { + final result = api_instance.checkDuplicateAsset(checkDuplicateAssetDto); + print(result); +} catch (e) { + print('Exception when calling AssetApi->checkDuplicateAsset: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **checkDuplicateAssetDto** | [**CheckDuplicateAssetDto**](CheckDuplicateAssetDto.md)| | + +### Return type + +[**CheckDuplicateAssetResponseDto**](CheckDuplicateAssetResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **deleteAsset** +> List deleteAsset(deleteAssetDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final deleteAssetDto = DeleteAssetDto(); // DeleteAssetDto | + +try { + final result = api_instance.deleteAsset(deleteAssetDto); + print(result); +} catch (e) { + print('Exception when calling AssetApi->deleteAsset: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **deleteAssetDto** | [**DeleteAssetDto**](DeleteAssetDto.md)| | + +### Return type + +[**List**](DeleteAssetResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **downloadFile** +> Object downloadFile(aid, did, isThumb, isWeb) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final aid = aid_example; // String | +final did = did_example; // String | +final isThumb = true; // bool | +final isWeb = true; // bool | + +try { + final result = api_instance.downloadFile(aid, did, isThumb, isWeb); + print(result); +} catch (e) { + print('Exception when calling AssetApi->downloadFile: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **aid** | **String**| | + **did** | **String**| | + **isThumb** | **bool**| | [optional] + **isWeb** | **bool**| | [optional] + +### Return type + +[**Object**](Object.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getAllAssets** +> List getAllAssets() + + + +Get all AssetEntity belong to the user + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); + +try { + final result = api_instance.getAllAssets(); + print(result); +} catch (e) { + print('Exception when calling AssetApi->getAllAssets: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**List**](AssetResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getAssetById** +> AssetResponseDto getAssetById(assetId) + + + +Get a single asset's information + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final assetId = assetId_example; // String | + +try { + final result = api_instance.getAssetById(assetId); + print(result); +} catch (e) { + print('Exception when calling AssetApi->getAssetById: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **assetId** | **String**| | + +### Return type + +[**AssetResponseDto**](AssetResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getAssetSearchTerms** +> List getAssetSearchTerms() + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); + +try { + final result = api_instance.getAssetSearchTerms(); + print(result); +} catch (e) { + print('Exception when calling AssetApi->getAssetSearchTerms: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +**List** + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getAssetThumbnail** +> Object getAssetThumbnail(assetId) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final assetId = assetId_example; // String | + +try { + final result = api_instance.getAssetThumbnail(assetId); + print(result); +} catch (e) { + print('Exception when calling AssetApi->getAssetThumbnail: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **assetId** | **String**| | + +### Return type + +[**Object**](Object.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getCuratedLocations** +> List getCuratedLocations() + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); + +try { + final result = api_instance.getCuratedLocations(); + print(result); +} catch (e) { + print('Exception when calling AssetApi->getCuratedLocations: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**List**](CuratedLocationsResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getCuratedObjects** +> List getCuratedObjects() + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); + +try { + final result = api_instance.getCuratedObjects(); + print(result); +} catch (e) { + print('Exception when calling AssetApi->getCuratedObjects: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**List**](CuratedObjectsResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getUserAssetsByDeviceId** +> List getUserAssetsByDeviceId(deviceId) + + + +Get all asset of a device that are in the database, ID only. + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final deviceId = deviceId_example; // String | + +try { + final result = api_instance.getUserAssetsByDeviceId(deviceId); + print(result); +} catch (e) { + print('Exception when calling AssetApi->getUserAssetsByDeviceId: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **deviceId** | **String**| | + +### Return type + +**List** + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **searchAsset** +> List searchAsset(searchAssetDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final searchAssetDto = SearchAssetDto(); // SearchAssetDto | + +try { + final result = api_instance.searchAsset(searchAssetDto); + print(result); +} catch (e) { + print('Exception when calling AssetApi->searchAsset: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **searchAssetDto** | [**SearchAssetDto**](SearchAssetDto.md)| | + +### Return type + +[**List**](AssetResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **serveFile** +> Object serveFile(aid, did, isThumb, isWeb) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final aid = aid_example; // String | +final did = did_example; // String | +final isThumb = true; // bool | +final isWeb = true; // bool | + +try { + final result = api_instance.serveFile(aid, did, isThumb, isWeb); + print(result); +} catch (e) { + print('Exception when calling AssetApi->serveFile: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **aid** | **String**| | + **did** | **String**| | + **isThumb** | **bool**| | [optional] + **isWeb** | **bool**| | [optional] + +### Return type + +[**Object**](Object.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **uploadFile** +> AssetFileUploadResponseDto uploadFile(assetData) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AssetApi(); +final assetData = BINARY_DATA_HERE; // MultipartFile | + +try { + final result = api_instance.uploadFile(assetData); + print(result); +} catch (e) { + print('Exception when calling AssetApi->uploadFile: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **assetData** | **MultipartFile**| | + +### Return type + +[**AssetFileUploadResponseDto**](AssetFileUploadResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: multipart/form-data + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/mobile/openapi/doc/AssetFileUploadResponseDto.md b/mobile/openapi/doc/AssetFileUploadResponseDto.md new file mode 100644 index 000000000..1b4f599e1 --- /dev/null +++ b/mobile/openapi/doc/AssetFileUploadResponseDto.md @@ -0,0 +1,15 @@ +# openapi.model.AssetFileUploadResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/AssetResponseDto.md b/mobile/openapi/doc/AssetResponseDto.md new file mode 100644 index 000000000..e693549f6 --- /dev/null +++ b/mobile/openapi/doc/AssetResponseDto.md @@ -0,0 +1,30 @@ +# openapi.model.AssetResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**type** | [**AssetTypeEnum**](AssetTypeEnum.md) | | +**id** | **String** | | +**deviceAssetId** | **String** | | +**ownerId** | **String** | | +**deviceId** | **String** | | +**originalPath** | **String** | | +**resizePath** | **String** | | +**createdAt** | **String** | | +**modifiedAt** | **String** | | +**isFavorite** | **bool** | | +**mimeType** | **String** | | +**duration** | **String** | | +**webpPath** | **String** | | +**encodedVideoPath** | **String** | | +**exifInfo** | [**ExifResponseDto**](ExifResponseDto.md) | | [optional] +**smartInfo** | [**SmartInfoResponseDto**](SmartInfoResponseDto.md) | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/AssetTypeEnum.md b/mobile/openapi/doc/AssetTypeEnum.md new file mode 100644 index 000000000..8d514b090 --- /dev/null +++ b/mobile/openapi/doc/AssetTypeEnum.md @@ -0,0 +1,14 @@ +# openapi.model.AssetTypeEnum + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/AuthenticationApi.md b/mobile/openapi/doc/AuthenticationApi.md new file mode 100644 index 000000000..46590ff5a --- /dev/null +++ b/mobile/openapi/doc/AuthenticationApi.md @@ -0,0 +1,141 @@ +# openapi.api.AuthenticationApi + +## Load the API package +```dart +import 'package:openapi/api.dart'; +``` + +All URIs are relative to */api* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**adminSignUp**](AuthenticationApi.md#adminsignup) | **POST** /auth/admin-sign-up | +[**login**](AuthenticationApi.md#login) | **POST** /auth/login | +[**validateAccessToken**](AuthenticationApi.md#validateaccesstoken) | **POST** /auth/validateToken | + + +# **adminSignUp** +> AdminSignupResponseDto adminSignUp(signUpDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; + +final api_instance = AuthenticationApi(); +final signUpDto = SignUpDto(); // SignUpDto | + +try { + final result = api_instance.adminSignUp(signUpDto); + print(result); +} catch (e) { + print('Exception when calling AuthenticationApi->adminSignUp: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **signUpDto** | [**SignUpDto**](SignUpDto.md)| | + +### Return type + +[**AdminSignupResponseDto**](AdminSignupResponseDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **login** +> LoginResponseDto login(loginCredentialDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; + +final api_instance = AuthenticationApi(); +final loginCredentialDto = LoginCredentialDto(); // LoginCredentialDto | + +try { + final result = api_instance.login(loginCredentialDto); + print(result); +} catch (e) { + print('Exception when calling AuthenticationApi->login: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **loginCredentialDto** | [**LoginCredentialDto**](LoginCredentialDto.md)| | + +### Return type + +[**LoginResponseDto**](LoginResponseDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **validateAccessToken** +> ValidateAccessTokenResponseDto validateAccessToken() + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = AuthenticationApi(); + +try { + final result = api_instance.validateAccessToken(); + print(result); +} catch (e) { + print('Exception when calling AuthenticationApi->validateAccessToken: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**ValidateAccessTokenResponseDto**](ValidateAccessTokenResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/mobile/openapi/doc/CheckDuplicateAssetDto.md b/mobile/openapi/doc/CheckDuplicateAssetDto.md new file mode 100644 index 000000000..259cdfc81 --- /dev/null +++ b/mobile/openapi/doc/CheckDuplicateAssetDto.md @@ -0,0 +1,16 @@ +# openapi.model.CheckDuplicateAssetDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**deviceAssetId** | **String** | | +**deviceId** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/CheckDuplicateAssetResponseDto.md b/mobile/openapi/doc/CheckDuplicateAssetResponseDto.md new file mode 100644 index 000000000..736d86224 --- /dev/null +++ b/mobile/openapi/doc/CheckDuplicateAssetResponseDto.md @@ -0,0 +1,15 @@ +# openapi.model.CheckDuplicateAssetResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**isExist** | **bool** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/CreateAlbumDto.md b/mobile/openapi/doc/CreateAlbumDto.md new file mode 100644 index 000000000..2f91dba10 --- /dev/null +++ b/mobile/openapi/doc/CreateAlbumDto.md @@ -0,0 +1,17 @@ +# openapi.model.CreateAlbumDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**albumName** | **String** | | +**sharedWithUserIds** | **List** | | [optional] [default to const []] +**assetIds** | **List** | | [optional] [default to const []] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/CreateDeviceInfoDto.md b/mobile/openapi/doc/CreateDeviceInfoDto.md new file mode 100644 index 000000000..d0629bb2d --- /dev/null +++ b/mobile/openapi/doc/CreateDeviceInfoDto.md @@ -0,0 +1,17 @@ +# openapi.model.CreateDeviceInfoDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**deviceType** | [**DeviceTypeEnum**](DeviceTypeEnum.md) | | +**deviceId** | **String** | | +**isAutoBackup** | **bool** | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/CreateProfileImageResponseDto.md b/mobile/openapi/doc/CreateProfileImageResponseDto.md new file mode 100644 index 000000000..3323e7df4 --- /dev/null +++ b/mobile/openapi/doc/CreateProfileImageResponseDto.md @@ -0,0 +1,16 @@ +# openapi.model.CreateProfileImageResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**userId** | **String** | | +**profileImagePath** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/CreateUserDto.md b/mobile/openapi/doc/CreateUserDto.md new file mode 100644 index 000000000..c7b8b4ca2 --- /dev/null +++ b/mobile/openapi/doc/CreateUserDto.md @@ -0,0 +1,18 @@ +# openapi.model.CreateUserDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**email** | **String** | | +**password** | **String** | | +**firstName** | **String** | | +**lastName** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/CuratedLocationsResponseDto.md b/mobile/openapi/doc/CuratedLocationsResponseDto.md new file mode 100644 index 000000000..abd86ea53 --- /dev/null +++ b/mobile/openapi/doc/CuratedLocationsResponseDto.md @@ -0,0 +1,19 @@ +# openapi.model.CuratedLocationsResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | +**city** | **String** | | +**resizePath** | **String** | | +**deviceAssetId** | **String** | | +**deviceId** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/CuratedObjectsResponseDto.md b/mobile/openapi/doc/CuratedObjectsResponseDto.md new file mode 100644 index 000000000..559f25148 --- /dev/null +++ b/mobile/openapi/doc/CuratedObjectsResponseDto.md @@ -0,0 +1,19 @@ +# openapi.model.CuratedObjectsResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | +**object** | **String** | | +**resizePath** | **String** | | +**deviceAssetId** | **String** | | +**deviceId** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/DeleteAssetDto.md b/mobile/openapi/doc/DeleteAssetDto.md new file mode 100644 index 000000000..3b60d4ece --- /dev/null +++ b/mobile/openapi/doc/DeleteAssetDto.md @@ -0,0 +1,15 @@ +# openapi.model.DeleteAssetDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ids** | **List** | | [default to const []] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/DeleteAssetResponseDto.md b/mobile/openapi/doc/DeleteAssetResponseDto.md new file mode 100644 index 000000000..4cd44e030 --- /dev/null +++ b/mobile/openapi/doc/DeleteAssetResponseDto.md @@ -0,0 +1,16 @@ +# openapi.model.DeleteAssetResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**status** | [**DeleteAssetStatus**](DeleteAssetStatus.md) | | +**id** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/DeleteAssetStatus.md b/mobile/openapi/doc/DeleteAssetStatus.md new file mode 100644 index 000000000..4616d0ae0 --- /dev/null +++ b/mobile/openapi/doc/DeleteAssetStatus.md @@ -0,0 +1,14 @@ +# openapi.model.DeleteAssetStatus + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/DeviceInfoApi.md b/mobile/openapi/doc/DeviceInfoApi.md new file mode 100644 index 000000000..d1c032e65 --- /dev/null +++ b/mobile/openapi/doc/DeviceInfoApi.md @@ -0,0 +1,109 @@ +# openapi.api.DeviceInfoApi + +## Load the API package +```dart +import 'package:openapi/api.dart'; +``` + +All URIs are relative to */api* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**createDeviceInfo**](DeviceInfoApi.md#createdeviceinfo) | **POST** /device-info | +[**updateDeviceInfo**](DeviceInfoApi.md#updatedeviceinfo) | **PATCH** /device-info | + + +# **createDeviceInfo** +> DeviceInfoResponseDto createDeviceInfo(createDeviceInfoDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = DeviceInfoApi(); +final createDeviceInfoDto = CreateDeviceInfoDto(); // CreateDeviceInfoDto | + +try { + final result = api_instance.createDeviceInfo(createDeviceInfoDto); + print(result); +} catch (e) { + print('Exception when calling DeviceInfoApi->createDeviceInfo: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **createDeviceInfoDto** | [**CreateDeviceInfoDto**](CreateDeviceInfoDto.md)| | + +### Return type + +[**DeviceInfoResponseDto**](DeviceInfoResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **updateDeviceInfo** +> DeviceInfoResponseDto updateDeviceInfo(updateDeviceInfoDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = DeviceInfoApi(); +final updateDeviceInfoDto = UpdateDeviceInfoDto(); // UpdateDeviceInfoDto | + +try { + final result = api_instance.updateDeviceInfo(updateDeviceInfoDto); + print(result); +} catch (e) { + print('Exception when calling DeviceInfoApi->updateDeviceInfo: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **updateDeviceInfoDto** | [**UpdateDeviceInfoDto**](UpdateDeviceInfoDto.md)| | + +### Return type + +[**DeviceInfoResponseDto**](DeviceInfoResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/mobile/openapi/doc/DeviceInfoResponseDto.md b/mobile/openapi/doc/DeviceInfoResponseDto.md new file mode 100644 index 000000000..95edd86ab --- /dev/null +++ b/mobile/openapi/doc/DeviceInfoResponseDto.md @@ -0,0 +1,20 @@ +# openapi.model.DeviceInfoResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **int** | | +**deviceType** | [**DeviceTypeEnum**](DeviceTypeEnum.md) | | +**userId** | **String** | | +**deviceId** | **String** | | +**createdAt** | **String** | | +**isAutoBackup** | **bool** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/DeviceTypeEnum.md b/mobile/openapi/doc/DeviceTypeEnum.md new file mode 100644 index 000000000..ab8f99acb --- /dev/null +++ b/mobile/openapi/doc/DeviceTypeEnum.md @@ -0,0 +1,14 @@ +# openapi.model.DeviceTypeEnum + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/ExifResponseDto.md b/mobile/openapi/doc/ExifResponseDto.md new file mode 100644 index 000000000..0e96bdcbe --- /dev/null +++ b/mobile/openapi/doc/ExifResponseDto.md @@ -0,0 +1,34 @@ +# openapi.model.ExifResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | [optional] +**make** | **String** | | [optional] +**model** | **String** | | [optional] +**imageName** | **String** | | [optional] +**exifImageWidth** | **num** | | [optional] +**exifImageHeight** | **num** | | [optional] +**fileSizeInByte** | **num** | | [optional] +**orientation** | **String** | | [optional] +**dateTimeOriginal** | [**DateTime**](DateTime.md) | | [optional] +**modifyDate** | [**DateTime**](DateTime.md) | | [optional] +**lensModel** | **String** | | [optional] +**fNumber** | **num** | | [optional] +**focalLength** | **num** | | [optional] +**iso** | **num** | | [optional] +**exposureTime** | **num** | | [optional] +**latitude** | **num** | | [optional] +**longitude** | **num** | | [optional] +**city** | **String** | | [optional] +**state** | **String** | | [optional] +**country** | **String** | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/LoginCredentialDto.md b/mobile/openapi/doc/LoginCredentialDto.md new file mode 100644 index 000000000..bf8eb3d21 --- /dev/null +++ b/mobile/openapi/doc/LoginCredentialDto.md @@ -0,0 +1,16 @@ +# openapi.model.LoginCredentialDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**email** | **String** | | +**password** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/LoginResponseDto.md b/mobile/openapi/doc/LoginResponseDto.md new file mode 100644 index 000000000..b4033fe52 --- /dev/null +++ b/mobile/openapi/doc/LoginResponseDto.md @@ -0,0 +1,22 @@ +# openapi.model.LoginResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**accessToken** | **String** | | [readonly] +**userId** | **String** | | [readonly] +**userEmail** | **String** | | [readonly] +**firstName** | **String** | | [readonly] +**lastName** | **String** | | [readonly] +**profileImagePath** | **String** | | [readonly] +**isAdmin** | **bool** | | [readonly] +**shouldChangePassword** | **bool** | | [readonly] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/RemoveAssetsDto.md b/mobile/openapi/doc/RemoveAssetsDto.md new file mode 100644 index 000000000..d2ab84732 --- /dev/null +++ b/mobile/openapi/doc/RemoveAssetsDto.md @@ -0,0 +1,15 @@ +# openapi.model.RemoveAssetsDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**assetIds** | **List** | | [default to const []] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/SearchAssetDto.md b/mobile/openapi/doc/SearchAssetDto.md new file mode 100644 index 000000000..1eadd2a0c --- /dev/null +++ b/mobile/openapi/doc/SearchAssetDto.md @@ -0,0 +1,15 @@ +# openapi.model.SearchAssetDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**searchTerm** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/ServerInfoApi.md b/mobile/openapi/doc/ServerInfoApi.md new file mode 100644 index 000000000..7d2840f8c --- /dev/null +++ b/mobile/openapi/doc/ServerInfoApi.md @@ -0,0 +1,127 @@ +# openapi.api.ServerInfoApi + +## Load the API package +```dart +import 'package:openapi/api.dart'; +``` + +All URIs are relative to */api* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**getServerInfo**](ServerInfoApi.md#getserverinfo) | **GET** /server-info | +[**getServerVersion**](ServerInfoApi.md#getserverversion) | **GET** /server-info/version | +[**pingServer**](ServerInfoApi.md#pingserver) | **GET** /server-info/ping | + + +# **getServerInfo** +> ServerInfoResponseDto getServerInfo() + + + +### Example +```dart +import 'package:openapi/api.dart'; + +final api_instance = ServerInfoApi(); + +try { + final result = api_instance.getServerInfo(); + print(result); +} catch (e) { + print('Exception when calling ServerInfoApi->getServerInfo: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**ServerInfoResponseDto**](ServerInfoResponseDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getServerVersion** +> ServerVersionReponseDto getServerVersion() + + + +### Example +```dart +import 'package:openapi/api.dart'; + +final api_instance = ServerInfoApi(); + +try { + final result = api_instance.getServerVersion(); + print(result); +} catch (e) { + print('Exception when calling ServerInfoApi->getServerVersion: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**ServerVersionReponseDto**](ServerVersionReponseDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **pingServer** +> ServerPingResponse pingServer() + + + +### Example +```dart +import 'package:openapi/api.dart'; + +final api_instance = ServerInfoApi(); + +try { + final result = api_instance.pingServer(); + print(result); +} catch (e) { + print('Exception when calling ServerInfoApi->pingServer: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**ServerPingResponse**](ServerPingResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/mobile/openapi/doc/ServerInfoResponseDto.md b/mobile/openapi/doc/ServerInfoResponseDto.md new file mode 100644 index 000000000..75694d60d --- /dev/null +++ b/mobile/openapi/doc/ServerInfoResponseDto.md @@ -0,0 +1,21 @@ +# openapi.model.ServerInfoResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**diskSizeRaw** | **int** | | +**diskUseRaw** | **int** | | +**diskAvailableRaw** | **int** | | +**diskUsagePercentage** | **double** | | +**diskSize** | **String** | | +**diskUse** | **String** | | +**diskAvailable** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/ServerPingResponse.md b/mobile/openapi/doc/ServerPingResponse.md new file mode 100644 index 000000000..97a79869f --- /dev/null +++ b/mobile/openapi/doc/ServerPingResponse.md @@ -0,0 +1,15 @@ +# openapi.model.ServerPingResponse + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**res** | **String** | | [readonly] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/ServerVersionReponseDto.md b/mobile/openapi/doc/ServerVersionReponseDto.md new file mode 100644 index 000000000..e40920e50 --- /dev/null +++ b/mobile/openapi/doc/ServerVersionReponseDto.md @@ -0,0 +1,18 @@ +# openapi.model.ServerVersionReponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**major** | **int** | | +**minor** | **int** | | +**patch_** | **int** | | +**build** | **int** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/SignUpDto.md b/mobile/openapi/doc/SignUpDto.md new file mode 100644 index 000000000..6ca6759a9 --- /dev/null +++ b/mobile/openapi/doc/SignUpDto.md @@ -0,0 +1,18 @@ +# openapi.model.SignUpDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**email** | **String** | | +**password** | **String** | | +**firstName** | **String** | | +**lastName** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/SmartInfoResponseDto.md b/mobile/openapi/doc/SmartInfoResponseDto.md new file mode 100644 index 000000000..84a273768 --- /dev/null +++ b/mobile/openapi/doc/SmartInfoResponseDto.md @@ -0,0 +1,17 @@ +# openapi.model.SmartInfoResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | [optional] +**tags** | **List** | | [optional] [default to const []] +**objects** | **List** | | [optional] [default to const []] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/UpdateAlbumDto.md b/mobile/openapi/doc/UpdateAlbumDto.md new file mode 100644 index 000000000..e31c8b41e --- /dev/null +++ b/mobile/openapi/doc/UpdateAlbumDto.md @@ -0,0 +1,16 @@ +# openapi.model.UpdateAlbumDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**albumName** | **String** | | +**ownerId** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/UpdateDeviceInfoDto.md b/mobile/openapi/doc/UpdateDeviceInfoDto.md new file mode 100644 index 000000000..75c98bf1b --- /dev/null +++ b/mobile/openapi/doc/UpdateDeviceInfoDto.md @@ -0,0 +1,17 @@ +# openapi.model.UpdateDeviceInfoDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**deviceType** | [**DeviceTypeEnum**](DeviceTypeEnum.md) | | +**deviceId** | **String** | | +**isAutoBackup** | **bool** | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/UpdateUserDto.md b/mobile/openapi/doc/UpdateUserDto.md new file mode 100644 index 000000000..1bdb496c5 --- /dev/null +++ b/mobile/openapi/doc/UpdateUserDto.md @@ -0,0 +1,21 @@ +# openapi.model.UpdateUserDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | +**password** | **String** | | [optional] +**firstName** | **String** | | [optional] +**lastName** | **String** | | [optional] +**isAdmin** | **bool** | | [optional] +**shouldChangePassword** | **bool** | | [optional] +**profileImagePath** | **String** | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/UserApi.md b/mobile/openapi/doc/UserApi.md new file mode 100644 index 000000000..9a6aea5da --- /dev/null +++ b/mobile/openapi/doc/UserApi.md @@ -0,0 +1,329 @@ +# openapi.api.UserApi + +## Load the API package +```dart +import 'package:openapi/api.dart'; +``` + +All URIs are relative to */api* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**createProfileImage**](UserApi.md#createprofileimage) | **POST** /user/profile-image | +[**createUser**](UserApi.md#createuser) | **POST** /user | +[**getAllUsers**](UserApi.md#getallusers) | **GET** /user | +[**getMyUserInfo**](UserApi.md#getmyuserinfo) | **GET** /user/me | +[**getProfileImage**](UserApi.md#getprofileimage) | **GET** /user/profile-image/{userId} | +[**getUserCount**](UserApi.md#getusercount) | **GET** /user/count | +[**updateUser**](UserApi.md#updateuser) | **PUT** /user | + + +# **createProfileImage** +> CreateProfileImageResponseDto createProfileImage(file) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = UserApi(); +final file = BINARY_DATA_HERE; // MultipartFile | + +try { + final result = api_instance.createProfileImage(file); + print(result); +} catch (e) { + print('Exception when calling UserApi->createProfileImage: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **file** | **MultipartFile**| | + +### Return type + +[**CreateProfileImageResponseDto**](CreateProfileImageResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: multipart/form-data + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **createUser** +> UserResponseDto createUser(createUserDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = UserApi(); +final createUserDto = CreateUserDto(); // CreateUserDto | + +try { + final result = api_instance.createUser(createUserDto); + print(result); +} catch (e) { + print('Exception when calling UserApi->createUser: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **createUserDto** | [**CreateUserDto**](CreateUserDto.md)| | + +### Return type + +[**UserResponseDto**](UserResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getAllUsers** +> List getAllUsers(isAll) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = UserApi(); +final isAll = true; // bool | + +try { + final result = api_instance.getAllUsers(isAll); + print(result); +} catch (e) { + print('Exception when calling UserApi->getAllUsers: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **isAll** | **bool**| | + +### Return type + +[**List**](UserResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getMyUserInfo** +> UserResponseDto getMyUserInfo() + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = UserApi(); + +try { + final result = api_instance.getMyUserInfo(); + print(result); +} catch (e) { + print('Exception when calling UserApi->getMyUserInfo: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**UserResponseDto**](UserResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getProfileImage** +> Object getProfileImage(userId) + + + +### Example +```dart +import 'package:openapi/api.dart'; + +final api_instance = UserApi(); +final userId = userId_example; // String | + +try { + final result = api_instance.getProfileImage(userId); + print(result); +} catch (e) { + print('Exception when calling UserApi->getProfileImage: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **userId** | **String**| | + +### Return type + +[**Object**](Object.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getUserCount** +> UserCountResponseDto getUserCount() + + + +### Example +```dart +import 'package:openapi/api.dart'; + +final api_instance = UserApi(); + +try { + final result = api_instance.getUserCount(); + print(result); +} catch (e) { + print('Exception when calling UserApi->getUserCount: $e\n'); +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**UserCountResponseDto**](UserCountResponseDto.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **updateUser** +> UserResponseDto updateUser(updateUserDto) + + + +### Example +```dart +import 'package:openapi/api.dart'; +// TODO Configure HTTP Bearer authorization: bearer +// Case 1. Use String Token +//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); + +final api_instance = UserApi(); +final updateUserDto = UpdateUserDto(); // UpdateUserDto | + +try { + final result = api_instance.updateUser(updateUserDto); + print(result); +} catch (e) { + print('Exception when calling UserApi->updateUser: $e\n'); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **updateUserDto** | [**UpdateUserDto**](UpdateUserDto.md)| | + +### Return type + +[**UserResponseDto**](UserResponseDto.md) + +### Authorization + +[bearer](../README.md#bearer) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/mobile/openapi/doc/UserCountResponseDto.md b/mobile/openapi/doc/UserCountResponseDto.md new file mode 100644 index 000000000..65dab5686 --- /dev/null +++ b/mobile/openapi/doc/UserCountResponseDto.md @@ -0,0 +1,15 @@ +# openapi.model.UserCountResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**userCount** | **int** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/UserResponseDto.md b/mobile/openapi/doc/UserResponseDto.md new file mode 100644 index 000000000..d56b444ee --- /dev/null +++ b/mobile/openapi/doc/UserResponseDto.md @@ -0,0 +1,22 @@ +# openapi.model.UserResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | +**email** | **String** | | +**firstName** | **String** | | +**lastName** | **String** | | +**createdAt** | **String** | | +**profileImagePath** | **String** | | +**shouldChangePassword** | **bool** | | +**isAdmin** | **bool** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/doc/ValidateAccessTokenResponseDto.md b/mobile/openapi/doc/ValidateAccessTokenResponseDto.md new file mode 100644 index 000000000..60e1e02cb --- /dev/null +++ b/mobile/openapi/doc/ValidateAccessTokenResponseDto.md @@ -0,0 +1,15 @@ +# openapi.model.ValidateAccessTokenResponseDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**authStatus** | **bool** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/git_push.sh b/mobile/openapi/git_push.sh new file mode 100644 index 000000000..f53a75d4f --- /dev/null +++ b/mobile/openapi/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart new file mode 100644 index 000000000..9d632532f --- /dev/null +++ b/mobile/openapi/lib/api.dart @@ -0,0 +1,82 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +library openapi.api; + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:http/http.dart'; +import 'package:intl/intl.dart'; +import 'package:meta/meta.dart'; + +part 'api_client.dart'; +part 'api_helper.dart'; +part 'api_exception.dart'; +part 'auth/authentication.dart'; +part 'auth/api_key_auth.dart'; +part 'auth/oauth.dart'; +part 'auth/http_basic_auth.dart'; +part 'auth/http_bearer_auth.dart'; + +part 'api/album_api.dart'; +part 'api/asset_api.dart'; +part 'api/authentication_api.dart'; +part 'api/device_info_api.dart'; +part 'api/server_info_api.dart'; +part 'api/user_api.dart'; + +part 'model/add_assets_dto.dart'; +part 'model/add_users_dto.dart'; +part 'model/admin_signup_response_dto.dart'; +part 'model/album_response_dto.dart'; +part 'model/asset_file_upload_response_dto.dart'; +part 'model/asset_response_dto.dart'; +part 'model/asset_type_enum.dart'; +part 'model/check_duplicate_asset_dto.dart'; +part 'model/check_duplicate_asset_response_dto.dart'; +part 'model/create_album_dto.dart'; +part 'model/create_device_info_dto.dart'; +part 'model/create_profile_image_response_dto.dart'; +part 'model/create_user_dto.dart'; +part 'model/curated_locations_response_dto.dart'; +part 'model/curated_objects_response_dto.dart'; +part 'model/delete_asset_dto.dart'; +part 'model/delete_asset_response_dto.dart'; +part 'model/delete_asset_status.dart'; +part 'model/device_info_response_dto.dart'; +part 'model/device_type_enum.dart'; +part 'model/exif_response_dto.dart'; +part 'model/login_credential_dto.dart'; +part 'model/login_response_dto.dart'; +part 'model/remove_assets_dto.dart'; +part 'model/search_asset_dto.dart'; +part 'model/server_info_response_dto.dart'; +part 'model/server_ping_response.dart'; +part 'model/server_version_reponse_dto.dart'; +part 'model/sign_up_dto.dart'; +part 'model/smart_info_response_dto.dart'; +part 'model/update_album_dto.dart'; +part 'model/update_device_info_dto.dart'; +part 'model/update_user_dto.dart'; +part 'model/user_count_response_dto.dart'; +part 'model/user_response_dto.dart'; +part 'model/validate_access_token_response_dto.dart'; + + +const _delimiters = {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'}; +const _dateEpochMarker = 'epoch'; +final _dateFormatter = DateFormat('yyyy-MM-dd'); +final _regList = RegExp(r'^List<(.*)>$'); +final _regSet = RegExp(r'^Set<(.*)>$'); +final _regMap = RegExp(r'^Map$'); + +ApiClient defaultApiClient = ApiClient(); diff --git a/mobile/openapi/lib/api/album_api.dart b/mobile/openapi/lib/api/album_api.dart new file mode 100644 index 000000000..b0d7f5b8c --- /dev/null +++ b/mobile/openapi/lib/api/album_api.dart @@ -0,0 +1,452 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class AlbumApi { + AlbumApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'PUT /album/{albumId}/assets' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [AddAssetsDto] addAssetsDto (required): + Future addAssetsToAlbumWithHttpInfo(String albumId, AddAssetsDto addAssetsDto,) async { + // ignore: prefer_const_declarations + final path = r'/album/{albumId}/assets' + .replaceAll('{albumId}', albumId); + + // ignore: prefer_final_locals + Object? postBody = addAssetsDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'PUT', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [AddAssetsDto] addAssetsDto (required): + Future addAssetsToAlbum(String albumId, AddAssetsDto addAssetsDto,) async { + final response = await addAssetsToAlbumWithHttpInfo(albumId, addAssetsDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AlbumResponseDto',) as AlbumResponseDto; + + } + return null; + } + + /// Performs an HTTP 'PUT /album/{albumId}/users' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [AddUsersDto] addUsersDto (required): + Future addUsersToAlbumWithHttpInfo(String albumId, AddUsersDto addUsersDto,) async { + // ignore: prefer_const_declarations + final path = r'/album/{albumId}/users' + .replaceAll('{albumId}', albumId); + + // ignore: prefer_final_locals + Object? postBody = addUsersDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'PUT', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [AddUsersDto] addUsersDto (required): + Future addUsersToAlbum(String albumId, AddUsersDto addUsersDto,) async { + final response = await addUsersToAlbumWithHttpInfo(albumId, addUsersDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AlbumResponseDto',) as AlbumResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /album' operation and returns the [Response]. + /// Parameters: + /// + /// * [CreateAlbumDto] createAlbumDto (required): + Future createAlbumWithHttpInfo(CreateAlbumDto createAlbumDto,) async { + // ignore: prefer_const_declarations + final path = r'/album'; + + // ignore: prefer_final_locals + Object? postBody = createAlbumDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [CreateAlbumDto] createAlbumDto (required): + Future createAlbum(CreateAlbumDto createAlbumDto,) async { + final response = await createAlbumWithHttpInfo(createAlbumDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AlbumResponseDto',) as AlbumResponseDto; + + } + return null; + } + + /// Performs an HTTP 'DELETE /album/{albumId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] albumId (required): + Future deleteAlbumWithHttpInfo(String albumId,) async { + // ignore: prefer_const_declarations + final path = r'/album/{albumId}' + .replaceAll('{albumId}', albumId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] albumId (required): + Future deleteAlbum(String albumId,) async { + final response = await deleteAlbumWithHttpInfo(albumId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'GET /album/{albumId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] albumId (required): + Future getAlbumInfoWithHttpInfo(String albumId,) async { + // ignore: prefer_const_declarations + final path = r'/album/{albumId}' + .replaceAll('{albumId}', albumId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] albumId (required): + Future getAlbumInfo(String albumId,) async { + final response = await getAlbumInfoWithHttpInfo(albumId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AlbumResponseDto',) as AlbumResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /album' operation and returns the [Response]. + /// Parameters: + /// + /// * [bool] shared: + Future getAllAlbumsWithHttpInfo({ bool? shared, }) async { + // ignore: prefer_const_declarations + final path = r'/album'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + if (shared != null) { + queryParams.addAll(_queryParams('', 'shared', shared)); + } + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [bool] shared: + Future?> getAllAlbums({ bool? shared, }) async { + final response = await getAllAlbumsWithHttpInfo( shared: shared, ); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// Performs an HTTP 'DELETE /album/{albumId}/assets' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [RemoveAssetsDto] removeAssetsDto (required): + Future removeAssetFromAlbumWithHttpInfo(String albumId, RemoveAssetsDto removeAssetsDto,) async { + // ignore: prefer_const_declarations + final path = r'/album/{albumId}/assets' + .replaceAll('{albumId}', albumId); + + // ignore: prefer_final_locals + Object? postBody = removeAssetsDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [RemoveAssetsDto] removeAssetsDto (required): + Future removeAssetFromAlbum(String albumId, RemoveAssetsDto removeAssetsDto,) async { + final response = await removeAssetFromAlbumWithHttpInfo(albumId, removeAssetsDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'DELETE /album/{albumId}/user/{userId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [String] userId (required): + Future removeUserFromAlbumWithHttpInfo(String albumId, String userId,) async { + // ignore: prefer_const_declarations + final path = r'/album/{albumId}/user/{userId}' + .replaceAll('{albumId}', albumId) + .replaceAll('{userId}', userId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [String] userId (required): + Future removeUserFromAlbum(String albumId, String userId,) async { + final response = await removeUserFromAlbumWithHttpInfo(albumId, userId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'PATCH /album/{albumId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [UpdateAlbumDto] updateAlbumDto (required): + Future updateAlbumInfoWithHttpInfo(String albumId, UpdateAlbumDto updateAlbumDto,) async { + // ignore: prefer_const_declarations + final path = r'/album/{albumId}' + .replaceAll('{albumId}', albumId); + + // ignore: prefer_final_locals + Object? postBody = updateAlbumDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'PATCH', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] albumId (required): + /// + /// * [UpdateAlbumDto] updateAlbumDto (required): + Future updateAlbumInfo(String albumId, UpdateAlbumDto updateAlbumDto,) async { + final response = await updateAlbumInfoWithHttpInfo(albumId, updateAlbumDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AlbumResponseDto',) as AlbumResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/asset_api.dart b/mobile/openapi/lib/api/asset_api.dart new file mode 100644 index 000000000..7d541c69f --- /dev/null +++ b/mobile/openapi/lib/api/asset_api.dart @@ -0,0 +1,715 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class AssetApi { + AssetApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// + /// + /// Check duplicated asset before uploading - for Web upload used + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [CheckDuplicateAssetDto] checkDuplicateAssetDto (required): + Future checkDuplicateAssetWithHttpInfo(CheckDuplicateAssetDto checkDuplicateAssetDto,) async { + // ignore: prefer_const_declarations + final path = r'/asset/check'; + + // ignore: prefer_final_locals + Object? postBody = checkDuplicateAssetDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// + /// + /// Check duplicated asset before uploading - for Web upload used + /// + /// Parameters: + /// + /// * [CheckDuplicateAssetDto] checkDuplicateAssetDto (required): + Future checkDuplicateAsset(CheckDuplicateAssetDto checkDuplicateAssetDto,) async { + final response = await checkDuplicateAssetWithHttpInfo(checkDuplicateAssetDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'CheckDuplicateAssetResponseDto',) as CheckDuplicateAssetResponseDto; + + } + return null; + } + + /// Performs an HTTP 'DELETE /asset' operation and returns the [Response]. + /// Parameters: + /// + /// * [DeleteAssetDto] deleteAssetDto (required): + Future deleteAssetWithHttpInfo(DeleteAssetDto deleteAssetDto,) async { + // ignore: prefer_const_declarations + final path = r'/asset'; + + // ignore: prefer_final_locals + Object? postBody = deleteAssetDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [DeleteAssetDto] deleteAssetDto (required): + Future?> deleteAsset(DeleteAssetDto deleteAssetDto,) async { + final response = await deleteAssetWithHttpInfo(deleteAssetDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// Performs an HTTP 'GET /asset/download' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] aid (required): + /// + /// * [String] did (required): + /// + /// * [bool] isThumb: + /// + /// * [bool] isWeb: + Future downloadFileWithHttpInfo(String aid, String did, { bool? isThumb, bool? isWeb, }) async { + // ignore: prefer_const_declarations + final path = r'/asset/download'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + queryParams.addAll(_queryParams('', 'aid', aid)); + queryParams.addAll(_queryParams('', 'did', did)); + if (isThumb != null) { + queryParams.addAll(_queryParams('', 'isThumb', isThumb)); + } + if (isWeb != null) { + queryParams.addAll(_queryParams('', 'isWeb', isWeb)); + } + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] aid (required): + /// + /// * [String] did (required): + /// + /// * [bool] isThumb: + /// + /// * [bool] isWeb: + Future downloadFile(String aid, String did, { bool? isThumb, bool? isWeb, }) async { + final response = await downloadFileWithHttpInfo(aid, did, isThumb: isThumb, isWeb: isWeb, ); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'Object',) as Object; + + } + return null; + } + + /// + /// + /// Get all AssetEntity belong to the user + /// + /// Note: This method returns the HTTP [Response]. + Future getAllAssetsWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/asset'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// + /// + /// Get all AssetEntity belong to the user + Future?> getAllAssets() async { + final response = await getAllAssetsWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// + /// + /// Get a single asset's information + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [String] assetId (required): + Future getAssetByIdWithHttpInfo(String assetId,) async { + // ignore: prefer_const_declarations + final path = r'/asset/assetById/{assetId}' + .replaceAll('{assetId}', assetId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// + /// + /// Get a single asset's information + /// + /// Parameters: + /// + /// * [String] assetId (required): + Future getAssetById(String assetId,) async { + final response = await getAssetByIdWithHttpInfo(assetId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetResponseDto',) as AssetResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /asset/searchTerm' operation and returns the [Response]. + Future getAssetSearchTermsWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/asset/searchTerm'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future?> getAssetSearchTerms() async { + final response = await getAssetSearchTermsWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// Performs an HTTP 'GET /asset/thumbnail/{assetId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] assetId (required): + Future getAssetThumbnailWithHttpInfo(String assetId,) async { + // ignore: prefer_const_declarations + final path = r'/asset/thumbnail/{assetId}' + .replaceAll('{assetId}', assetId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] assetId (required): + Future getAssetThumbnail(String assetId,) async { + final response = await getAssetThumbnailWithHttpInfo(assetId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'Object',) as Object; + + } + return null; + } + + /// Performs an HTTP 'GET /asset/allLocation' operation and returns the [Response]. + Future getCuratedLocationsWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/asset/allLocation'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future?> getCuratedLocations() async { + final response = await getCuratedLocationsWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// Performs an HTTP 'GET /asset/allObjects' operation and returns the [Response]. + Future getCuratedObjectsWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/asset/allObjects'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future?> getCuratedObjects() async { + final response = await getCuratedObjectsWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// + /// + /// Get all asset of a device that are in the database, ID only. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [String] deviceId (required): + Future getUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async { + // ignore: prefer_const_declarations + final path = r'/asset/{deviceId}' + .replaceAll('{deviceId}', deviceId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// + /// + /// Get all asset of a device that are in the database, ID only. + /// + /// Parameters: + /// + /// * [String] deviceId (required): + Future?> getUserAssetsByDeviceId(String deviceId,) async { + final response = await getUserAssetsByDeviceIdWithHttpInfo(deviceId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// Performs an HTTP 'POST /asset/search' operation and returns the [Response]. + /// Parameters: + /// + /// * [SearchAssetDto] searchAssetDto (required): + Future searchAssetWithHttpInfo(SearchAssetDto searchAssetDto,) async { + // ignore: prefer_const_declarations + final path = r'/asset/search'; + + // ignore: prefer_final_locals + Object? postBody = searchAssetDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [SearchAssetDto] searchAssetDto (required): + Future?> searchAsset(SearchAssetDto searchAssetDto,) async { + final response = await searchAssetWithHttpInfo(searchAssetDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// Performs an HTTP 'GET /asset/file' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] aid (required): + /// + /// * [String] did (required): + /// + /// * [bool] isThumb: + /// + /// * [bool] isWeb: + Future serveFileWithHttpInfo(String aid, String did, { bool? isThumb, bool? isWeb, }) async { + // ignore: prefer_const_declarations + final path = r'/asset/file'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + queryParams.addAll(_queryParams('', 'aid', aid)); + queryParams.addAll(_queryParams('', 'did', did)); + if (isThumb != null) { + queryParams.addAll(_queryParams('', 'isThumb', isThumb)); + } + if (isWeb != null) { + queryParams.addAll(_queryParams('', 'isWeb', isWeb)); + } + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] aid (required): + /// + /// * [String] did (required): + /// + /// * [bool] isThumb: + /// + /// * [bool] isWeb: + Future serveFile(String aid, String did, { bool? isThumb, bool? isWeb, }) async { + final response = await serveFileWithHttpInfo(aid, did, isThumb: isThumb, isWeb: isWeb, ); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'Object',) as Object; + + } + return null; + } + + /// Performs an HTTP 'POST /asset/upload' operation and returns the [Response]. + /// Parameters: + /// + /// * [MultipartFile] assetData (required): + Future uploadFileWithHttpInfo(MultipartFile assetData,) async { + // ignore: prefer_const_declarations + final path = r'/asset/upload'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['multipart/form-data']; + + bool hasFields = false; + final mp = MultipartRequest('POST', Uri.parse(path)); + if (assetData != null) { + hasFields = true; + mp.fields[r'assetData'] = assetData.field; + mp.files.add(assetData); + } + if (hasFields) { + postBody = mp; + } + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [MultipartFile] assetData (required): + Future uploadFile(MultipartFile assetData,) async { + final response = await uploadFileWithHttpInfo(assetData,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetFileUploadResponseDto',) as AssetFileUploadResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/authentication_api.dart b/mobile/openapi/lib/api/authentication_api.dart new file mode 100644 index 000000000..5fda658ea --- /dev/null +++ b/mobile/openapi/lib/api/authentication_api.dart @@ -0,0 +1,153 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class AuthenticationApi { + AuthenticationApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /auth/admin-sign-up' operation and returns the [Response]. + /// Parameters: + /// + /// * [SignUpDto] signUpDto (required): + Future adminSignUpWithHttpInfo(SignUpDto signUpDto,) async { + // ignore: prefer_const_declarations + final path = r'/auth/admin-sign-up'; + + // ignore: prefer_final_locals + Object? postBody = signUpDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [SignUpDto] signUpDto (required): + Future adminSignUp(SignUpDto signUpDto,) async { + final response = await adminSignUpWithHttpInfo(signUpDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AdminSignupResponseDto',) as AdminSignupResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /auth/login' operation and returns the [Response]. + /// Parameters: + /// + /// * [LoginCredentialDto] loginCredentialDto (required): + Future loginWithHttpInfo(LoginCredentialDto loginCredentialDto,) async { + // ignore: prefer_const_declarations + final path = r'/auth/login'; + + // ignore: prefer_final_locals + Object? postBody = loginCredentialDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [LoginCredentialDto] loginCredentialDto (required): + Future login(LoginCredentialDto loginCredentialDto,) async { + final response = await loginWithHttpInfo(loginCredentialDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'LoginResponseDto',) as LoginResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /auth/validateToken' operation and returns the [Response]. + Future validateAccessTokenWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/auth/validateToken'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future validateAccessToken() async { + final response = await validateAccessTokenWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ValidateAccessTokenResponseDto',) as ValidateAccessTokenResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/device_info_api.dart b/mobile/openapi/lib/api/device_info_api.dart new file mode 100644 index 000000000..c365ac60d --- /dev/null +++ b/mobile/openapi/lib/api/device_info_api.dart @@ -0,0 +1,112 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class DeviceInfoApi { + DeviceInfoApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /device-info' operation and returns the [Response]. + /// Parameters: + /// + /// * [CreateDeviceInfoDto] createDeviceInfoDto (required): + Future createDeviceInfoWithHttpInfo(CreateDeviceInfoDto createDeviceInfoDto,) async { + // ignore: prefer_const_declarations + final path = r'/device-info'; + + // ignore: prefer_final_locals + Object? postBody = createDeviceInfoDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [CreateDeviceInfoDto] createDeviceInfoDto (required): + Future createDeviceInfo(CreateDeviceInfoDto createDeviceInfoDto,) async { + final response = await createDeviceInfoWithHttpInfo(createDeviceInfoDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'DeviceInfoResponseDto',) as DeviceInfoResponseDto; + + } + return null; + } + + /// Performs an HTTP 'PATCH /device-info' operation and returns the [Response]. + /// Parameters: + /// + /// * [UpdateDeviceInfoDto] updateDeviceInfoDto (required): + Future updateDeviceInfoWithHttpInfo(UpdateDeviceInfoDto updateDeviceInfoDto,) async { + // ignore: prefer_const_declarations + final path = r'/device-info'; + + // ignore: prefer_final_locals + Object? postBody = updateDeviceInfoDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'PATCH', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [UpdateDeviceInfoDto] updateDeviceInfoDto (required): + Future updateDeviceInfo(UpdateDeviceInfoDto updateDeviceInfoDto,) async { + final response = await updateDeviceInfoWithHttpInfo(updateDeviceInfoDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'DeviceInfoResponseDto',) as DeviceInfoResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/server_info_api.dart b/mobile/openapi/lib/api/server_info_api.dart new file mode 100644 index 000000000..8af914b1c --- /dev/null +++ b/mobile/openapi/lib/api/server_info_api.dart @@ -0,0 +1,141 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class ServerInfoApi { + ServerInfoApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'GET /server-info' operation and returns the [Response]. + Future getServerInfoWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/server-info'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getServerInfo() async { + final response = await getServerInfoWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ServerInfoResponseDto',) as ServerInfoResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /server-info/version' operation and returns the [Response]. + Future getServerVersionWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/server-info/version'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getServerVersion() async { + final response = await getServerVersionWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ServerVersionReponseDto',) as ServerVersionReponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /server-info/ping' operation and returns the [Response]. + Future pingServerWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/server-info/ping'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future pingServer() async { + final response = await pingServerWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ServerPingResponse',) as ServerPingResponse; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/user_api.dart b/mobile/openapi/lib/api/user_api.dart new file mode 100644 index 000000000..69bd819de --- /dev/null +++ b/mobile/openapi/lib/api/user_api.dart @@ -0,0 +1,351 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class UserApi { + UserApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /user/profile-image' operation and returns the [Response]. + /// Parameters: + /// + /// * [MultipartFile] file (required): + Future createProfileImageWithHttpInfo(MultipartFile file,) async { + // ignore: prefer_const_declarations + final path = r'/user/profile-image'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['multipart/form-data']; + + bool hasFields = false; + final mp = MultipartRequest('POST', Uri.parse(path)); + if (file != null) { + hasFields = true; + mp.fields[r'file'] = file.field; + mp.files.add(file); + } + if (hasFields) { + postBody = mp; + } + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [MultipartFile] file (required): + Future createProfileImage(MultipartFile file,) async { + final response = await createProfileImageWithHttpInfo(file,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'CreateProfileImageResponseDto',) as CreateProfileImageResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /user' operation and returns the [Response]. + /// Parameters: + /// + /// * [CreateUserDto] createUserDto (required): + Future createUserWithHttpInfo(CreateUserDto createUserDto,) async { + // ignore: prefer_const_declarations + final path = r'/user'; + + // ignore: prefer_final_locals + Object? postBody = createUserDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [CreateUserDto] createUserDto (required): + Future createUser(CreateUserDto createUserDto,) async { + final response = await createUserWithHttpInfo(createUserDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /user' operation and returns the [Response]. + /// Parameters: + /// + /// * [bool] isAll (required): + Future getAllUsersWithHttpInfo(bool isAll,) async { + // ignore: prefer_const_declarations + final path = r'/user'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + queryParams.addAll(_queryParams('', 'isAll', isAll)); + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [bool] isAll (required): + Future?> getAllUsers(bool isAll,) async { + final response = await getAllUsersWithHttpInfo(isAll,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(); + + } + return null; + } + + /// Performs an HTTP 'GET /user/me' operation and returns the [Response]. + Future getMyUserInfoWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/user/me'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getMyUserInfo() async { + final response = await getMyUserInfoWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /user/profile-image/{userId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] userId (required): + Future getProfileImageWithHttpInfo(String userId,) async { + // ignore: prefer_const_declarations + final path = r'/user/profile-image/{userId}' + .replaceAll('{userId}', userId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] userId (required): + Future getProfileImage(String userId,) async { + final response = await getProfileImageWithHttpInfo(userId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'Object',) as Object; + + } + return null; + } + + /// Performs an HTTP 'GET /user/count' operation and returns the [Response]. + Future getUserCountWithHttpInfo() async { + // ignore: prefer_const_declarations + final path = r'/user/count'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + path, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getUserCount() async { + final response = await getUserCountWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserCountResponseDto',) as UserCountResponseDto; + + } + return null; + } + + /// Performs an HTTP 'PUT /user' operation and returns the [Response]. + /// Parameters: + /// + /// * [UpdateUserDto] updateUserDto (required): + Future updateUserWithHttpInfo(UpdateUserDto updateUserDto,) async { + // ignore: prefer_const_declarations + final path = r'/user'; + + // ignore: prefer_final_locals + Object? postBody = updateUserDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + path, + 'PUT', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [UpdateUserDto] updateUserDto (required): + Future updateUser(UpdateUserDto updateUserDto,) async { + final response = await updateUserWithHttpInfo(updateUserDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart new file mode 100644 index 000000000..ae695c969 --- /dev/null +++ b/mobile/openapi/lib/api_client.dart @@ -0,0 +1,327 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ApiClient { + ApiClient({this.basePath = '/api', this.authentication}); + + final String basePath; + + var _client = Client(); + + /// Returns the current HTTP [Client] instance to use in this class. + /// + /// The return value is guaranteed to never be null. + Client get client => _client; + + /// Requests to use a new HTTP [Client] in this class. + set client(Client newClient) { + _client = newClient; + } + + final _defaultHeaderMap = {}; + final Authentication? authentication; + + void addDefaultHeader(String key, String value) { + _defaultHeaderMap[key] = value; + } + + Map get defaultHeaderMap => _defaultHeaderMap; + + // We don't use a Map for queryParams. + // If collectionFormat is 'multi', a key might appear multiple times. + Future invokeAPI( + String path, + String method, + List queryParams, + Object? body, + Map headerParams, + Map formParams, + String? contentType, + ) async { + _updateParamsForAuth(queryParams, headerParams); + + headerParams.addAll(_defaultHeaderMap); + if (contentType != null) { + headerParams['Content-Type'] = contentType; + } + + final urlEncodedQueryParams = queryParams.map((param) => '$param'); + final queryString = urlEncodedQueryParams.isNotEmpty ? '?${urlEncodedQueryParams.join('&')}' : ''; + final uri = Uri.parse('$basePath$path$queryString'); + + try { + // Special case for uploading a single file which isn't a 'multipart/form-data'. + if ( + body is MultipartFile && (contentType == null || + !contentType.toLowerCase().startsWith('multipart/form-data')) + ) { + final request = StreamedRequest(method, uri); + request.headers.addAll(headerParams); + request.contentLength = body.length; + body.finalize().listen( + request.sink.add, + onDone: request.sink.close, + // ignore: avoid_types_on_closure_parameters + onError: (Object error, StackTrace trace) => request.sink.close(), + cancelOnError: true, + ); + final response = await _client.send(request); + return Response.fromStream(response); + } + + if (body is MultipartRequest) { + final request = MultipartRequest(method, uri); + request.fields.addAll(body.fields); + request.files.addAll(body.files); + request.headers.addAll(body.headers); + request.headers.addAll(headerParams); + final response = await _client.send(request); + return Response.fromStream(response); + } + + final msgBody = contentType == 'application/x-www-form-urlencoded' + ? formParams + : await serializeAsync(body); + final nullableHeaderParams = headerParams.isEmpty ? null : headerParams; + + switch(method) { + case 'POST': return await _client.post(uri, headers: nullableHeaderParams, body: msgBody,); + case 'PUT': return await _client.put(uri, headers: nullableHeaderParams, body: msgBody,); + case 'DELETE': return await _client.delete(uri, headers: nullableHeaderParams, body: msgBody,); + case 'PATCH': return await _client.patch(uri, headers: nullableHeaderParams, body: msgBody,); + case 'HEAD': return await _client.head(uri, headers: nullableHeaderParams,); + case 'GET': return await _client.get(uri, headers: nullableHeaderParams,); + } + } on SocketException catch (error, trace) { + throw ApiException.withInner( + HttpStatus.badRequest, + 'Socket operation failed: $method $path', + error, + trace, + ); + } on TlsException catch (error, trace) { + throw ApiException.withInner( + HttpStatus.badRequest, + 'TLS/SSL communication failed: $method $path', + error, + trace, + ); + } on IOException catch (error, trace) { + throw ApiException.withInner( + HttpStatus.badRequest, + 'I/O operation failed: $method $path', + error, + trace, + ); + } on ClientException catch (error, trace) { + throw ApiException.withInner( + HttpStatus.badRequest, + 'HTTP connection failed: $method $path', + error, + trace, + ); + } on Exception catch (error, trace) { + throw ApiException.withInner( + HttpStatus.badRequest, + 'Exception occurred: $method $path', + error, + trace, + ); + } + + throw ApiException( + HttpStatus.badRequest, + 'Invalid HTTP operation: $method $path', + ); + } + + Future deserializeAsync(String json, String targetType, {bool growable = false,}) async => + // ignore: deprecated_member_use_from_same_package + deserialize(json, targetType, growable: growable); + + @Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use deserializeAsync() instead.') + dynamic deserialize(String json, String targetType, {bool growable = false,}) { + // Remove all spaces. Necessary for regular expressions as well. + targetType = targetType.replaceAll(' ', ''); // ignore: parameter_assignments + + // If the expected target type is String, nothing to do... + return targetType == 'String' + ? json + : _deserialize(jsonDecode(json), targetType, growable: growable); + } + + // ignore: deprecated_member_use_from_same_package + Future serializeAsync(Object? value) async => serialize(value); + + @Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use serializeAsync() instead.') + String serialize(Object? value) => value == null ? '' : json.encode(value); + + /// Update query and header parameters based on authentication settings. + void _updateParamsForAuth( + List queryParams, + Map headerParams, + ) { + if (authentication != null) { + authentication!.applyToParams(queryParams, headerParams); + } + } + + static dynamic _deserialize(dynamic value, String targetType, {bool growable = false}) { + try { + switch (targetType) { + case 'String': + return value is String ? value : value.toString(); + case 'int': + return value is int ? value : int.parse('$value'); + case 'double': + return value is double ? value : double.parse('$value'); + case 'bool': + if (value is bool) { + return value; + } + final valueString = '$value'.toLowerCase(); + return valueString == 'true' || valueString == '1'; + case 'DateTime': + return value is DateTime ? value : DateTime.tryParse(value); + case 'AddAssetsDto': + return AddAssetsDto.fromJson(value); + case 'AddUsersDto': + return AddUsersDto.fromJson(value); + case 'AdminSignupResponseDto': + return AdminSignupResponseDto.fromJson(value); + case 'AlbumResponseDto': + return AlbumResponseDto.fromJson(value); + case 'AssetFileUploadResponseDto': + return AssetFileUploadResponseDto.fromJson(value); + case 'AssetResponseDto': + return AssetResponseDto.fromJson(value); + case 'AssetTypeEnum': + return AssetTypeEnumTypeTransformer().decode(value); + case 'CheckDuplicateAssetDto': + return CheckDuplicateAssetDto.fromJson(value); + case 'CheckDuplicateAssetResponseDto': + return CheckDuplicateAssetResponseDto.fromJson(value); + case 'CreateAlbumDto': + return CreateAlbumDto.fromJson(value); + case 'CreateDeviceInfoDto': + return CreateDeviceInfoDto.fromJson(value); + case 'CreateProfileImageResponseDto': + return CreateProfileImageResponseDto.fromJson(value); + case 'CreateUserDto': + return CreateUserDto.fromJson(value); + case 'CuratedLocationsResponseDto': + return CuratedLocationsResponseDto.fromJson(value); + case 'CuratedObjectsResponseDto': + return CuratedObjectsResponseDto.fromJson(value); + case 'DeleteAssetDto': + return DeleteAssetDto.fromJson(value); + case 'DeleteAssetResponseDto': + return DeleteAssetResponseDto.fromJson(value); + case 'DeleteAssetStatus': + return DeleteAssetStatusTypeTransformer().decode(value); + case 'DeviceInfoResponseDto': + return DeviceInfoResponseDto.fromJson(value); + case 'DeviceTypeEnum': + return DeviceTypeEnumTypeTransformer().decode(value); + case 'ExifResponseDto': + return ExifResponseDto.fromJson(value); + case 'LoginCredentialDto': + return LoginCredentialDto.fromJson(value); + case 'LoginResponseDto': + return LoginResponseDto.fromJson(value); + case 'RemoveAssetsDto': + return RemoveAssetsDto.fromJson(value); + case 'SearchAssetDto': + return SearchAssetDto.fromJson(value); + case 'ServerInfoResponseDto': + return ServerInfoResponseDto.fromJson(value); + case 'ServerPingResponse': + return ServerPingResponse.fromJson(value); + case 'ServerVersionReponseDto': + return ServerVersionReponseDto.fromJson(value); + case 'SignUpDto': + return SignUpDto.fromJson(value); + case 'SmartInfoResponseDto': + return SmartInfoResponseDto.fromJson(value); + case 'UpdateAlbumDto': + return UpdateAlbumDto.fromJson(value); + case 'UpdateDeviceInfoDto': + return UpdateDeviceInfoDto.fromJson(value); + case 'UpdateUserDto': + return UpdateUserDto.fromJson(value); + case 'UserCountResponseDto': + return UserCountResponseDto.fromJson(value); + case 'UserResponseDto': + return UserResponseDto.fromJson(value); + case 'ValidateAccessTokenResponseDto': + return ValidateAccessTokenResponseDto.fromJson(value); + default: + dynamic match; + if (value is List && (match = _regList.firstMatch(targetType)?.group(1)) != null) { + return value + .map((dynamic v) => _deserialize(v, match, growable: growable,)) + .toList(growable: growable); + } + if (value is Set && (match = _regSet.firstMatch(targetType)?.group(1)) != null) { + return value + .map((dynamic v) => _deserialize(v, match, growable: growable,)) + .toSet(); + } + if (value is Map && (match = _regMap.firstMatch(targetType)?.group(1)) != null) { + return Map.fromIterables( + value.keys.cast(), + value.values.map((dynamic v) => _deserialize(v, match, growable: growable,)), + ); + } + } + } on Exception catch (error, trace) { + throw ApiException.withInner(HttpStatus.internalServerError, 'Exception during deserialization.', error, trace,); + } + throw ApiException(HttpStatus.internalServerError, 'Could not find a suitable class for deserialization',); + } +} + +/// Primarily intended for use in an isolate. +class DeserializationMessage { + const DeserializationMessage({ + required this.json, + required this.targetType, + this.growable = false, + }); + + /// The JSON value to deserialize. + final String json; + + /// Target type to deserialize to. + final String targetType; + + /// Whether to make deserialized lists or maps growable. + final bool growable; +} + +/// Primarily intended for use in an isolate. +Future deserializeAsync(DeserializationMessage message) async { + // Remove all spaces. Necessary for regular expressions as well. + final targetType = message.targetType.replaceAll(' ', ''); + + // If the expected target type is String, nothing to do... + return targetType == 'String' + ? message.json + : ApiClient._deserialize( + jsonDecode(message.json), + targetType, + growable: message.growable, + ); +} + +/// Primarily intended for use in an isolate. +Future serializeAsync(Object? value) async => value == null ? '' : json.encode(value); diff --git a/mobile/openapi/lib/api_exception.dart b/mobile/openapi/lib/api_exception.dart new file mode 100644 index 000000000..796f7f7ee --- /dev/null +++ b/mobile/openapi/lib/api_exception.dart @@ -0,0 +1,33 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ApiException implements Exception { + ApiException(this.code, this.message); + + ApiException.withInner(this.code, this.message, this.innerException, this.stackTrace); + + int code = 0; + String? message; + Exception? innerException; + StackTrace? stackTrace; + + @override + String toString() { + if (message == null) { + return 'ApiException'; + } + if (innerException == null) { + return 'ApiException $code: $message'; + } + return 'ApiException $code: $message (Inner exception: $innerException)\n\n$stackTrace'; + } +} diff --git a/mobile/openapi/lib/api_helper.dart b/mobile/openapi/lib/api_helper.dart new file mode 100644 index 000000000..325446498 --- /dev/null +++ b/mobile/openapi/lib/api_helper.dart @@ -0,0 +1,110 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class QueryParam { + const QueryParam(this.name, this.value); + + final String name; + final String value; + + @override + String toString() => '${Uri.encodeQueryComponent(name)}=${Uri.encodeQueryComponent(value)}'; +} + +// Ported from the Java version. +Iterable _queryParams(String collectionFormat, String name, dynamic value,) { + // Assertions to run in debug mode only. + assert(name.isNotEmpty, 'Parameter cannot be an empty string.'); + + final params = []; + + if (value is List) { + if (collectionFormat == 'multi') { + return value.map((dynamic v) => QueryParam(name, parameterToString(v)),); + } + + // Default collection format is 'csv'. + if (collectionFormat.isEmpty) { + collectionFormat = 'csv'; // ignore: parameter_assignments + } + + final delimiter = _delimiters[collectionFormat] ?? ','; + + params.add(QueryParam(name, value.map(parameterToString).join(delimiter),)); + } else if (value != null) { + params.add(QueryParam(name, parameterToString(value))); + } + + return params; +} + +/// Format the given parameter object into a [String]. +String parameterToString(dynamic value) { + if (value == null) { + return ''; + } + if (value is DateTime) { + return value.toUtc().toIso8601String(); + } + if (value is AssetTypeEnum) { + return AssetTypeEnumTypeTransformer().encode(value).toString(); + } + if (value is DeleteAssetStatus) { + return DeleteAssetStatusTypeTransformer().encode(value).toString(); + } + if (value is DeviceTypeEnum) { + return DeviceTypeEnumTypeTransformer().encode(value).toString(); + } + return value.toString(); +} + +/// Returns the decoded body as UTF-8 if the given headers indicate an 'application/json' +/// content type. Otherwise, returns the decoded body as decoded by dart:http package. +Future _decodeBodyBytes(Response response) async { + final contentType = response.headers['content-type']; + return contentType != null && contentType.toLowerCase().startsWith('application/json') + ? response.bodyBytes.isEmpty ? '' : utf8.decode(response.bodyBytes) + : response.body; +} + +/// Returns a valid [T] value found at the specified Map [key], null otherwise. +T? mapValueOfType(dynamic map, String key) { + final dynamic value = map is Map ? map[key] : null; + return value is T ? value : null; +} + +/// Returns a valid Map found at the specified Map [key], null otherwise. +Map? mapCastOfType(dynamic map, String key) { + final dynamic value = map is Map ? map[key] : null; + return value is Map ? value.cast() : null; +} + +/// Returns a valid [DateTime] found at the specified Map [key], null otherwise. +DateTime? mapDateTime(dynamic map, String key, [String? pattern]) { + final dynamic value = map is Map ? map[key] : null; + if (value != null) { + int? millis; + if (value is int) { + millis = value; + } else if (value is String) { + if (pattern == _dateEpochMarker) { + millis = int.tryParse(value); + } else { + return DateTime.tryParse(value); + } + } + if (millis != null) { + return DateTime.fromMillisecondsSinceEpoch(millis, isUtc: true); + } + } + return null; +} diff --git a/mobile/openapi/lib/auth/api_key_auth.dart b/mobile/openapi/lib/auth/api_key_auth.dart new file mode 100644 index 000000000..e304eda32 --- /dev/null +++ b/mobile/openapi/lib/auth/api_key_auth.dart @@ -0,0 +1,40 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ApiKeyAuth implements Authentication { + ApiKeyAuth(this.location, this.paramName); + + final String location; + final String paramName; + + String apiKeyPrefix = ''; + String apiKey = ''; + + @override + void applyToParams(List queryParams, Map headerParams) { + final paramValue = apiKeyPrefix.isEmpty ? apiKey : '$apiKeyPrefix $apiKey'; + + if (paramValue.isNotEmpty) { + if (location == 'query') { + queryParams.add(QueryParam(paramName, paramValue)); + } else if (location == 'header') { + headerParams[paramName] = paramValue; + } else if (location == 'cookie') { + headerParams.update( + 'Cookie', + (existingCookie) => '$existingCookie; $paramName=$paramValue', + ifAbsent: () => '$paramName=$paramValue', + ); + } + } + } +} diff --git a/mobile/openapi/lib/auth/authentication.dart b/mobile/openapi/lib/auth/authentication.dart new file mode 100644 index 000000000..49baf7c46 --- /dev/null +++ b/mobile/openapi/lib/auth/authentication.dart @@ -0,0 +1,17 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +// ignore: one_member_abstracts +abstract class Authentication { + /// Apply authentication settings to header and query params. + void applyToParams(List queryParams, Map headerParams); +} diff --git a/mobile/openapi/lib/auth/http_basic_auth.dart b/mobile/openapi/lib/auth/http_basic_auth.dart new file mode 100644 index 000000000..81abd7185 --- /dev/null +++ b/mobile/openapi/lib/auth/http_basic_auth.dart @@ -0,0 +1,26 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class HttpBasicAuth implements Authentication { + HttpBasicAuth({this.username = '', this.password = ''}); + + String username; + String password; + + @override + void applyToParams(List queryParams, Map headerParams) { + if (username.isNotEmpty && password.isNotEmpty) { + final credentials = '$username:$password'; + headerParams['Authorization'] = 'Basic ${base64.encode(utf8.encode(credentials))}'; + } + } +} diff --git a/mobile/openapi/lib/auth/http_bearer_auth.dart b/mobile/openapi/lib/auth/http_bearer_auth.dart new file mode 100644 index 000000000..213f3483b --- /dev/null +++ b/mobile/openapi/lib/auth/http_bearer_auth.dart @@ -0,0 +1,49 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +typedef HttpBearerAuthProvider = String Function(); + +class HttpBearerAuth implements Authentication { + HttpBearerAuth(); + + dynamic _accessToken; + + dynamic get accessToken => _accessToken; + + set accessToken(dynamic accessToken) { + if (accessToken is! String && accessToken is! HttpBearerAuthProvider) { + throw ArgumentError('accessToken value must be either a String or a String Function().'); + } + _accessToken = accessToken; + } + + @override + void applyToParams(List queryParams, Map headerParams) { + if (_accessToken == null) { + return; + } + + String accessToken; + + if (_accessToken is String) { + accessToken = _accessToken; + } else if (_accessToken is HttpBearerAuthProvider) { + accessToken = _accessToken!(); + } else { + return; + } + + if (accessToken.isNotEmpty) { + headerParams['Authorization'] = 'Bearer $accessToken'; + } + } +} diff --git a/mobile/openapi/lib/auth/oauth.dart b/mobile/openapi/lib/auth/oauth.dart new file mode 100644 index 000000000..e9b87cffb --- /dev/null +++ b/mobile/openapi/lib/auth/oauth.dart @@ -0,0 +1,24 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class OAuth implements Authentication { + OAuth({this.accessToken = ''}); + + String accessToken; + + @override + void applyToParams(List queryParams, Map headerParams) { + if (accessToken.isNotEmpty) { + headerParams['Authorization'] = 'Bearer $accessToken'; + } + } +} diff --git a/mobile/openapi/lib/model/add_assets_dto.dart b/mobile/openapi/lib/model/add_assets_dto.dart new file mode 100644 index 000000000..bebbaeb08 --- /dev/null +++ b/mobile/openapi/lib/model/add_assets_dto.dart @@ -0,0 +1,113 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class AddAssetsDto { + /// Returns a new [AddAssetsDto] instance. + AddAssetsDto({ + this.assetIds = const [], + }); + + List assetIds; + + @override + bool operator ==(Object other) => identical(this, other) || other is AddAssetsDto && + other.assetIds == assetIds; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (assetIds.hashCode); + + @override + String toString() => 'AddAssetsDto[assetIds=$assetIds]'; + + Map toJson() { + final _json = {}; + _json[r'assetIds'] = assetIds; + return _json; + } + + /// Returns a new [AddAssetsDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static AddAssetsDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "AddAssetsDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "AddAssetsDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return AddAssetsDto( + assetIds: json[r'assetIds'] is List + ? (json[r'assetIds'] as List).cast() + : const [], + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AddAssetsDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AddAssetsDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of AddAssetsDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AddAssetsDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'assetIds', + }; +} + diff --git a/mobile/openapi/lib/model/add_users_dto.dart b/mobile/openapi/lib/model/add_users_dto.dart new file mode 100644 index 000000000..6e0b5a88f --- /dev/null +++ b/mobile/openapi/lib/model/add_users_dto.dart @@ -0,0 +1,113 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class AddUsersDto { + /// Returns a new [AddUsersDto] instance. + AddUsersDto({ + this.sharedUserIds = const [], + }); + + List sharedUserIds; + + @override + bool operator ==(Object other) => identical(this, other) || other is AddUsersDto && + other.sharedUserIds == sharedUserIds; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (sharedUserIds.hashCode); + + @override + String toString() => 'AddUsersDto[sharedUserIds=$sharedUserIds]'; + + Map toJson() { + final _json = {}; + _json[r'sharedUserIds'] = sharedUserIds; + return _json; + } + + /// Returns a new [AddUsersDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static AddUsersDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "AddUsersDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "AddUsersDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return AddUsersDto( + sharedUserIds: json[r'sharedUserIds'] is List + ? (json[r'sharedUserIds'] as List).cast() + : const [], + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AddUsersDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AddUsersDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of AddUsersDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AddUsersDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'sharedUserIds', + }; +} + diff --git a/mobile/openapi/lib/model/admin_signup_response_dto.dart b/mobile/openapi/lib/model/admin_signup_response_dto.dart new file mode 100644 index 000000000..875744969 --- /dev/null +++ b/mobile/openapi/lib/model/admin_signup_response_dto.dart @@ -0,0 +1,143 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class AdminSignupResponseDto { + /// Returns a new [AdminSignupResponseDto] instance. + AdminSignupResponseDto({ + required this.id, + required this.email, + required this.firstName, + required this.lastName, + required this.createdAt, + }); + + String id; + + String email; + + String firstName; + + String lastName; + + String createdAt; + + @override + bool operator ==(Object other) => identical(this, other) || other is AdminSignupResponseDto && + other.id == id && + other.email == email && + other.firstName == firstName && + other.lastName == lastName && + other.createdAt == createdAt; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (email.hashCode) + + (firstName.hashCode) + + (lastName.hashCode) + + (createdAt.hashCode); + + @override + String toString() => 'AdminSignupResponseDto[id=$id, email=$email, firstName=$firstName, lastName=$lastName, createdAt=$createdAt]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + _json[r'email'] = email; + _json[r'firstName'] = firstName; + _json[r'lastName'] = lastName; + _json[r'createdAt'] = createdAt; + return _json; + } + + /// Returns a new [AdminSignupResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static AdminSignupResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "AdminSignupResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "AdminSignupResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return AdminSignupResponseDto( + id: mapValueOfType(json, r'id')!, + email: mapValueOfType(json, r'email')!, + firstName: mapValueOfType(json, r'firstName')!, + lastName: mapValueOfType(json, r'lastName')!, + createdAt: mapValueOfType(json, r'createdAt')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AdminSignupResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AdminSignupResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of AdminSignupResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AdminSignupResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'email', + 'firstName', + 'lastName', + 'createdAt', + }; +} + diff --git a/mobile/openapi/lib/model/album_response_dto.dart b/mobile/openapi/lib/model/album_response_dto.dart new file mode 100644 index 000000000..80ee699e4 --- /dev/null +++ b/mobile/openapi/lib/model/album_response_dto.dart @@ -0,0 +1,171 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class AlbumResponseDto { + /// Returns a new [AlbumResponseDto] instance. + AlbumResponseDto({ + required this.id, + required this.ownerId, + required this.albumName, + required this.createdAt, + required this.albumThumbnailAssetId, + required this.shared, + this.sharedUsers = const [], + this.assets = const [], + }); + + String id; + + String ownerId; + + String albumName; + + String createdAt; + + String? albumThumbnailAssetId; + + bool shared; + + List sharedUsers; + + List assets; + + @override + bool operator ==(Object other) => identical(this, other) || other is AlbumResponseDto && + other.id == id && + other.ownerId == ownerId && + other.albumName == albumName && + other.createdAt == createdAt && + other.albumThumbnailAssetId == albumThumbnailAssetId && + other.shared == shared && + other.sharedUsers == sharedUsers && + other.assets == assets; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (ownerId.hashCode) + + (albumName.hashCode) + + (createdAt.hashCode) + + (albumThumbnailAssetId == null ? 0 : albumThumbnailAssetId!.hashCode) + + (shared.hashCode) + + (sharedUsers.hashCode) + + (assets.hashCode); + + @override + String toString() => 'AlbumResponseDto[id=$id, ownerId=$ownerId, albumName=$albumName, createdAt=$createdAt, albumThumbnailAssetId=$albumThumbnailAssetId, shared=$shared, sharedUsers=$sharedUsers, assets=$assets]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + _json[r'ownerId'] = ownerId; + _json[r'albumName'] = albumName; + _json[r'createdAt'] = createdAt; + if (albumThumbnailAssetId != null) { + _json[r'albumThumbnailAssetId'] = albumThumbnailAssetId; + } else { + _json[r'albumThumbnailAssetId'] = null; + } + _json[r'shared'] = shared; + _json[r'sharedUsers'] = sharedUsers; + _json[r'assets'] = assets; + return _json; + } + + /// Returns a new [AlbumResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static AlbumResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "AlbumResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "AlbumResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return AlbumResponseDto( + id: mapValueOfType(json, r'id')!, + ownerId: mapValueOfType(json, r'ownerId')!, + albumName: mapValueOfType(json, r'albumName')!, + createdAt: mapValueOfType(json, r'createdAt')!, + albumThumbnailAssetId: mapValueOfType(json, r'albumThumbnailAssetId'), + shared: mapValueOfType(json, r'shared')!, + sharedUsers: UserResponseDto.listFromJson(json[r'sharedUsers'])!, + assets: AssetResponseDto.listFromJson(json[r'assets'])!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AlbumResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AlbumResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of AlbumResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AlbumResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'ownerId', + 'albumName', + 'createdAt', + 'albumThumbnailAssetId', + 'shared', + 'sharedUsers', + 'assets', + }; +} + diff --git a/mobile/openapi/lib/model/asset_file_upload_response_dto.dart b/mobile/openapi/lib/model/asset_file_upload_response_dto.dart new file mode 100644 index 000000000..40583b6ce --- /dev/null +++ b/mobile/openapi/lib/model/asset_file_upload_response_dto.dart @@ -0,0 +1,111 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class AssetFileUploadResponseDto { + /// Returns a new [AssetFileUploadResponseDto] instance. + AssetFileUploadResponseDto({ + required this.id, + }); + + String id; + + @override + bool operator ==(Object other) => identical(this, other) || other is AssetFileUploadResponseDto && + other.id == id; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode); + + @override + String toString() => 'AssetFileUploadResponseDto[id=$id]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + return _json; + } + + /// Returns a new [AssetFileUploadResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static AssetFileUploadResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "AssetFileUploadResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "AssetFileUploadResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return AssetFileUploadResponseDto( + id: mapValueOfType(json, r'id')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AssetFileUploadResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AssetFileUploadResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of AssetFileUploadResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AssetFileUploadResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + }; +} + diff --git a/mobile/openapi/lib/model/asset_response_dto.dart b/mobile/openapi/lib/model/asset_response_dto.dart new file mode 100644 index 000000000..cd1e83c5f --- /dev/null +++ b/mobile/openapi/lib/model/asset_response_dto.dart @@ -0,0 +1,265 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class AssetResponseDto { + /// Returns a new [AssetResponseDto] instance. + AssetResponseDto({ + required this.type, + required this.id, + required this.deviceAssetId, + required this.ownerId, + required this.deviceId, + required this.originalPath, + required this.resizePath, + required this.createdAt, + required this.modifiedAt, + required this.isFavorite, + required this.mimeType, + required this.duration, + required this.webpPath, + required this.encodedVideoPath, + this.exifInfo, + this.smartInfo, + }); + + AssetTypeEnum type; + + String id; + + String deviceAssetId; + + String ownerId; + + String deviceId; + + String originalPath; + + String? resizePath; + + String createdAt; + + String modifiedAt; + + bool isFavorite; + + String? mimeType; + + String duration; + + String? webpPath; + + String? encodedVideoPath; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + ExifResponseDto? exifInfo; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + SmartInfoResponseDto? smartInfo; + + @override + bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto && + other.type == type && + other.id == id && + other.deviceAssetId == deviceAssetId && + other.ownerId == ownerId && + other.deviceId == deviceId && + other.originalPath == originalPath && + other.resizePath == resizePath && + other.createdAt == createdAt && + other.modifiedAt == modifiedAt && + other.isFavorite == isFavorite && + other.mimeType == mimeType && + other.duration == duration && + other.webpPath == webpPath && + other.encodedVideoPath == encodedVideoPath && + other.exifInfo == exifInfo && + other.smartInfo == smartInfo; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (type.hashCode) + + (id.hashCode) + + (deviceAssetId.hashCode) + + (ownerId.hashCode) + + (deviceId.hashCode) + + (originalPath.hashCode) + + (resizePath == null ? 0 : resizePath!.hashCode) + + (createdAt.hashCode) + + (modifiedAt.hashCode) + + (isFavorite.hashCode) + + (mimeType == null ? 0 : mimeType!.hashCode) + + (duration.hashCode) + + (webpPath == null ? 0 : webpPath!.hashCode) + + (encodedVideoPath == null ? 0 : encodedVideoPath!.hashCode) + + (exifInfo == null ? 0 : exifInfo!.hashCode) + + (smartInfo == null ? 0 : smartInfo!.hashCode); + + @override + String toString() => 'AssetResponseDto[type=$type, id=$id, deviceAssetId=$deviceAssetId, ownerId=$ownerId, deviceId=$deviceId, originalPath=$originalPath, resizePath=$resizePath, createdAt=$createdAt, modifiedAt=$modifiedAt, isFavorite=$isFavorite, mimeType=$mimeType, duration=$duration, webpPath=$webpPath, encodedVideoPath=$encodedVideoPath, exifInfo=$exifInfo, smartInfo=$smartInfo]'; + + Map toJson() { + final _json = {}; + _json[r'type'] = type; + _json[r'id'] = id; + _json[r'deviceAssetId'] = deviceAssetId; + _json[r'ownerId'] = ownerId; + _json[r'deviceId'] = deviceId; + _json[r'originalPath'] = originalPath; + if (resizePath != null) { + _json[r'resizePath'] = resizePath; + } else { + _json[r'resizePath'] = null; + } + _json[r'createdAt'] = createdAt; + _json[r'modifiedAt'] = modifiedAt; + _json[r'isFavorite'] = isFavorite; + if (mimeType != null) { + _json[r'mimeType'] = mimeType; + } else { + _json[r'mimeType'] = null; + } + _json[r'duration'] = duration; + if (webpPath != null) { + _json[r'webpPath'] = webpPath; + } else { + _json[r'webpPath'] = null; + } + if (encodedVideoPath != null) { + _json[r'encodedVideoPath'] = encodedVideoPath; + } else { + _json[r'encodedVideoPath'] = null; + } + if (exifInfo != null) { + _json[r'exifInfo'] = exifInfo; + } else { + _json[r'exifInfo'] = null; + } + if (smartInfo != null) { + _json[r'smartInfo'] = smartInfo; + } else { + _json[r'smartInfo'] = null; + } + return _json; + } + + /// Returns a new [AssetResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static AssetResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "AssetResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "AssetResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return AssetResponseDto( + type: AssetTypeEnum.fromJson(json[r'type'])!, + id: mapValueOfType(json, r'id')!, + deviceAssetId: mapValueOfType(json, r'deviceAssetId')!, + ownerId: mapValueOfType(json, r'ownerId')!, + deviceId: mapValueOfType(json, r'deviceId')!, + originalPath: mapValueOfType(json, r'originalPath')!, + resizePath: mapValueOfType(json, r'resizePath'), + createdAt: mapValueOfType(json, r'createdAt')!, + modifiedAt: mapValueOfType(json, r'modifiedAt')!, + isFavorite: mapValueOfType(json, r'isFavorite')!, + mimeType: mapValueOfType(json, r'mimeType'), + duration: mapValueOfType(json, r'duration')!, + webpPath: mapValueOfType(json, r'webpPath'), + encodedVideoPath: mapValueOfType(json, r'encodedVideoPath'), + exifInfo: ExifResponseDto.fromJson(json[r'exifInfo']), + smartInfo: SmartInfoResponseDto.fromJson(json[r'smartInfo']), + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AssetResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AssetResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of AssetResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = AssetResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'type', + 'id', + 'deviceAssetId', + 'ownerId', + 'deviceId', + 'originalPath', + 'resizePath', + 'createdAt', + 'modifiedAt', + 'isFavorite', + 'mimeType', + 'duration', + 'webpPath', + 'encodedVideoPath', + }; +} + diff --git a/mobile/openapi/lib/model/asset_type_enum.dart b/mobile/openapi/lib/model/asset_type_enum.dart new file mode 100644 index 000000000..bf1d3ba19 --- /dev/null +++ b/mobile/openapi/lib/model/asset_type_enum.dart @@ -0,0 +1,91 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class AssetTypeEnum { + /// Instantiate a new enum with the provided [value]. + const AssetTypeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const IMAGE = AssetTypeEnum._(r'IMAGE'); + static const VIDEO = AssetTypeEnum._(r'VIDEO'); + static const AUDIO = AssetTypeEnum._(r'AUDIO'); + static const OTHER = AssetTypeEnum._(r'OTHER'); + + /// List of all possible values in this [enum][AssetTypeEnum]. + static const values = [ + IMAGE, + VIDEO, + AUDIO, + OTHER, + ]; + + static AssetTypeEnum? fromJson(dynamic value) => AssetTypeEnumTypeTransformer().decode(value); + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = AssetTypeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [AssetTypeEnum] to String, +/// and [decode] dynamic data back to [AssetTypeEnum]. +class AssetTypeEnumTypeTransformer { + factory AssetTypeEnumTypeTransformer() => _instance ??= const AssetTypeEnumTypeTransformer._(); + + const AssetTypeEnumTypeTransformer._(); + + String encode(AssetTypeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a AssetTypeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + AssetTypeEnum? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data.toString()) { + case r'IMAGE': return AssetTypeEnum.IMAGE; + case r'VIDEO': return AssetTypeEnum.VIDEO; + case r'AUDIO': return AssetTypeEnum.AUDIO; + case r'OTHER': return AssetTypeEnum.OTHER; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [AssetTypeEnumTypeTransformer] instance. + static AssetTypeEnumTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/check_duplicate_asset_dto.dart b/mobile/openapi/lib/model/check_duplicate_asset_dto.dart new file mode 100644 index 000000000..8644381cb --- /dev/null +++ b/mobile/openapi/lib/model/check_duplicate_asset_dto.dart @@ -0,0 +1,119 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CheckDuplicateAssetDto { + /// Returns a new [CheckDuplicateAssetDto] instance. + CheckDuplicateAssetDto({ + required this.deviceAssetId, + required this.deviceId, + }); + + String deviceAssetId; + + String deviceId; + + @override + bool operator ==(Object other) => identical(this, other) || other is CheckDuplicateAssetDto && + other.deviceAssetId == deviceAssetId && + other.deviceId == deviceId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (deviceAssetId.hashCode) + + (deviceId.hashCode); + + @override + String toString() => 'CheckDuplicateAssetDto[deviceAssetId=$deviceAssetId, deviceId=$deviceId]'; + + Map toJson() { + final _json = {}; + _json[r'deviceAssetId'] = deviceAssetId; + _json[r'deviceId'] = deviceId; + return _json; + } + + /// Returns a new [CheckDuplicateAssetDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CheckDuplicateAssetDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CheckDuplicateAssetDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CheckDuplicateAssetDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CheckDuplicateAssetDto( + deviceAssetId: mapValueOfType(json, r'deviceAssetId')!, + deviceId: mapValueOfType(json, r'deviceId')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CheckDuplicateAssetDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CheckDuplicateAssetDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CheckDuplicateAssetDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CheckDuplicateAssetDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'deviceAssetId', + 'deviceId', + }; +} + diff --git a/mobile/openapi/lib/model/check_duplicate_asset_response_dto.dart b/mobile/openapi/lib/model/check_duplicate_asset_response_dto.dart new file mode 100644 index 000000000..5c5453fd8 --- /dev/null +++ b/mobile/openapi/lib/model/check_duplicate_asset_response_dto.dart @@ -0,0 +1,111 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CheckDuplicateAssetResponseDto { + /// Returns a new [CheckDuplicateAssetResponseDto] instance. + CheckDuplicateAssetResponseDto({ + required this.isExist, + }); + + bool isExist; + + @override + bool operator ==(Object other) => identical(this, other) || other is CheckDuplicateAssetResponseDto && + other.isExist == isExist; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (isExist.hashCode); + + @override + String toString() => 'CheckDuplicateAssetResponseDto[isExist=$isExist]'; + + Map toJson() { + final _json = {}; + _json[r'isExist'] = isExist; + return _json; + } + + /// Returns a new [CheckDuplicateAssetResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CheckDuplicateAssetResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CheckDuplicateAssetResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CheckDuplicateAssetResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CheckDuplicateAssetResponseDto( + isExist: mapValueOfType(json, r'isExist')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CheckDuplicateAssetResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CheckDuplicateAssetResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CheckDuplicateAssetResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CheckDuplicateAssetResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'isExist', + }; +} + diff --git a/mobile/openapi/lib/model/create_album_dto.dart b/mobile/openapi/lib/model/create_album_dto.dart new file mode 100644 index 000000000..202a474be --- /dev/null +++ b/mobile/openapi/lib/model/create_album_dto.dart @@ -0,0 +1,129 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CreateAlbumDto { + /// Returns a new [CreateAlbumDto] instance. + CreateAlbumDto({ + required this.albumName, + this.sharedWithUserIds = const [], + this.assetIds = const [], + }); + + String albumName; + + List sharedWithUserIds; + + List assetIds; + + @override + bool operator ==(Object other) => identical(this, other) || other is CreateAlbumDto && + other.albumName == albumName && + other.sharedWithUserIds == sharedWithUserIds && + other.assetIds == assetIds; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (albumName.hashCode) + + (sharedWithUserIds.hashCode) + + (assetIds.hashCode); + + @override + String toString() => 'CreateAlbumDto[albumName=$albumName, sharedWithUserIds=$sharedWithUserIds, assetIds=$assetIds]'; + + Map toJson() { + final _json = {}; + _json[r'albumName'] = albumName; + _json[r'sharedWithUserIds'] = sharedWithUserIds; + _json[r'assetIds'] = assetIds; + return _json; + } + + /// Returns a new [CreateAlbumDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CreateAlbumDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CreateAlbumDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CreateAlbumDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CreateAlbumDto( + albumName: mapValueOfType(json, r'albumName')!, + sharedWithUserIds: json[r'sharedWithUserIds'] is List + ? (json[r'sharedWithUserIds'] as List).cast() + : const [], + assetIds: json[r'assetIds'] is List + ? (json[r'assetIds'] as List).cast() + : const [], + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CreateAlbumDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateAlbumDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CreateAlbumDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateAlbumDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'albumName', + }; +} + diff --git a/mobile/openapi/lib/model/create_device_info_dto.dart b/mobile/openapi/lib/model/create_device_info_dto.dart new file mode 100644 index 000000000..1c2cf46e1 --- /dev/null +++ b/mobile/openapi/lib/model/create_device_info_dto.dart @@ -0,0 +1,136 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CreateDeviceInfoDto { + /// Returns a new [CreateDeviceInfoDto] instance. + CreateDeviceInfoDto({ + required this.deviceType, + required this.deviceId, + this.isAutoBackup, + }); + + DeviceTypeEnum deviceType; + + String deviceId; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? isAutoBackup; + + @override + bool operator ==(Object other) => identical(this, other) || other is CreateDeviceInfoDto && + other.deviceType == deviceType && + other.deviceId == deviceId && + other.isAutoBackup == isAutoBackup; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (deviceType.hashCode) + + (deviceId.hashCode) + + (isAutoBackup == null ? 0 : isAutoBackup!.hashCode); + + @override + String toString() => 'CreateDeviceInfoDto[deviceType=$deviceType, deviceId=$deviceId, isAutoBackup=$isAutoBackup]'; + + Map toJson() { + final _json = {}; + _json[r'deviceType'] = deviceType; + _json[r'deviceId'] = deviceId; + if (isAutoBackup != null) { + _json[r'isAutoBackup'] = isAutoBackup; + } else { + _json[r'isAutoBackup'] = null; + } + return _json; + } + + /// Returns a new [CreateDeviceInfoDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CreateDeviceInfoDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CreateDeviceInfoDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CreateDeviceInfoDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CreateDeviceInfoDto( + deviceType: DeviceTypeEnum.fromJson(json[r'deviceType'])!, + deviceId: mapValueOfType(json, r'deviceId')!, + isAutoBackup: mapValueOfType(json, r'isAutoBackup'), + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CreateDeviceInfoDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateDeviceInfoDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CreateDeviceInfoDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateDeviceInfoDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'deviceType', + 'deviceId', + }; +} + diff --git a/mobile/openapi/lib/model/create_profile_image_response_dto.dart b/mobile/openapi/lib/model/create_profile_image_response_dto.dart new file mode 100644 index 000000000..fc7321cbb --- /dev/null +++ b/mobile/openapi/lib/model/create_profile_image_response_dto.dart @@ -0,0 +1,119 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CreateProfileImageResponseDto { + /// Returns a new [CreateProfileImageResponseDto] instance. + CreateProfileImageResponseDto({ + required this.userId, + required this.profileImagePath, + }); + + String userId; + + String profileImagePath; + + @override + bool operator ==(Object other) => identical(this, other) || other is CreateProfileImageResponseDto && + other.userId == userId && + other.profileImagePath == profileImagePath; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (userId.hashCode) + + (profileImagePath.hashCode); + + @override + String toString() => 'CreateProfileImageResponseDto[userId=$userId, profileImagePath=$profileImagePath]'; + + Map toJson() { + final _json = {}; + _json[r'userId'] = userId; + _json[r'profileImagePath'] = profileImagePath; + return _json; + } + + /// Returns a new [CreateProfileImageResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CreateProfileImageResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CreateProfileImageResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CreateProfileImageResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CreateProfileImageResponseDto( + userId: mapValueOfType(json, r'userId')!, + profileImagePath: mapValueOfType(json, r'profileImagePath')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CreateProfileImageResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateProfileImageResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CreateProfileImageResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateProfileImageResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'userId', + 'profileImagePath', + }; +} + diff --git a/mobile/openapi/lib/model/create_user_dto.dart b/mobile/openapi/lib/model/create_user_dto.dart new file mode 100644 index 000000000..b8977d46d --- /dev/null +++ b/mobile/openapi/lib/model/create_user_dto.dart @@ -0,0 +1,135 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CreateUserDto { + /// Returns a new [CreateUserDto] instance. + CreateUserDto({ + required this.email, + required this.password, + required this.firstName, + required this.lastName, + }); + + String email; + + String password; + + String firstName; + + String lastName; + + @override + bool operator ==(Object other) => identical(this, other) || other is CreateUserDto && + other.email == email && + other.password == password && + other.firstName == firstName && + other.lastName == lastName; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (email.hashCode) + + (password.hashCode) + + (firstName.hashCode) + + (lastName.hashCode); + + @override + String toString() => 'CreateUserDto[email=$email, password=$password, firstName=$firstName, lastName=$lastName]'; + + Map toJson() { + final _json = {}; + _json[r'email'] = email; + _json[r'password'] = password; + _json[r'firstName'] = firstName; + _json[r'lastName'] = lastName; + return _json; + } + + /// Returns a new [CreateUserDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CreateUserDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CreateUserDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CreateUserDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CreateUserDto( + email: mapValueOfType(json, r'email')!, + password: mapValueOfType(json, r'password')!, + firstName: mapValueOfType(json, r'firstName')!, + lastName: mapValueOfType(json, r'lastName')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CreateUserDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateUserDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CreateUserDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CreateUserDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'email', + 'password', + 'firstName', + 'lastName', + }; +} + diff --git a/mobile/openapi/lib/model/curated_locations_response_dto.dart b/mobile/openapi/lib/model/curated_locations_response_dto.dart new file mode 100644 index 000000000..5117aa990 --- /dev/null +++ b/mobile/openapi/lib/model/curated_locations_response_dto.dart @@ -0,0 +1,143 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CuratedLocationsResponseDto { + /// Returns a new [CuratedLocationsResponseDto] instance. + CuratedLocationsResponseDto({ + required this.id, + required this.city, + required this.resizePath, + required this.deviceAssetId, + required this.deviceId, + }); + + String id; + + String city; + + String resizePath; + + String deviceAssetId; + + String deviceId; + + @override + bool operator ==(Object other) => identical(this, other) || other is CuratedLocationsResponseDto && + other.id == id && + other.city == city && + other.resizePath == resizePath && + other.deviceAssetId == deviceAssetId && + other.deviceId == deviceId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (city.hashCode) + + (resizePath.hashCode) + + (deviceAssetId.hashCode) + + (deviceId.hashCode); + + @override + String toString() => 'CuratedLocationsResponseDto[id=$id, city=$city, resizePath=$resizePath, deviceAssetId=$deviceAssetId, deviceId=$deviceId]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + _json[r'city'] = city; + _json[r'resizePath'] = resizePath; + _json[r'deviceAssetId'] = deviceAssetId; + _json[r'deviceId'] = deviceId; + return _json; + } + + /// Returns a new [CuratedLocationsResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CuratedLocationsResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CuratedLocationsResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CuratedLocationsResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CuratedLocationsResponseDto( + id: mapValueOfType(json, r'id')!, + city: mapValueOfType(json, r'city')!, + resizePath: mapValueOfType(json, r'resizePath')!, + deviceAssetId: mapValueOfType(json, r'deviceAssetId')!, + deviceId: mapValueOfType(json, r'deviceId')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CuratedLocationsResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CuratedLocationsResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CuratedLocationsResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CuratedLocationsResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'city', + 'resizePath', + 'deviceAssetId', + 'deviceId', + }; +} + diff --git a/mobile/openapi/lib/model/curated_objects_response_dto.dart b/mobile/openapi/lib/model/curated_objects_response_dto.dart new file mode 100644 index 000000000..00662c5f1 --- /dev/null +++ b/mobile/openapi/lib/model/curated_objects_response_dto.dart @@ -0,0 +1,143 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CuratedObjectsResponseDto { + /// Returns a new [CuratedObjectsResponseDto] instance. + CuratedObjectsResponseDto({ + required this.id, + required this.object, + required this.resizePath, + required this.deviceAssetId, + required this.deviceId, + }); + + String id; + + String object; + + String resizePath; + + String deviceAssetId; + + String deviceId; + + @override + bool operator ==(Object other) => identical(this, other) || other is CuratedObjectsResponseDto && + other.id == id && + other.object == object && + other.resizePath == resizePath && + other.deviceAssetId == deviceAssetId && + other.deviceId == deviceId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (object.hashCode) + + (resizePath.hashCode) + + (deviceAssetId.hashCode) + + (deviceId.hashCode); + + @override + String toString() => 'CuratedObjectsResponseDto[id=$id, object=$object, resizePath=$resizePath, deviceAssetId=$deviceAssetId, deviceId=$deviceId]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + _json[r'object'] = object; + _json[r'resizePath'] = resizePath; + _json[r'deviceAssetId'] = deviceAssetId; + _json[r'deviceId'] = deviceId; + return _json; + } + + /// Returns a new [CuratedObjectsResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CuratedObjectsResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "CuratedObjectsResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "CuratedObjectsResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CuratedObjectsResponseDto( + id: mapValueOfType(json, r'id')!, + object: mapValueOfType(json, r'object')!, + resizePath: mapValueOfType(json, r'resizePath')!, + deviceAssetId: mapValueOfType(json, r'deviceAssetId')!, + deviceId: mapValueOfType(json, r'deviceId')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CuratedObjectsResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CuratedObjectsResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CuratedObjectsResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CuratedObjectsResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'object', + 'resizePath', + 'deviceAssetId', + 'deviceId', + }; +} + diff --git a/mobile/openapi/lib/model/delete_asset_dto.dart b/mobile/openapi/lib/model/delete_asset_dto.dart new file mode 100644 index 000000000..4830dd40c --- /dev/null +++ b/mobile/openapi/lib/model/delete_asset_dto.dart @@ -0,0 +1,113 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class DeleteAssetDto { + /// Returns a new [DeleteAssetDto] instance. + DeleteAssetDto({ + this.ids = const [], + }); + + List ids; + + @override + bool operator ==(Object other) => identical(this, other) || other is DeleteAssetDto && + other.ids == ids; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (ids.hashCode); + + @override + String toString() => 'DeleteAssetDto[ids=$ids]'; + + Map toJson() { + final _json = {}; + _json[r'ids'] = ids; + return _json; + } + + /// Returns a new [DeleteAssetDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static DeleteAssetDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "DeleteAssetDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "DeleteAssetDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return DeleteAssetDto( + ids: json[r'ids'] is List + ? (json[r'ids'] as List).cast() + : const [], + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = DeleteAssetDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = DeleteAssetDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of DeleteAssetDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = DeleteAssetDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'ids', + }; +} + diff --git a/mobile/openapi/lib/model/delete_asset_response_dto.dart b/mobile/openapi/lib/model/delete_asset_response_dto.dart new file mode 100644 index 000000000..b71336aca --- /dev/null +++ b/mobile/openapi/lib/model/delete_asset_response_dto.dart @@ -0,0 +1,119 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class DeleteAssetResponseDto { + /// Returns a new [DeleteAssetResponseDto] instance. + DeleteAssetResponseDto({ + required this.status, + required this.id, + }); + + DeleteAssetStatus status; + + String id; + + @override + bool operator ==(Object other) => identical(this, other) || other is DeleteAssetResponseDto && + other.status == status && + other.id == id; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (status.hashCode) + + (id.hashCode); + + @override + String toString() => 'DeleteAssetResponseDto[status=$status, id=$id]'; + + Map toJson() { + final _json = {}; + _json[r'status'] = status; + _json[r'id'] = id; + return _json; + } + + /// Returns a new [DeleteAssetResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static DeleteAssetResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "DeleteAssetResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "DeleteAssetResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return DeleteAssetResponseDto( + status: DeleteAssetStatus.fromJson(json[r'status'])!, + id: mapValueOfType(json, r'id')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = DeleteAssetResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = DeleteAssetResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of DeleteAssetResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = DeleteAssetResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'status', + 'id', + }; +} + diff --git a/mobile/openapi/lib/model/delete_asset_status.dart b/mobile/openapi/lib/model/delete_asset_status.dart new file mode 100644 index 000000000..045115aa5 --- /dev/null +++ b/mobile/openapi/lib/model/delete_asset_status.dart @@ -0,0 +1,85 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class DeleteAssetStatus { + /// Instantiate a new enum with the provided [value]. + const DeleteAssetStatus._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const SUCCESS = DeleteAssetStatus._(r'SUCCESS'); + static const FAILED = DeleteAssetStatus._(r'FAILED'); + + /// List of all possible values in this [enum][DeleteAssetStatus]. + static const values = [ + SUCCESS, + FAILED, + ]; + + static DeleteAssetStatus? fromJson(dynamic value) => DeleteAssetStatusTypeTransformer().decode(value); + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = DeleteAssetStatus.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [DeleteAssetStatus] to String, +/// and [decode] dynamic data back to [DeleteAssetStatus]. +class DeleteAssetStatusTypeTransformer { + factory DeleteAssetStatusTypeTransformer() => _instance ??= const DeleteAssetStatusTypeTransformer._(); + + const DeleteAssetStatusTypeTransformer._(); + + String encode(DeleteAssetStatus data) => data.value; + + /// Decodes a [dynamic value][data] to a DeleteAssetStatus. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + DeleteAssetStatus? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data.toString()) { + case r'SUCCESS': return DeleteAssetStatus.SUCCESS; + case r'FAILED': return DeleteAssetStatus.FAILED; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [DeleteAssetStatusTypeTransformer] instance. + static DeleteAssetStatusTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/device_info_response_dto.dart b/mobile/openapi/lib/model/device_info_response_dto.dart new file mode 100644 index 000000000..ad831c469 --- /dev/null +++ b/mobile/openapi/lib/model/device_info_response_dto.dart @@ -0,0 +1,151 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class DeviceInfoResponseDto { + /// Returns a new [DeviceInfoResponseDto] instance. + DeviceInfoResponseDto({ + required this.id, + required this.deviceType, + required this.userId, + required this.deviceId, + required this.createdAt, + required this.isAutoBackup, + }); + + int id; + + DeviceTypeEnum deviceType; + + String userId; + + String deviceId; + + String createdAt; + + bool isAutoBackup; + + @override + bool operator ==(Object other) => identical(this, other) || other is DeviceInfoResponseDto && + other.id == id && + other.deviceType == deviceType && + other.userId == userId && + other.deviceId == deviceId && + other.createdAt == createdAt && + other.isAutoBackup == isAutoBackup; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (deviceType.hashCode) + + (userId.hashCode) + + (deviceId.hashCode) + + (createdAt.hashCode) + + (isAutoBackup.hashCode); + + @override + String toString() => 'DeviceInfoResponseDto[id=$id, deviceType=$deviceType, userId=$userId, deviceId=$deviceId, createdAt=$createdAt, isAutoBackup=$isAutoBackup]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + _json[r'deviceType'] = deviceType; + _json[r'userId'] = userId; + _json[r'deviceId'] = deviceId; + _json[r'createdAt'] = createdAt; + _json[r'isAutoBackup'] = isAutoBackup; + return _json; + } + + /// Returns a new [DeviceInfoResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static DeviceInfoResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "DeviceInfoResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "DeviceInfoResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return DeviceInfoResponseDto( + id: mapValueOfType(json, r'id')!, + deviceType: DeviceTypeEnum.fromJson(json[r'deviceType'])!, + userId: mapValueOfType(json, r'userId')!, + deviceId: mapValueOfType(json, r'deviceId')!, + createdAt: mapValueOfType(json, r'createdAt')!, + isAutoBackup: mapValueOfType(json, r'isAutoBackup')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = DeviceInfoResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = DeviceInfoResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of DeviceInfoResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = DeviceInfoResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'deviceType', + 'userId', + 'deviceId', + 'createdAt', + 'isAutoBackup', + }; +} + diff --git a/mobile/openapi/lib/model/device_type_enum.dart b/mobile/openapi/lib/model/device_type_enum.dart new file mode 100644 index 000000000..15f81c3d4 --- /dev/null +++ b/mobile/openapi/lib/model/device_type_enum.dart @@ -0,0 +1,88 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class DeviceTypeEnum { + /// Instantiate a new enum with the provided [value]. + const DeviceTypeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const IOS = DeviceTypeEnum._(r'IOS'); + static const ANDROID = DeviceTypeEnum._(r'ANDROID'); + static const WEB = DeviceTypeEnum._(r'WEB'); + + /// List of all possible values in this [enum][DeviceTypeEnum]. + static const values = [ + IOS, + ANDROID, + WEB, + ]; + + static DeviceTypeEnum? fromJson(dynamic value) => DeviceTypeEnumTypeTransformer().decode(value); + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = DeviceTypeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [DeviceTypeEnum] to String, +/// and [decode] dynamic data back to [DeviceTypeEnum]. +class DeviceTypeEnumTypeTransformer { + factory DeviceTypeEnumTypeTransformer() => _instance ??= const DeviceTypeEnumTypeTransformer._(); + + const DeviceTypeEnumTypeTransformer._(); + + String encode(DeviceTypeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a DeviceTypeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + DeviceTypeEnum? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data.toString()) { + case r'IOS': return DeviceTypeEnum.IOS; + case r'ANDROID': return DeviceTypeEnum.ANDROID; + case r'WEB': return DeviceTypeEnum.WEB; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [DeviceTypeEnumTypeTransformer] instance. + static DeviceTypeEnumTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/exif_response_dto.dart b/mobile/openapi/lib/model/exif_response_dto.dart new file mode 100644 index 000000000..199c955e9 --- /dev/null +++ b/mobile/openapi/lib/model/exif_response_dto.dart @@ -0,0 +1,341 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ExifResponseDto { + /// Returns a new [ExifResponseDto] instance. + ExifResponseDto({ + this.id, + this.make, + this.model, + this.imageName, + this.exifImageWidth, + this.exifImageHeight, + this.fileSizeInByte, + this.orientation, + this.dateTimeOriginal, + this.modifyDate, + this.lensModel, + this.fNumber, + this.focalLength, + this.iso, + this.exposureTime, + this.latitude, + this.longitude, + this.city, + this.state, + this.country, + }); + + String? id; + + String? make; + + String? model; + + String? imageName; + + num? exifImageWidth; + + num? exifImageHeight; + + num? fileSizeInByte; + + String? orientation; + + DateTime? dateTimeOriginal; + + DateTime? modifyDate; + + String? lensModel; + + num? fNumber; + + num? focalLength; + + num? iso; + + num? exposureTime; + + num? latitude; + + num? longitude; + + String? city; + + String? state; + + String? country; + + @override + bool operator ==(Object other) => identical(this, other) || other is ExifResponseDto && + other.id == id && + other.make == make && + other.model == model && + other.imageName == imageName && + other.exifImageWidth == exifImageWidth && + other.exifImageHeight == exifImageHeight && + other.fileSizeInByte == fileSizeInByte && + other.orientation == orientation && + other.dateTimeOriginal == dateTimeOriginal && + other.modifyDate == modifyDate && + other.lensModel == lensModel && + other.fNumber == fNumber && + other.focalLength == focalLength && + other.iso == iso && + other.exposureTime == exposureTime && + other.latitude == latitude && + other.longitude == longitude && + other.city == city && + other.state == state && + other.country == country; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id == null ? 0 : id!.hashCode) + + (make == null ? 0 : make!.hashCode) + + (model == null ? 0 : model!.hashCode) + + (imageName == null ? 0 : imageName!.hashCode) + + (exifImageWidth == null ? 0 : exifImageWidth!.hashCode) + + (exifImageHeight == null ? 0 : exifImageHeight!.hashCode) + + (fileSizeInByte == null ? 0 : fileSizeInByte!.hashCode) + + (orientation == null ? 0 : orientation!.hashCode) + + (dateTimeOriginal == null ? 0 : dateTimeOriginal!.hashCode) + + (modifyDate == null ? 0 : modifyDate!.hashCode) + + (lensModel == null ? 0 : lensModel!.hashCode) + + (fNumber == null ? 0 : fNumber!.hashCode) + + (focalLength == null ? 0 : focalLength!.hashCode) + + (iso == null ? 0 : iso!.hashCode) + + (exposureTime == null ? 0 : exposureTime!.hashCode) + + (latitude == null ? 0 : latitude!.hashCode) + + (longitude == null ? 0 : longitude!.hashCode) + + (city == null ? 0 : city!.hashCode) + + (state == null ? 0 : state!.hashCode) + + (country == null ? 0 : country!.hashCode); + + @override + String toString() => 'ExifResponseDto[id=$id, make=$make, model=$model, imageName=$imageName, exifImageWidth=$exifImageWidth, exifImageHeight=$exifImageHeight, fileSizeInByte=$fileSizeInByte, orientation=$orientation, dateTimeOriginal=$dateTimeOriginal, modifyDate=$modifyDate, lensModel=$lensModel, fNumber=$fNumber, focalLength=$focalLength, iso=$iso, exposureTime=$exposureTime, latitude=$latitude, longitude=$longitude, city=$city, state=$state, country=$country]'; + + Map toJson() { + final _json = {}; + if (id != null) { + _json[r'id'] = id; + } else { + _json[r'id'] = null; + } + if (make != null) { + _json[r'make'] = make; + } else { + _json[r'make'] = null; + } + if (model != null) { + _json[r'model'] = model; + } else { + _json[r'model'] = null; + } + if (imageName != null) { + _json[r'imageName'] = imageName; + } else { + _json[r'imageName'] = null; + } + if (exifImageWidth != null) { + _json[r'exifImageWidth'] = exifImageWidth; + } else { + _json[r'exifImageWidth'] = null; + } + if (exifImageHeight != null) { + _json[r'exifImageHeight'] = exifImageHeight; + } else { + _json[r'exifImageHeight'] = null; + } + if (fileSizeInByte != null) { + _json[r'fileSizeInByte'] = fileSizeInByte; + } else { + _json[r'fileSizeInByte'] = null; + } + if (orientation != null) { + _json[r'orientation'] = orientation; + } else { + _json[r'orientation'] = null; + } + if (dateTimeOriginal != null) { + _json[r'dateTimeOriginal'] = dateTimeOriginal!.toUtc().toIso8601String(); + } else { + _json[r'dateTimeOriginal'] = null; + } + if (modifyDate != null) { + _json[r'modifyDate'] = modifyDate!.toUtc().toIso8601String(); + } else { + _json[r'modifyDate'] = null; + } + if (lensModel != null) { + _json[r'lensModel'] = lensModel; + } else { + _json[r'lensModel'] = null; + } + if (fNumber != null) { + _json[r'fNumber'] = fNumber; + } else { + _json[r'fNumber'] = null; + } + if (focalLength != null) { + _json[r'focalLength'] = focalLength; + } else { + _json[r'focalLength'] = null; + } + if (iso != null) { + _json[r'iso'] = iso; + } else { + _json[r'iso'] = null; + } + if (exposureTime != null) { + _json[r'exposureTime'] = exposureTime; + } else { + _json[r'exposureTime'] = null; + } + if (latitude != null) { + _json[r'latitude'] = latitude; + } else { + _json[r'latitude'] = null; + } + if (longitude != null) { + _json[r'longitude'] = longitude; + } else { + _json[r'longitude'] = null; + } + if (city != null) { + _json[r'city'] = city; + } else { + _json[r'city'] = null; + } + if (state != null) { + _json[r'state'] = state; + } else { + _json[r'state'] = null; + } + if (country != null) { + _json[r'country'] = country; + } else { + _json[r'country'] = null; + } + return _json; + } + + /// Returns a new [ExifResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ExifResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "ExifResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "ExifResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return ExifResponseDto( + id: mapValueOfType(json, r'id'), + make: mapValueOfType(json, r'make'), + model: mapValueOfType(json, r'model'), + imageName: mapValueOfType(json, r'imageName'), + exifImageWidth: json[r'exifImageWidth'] == null + ? null + : num.parse(json[r'exifImageWidth'].toString()), + exifImageHeight: json[r'exifImageHeight'] == null + ? null + : num.parse(json[r'exifImageHeight'].toString()), + fileSizeInByte: json[r'fileSizeInByte'] == null + ? null + : num.parse(json[r'fileSizeInByte'].toString()), + orientation: mapValueOfType(json, r'orientation'), + dateTimeOriginal: mapDateTime(json, r'dateTimeOriginal', ''), + modifyDate: mapDateTime(json, r'modifyDate', ''), + lensModel: mapValueOfType(json, r'lensModel'), + fNumber: json[r'fNumber'] == null + ? null + : num.parse(json[r'fNumber'].toString()), + focalLength: json[r'focalLength'] == null + ? null + : num.parse(json[r'focalLength'].toString()), + iso: json[r'iso'] == null + ? null + : num.parse(json[r'iso'].toString()), + exposureTime: json[r'exposureTime'] == null + ? null + : num.parse(json[r'exposureTime'].toString()), + latitude: json[r'latitude'] == null + ? null + : num.parse(json[r'latitude'].toString()), + longitude: json[r'longitude'] == null + ? null + : num.parse(json[r'longitude'].toString()), + city: mapValueOfType(json, r'city'), + state: mapValueOfType(json, r'state'), + country: mapValueOfType(json, r'country'), + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = ExifResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ExifResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ExifResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ExifResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/login_credential_dto.dart b/mobile/openapi/lib/model/login_credential_dto.dart new file mode 100644 index 000000000..b8a23be59 --- /dev/null +++ b/mobile/openapi/lib/model/login_credential_dto.dart @@ -0,0 +1,119 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class LoginCredentialDto { + /// Returns a new [LoginCredentialDto] instance. + LoginCredentialDto({ + required this.email, + required this.password, + }); + + String email; + + String password; + + @override + bool operator ==(Object other) => identical(this, other) || other is LoginCredentialDto && + other.email == email && + other.password == password; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (email.hashCode) + + (password.hashCode); + + @override + String toString() => 'LoginCredentialDto[email=$email, password=$password]'; + + Map toJson() { + final _json = {}; + _json[r'email'] = email; + _json[r'password'] = password; + return _json; + } + + /// Returns a new [LoginCredentialDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static LoginCredentialDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "LoginCredentialDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "LoginCredentialDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return LoginCredentialDto( + email: mapValueOfType(json, r'email')!, + password: mapValueOfType(json, r'password')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = LoginCredentialDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = LoginCredentialDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of LoginCredentialDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = LoginCredentialDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'email', + 'password', + }; +} + diff --git a/mobile/openapi/lib/model/login_response_dto.dart b/mobile/openapi/lib/model/login_response_dto.dart new file mode 100644 index 000000000..4eec0475a --- /dev/null +++ b/mobile/openapi/lib/model/login_response_dto.dart @@ -0,0 +1,167 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class LoginResponseDto { + /// Returns a new [LoginResponseDto] instance. + LoginResponseDto({ + required this.accessToken, + required this.userId, + required this.userEmail, + required this.firstName, + required this.lastName, + required this.profileImagePath, + required this.isAdmin, + required this.shouldChangePassword, + }); + + String accessToken; + + String userId; + + String userEmail; + + String firstName; + + String lastName; + + String profileImagePath; + + bool isAdmin; + + bool shouldChangePassword; + + @override + bool operator ==(Object other) => identical(this, other) || other is LoginResponseDto && + other.accessToken == accessToken && + other.userId == userId && + other.userEmail == userEmail && + other.firstName == firstName && + other.lastName == lastName && + other.profileImagePath == profileImagePath && + other.isAdmin == isAdmin && + other.shouldChangePassword == shouldChangePassword; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (accessToken.hashCode) + + (userId.hashCode) + + (userEmail.hashCode) + + (firstName.hashCode) + + (lastName.hashCode) + + (profileImagePath.hashCode) + + (isAdmin.hashCode) + + (shouldChangePassword.hashCode); + + @override + String toString() => 'LoginResponseDto[accessToken=$accessToken, userId=$userId, userEmail=$userEmail, firstName=$firstName, lastName=$lastName, profileImagePath=$profileImagePath, isAdmin=$isAdmin, shouldChangePassword=$shouldChangePassword]'; + + Map toJson() { + final _json = {}; + _json[r'accessToken'] = accessToken; + _json[r'userId'] = userId; + _json[r'userEmail'] = userEmail; + _json[r'firstName'] = firstName; + _json[r'lastName'] = lastName; + _json[r'profileImagePath'] = profileImagePath; + _json[r'isAdmin'] = isAdmin; + _json[r'shouldChangePassword'] = shouldChangePassword; + return _json; + } + + /// Returns a new [LoginResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static LoginResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "LoginResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "LoginResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return LoginResponseDto( + accessToken: mapValueOfType(json, r'accessToken')!, + userId: mapValueOfType(json, r'userId')!, + userEmail: mapValueOfType(json, r'userEmail')!, + firstName: mapValueOfType(json, r'firstName')!, + lastName: mapValueOfType(json, r'lastName')!, + profileImagePath: mapValueOfType(json, r'profileImagePath')!, + isAdmin: mapValueOfType(json, r'isAdmin')!, + shouldChangePassword: mapValueOfType(json, r'shouldChangePassword')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = LoginResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = LoginResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of LoginResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = LoginResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'accessToken', + 'userId', + 'userEmail', + 'firstName', + 'lastName', + 'profileImagePath', + 'isAdmin', + 'shouldChangePassword', + }; +} + diff --git a/mobile/openapi/lib/model/remove_assets_dto.dart b/mobile/openapi/lib/model/remove_assets_dto.dart new file mode 100644 index 000000000..1457bac38 --- /dev/null +++ b/mobile/openapi/lib/model/remove_assets_dto.dart @@ -0,0 +1,113 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RemoveAssetsDto { + /// Returns a new [RemoveAssetsDto] instance. + RemoveAssetsDto({ + this.assetIds = const [], + }); + + List assetIds; + + @override + bool operator ==(Object other) => identical(this, other) || other is RemoveAssetsDto && + other.assetIds == assetIds; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (assetIds.hashCode); + + @override + String toString() => 'RemoveAssetsDto[assetIds=$assetIds]'; + + Map toJson() { + final _json = {}; + _json[r'assetIds'] = assetIds; + return _json; + } + + /// Returns a new [RemoveAssetsDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RemoveAssetsDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "RemoveAssetsDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "RemoveAssetsDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return RemoveAssetsDto( + assetIds: json[r'assetIds'] is List + ? (json[r'assetIds'] as List).cast() + : const [], + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = RemoveAssetsDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = RemoveAssetsDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RemoveAssetsDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = RemoveAssetsDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'assetIds', + }; +} + diff --git a/mobile/openapi/lib/model/search_asset_dto.dart b/mobile/openapi/lib/model/search_asset_dto.dart new file mode 100644 index 000000000..d90682750 --- /dev/null +++ b/mobile/openapi/lib/model/search_asset_dto.dart @@ -0,0 +1,111 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class SearchAssetDto { + /// Returns a new [SearchAssetDto] instance. + SearchAssetDto({ + required this.searchTerm, + }); + + String searchTerm; + + @override + bool operator ==(Object other) => identical(this, other) || other is SearchAssetDto && + other.searchTerm == searchTerm; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (searchTerm.hashCode); + + @override + String toString() => 'SearchAssetDto[searchTerm=$searchTerm]'; + + Map toJson() { + final _json = {}; + _json[r'searchTerm'] = searchTerm; + return _json; + } + + /// Returns a new [SearchAssetDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static SearchAssetDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "SearchAssetDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "SearchAssetDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return SearchAssetDto( + searchTerm: mapValueOfType(json, r'searchTerm')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = SearchAssetDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = SearchAssetDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of SearchAssetDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = SearchAssetDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'searchTerm', + }; +} + diff --git a/mobile/openapi/lib/model/server_info_response_dto.dart b/mobile/openapi/lib/model/server_info_response_dto.dart new file mode 100644 index 000000000..0bc23439c --- /dev/null +++ b/mobile/openapi/lib/model/server_info_response_dto.dart @@ -0,0 +1,159 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ServerInfoResponseDto { + /// Returns a new [ServerInfoResponseDto] instance. + ServerInfoResponseDto({ + required this.diskSizeRaw, + required this.diskUseRaw, + required this.diskAvailableRaw, + required this.diskUsagePercentage, + required this.diskSize, + required this.diskUse, + required this.diskAvailable, + }); + + int diskSizeRaw; + + int diskUseRaw; + + int diskAvailableRaw; + + double diskUsagePercentage; + + String diskSize; + + String diskUse; + + String diskAvailable; + + @override + bool operator ==(Object other) => identical(this, other) || other is ServerInfoResponseDto && + other.diskSizeRaw == diskSizeRaw && + other.diskUseRaw == diskUseRaw && + other.diskAvailableRaw == diskAvailableRaw && + other.diskUsagePercentage == diskUsagePercentage && + other.diskSize == diskSize && + other.diskUse == diskUse && + other.diskAvailable == diskAvailable; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (diskSizeRaw.hashCode) + + (diskUseRaw.hashCode) + + (diskAvailableRaw.hashCode) + + (diskUsagePercentage.hashCode) + + (diskSize.hashCode) + + (diskUse.hashCode) + + (diskAvailable.hashCode); + + @override + String toString() => 'ServerInfoResponseDto[diskSizeRaw=$diskSizeRaw, diskUseRaw=$diskUseRaw, diskAvailableRaw=$diskAvailableRaw, diskUsagePercentage=$diskUsagePercentage, diskSize=$diskSize, diskUse=$diskUse, diskAvailable=$diskAvailable]'; + + Map toJson() { + final _json = {}; + _json[r'diskSizeRaw'] = diskSizeRaw; + _json[r'diskUseRaw'] = diskUseRaw; + _json[r'diskAvailableRaw'] = diskAvailableRaw; + _json[r'diskUsagePercentage'] = diskUsagePercentage; + _json[r'diskSize'] = diskSize; + _json[r'diskUse'] = diskUse; + _json[r'diskAvailable'] = diskAvailable; + return _json; + } + + /// Returns a new [ServerInfoResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ServerInfoResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "ServerInfoResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "ServerInfoResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return ServerInfoResponseDto( + diskSizeRaw: mapValueOfType(json, r'diskSizeRaw')!, + diskUseRaw: mapValueOfType(json, r'diskUseRaw')!, + diskAvailableRaw: mapValueOfType(json, r'diskAvailableRaw')!, + diskUsagePercentage: mapValueOfType(json, r'diskUsagePercentage')!, + diskSize: mapValueOfType(json, r'diskSize')!, + diskUse: mapValueOfType(json, r'diskUse')!, + diskAvailable: mapValueOfType(json, r'diskAvailable')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = ServerInfoResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ServerInfoResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ServerInfoResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ServerInfoResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'diskSizeRaw', + 'diskUseRaw', + 'diskAvailableRaw', + 'diskUsagePercentage', + 'diskSize', + 'diskUse', + 'diskAvailable', + }; +} + diff --git a/mobile/openapi/lib/model/server_ping_response.dart b/mobile/openapi/lib/model/server_ping_response.dart new file mode 100644 index 000000000..56af4fa5b --- /dev/null +++ b/mobile/openapi/lib/model/server_ping_response.dart @@ -0,0 +1,111 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ServerPingResponse { + /// Returns a new [ServerPingResponse] instance. + ServerPingResponse({ + required this.res, + }); + + String res; + + @override + bool operator ==(Object other) => identical(this, other) || other is ServerPingResponse && + other.res == res; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (res.hashCode); + + @override + String toString() => 'ServerPingResponse[res=$res]'; + + Map toJson() { + final _json = {}; + _json[r'res'] = res; + return _json; + } + + /// Returns a new [ServerPingResponse] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ServerPingResponse? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "ServerPingResponse[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "ServerPingResponse[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return ServerPingResponse( + res: mapValueOfType(json, r'res')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = ServerPingResponse.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ServerPingResponse.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ServerPingResponse-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ServerPingResponse.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'res', + }; +} + diff --git a/mobile/openapi/lib/model/server_version_reponse_dto.dart b/mobile/openapi/lib/model/server_version_reponse_dto.dart new file mode 100644 index 000000000..72caaf194 --- /dev/null +++ b/mobile/openapi/lib/model/server_version_reponse_dto.dart @@ -0,0 +1,135 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ServerVersionReponseDto { + /// Returns a new [ServerVersionReponseDto] instance. + ServerVersionReponseDto({ + required this.major, + required this.minor, + required this.patch_, + required this.build, + }); + + int major; + + int minor; + + int patch_; + + int build; + + @override + bool operator ==(Object other) => identical(this, other) || other is ServerVersionReponseDto && + other.major == major && + other.minor == minor && + other.patch_ == patch_ && + other.build == build; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (major.hashCode) + + (minor.hashCode) + + (patch_.hashCode) + + (build.hashCode); + + @override + String toString() => 'ServerVersionReponseDto[major=$major, minor=$minor, patch_=$patch_, build=$build]'; + + Map toJson() { + final _json = {}; + _json[r'major'] = major; + _json[r'minor'] = minor; + _json[r'patch'] = patch_; + _json[r'build'] = build; + return _json; + } + + /// Returns a new [ServerVersionReponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ServerVersionReponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "ServerVersionReponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "ServerVersionReponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return ServerVersionReponseDto( + major: mapValueOfType(json, r'major')!, + minor: mapValueOfType(json, r'minor')!, + patch_: mapValueOfType(json, r'patch')!, + build: mapValueOfType(json, r'build')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = ServerVersionReponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ServerVersionReponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ServerVersionReponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ServerVersionReponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'major', + 'minor', + 'patch', + 'build', + }; +} + diff --git a/mobile/openapi/lib/model/sign_up_dto.dart b/mobile/openapi/lib/model/sign_up_dto.dart new file mode 100644 index 000000000..dc027a3ce --- /dev/null +++ b/mobile/openapi/lib/model/sign_up_dto.dart @@ -0,0 +1,135 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class SignUpDto { + /// Returns a new [SignUpDto] instance. + SignUpDto({ + required this.email, + required this.password, + required this.firstName, + required this.lastName, + }); + + String email; + + String password; + + String firstName; + + String lastName; + + @override + bool operator ==(Object other) => identical(this, other) || other is SignUpDto && + other.email == email && + other.password == password && + other.firstName == firstName && + other.lastName == lastName; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (email.hashCode) + + (password.hashCode) + + (firstName.hashCode) + + (lastName.hashCode); + + @override + String toString() => 'SignUpDto[email=$email, password=$password, firstName=$firstName, lastName=$lastName]'; + + Map toJson() { + final _json = {}; + _json[r'email'] = email; + _json[r'password'] = password; + _json[r'firstName'] = firstName; + _json[r'lastName'] = lastName; + return _json; + } + + /// Returns a new [SignUpDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static SignUpDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "SignUpDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "SignUpDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return SignUpDto( + email: mapValueOfType(json, r'email')!, + password: mapValueOfType(json, r'password')!, + firstName: mapValueOfType(json, r'firstName')!, + lastName: mapValueOfType(json, r'lastName')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = SignUpDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = SignUpDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of SignUpDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = SignUpDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'email', + 'password', + 'firstName', + 'lastName', + }; +} + diff --git a/mobile/openapi/lib/model/smart_info_response_dto.dart b/mobile/openapi/lib/model/smart_info_response_dto.dart new file mode 100644 index 000000000..e291cf13e --- /dev/null +++ b/mobile/openapi/lib/model/smart_info_response_dto.dart @@ -0,0 +1,146 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class SmartInfoResponseDto { + /// Returns a new [SmartInfoResponseDto] instance. + SmartInfoResponseDto({ + this.id, + this.tags = const [], + this.objects = const [], + }); + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? id; + + List? tags; + + List? objects; + + @override + bool operator ==(Object other) => identical(this, other) || other is SmartInfoResponseDto && + other.id == id && + other.tags == tags && + other.objects == objects; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id == null ? 0 : id!.hashCode) + + (tags == null ? 0 : tags!.hashCode) + + (objects == null ? 0 : objects!.hashCode); + + @override + String toString() => 'SmartInfoResponseDto[id=$id, tags=$tags, objects=$objects]'; + + Map toJson() { + final _json = {}; + if (id != null) { + _json[r'id'] = id; + } else { + _json[r'id'] = null; + } + if (tags != null) { + _json[r'tags'] = tags; + } else { + _json[r'tags'] = null; + } + if (objects != null) { + _json[r'objects'] = objects; + } else { + _json[r'objects'] = null; + } + return _json; + } + + /// Returns a new [SmartInfoResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static SmartInfoResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "SmartInfoResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "SmartInfoResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return SmartInfoResponseDto( + id: mapValueOfType(json, r'id'), + tags: json[r'tags'] is List + ? (json[r'tags'] as List).cast() + : const [], + objects: json[r'objects'] is List + ? (json[r'objects'] as List).cast() + : const [], + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = SmartInfoResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = SmartInfoResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of SmartInfoResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = SmartInfoResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/update_album_dto.dart b/mobile/openapi/lib/model/update_album_dto.dart new file mode 100644 index 000000000..74f680b18 --- /dev/null +++ b/mobile/openapi/lib/model/update_album_dto.dart @@ -0,0 +1,119 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class UpdateAlbumDto { + /// Returns a new [UpdateAlbumDto] instance. + UpdateAlbumDto({ + required this.albumName, + required this.ownerId, + }); + + String albumName; + + String ownerId; + + @override + bool operator ==(Object other) => identical(this, other) || other is UpdateAlbumDto && + other.albumName == albumName && + other.ownerId == ownerId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (albumName.hashCode) + + (ownerId.hashCode); + + @override + String toString() => 'UpdateAlbumDto[albumName=$albumName, ownerId=$ownerId]'; + + Map toJson() { + final _json = {}; + _json[r'albumName'] = albumName; + _json[r'ownerId'] = ownerId; + return _json; + } + + /// Returns a new [UpdateAlbumDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static UpdateAlbumDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "UpdateAlbumDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "UpdateAlbumDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return UpdateAlbumDto( + albumName: mapValueOfType(json, r'albumName')!, + ownerId: mapValueOfType(json, r'ownerId')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = UpdateAlbumDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UpdateAlbumDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of UpdateAlbumDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UpdateAlbumDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'albumName', + 'ownerId', + }; +} + diff --git a/mobile/openapi/lib/model/update_device_info_dto.dart b/mobile/openapi/lib/model/update_device_info_dto.dart new file mode 100644 index 000000000..c11a2df56 --- /dev/null +++ b/mobile/openapi/lib/model/update_device_info_dto.dart @@ -0,0 +1,136 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class UpdateDeviceInfoDto { + /// Returns a new [UpdateDeviceInfoDto] instance. + UpdateDeviceInfoDto({ + required this.deviceType, + required this.deviceId, + this.isAutoBackup, + }); + + DeviceTypeEnum deviceType; + + String deviceId; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? isAutoBackup; + + @override + bool operator ==(Object other) => identical(this, other) || other is UpdateDeviceInfoDto && + other.deviceType == deviceType && + other.deviceId == deviceId && + other.isAutoBackup == isAutoBackup; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (deviceType.hashCode) + + (deviceId.hashCode) + + (isAutoBackup == null ? 0 : isAutoBackup!.hashCode); + + @override + String toString() => 'UpdateDeviceInfoDto[deviceType=$deviceType, deviceId=$deviceId, isAutoBackup=$isAutoBackup]'; + + Map toJson() { + final _json = {}; + _json[r'deviceType'] = deviceType; + _json[r'deviceId'] = deviceId; + if (isAutoBackup != null) { + _json[r'isAutoBackup'] = isAutoBackup; + } else { + _json[r'isAutoBackup'] = null; + } + return _json; + } + + /// Returns a new [UpdateDeviceInfoDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static UpdateDeviceInfoDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "UpdateDeviceInfoDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "UpdateDeviceInfoDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return UpdateDeviceInfoDto( + deviceType: DeviceTypeEnum.fromJson(json[r'deviceType'])!, + deviceId: mapValueOfType(json, r'deviceId')!, + isAutoBackup: mapValueOfType(json, r'isAutoBackup'), + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = UpdateDeviceInfoDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UpdateDeviceInfoDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of UpdateDeviceInfoDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UpdateDeviceInfoDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'deviceType', + 'deviceId', + }; +} + diff --git a/mobile/openapi/lib/model/update_user_dto.dart b/mobile/openapi/lib/model/update_user_dto.dart new file mode 100644 index 000000000..d91de3aa0 --- /dev/null +++ b/mobile/openapi/lib/model/update_user_dto.dart @@ -0,0 +1,213 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class UpdateUserDto { + /// Returns a new [UpdateUserDto] instance. + UpdateUserDto({ + required this.id, + this.password, + this.firstName, + this.lastName, + this.isAdmin, + this.shouldChangePassword, + this.profileImagePath, + }); + + String id; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? password; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? firstName; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? lastName; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? isAdmin; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? shouldChangePassword; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? profileImagePath; + + @override + bool operator ==(Object other) => identical(this, other) || other is UpdateUserDto && + other.id == id && + other.password == password && + other.firstName == firstName && + other.lastName == lastName && + other.isAdmin == isAdmin && + other.shouldChangePassword == shouldChangePassword && + other.profileImagePath == profileImagePath; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (password == null ? 0 : password!.hashCode) + + (firstName == null ? 0 : firstName!.hashCode) + + (lastName == null ? 0 : lastName!.hashCode) + + (isAdmin == null ? 0 : isAdmin!.hashCode) + + (shouldChangePassword == null ? 0 : shouldChangePassword!.hashCode) + + (profileImagePath == null ? 0 : profileImagePath!.hashCode); + + @override + String toString() => 'UpdateUserDto[id=$id, password=$password, firstName=$firstName, lastName=$lastName, isAdmin=$isAdmin, shouldChangePassword=$shouldChangePassword, profileImagePath=$profileImagePath]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + if (password != null) { + _json[r'password'] = password; + } else { + _json[r'password'] = null; + } + if (firstName != null) { + _json[r'firstName'] = firstName; + } else { + _json[r'firstName'] = null; + } + if (lastName != null) { + _json[r'lastName'] = lastName; + } else { + _json[r'lastName'] = null; + } + if (isAdmin != null) { + _json[r'isAdmin'] = isAdmin; + } else { + _json[r'isAdmin'] = null; + } + if (shouldChangePassword != null) { + _json[r'shouldChangePassword'] = shouldChangePassword; + } else { + _json[r'shouldChangePassword'] = null; + } + if (profileImagePath != null) { + _json[r'profileImagePath'] = profileImagePath; + } else { + _json[r'profileImagePath'] = null; + } + return _json; + } + + /// Returns a new [UpdateUserDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static UpdateUserDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "UpdateUserDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "UpdateUserDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return UpdateUserDto( + id: mapValueOfType(json, r'id')!, + password: mapValueOfType(json, r'password'), + firstName: mapValueOfType(json, r'firstName'), + lastName: mapValueOfType(json, r'lastName'), + isAdmin: mapValueOfType(json, r'isAdmin'), + shouldChangePassword: mapValueOfType(json, r'shouldChangePassword'), + profileImagePath: mapValueOfType(json, r'profileImagePath'), + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = UpdateUserDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UpdateUserDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of UpdateUserDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UpdateUserDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + }; +} + diff --git a/mobile/openapi/lib/model/user_count_response_dto.dart b/mobile/openapi/lib/model/user_count_response_dto.dart new file mode 100644 index 000000000..ba11a4c36 --- /dev/null +++ b/mobile/openapi/lib/model/user_count_response_dto.dart @@ -0,0 +1,111 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class UserCountResponseDto { + /// Returns a new [UserCountResponseDto] instance. + UserCountResponseDto({ + required this.userCount, + }); + + int userCount; + + @override + bool operator ==(Object other) => identical(this, other) || other is UserCountResponseDto && + other.userCount == userCount; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (userCount.hashCode); + + @override + String toString() => 'UserCountResponseDto[userCount=$userCount]'; + + Map toJson() { + final _json = {}; + _json[r'userCount'] = userCount; + return _json; + } + + /// Returns a new [UserCountResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static UserCountResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "UserCountResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "UserCountResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return UserCountResponseDto( + userCount: mapValueOfType(json, r'userCount')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = UserCountResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UserCountResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of UserCountResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UserCountResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'userCount', + }; +} + diff --git a/mobile/openapi/lib/model/user_response_dto.dart b/mobile/openapi/lib/model/user_response_dto.dart new file mode 100644 index 000000000..740808ce2 --- /dev/null +++ b/mobile/openapi/lib/model/user_response_dto.dart @@ -0,0 +1,167 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class UserResponseDto { + /// Returns a new [UserResponseDto] instance. + UserResponseDto({ + required this.id, + required this.email, + required this.firstName, + required this.lastName, + required this.createdAt, + required this.profileImagePath, + required this.shouldChangePassword, + required this.isAdmin, + }); + + String id; + + String email; + + String firstName; + + String lastName; + + String createdAt; + + String profileImagePath; + + bool shouldChangePassword; + + bool isAdmin; + + @override + bool operator ==(Object other) => identical(this, other) || other is UserResponseDto && + other.id == id && + other.email == email && + other.firstName == firstName && + other.lastName == lastName && + other.createdAt == createdAt && + other.profileImagePath == profileImagePath && + other.shouldChangePassword == shouldChangePassword && + other.isAdmin == isAdmin; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (email.hashCode) + + (firstName.hashCode) + + (lastName.hashCode) + + (createdAt.hashCode) + + (profileImagePath.hashCode) + + (shouldChangePassword.hashCode) + + (isAdmin.hashCode); + + @override + String toString() => 'UserResponseDto[id=$id, email=$email, firstName=$firstName, lastName=$lastName, createdAt=$createdAt, profileImagePath=$profileImagePath, shouldChangePassword=$shouldChangePassword, isAdmin=$isAdmin]'; + + Map toJson() { + final _json = {}; + _json[r'id'] = id; + _json[r'email'] = email; + _json[r'firstName'] = firstName; + _json[r'lastName'] = lastName; + _json[r'createdAt'] = createdAt; + _json[r'profileImagePath'] = profileImagePath; + _json[r'shouldChangePassword'] = shouldChangePassword; + _json[r'isAdmin'] = isAdmin; + return _json; + } + + /// Returns a new [UserResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static UserResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "UserResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "UserResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return UserResponseDto( + id: mapValueOfType(json, r'id')!, + email: mapValueOfType(json, r'email')!, + firstName: mapValueOfType(json, r'firstName')!, + lastName: mapValueOfType(json, r'lastName')!, + createdAt: mapValueOfType(json, r'createdAt')!, + profileImagePath: mapValueOfType(json, r'profileImagePath')!, + shouldChangePassword: mapValueOfType(json, r'shouldChangePassword')!, + isAdmin: mapValueOfType(json, r'isAdmin')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = UserResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UserResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of UserResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = UserResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'email', + 'firstName', + 'lastName', + 'createdAt', + 'profileImagePath', + 'shouldChangePassword', + 'isAdmin', + }; +} + diff --git a/mobile/openapi/lib/model/validate_access_token_response_dto.dart b/mobile/openapi/lib/model/validate_access_token_response_dto.dart new file mode 100644 index 000000000..b3f9f9735 --- /dev/null +++ b/mobile/openapi/lib/model/validate_access_token_response_dto.dart @@ -0,0 +1,111 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ValidateAccessTokenResponseDto { + /// Returns a new [ValidateAccessTokenResponseDto] instance. + ValidateAccessTokenResponseDto({ + required this.authStatus, + }); + + bool authStatus; + + @override + bool operator ==(Object other) => identical(this, other) || other is ValidateAccessTokenResponseDto && + other.authStatus == authStatus; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (authStatus.hashCode); + + @override + String toString() => 'ValidateAccessTokenResponseDto[authStatus=$authStatus]'; + + Map toJson() { + final _json = {}; + _json[r'authStatus'] = authStatus; + return _json; + } + + /// Returns a new [ValidateAccessTokenResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ValidateAccessTokenResponseDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "ValidateAccessTokenResponseDto[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "ValidateAccessTokenResponseDto[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return ValidateAccessTokenResponseDto( + authStatus: mapValueOfType(json, r'authStatus')!, + ); + } + return null; + } + + static List? listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = ValidateAccessTokenResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ValidateAccessTokenResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ValidateAccessTokenResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ValidateAccessTokenResponseDto.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'authStatus', + }; +} + diff --git a/mobile/openapi/pubspec.lock b/mobile/openapi/pubspec.lock new file mode 100644 index 000000000..e4c9e2004 --- /dev/null +++ b/mobile/openapi/pubspec.lock @@ -0,0 +1,355 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "31.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.0" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.9.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.5" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + coverage: + dependency: transitive + description: + name: coverage + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.4" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.11" + meta: + dependency: "direct main" + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.10" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + test: + dependency: "direct dev" + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "1.17.12" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.3" + test_core: + dependency: transitive + description: + name: test_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.2" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + vm_service: + dependency: transitive + description: + name: vm_service + url: "https://pub.dartlang.org" + source: hosted + version: "7.5.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" +sdks: + dart: ">=2.16.0 <3.0.0" diff --git a/mobile/openapi/pubspec.yaml b/mobile/openapi/pubspec.yaml new file mode 100644 index 000000000..00043ba66 --- /dev/null +++ b/mobile/openapi/pubspec.yaml @@ -0,0 +1,16 @@ +# +# AUTO-GENERATED FILE, DO NOT MODIFY! +# + +name: 'openapi' +version: '1.0.0' +description: 'OpenAPI API client' +homepage: 'homepage' +environment: + sdk: '>=2.12.0 <3.0.0' +dependencies: + http: '>=0.13.0 <0.14.0' + intl: '^0.17.0' + meta: '^1.1.8' +dev_dependencies: + test: '>=1.16.0 <1.18.0' diff --git a/mobile/openapi/test/add_assets_dto_test.dart b/mobile/openapi/test/add_assets_dto_test.dart new file mode 100644 index 000000000..ec660c400 --- /dev/null +++ b/mobile/openapi/test/add_assets_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for AddAssetsDto +void main() { + // final instance = AddAssetsDto(); + + group('test AddAssetsDto', () { + // List assetIds (default value: const []) + test('to test the property `assetIds`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/add_users_dto_test.dart b/mobile/openapi/test/add_users_dto_test.dart new file mode 100644 index 000000000..3dadfd8b4 --- /dev/null +++ b/mobile/openapi/test/add_users_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for AddUsersDto +void main() { + // final instance = AddUsersDto(); + + group('test AddUsersDto', () { + // List sharedUserIds (default value: const []) + test('to test the property `sharedUserIds`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/admin_signup_response_dto_test.dart b/mobile/openapi/test/admin_signup_response_dto_test.dart new file mode 100644 index 000000000..d71763a32 --- /dev/null +++ b/mobile/openapi/test/admin_signup_response_dto_test.dart @@ -0,0 +1,47 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for AdminSignupResponseDto +void main() { + // final instance = AdminSignupResponseDto(); + + group('test AdminSignupResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String email + test('to test the property `email`', () async { + // TODO + }); + + // String firstName + test('to test the property `firstName`', () async { + // TODO + }); + + // String lastName + test('to test the property `lastName`', () async { + // TODO + }); + + // String createdAt + test('to test the property `createdAt`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/album_api_test.dart b/mobile/openapi/test/album_api_test.dart new file mode 100644 index 000000000..f13e7fa76 --- /dev/null +++ b/mobile/openapi/test/album_api_test.dart @@ -0,0 +1,66 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + + +/// tests for AlbumApi +void main() { + // final instance = AlbumApi(); + + group('tests for AlbumApi', () { + //Future addAssetsToAlbum(String albumId, AddAssetsDto addAssetsDto) async + test('test addAssetsToAlbum', () async { + // TODO + }); + + //Future addUsersToAlbum(String albumId, AddUsersDto addUsersDto) async + test('test addUsersToAlbum', () async { + // TODO + }); + + //Future createAlbum(CreateAlbumDto createAlbumDto) async + test('test createAlbum', () async { + // TODO + }); + + //Future deleteAlbum(String albumId) async + test('test deleteAlbum', () async { + // TODO + }); + + //Future getAlbumInfo(String albumId) async + test('test getAlbumInfo', () async { + // TODO + }); + + //Future> getAllAlbums({ bool shared }) async + test('test getAllAlbums', () async { + // TODO + }); + + //Future removeAssetFromAlbum(String albumId, RemoveAssetsDto removeAssetsDto) async + test('test removeAssetFromAlbum', () async { + // TODO + }); + + //Future removeUserFromAlbum(String albumId, String userId) async + test('test removeUserFromAlbum', () async { + // TODO + }); + + //Future updateAlbumInfo(String albumId, UpdateAlbumDto updateAlbumDto) async + test('test updateAlbumInfo', () async { + // TODO + }); + + }); +} diff --git a/mobile/openapi/test/album_response_dto_test.dart b/mobile/openapi/test/album_response_dto_test.dart new file mode 100644 index 000000000..d1ad631e9 --- /dev/null +++ b/mobile/openapi/test/album_response_dto_test.dart @@ -0,0 +1,62 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for AlbumResponseDto +void main() { + // final instance = AlbumResponseDto(); + + group('test AlbumResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String ownerId + test('to test the property `ownerId`', () async { + // TODO + }); + + // String albumName + test('to test the property `albumName`', () async { + // TODO + }); + + // String createdAt + test('to test the property `createdAt`', () async { + // TODO + }); + + // String albumThumbnailAssetId + test('to test the property `albumThumbnailAssetId`', () async { + // TODO + }); + + // bool shared + test('to test the property `shared`', () async { + // TODO + }); + + // List sharedUsers (default value: const []) + test('to test the property `sharedUsers`', () async { + // TODO + }); + + // List assets (default value: const []) + test('to test the property `assets`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/asset_api_test.dart b/mobile/openapi/test/asset_api_test.dart new file mode 100644 index 000000000..b855f19ea --- /dev/null +++ b/mobile/openapi/test/asset_api_test.dart @@ -0,0 +1,102 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + + +/// tests for AssetApi +void main() { + // final instance = AssetApi(); + + group('tests for AssetApi', () { + // + // + // Check duplicated asset before uploading - for Web upload used + // + //Future checkDuplicateAsset(CheckDuplicateAssetDto checkDuplicateAssetDto) async + test('test checkDuplicateAsset', () async { + // TODO + }); + + //Future deleteAsset(DeleteAssetDto deleteAssetDto) async + test('test deleteAsset', () async { + // TODO + }); + + //Future downloadFile(String aid, String did, { bool isThumb, bool isWeb }) async + test('test downloadFile', () async { + // TODO + }); + + // + // + // Get all AssetEntity belong to the user + // + //Future> getAllAssets() async + test('test getAllAssets', () async { + // TODO + }); + + // + // + // Get a single asset's information + // + //Future getAssetById(String assetId) async + test('test getAssetById', () async { + // TODO + }); + + //Future> getAssetSearchTerms() async + test('test getAssetSearchTerms', () async { + // TODO + }); + + //Future getAssetThumbnail(String assetId) async + test('test getAssetThumbnail', () async { + // TODO + }); + + //Future> getCuratedLocations() async + test('test getCuratedLocations', () async { + // TODO + }); + + //Future> getCuratedObjects() async + test('test getCuratedObjects', () async { + // TODO + }); + + // + // + // Get all asset of a device that are in the database, ID only. + // + //Future> getUserAssetsByDeviceId(String deviceId) async + test('test getUserAssetsByDeviceId', () async { + // TODO + }); + + //Future> searchAsset(SearchAssetDto searchAssetDto) async + test('test searchAsset', () async { + // TODO + }); + + //Future serveFile(String aid, String did, { bool isThumb, bool isWeb }) async + test('test serveFile', () async { + // TODO + }); + + //Future uploadFile(MultipartFile assetData) async + test('test uploadFile', () async { + // TODO + }); + + }); +} diff --git a/mobile/openapi/test/asset_file_upload_response_dto_test.dart b/mobile/openapi/test/asset_file_upload_response_dto_test.dart new file mode 100644 index 000000000..c53ca650c --- /dev/null +++ b/mobile/openapi/test/asset_file_upload_response_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for AssetFileUploadResponseDto +void main() { + // final instance = AssetFileUploadResponseDto(); + + group('test AssetFileUploadResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/asset_response_dto_test.dart b/mobile/openapi/test/asset_response_dto_test.dart new file mode 100644 index 000000000..95e9527bd --- /dev/null +++ b/mobile/openapi/test/asset_response_dto_test.dart @@ -0,0 +1,102 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for AssetResponseDto +void main() { + // final instance = AssetResponseDto(); + + group('test AssetResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String deviceAssetId + test('to test the property `deviceAssetId`', () async { + // TODO + }); + + // String ownerId + test('to test the property `ownerId`', () async { + // TODO + }); + + // String deviceId + test('to test the property `deviceId`', () async { + // TODO + }); + + // String type + test('to test the property `type`', () async { + // TODO + }); + + // String originalPath + test('to test the property `originalPath`', () async { + // TODO + }); + + // String resizePath + test('to test the property `resizePath`', () async { + // TODO + }); + + // String createdAt + test('to test the property `createdAt`', () async { + // TODO + }); + + // String modifiedAt + test('to test the property `modifiedAt`', () async { + // TODO + }); + + // bool isFavorite + test('to test the property `isFavorite`', () async { + // TODO + }); + + // String mimeType + test('to test the property `mimeType`', () async { + // TODO + }); + + // String duration + test('to test the property `duration`', () async { + // TODO + }); + + // String webpPath + test('to test the property `webpPath`', () async { + // TODO + }); + + // String encodedVideoPath + test('to test the property `encodedVideoPath`', () async { + // TODO + }); + + // ExifResponseDto exifInfo + test('to test the property `exifInfo`', () async { + // TODO + }); + + // SmartInfoResponseDto smartInfo + test('to test the property `smartInfo`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/asset_type_enum_test.dart b/mobile/openapi/test/asset_type_enum_test.dart new file mode 100644 index 000000000..a826ee679 --- /dev/null +++ b/mobile/openapi/test/asset_type_enum_test.dart @@ -0,0 +1,21 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for AssetTypeEnum +void main() { + + group('test AssetTypeEnum', () { + + }); + +} diff --git a/mobile/openapi/test/authentication_api_test.dart b/mobile/openapi/test/authentication_api_test.dart new file mode 100644 index 000000000..2ab9205f8 --- /dev/null +++ b/mobile/openapi/test/authentication_api_test.dart @@ -0,0 +1,36 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + + +/// tests for AuthenticationApi +void main() { + // final instance = AuthenticationApi(); + + group('tests for AuthenticationApi', () { + //Future adminSignUp(SignUpDto signUpDto) async + test('test adminSignUp', () async { + // TODO + }); + + //Future login(LoginCredentialDto loginCredentialDto) async + test('test login', () async { + // TODO + }); + + //Future validateAccessToken() async + test('test validateAccessToken', () async { + // TODO + }); + + }); +} diff --git a/mobile/openapi/test/check_duplicate_asset_dto_test.dart b/mobile/openapi/test/check_duplicate_asset_dto_test.dart new file mode 100644 index 000000000..2e8572da4 --- /dev/null +++ b/mobile/openapi/test/check_duplicate_asset_dto_test.dart @@ -0,0 +1,32 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CheckDuplicateAssetDto +void main() { + // final instance = CheckDuplicateAssetDto(); + + group('test CheckDuplicateAssetDto', () { + // String deviceAssetId + test('to test the property `deviceAssetId`', () async { + // TODO + }); + + // String deviceId + test('to test the property `deviceId`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/check_duplicate_asset_response_dto_test.dart b/mobile/openapi/test/check_duplicate_asset_response_dto_test.dart new file mode 100644 index 000000000..fbe09b776 --- /dev/null +++ b/mobile/openapi/test/check_duplicate_asset_response_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CheckDuplicateAssetResponseDto +void main() { + // final instance = CheckDuplicateAssetResponseDto(); + + group('test CheckDuplicateAssetResponseDto', () { + // bool isExist + test('to test the property `isExist`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/create_album_dto_test.dart b/mobile/openapi/test/create_album_dto_test.dart new file mode 100644 index 000000000..48263d393 --- /dev/null +++ b/mobile/openapi/test/create_album_dto_test.dart @@ -0,0 +1,37 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CreateAlbumDto +void main() { + // final instance = CreateAlbumDto(); + + group('test CreateAlbumDto', () { + // String albumName + test('to test the property `albumName`', () async { + // TODO + }); + + // List sharedWithUserIds (default value: const []) + test('to test the property `sharedWithUserIds`', () async { + // TODO + }); + + // List assetIds (default value: const []) + test('to test the property `assetIds`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/create_device_info_dto_test.dart b/mobile/openapi/test/create_device_info_dto_test.dart new file mode 100644 index 000000000..fe250e7e7 --- /dev/null +++ b/mobile/openapi/test/create_device_info_dto_test.dart @@ -0,0 +1,37 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CreateDeviceInfoDto +void main() { + // final instance = CreateDeviceInfoDto(); + + group('test CreateDeviceInfoDto', () { + // String deviceId + test('to test the property `deviceId`', () async { + // TODO + }); + + // String deviceType + test('to test the property `deviceType`', () async { + // TODO + }); + + // bool isAutoBackup + test('to test the property `isAutoBackup`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/create_profile_image_response_dto_test.dart b/mobile/openapi/test/create_profile_image_response_dto_test.dart new file mode 100644 index 000000000..83fee5b29 --- /dev/null +++ b/mobile/openapi/test/create_profile_image_response_dto_test.dart @@ -0,0 +1,32 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CreateProfileImageResponseDto +void main() { + // final instance = CreateProfileImageResponseDto(); + + group('test CreateProfileImageResponseDto', () { + // String userId + test('to test the property `userId`', () async { + // TODO + }); + + // String profileImagePath + test('to test the property `profileImagePath`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/create_user_dto_test.dart b/mobile/openapi/test/create_user_dto_test.dart new file mode 100644 index 000000000..8e2e7d445 --- /dev/null +++ b/mobile/openapi/test/create_user_dto_test.dart @@ -0,0 +1,42 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CreateUserDto +void main() { + // final instance = CreateUserDto(); + + group('test CreateUserDto', () { + // String email + test('to test the property `email`', () async { + // TODO + }); + + // String password + test('to test the property `password`', () async { + // TODO + }); + + // String firstName + test('to test the property `firstName`', () async { + // TODO + }); + + // String lastName + test('to test the property `lastName`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/curated_locations_response_dto_test.dart b/mobile/openapi/test/curated_locations_response_dto_test.dart new file mode 100644 index 000000000..da4cccf3d --- /dev/null +++ b/mobile/openapi/test/curated_locations_response_dto_test.dart @@ -0,0 +1,47 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CuratedLocationsResponseDto +void main() { + // final instance = CuratedLocationsResponseDto(); + + group('test CuratedLocationsResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String city + test('to test the property `city`', () async { + // TODO + }); + + // String resizePath + test('to test the property `resizePath`', () async { + // TODO + }); + + // String deviceAssetId + test('to test the property `deviceAssetId`', () async { + // TODO + }); + + // String deviceId + test('to test the property `deviceId`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/curated_objects_response_dto_test.dart b/mobile/openapi/test/curated_objects_response_dto_test.dart new file mode 100644 index 000000000..8ef640bd9 --- /dev/null +++ b/mobile/openapi/test/curated_objects_response_dto_test.dart @@ -0,0 +1,47 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for CuratedObjectsResponseDto +void main() { + // final instance = CuratedObjectsResponseDto(); + + group('test CuratedObjectsResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String object + test('to test the property `object`', () async { + // TODO + }); + + // String resizePath + test('to test the property `resizePath`', () async { + // TODO + }); + + // String deviceAssetId + test('to test the property `deviceAssetId`', () async { + // TODO + }); + + // String deviceId + test('to test the property `deviceId`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/delete_asset_dto_test.dart b/mobile/openapi/test/delete_asset_dto_test.dart new file mode 100644 index 000000000..4e04b65e9 --- /dev/null +++ b/mobile/openapi/test/delete_asset_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for DeleteAssetDto +void main() { + // final instance = DeleteAssetDto(); + + group('test DeleteAssetDto', () { + // List ids (default value: const []) + test('to test the property `ids`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/delete_asset_response_dto_test.dart b/mobile/openapi/test/delete_asset_response_dto_test.dart new file mode 100644 index 000000000..de09a5b31 --- /dev/null +++ b/mobile/openapi/test/delete_asset_response_dto_test.dart @@ -0,0 +1,32 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for DeleteAssetResponseDto +void main() { + // final instance = DeleteAssetResponseDto(); + + group('test DeleteAssetResponseDto', () { + // DeleteAssetStatus status + test('to test the property `status`', () async { + // TODO + }); + + // String id + test('to test the property `id`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/delete_asset_status_test.dart b/mobile/openapi/test/delete_asset_status_test.dart new file mode 100644 index 000000000..0dfc82ba6 --- /dev/null +++ b/mobile/openapi/test/delete_asset_status_test.dart @@ -0,0 +1,21 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for DeleteAssetStatus +void main() { + + group('test DeleteAssetStatus', () { + + }); + +} diff --git a/mobile/openapi/test/device_info_api_test.dart b/mobile/openapi/test/device_info_api_test.dart new file mode 100644 index 000000000..ce297de5d --- /dev/null +++ b/mobile/openapi/test/device_info_api_test.dart @@ -0,0 +1,31 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + + +/// tests for DeviceInfoApi +void main() { + // final instance = DeviceInfoApi(); + + group('tests for DeviceInfoApi', () { + //Future createDeviceInfo(CreateDeviceInfoDto createDeviceInfoDto) async + test('test createDeviceInfo', () async { + // TODO + }); + + //Future updateDeviceInfo(Object body) async + test('test updateDeviceInfo', () async { + // TODO + }); + + }); +} diff --git a/mobile/openapi/test/device_info_response_dto_test.dart b/mobile/openapi/test/device_info_response_dto_test.dart new file mode 100644 index 000000000..748f95d09 --- /dev/null +++ b/mobile/openapi/test/device_info_response_dto_test.dart @@ -0,0 +1,57 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for DeviceInfoResponseDto +void main() { + // final instance = DeviceInfoResponseDto(); + + group('test DeviceInfoResponseDto', () { + // num id + test('to test the property `id`', () async { + // TODO + }); + + // String userId + test('to test the property `userId`', () async { + // TODO + }); + + // String deviceId + test('to test the property `deviceId`', () async { + // TODO + }); + + // String deviceType + test('to test the property `deviceType`', () async { + // TODO + }); + + // String notificationToken + test('to test the property `notificationToken`', () async { + // TODO + }); + + // String createdAt + test('to test the property `createdAt`', () async { + // TODO + }); + + // bool isAutoBackup + test('to test the property `isAutoBackup`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/device_type_enum_test.dart b/mobile/openapi/test/device_type_enum_test.dart new file mode 100644 index 000000000..27b29a53e --- /dev/null +++ b/mobile/openapi/test/device_type_enum_test.dart @@ -0,0 +1,21 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for DeviceTypeEnum +void main() { + + group('test DeviceTypeEnum', () { + + }); + +} diff --git a/mobile/openapi/test/exif_response_dto_test.dart b/mobile/openapi/test/exif_response_dto_test.dart new file mode 100644 index 000000000..bf5164773 --- /dev/null +++ b/mobile/openapi/test/exif_response_dto_test.dart @@ -0,0 +1,122 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for ExifResponseDto +void main() { + // final instance = ExifResponseDto(); + + group('test ExifResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String make + test('to test the property `make`', () async { + // TODO + }); + + // String model + test('to test the property `model`', () async { + // TODO + }); + + // String imageName + test('to test the property `imageName`', () async { + // TODO + }); + + // num exifImageWidth + test('to test the property `exifImageWidth`', () async { + // TODO + }); + + // num exifImageHeight + test('to test the property `exifImageHeight`', () async { + // TODO + }); + + // num fileSizeInByte + test('to test the property `fileSizeInByte`', () async { + // TODO + }); + + // String orientation + test('to test the property `orientation`', () async { + // TODO + }); + + // DateTime dateTimeOriginal + test('to test the property `dateTimeOriginal`', () async { + // TODO + }); + + // DateTime modifyDate + test('to test the property `modifyDate`', () async { + // TODO + }); + + // String lensModel + test('to test the property `lensModel`', () async { + // TODO + }); + + // num fNumber + test('to test the property `fNumber`', () async { + // TODO + }); + + // num focalLength + test('to test the property `focalLength`', () async { + // TODO + }); + + // num iso + test('to test the property `iso`', () async { + // TODO + }); + + // num exposureTime + test('to test the property `exposureTime`', () async { + // TODO + }); + + // num latitude + test('to test the property `latitude`', () async { + // TODO + }); + + // num longitude + test('to test the property `longitude`', () async { + // TODO + }); + + // String city + test('to test the property `city`', () async { + // TODO + }); + + // String state + test('to test the property `state`', () async { + // TODO + }); + + // String country + test('to test the property `country`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/login_credential_dto_test.dart b/mobile/openapi/test/login_credential_dto_test.dart new file mode 100644 index 000000000..9995af730 --- /dev/null +++ b/mobile/openapi/test/login_credential_dto_test.dart @@ -0,0 +1,32 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for LoginCredentialDto +void main() { + // final instance = LoginCredentialDto(); + + group('test LoginCredentialDto', () { + // String email + test('to test the property `email`', () async { + // TODO + }); + + // String password + test('to test the property `password`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/login_response_dto_test.dart b/mobile/openapi/test/login_response_dto_test.dart new file mode 100644 index 000000000..f70779979 --- /dev/null +++ b/mobile/openapi/test/login_response_dto_test.dart @@ -0,0 +1,62 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for LoginResponseDto +void main() { + // final instance = LoginResponseDto(); + + group('test LoginResponseDto', () { + // String accessToken + test('to test the property `accessToken`', () async { + // TODO + }); + + // String userId + test('to test the property `userId`', () async { + // TODO + }); + + // String userEmail + test('to test the property `userEmail`', () async { + // TODO + }); + + // String firstName + test('to test the property `firstName`', () async { + // TODO + }); + + // String lastName + test('to test the property `lastName`', () async { + // TODO + }); + + // String profileImagePath + test('to test the property `profileImagePath`', () async { + // TODO + }); + + // bool isAdmin + test('to test the property `isAdmin`', () async { + // TODO + }); + + // bool shouldChangePassword + test('to test the property `shouldChangePassword`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/remove_assets_dto_test.dart b/mobile/openapi/test/remove_assets_dto_test.dart new file mode 100644 index 000000000..4e5b48bcb --- /dev/null +++ b/mobile/openapi/test/remove_assets_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for RemoveAssetsDto +void main() { + // final instance = RemoveAssetsDto(); + + group('test RemoveAssetsDto', () { + // List assetIds (default value: const []) + test('to test the property `assetIds`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/search_asset_dto_test.dart b/mobile/openapi/test/search_asset_dto_test.dart new file mode 100644 index 000000000..60021265c --- /dev/null +++ b/mobile/openapi/test/search_asset_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for SearchAssetDto +void main() { + // final instance = SearchAssetDto(); + + group('test SearchAssetDto', () { + // String searchTerm + test('to test the property `searchTerm`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/server_info_api_test.dart b/mobile/openapi/test/server_info_api_test.dart new file mode 100644 index 000000000..540f1280f --- /dev/null +++ b/mobile/openapi/test/server_info_api_test.dart @@ -0,0 +1,36 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + + +/// tests for ServerInfoApi +void main() { + // final instance = ServerInfoApi(); + + group('tests for ServerInfoApi', () { + //Future getServerInfo() async + test('test getServerInfo', () async { + // TODO + }); + + //Future getServerVersion() async + test('test getServerVersion', () async { + // TODO + }); + + //Future pingServer() async + test('test pingServer', () async { + // TODO + }); + + }); +} diff --git a/mobile/openapi/test/server_info_response_dto_test.dart b/mobile/openapi/test/server_info_response_dto_test.dart new file mode 100644 index 000000000..4deaa09a9 --- /dev/null +++ b/mobile/openapi/test/server_info_response_dto_test.dart @@ -0,0 +1,57 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for ServerInfoResponseDto +void main() { + // final instance = ServerInfoResponseDto(); + + group('test ServerInfoResponseDto', () { + // String diskSize + test('to test the property `diskSize`', () async { + // TODO + }); + + // String diskUse + test('to test the property `diskUse`', () async { + // TODO + }); + + // String diskAvailable + test('to test the property `diskAvailable`', () async { + // TODO + }); + + // num diskSizeRaw + test('to test the property `diskSizeRaw`', () async { + // TODO + }); + + // num diskUseRaw + test('to test the property `diskUseRaw`', () async { + // TODO + }); + + // num diskAvailableRaw + test('to test the property `diskAvailableRaw`', () async { + // TODO + }); + + // num diskUsagePercentage + test('to test the property `diskUsagePercentage`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/server_ping_response_test.dart b/mobile/openapi/test/server_ping_response_test.dart new file mode 100644 index 000000000..cb7268017 --- /dev/null +++ b/mobile/openapi/test/server_ping_response_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for ServerPingResponse +void main() { + // final instance = ServerPingResponse(); + + group('test ServerPingResponse', () { + // String res + test('to test the property `res`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/server_version_reponse_dto_test.dart b/mobile/openapi/test/server_version_reponse_dto_test.dart new file mode 100644 index 000000000..2c71afa99 --- /dev/null +++ b/mobile/openapi/test/server_version_reponse_dto_test.dart @@ -0,0 +1,42 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for ServerVersionReponseDto +void main() { + // final instance = ServerVersionReponseDto(); + + group('test ServerVersionReponseDto', () { + // num major + test('to test the property `major`', () async { + // TODO + }); + + // num minor + test('to test the property `minor`', () async { + // TODO + }); + + // num patch_ + test('to test the property `patch_`', () async { + // TODO + }); + + // num build + test('to test the property `build`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/sign_up_dto_test.dart b/mobile/openapi/test/sign_up_dto_test.dart new file mode 100644 index 000000000..4c4d376b8 --- /dev/null +++ b/mobile/openapi/test/sign_up_dto_test.dart @@ -0,0 +1,42 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for SignUpDto +void main() { + // final instance = SignUpDto(); + + group('test SignUpDto', () { + // String email + test('to test the property `email`', () async { + // TODO + }); + + // String password + test('to test the property `password`', () async { + // TODO + }); + + // String firstName + test('to test the property `firstName`', () async { + // TODO + }); + + // String lastName + test('to test the property `lastName`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/smart_info_response_dto_test.dart b/mobile/openapi/test/smart_info_response_dto_test.dart new file mode 100644 index 000000000..a5e901b7b --- /dev/null +++ b/mobile/openapi/test/smart_info_response_dto_test.dart @@ -0,0 +1,37 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for SmartInfoResponseDto +void main() { + // final instance = SmartInfoResponseDto(); + + group('test SmartInfoResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // List tags (default value: const []) + test('to test the property `tags`', () async { + // TODO + }); + + // List objects (default value: const []) + test('to test the property `objects`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/update_album_dto_test.dart b/mobile/openapi/test/update_album_dto_test.dart new file mode 100644 index 000000000..a03c12656 --- /dev/null +++ b/mobile/openapi/test/update_album_dto_test.dart @@ -0,0 +1,32 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for UpdateAlbumDto +void main() { + // final instance = UpdateAlbumDto(); + + group('test UpdateAlbumDto', () { + // String albumName + test('to test the property `albumName`', () async { + // TODO + }); + + // String ownerId + test('to test the property `ownerId`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/update_device_info_dto_test.dart b/mobile/openapi/test/update_device_info_dto_test.dart new file mode 100644 index 000000000..32bb95351 --- /dev/null +++ b/mobile/openapi/test/update_device_info_dto_test.dart @@ -0,0 +1,37 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for UpdateDeviceInfoDto +void main() { + // final instance = UpdateDeviceInfoDto(); + + group('test UpdateDeviceInfoDto', () { + // String deviceId + test('to test the property `deviceId`', () async { + // TODO + }); + + // String deviceType + test('to test the property `deviceType`', () async { + // TODO + }); + + // bool isAutoBackup + test('to test the property `isAutoBackup`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/update_user_dto_test.dart b/mobile/openapi/test/update_user_dto_test.dart new file mode 100644 index 000000000..3010100d8 --- /dev/null +++ b/mobile/openapi/test/update_user_dto_test.dart @@ -0,0 +1,57 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for UpdateUserDto +void main() { + // final instance = UpdateUserDto(); + + group('test UpdateUserDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String password + test('to test the property `password`', () async { + // TODO + }); + + // String firstName + test('to test the property `firstName`', () async { + // TODO + }); + + // String lastName + test('to test the property `lastName`', () async { + // TODO + }); + + // bool isAdmin + test('to test the property `isAdmin`', () async { + // TODO + }); + + // bool shouldChangePassword + test('to test the property `shouldChangePassword`', () async { + // TODO + }); + + // String profileImagePath + test('to test the property `profileImagePath`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/user_api_test.dart b/mobile/openapi/test/user_api_test.dart new file mode 100644 index 000000000..0d93508ee --- /dev/null +++ b/mobile/openapi/test/user_api_test.dart @@ -0,0 +1,56 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + + +/// tests for UserApi +void main() { + // final instance = UserApi(); + + group('tests for UserApi', () { + //Future createProfileImage(MultipartFile file) async + test('test createProfileImage', () async { + // TODO + }); + + //Future createUser(CreateUserDto createUserDto) async + test('test createUser', () async { + // TODO + }); + + //Future> getAllUsers(bool isAll) async + test('test getAllUsers', () async { + // TODO + }); + + //Future getMyUserInfo() async + test('test getMyUserInfo', () async { + // TODO + }); + + //Future getProfileImage(String userId) async + test('test getProfileImage', () async { + // TODO + }); + + //Future getUserCount() async + test('test getUserCount', () async { + // TODO + }); + + //Future updateUser(UpdateUserDto updateUserDto) async + test('test updateUser', () async { + // TODO + }); + + }); +} diff --git a/mobile/openapi/test/user_count_response_dto_test.dart b/mobile/openapi/test/user_count_response_dto_test.dart new file mode 100644 index 000000000..1f99d9511 --- /dev/null +++ b/mobile/openapi/test/user_count_response_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for UserCountResponseDto +void main() { + // final instance = UserCountResponseDto(); + + group('test UserCountResponseDto', () { + // num userCount + test('to test the property `userCount`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/user_response_dto_test.dart b/mobile/openapi/test/user_response_dto_test.dart new file mode 100644 index 000000000..861010fac --- /dev/null +++ b/mobile/openapi/test/user_response_dto_test.dart @@ -0,0 +1,62 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for UserResponseDto +void main() { + // final instance = UserResponseDto(); + + group('test UserResponseDto', () { + // String id + test('to test the property `id`', () async { + // TODO + }); + + // String email + test('to test the property `email`', () async { + // TODO + }); + + // String firstName + test('to test the property `firstName`', () async { + // TODO + }); + + // String lastName + test('to test the property `lastName`', () async { + // TODO + }); + + // String createdAt + test('to test the property `createdAt`', () async { + // TODO + }); + + // String profileImagePath + test('to test the property `profileImagePath`', () async { + // TODO + }); + + // bool shouldChangePassword + test('to test the property `shouldChangePassword`', () async { + // TODO + }); + + // bool isAdmin + test('to test the property `isAdmin`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/openapi/test/validate_access_token_response_dto_test.dart b/mobile/openapi/test/validate_access_token_response_dto_test.dart new file mode 100644 index 000000000..fff824700 --- /dev/null +++ b/mobile/openapi/test/validate_access_token_response_dto_test.dart @@ -0,0 +1,27 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for ValidateAccessTokenResponseDto +void main() { + // final instance = ValidateAccessTokenResponseDto(); + + group('test ValidateAccessTokenResponseDto', () { + // bool authStatus + test('to test the property `authStatus`', () async { + // TODO + }); + + + }); + +} diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 911cc10b1..ec0701faf 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -637,6 +637,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + openapi: + dependency: "direct main" + description: + path: openapi + relative: true + source: path + version: "1.0.0" package_config: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 6633f1146..5e284e3e6 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -48,6 +48,9 @@ dependencies: collection: ^1.16.0 http_parser: ^4.0.1 + openapi: + path: openapi + dev_dependencies: flutter_test: sdk: flutter @@ -76,3 +79,7 @@ flutter_icons: image_path_ios: "assets/immich-logo-no-outline.png" android: true # can specify file name here e.g. "ic_launcher" ios: true # can specify file name here e.g. "My-Launcher-Icon + +analyzer: + exclude: + - openapi/** diff --git a/server/apps/immich/src/api-v1/asset/asset.controller.ts b/server/apps/immich/src/api-v1/asset/asset.controller.ts index 45b554149..2a7b30ab5 100644 --- a/server/apps/immich/src/api-v1/asset/asset.controller.ts +++ b/server/apps/immich/src/api-v1/asset/asset.controller.ts @@ -19,11 +19,10 @@ import { } from '@nestjs/common'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; import { AssetService } from './asset.service'; -import { FileFieldsInterceptor, FileInterceptor } from '@nestjs/platform-express'; +import { FileInterceptor } from '@nestjs/platform-express'; import { assetUploadOption } from '../../config/asset-upload.config'; import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator'; import { ServeFileDto } from './dto/serve-file.dto'; -import { AssetEntity } from '@app/database/entities/asset.entity'; import { Response as Res } from 'express'; import { BackgroundTaskService } from '../../modules/background-task/background-task.service'; import { DeleteAssetDto } from './dto/delete-asset.dto'; @@ -43,6 +42,7 @@ import { CheckDuplicateAssetResponseDto } from './response-dto/check-duplicate-a import { AssetFileUploadDto } from './dto/asset-file-upload.dto'; import { CreateAssetDto } from './dto/create-asset.dto'; import { AssetFileUploadResponseDto } from './response-dto/asset-file-upload-response.dto'; +import { DeleteAssetResponseDto, DeleteAssetStatusEnum } from './response-dto/delete-asset-response.dto'; @UseGuards(JwtAuthGuard) @ApiBearerAuth() @@ -124,7 +124,7 @@ export class AssetController { } @Get('/searchTerm') - async getAssetSearchTerms(@GetAuthUser() authUser: AuthUserDto): Promise { + async getAssetSearchTerms(@GetAuthUser() authUser: AuthUserDto): Promise { return this.assetService.getAssetSearchTerm(authUser); } @@ -164,7 +164,10 @@ export class AssetController { } @Delete('/') - async deleteAsset(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) assetIds: DeleteAssetDto) { + async deleteAsset( + @GetAuthUser() authUser: AuthUserDto, + @Body(ValidationPipe) assetIds: DeleteAssetDto, + ): Promise { const deleteAssetList: AssetResponseDto[] = []; for (const id of assetIds.ids) { @@ -178,7 +181,7 @@ export class AssetController { const result = await this.assetService.deleteAssetById(authUser, assetIds); result.forEach((res) => { - deleteAssetList.filter((a) => a.id == res.id && res.status == 'success'); + deleteAssetList.filter((a) => a.id == res.id && res.status == DeleteAssetStatusEnum.SUCCESS); }); await this.backgroundTaskService.deleteFileOnDisk(deleteAssetList); diff --git a/server/apps/immich/src/api-v1/asset/asset.service.ts b/server/apps/immich/src/api-v1/asset/asset.service.ts index 647b45a31..e92e3c855 100644 --- a/server/apps/immich/src/api-v1/asset/asset.service.ts +++ b/server/apps/immich/src/api-v1/asset/asset.service.ts @@ -22,6 +22,7 @@ import { CuratedObjectsResponseDto } from './response-dto/curated-objects-respon import { AssetResponseDto, mapAsset } from './response-dto/asset-response.dto'; import { AssetFileUploadDto } from './dto/asset-file-upload.dto'; import { CreateAssetDto } from './dto/create-asset.dto'; +import { DeleteAssetResponseDto, DeleteAssetStatusEnum } from './response-dto/delete-asset-response.dto'; const fileInfo = promisify(stat); @@ -280,7 +281,7 @@ export class AssetService { return new StreamableFile(fileReadStream); } catch (e) { - Logger.error(`Cannot create read stream for asset ${asset.id}`, 'serveFile[IMAGE]'); + Logger.error(`Cannot create read stream for asset ${asset.id} ${JSON.stringify(e)}`, 'serveFile[IMAGE]'); throw new InternalServerErrorException( e, `Cannot read thumbnail file for asset ${asset.id} - contact your administrator`, @@ -354,8 +355,8 @@ export class AssetService { } } - public async deleteAssetById(authUser: AuthUserDto, assetIds: DeleteAssetDto) { - const result = []; + public async deleteAssetById(authUser: AuthUserDto, assetIds: DeleteAssetDto): Promise { + const result: DeleteAssetResponseDto[] = []; const target = assetIds.ids; for (const assetId of target) { @@ -367,12 +368,12 @@ export class AssetService { if (res.affected) { result.push({ id: assetId, - status: 'success', + status: DeleteAssetStatusEnum.SUCCESS, }); } else { result.push({ id: assetId, - status: 'failed', + status: DeleteAssetStatusEnum.FAILED, }); } } diff --git a/server/apps/immich/src/api-v1/asset/dto/asset-file-upload.dto.ts b/server/apps/immich/src/api-v1/asset/dto/asset-file-upload.dto.ts index ba57ee4df..25ca5a835 100644 --- a/server/apps/immich/src/api-v1/asset/dto/asset-file-upload.dto.ts +++ b/server/apps/immich/src/api-v1/asset/dto/asset-file-upload.dto.ts @@ -1,7 +1,5 @@ -import { AssetType } from '@app/database/entities/asset.entity'; import { ApiProperty } from '@nestjs/swagger'; -import { IsEnum, IsNotEmpty, IsOptional } from 'class-validator'; -import { CreateAssetDto } from './create-asset.dto'; +import { IsNotEmpty } from 'class-validator'; export class AssetFileUploadDto { @IsNotEmpty() diff --git a/server/apps/immich/src/api-v1/asset/dto/create-asset.dto.ts b/server/apps/immich/src/api-v1/asset/dto/create-asset.dto.ts index f1194ec4d..7a5bcd3c0 100644 --- a/server/apps/immich/src/api-v1/asset/dto/create-asset.dto.ts +++ b/server/apps/immich/src/api-v1/asset/dto/create-asset.dto.ts @@ -1,5 +1,6 @@ import { IsNotEmpty, IsOptional } from 'class-validator'; import { AssetType } from '@app/database/entities/asset.entity'; +import { ApiProperty } from '@nestjs/swagger'; export class CreateAssetDto { @IsNotEmpty() @@ -9,6 +10,7 @@ export class CreateAssetDto { deviceId!: string; @IsNotEmpty() + @ApiProperty({ enumName: 'AssetTypeEnum', enum: AssetType }) assetType!: AssetType; @IsNotEmpty() diff --git a/server/apps/immich/src/api-v1/asset/dto/get-all-asset-query.dto.ts b/server/apps/immich/src/api-v1/asset/dto/get-all-asset-query.dto.ts deleted file mode 100644 index 67f5e319f..000000000 --- a/server/apps/immich/src/api-v1/asset/dto/get-all-asset-query.dto.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IsOptional } from 'class-validator'; - -export class GetAllAssetQueryDto { - @IsOptional() - nextPageKey?: string; -} diff --git a/server/apps/immich/src/api-v1/asset/dto/get-all-asset-response.dto.ts b/server/apps/immich/src/api-v1/asset/dto/get-all-asset-response.dto.ts deleted file mode 100644 index 5af3e205a..000000000 --- a/server/apps/immich/src/api-v1/asset/dto/get-all-asset-response.dto.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { AssetEntity } from '@app/database/entities/asset.entity'; - -// TODO: this doesn't seem to be used -export class GetAllAssetReponseDto { - data!: Array<{ date: string; assets: Array }>; - count!: number; - nextPageKey!: string; -} diff --git a/server/apps/immich/src/api-v1/asset/dto/get-new-asset-query.dto.ts b/server/apps/immich/src/api-v1/asset/dto/get-new-asset-query.dto.ts deleted file mode 100644 index 2d98f0fb5..000000000 --- a/server/apps/immich/src/api-v1/asset/dto/get-new-asset-query.dto.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IsNotEmpty } from 'class-validator'; - -export class GetNewAssetQueryDto { - @IsNotEmpty() - latestDate!: string; -} diff --git a/server/apps/immich/src/api-v1/asset/dto/update-asset.dto.ts b/server/apps/immich/src/api-v1/asset/dto/update-asset.dto.ts deleted file mode 100644 index 891e14436..000000000 --- a/server/apps/immich/src/api-v1/asset/dto/update-asset.dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PartialType } from '@nestjs/mapped-types'; -import { CreateAssetDto } from './create-asset.dto'; - -export class UpdateAssetDto extends PartialType(CreateAssetDto) {} diff --git a/server/apps/immich/src/api-v1/asset/dto/update-exif.dto.ts b/server/apps/immich/src/api-v1/asset/dto/update-exif.dto.ts deleted file mode 100644 index 1bf506664..000000000 --- a/server/apps/immich/src/api-v1/asset/dto/update-exif.dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PartialType } from '@nestjs/mapped-types'; -import { CreateExifDto } from './create-exif.dto'; - -export class UpdateExifDto extends PartialType(CreateExifDto) {} diff --git a/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts index ef74145ab..5e4887fcd 100644 --- a/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts +++ b/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts @@ -1,4 +1,5 @@ import { AssetEntity, AssetType } from '@app/database/entities/asset.entity'; +import { ApiProperty } from '@nestjs/swagger'; import { ExifResponseDto, mapExif } from './exif-response.dto'; import { SmartInfoResponseDto, mapSmartInfo } from './smart-info-response.dto'; @@ -7,6 +8,8 @@ export class AssetResponseDto { deviceAssetId!: string; ownerId!: string; deviceId!: string; + + @ApiProperty({ enumName: 'AssetTypeEnum', enum: AssetType }) type!: AssetType; originalPath!: string; resizePath!: string | null; diff --git a/server/apps/immich/src/api-v1/asset/response-dto/delete-asset-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/delete-asset-response.dto.ts new file mode 100644 index 000000000..86f6afdf1 --- /dev/null +++ b/server/apps/immich/src/api-v1/asset/response-dto/delete-asset-response.dto.ts @@ -0,0 +1,13 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export enum DeleteAssetStatusEnum { + SUCCESS = 'SUCCESS', + FAILED = 'FAILED', +} + +export class DeleteAssetResponseDto { + id!: string; + + @ApiProperty({ type: 'string', enum: DeleteAssetStatusEnum, enumName: 'DeleteAssetStatus' }) + status!: DeleteAssetStatusEnum; +} diff --git a/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts index 57b0c8e9c..c43c55b4e 100644 --- a/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts +++ b/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts @@ -1,26 +1,26 @@ import { ExifEntity } from '@app/database/entities/exif.entity'; export class ExifResponseDto { - id!: string; - make: string | null = null; - model: string | null = null; - imageName: string | null = null; - exifImageWidth: number | null = null; - exifImageHeight: number | null = null; - fileSizeInByte: number | null = null; - orientation: string | null = null; - dateTimeOriginal: Date | null = null; - modifyDate: Date | null = null; - lensModel: string | null = null; - fNumber: number | null = null; - focalLength: number | null = null; - iso: number | null = null; - exposureTime: number | null = null; - latitude: number | null = null; - longitude: number | null = null; - city: string | null = null; - state: string | null = null; - country: string | null = null; + id?: string | null = null; + make?: string | null = null; + model?: string | null = null; + imageName?: string | null = null; + exifImageWidth?: number | null = null; + exifImageHeight?: number | null = null; + fileSizeInByte?: number | null = null; + orientation?: string | null = null; + dateTimeOriginal?: Date | null = null; + modifyDate?: Date | null = null; + lensModel?: string | null = null; + fNumber?: number | null = null; + focalLength?: number | null = null; + iso?: number | null = null; + exposureTime?: number | null = null; + latitude?: number | null = null; + longitude?: number | null = null; + city?: string | null = null; + state?: string | null = null; + country?: string | null = null; } export function mapExif(entity: ExifEntity): ExifResponseDto { diff --git a/server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts b/server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts index 151d59e6f..9d4d770de 100644 --- a/server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts +++ b/server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts @@ -1,7 +1,10 @@ +import { ApiProperty } from '@nestjs/swagger'; + export class ValidateAccessTokenResponseDto { constructor(authStatus: boolean) { this.authStatus = authStatus; } - authStatus: boolean; + @ApiProperty({ type: 'boolean' }) + authStatus!: boolean; } diff --git a/server/apps/immich/src/api-v1/device-info/dto/create-device-info.dto.ts b/server/apps/immich/src/api-v1/device-info/dto/create-device-info.dto.ts index a9db6ea43..29dddea81 100644 --- a/server/apps/immich/src/api-v1/device-info/dto/create-device-info.dto.ts +++ b/server/apps/immich/src/api-v1/device-info/dto/create-device-info.dto.ts @@ -1,11 +1,13 @@ import { IsNotEmpty, IsOptional } from 'class-validator'; import { DeviceType } from '@app/database/entities/device-info.entity'; +import { ApiProperty } from '@nestjs/swagger'; export class CreateDeviceInfoDto { @IsNotEmpty() deviceId!: string; @IsNotEmpty() + @ApiProperty({ enumName: 'DeviceTypeEnum', enum: DeviceType }) deviceType!: DeviceType; @IsOptional() diff --git a/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts b/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts index cd2be701a..a047e852b 100644 --- a/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts +++ b/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts @@ -1,4 +1,17 @@ +import { DeviceType } from '@app/database/entities/device-info.entity'; import { PartialType } from '@nestjs/mapped-types'; +import { ApiProperty } from '@nestjs/swagger'; +import { IsNotEmpty, IsOptional } from 'class-validator'; import { CreateDeviceInfoDto } from './create-device-info.dto'; -export class UpdateDeviceInfoDto extends PartialType(CreateDeviceInfoDto) {} +export class UpdateDeviceInfoDto { + @IsNotEmpty() + deviceId!: string; + + @IsNotEmpty() + @ApiProperty({ enumName: 'DeviceTypeEnum', enum: DeviceType }) + deviceType!: DeviceType; + + @IsOptional() + isAutoBackup?: boolean; +} diff --git a/server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts b/server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts index e36389d33..5c1bcfadf 100644 --- a/server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts +++ b/server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts @@ -1,11 +1,15 @@ import { DeviceInfoEntity, DeviceType } from '@app/database/entities/device-info.entity'; +import { ApiProperty } from '@nestjs/swagger'; export class DeviceInfoResponseDto { + @ApiProperty({ type: 'integer' }) id!: number; userId!: string; deviceId!: string; + + @ApiProperty({ enumName: 'DeviceTypeEnum', enum: DeviceType }) deviceType!: DeviceType; - notificationToken!: string | null; + createdAt!: string; isAutoBackup!: boolean; } @@ -16,7 +20,6 @@ export function mapDeviceInfoResponse(entity: DeviceInfoEntity): DeviceInfoRespo userId: entity.userId, deviceId: entity.deviceId, deviceType: entity.deviceType, - notificationToken: entity.notificationToken, createdAt: entity.createdAt, isAutoBackup: entity.isAutoBackup, }; diff --git a/server/apps/immich/src/api-v1/server-info/response-dto/server-info-response.dto.ts b/server/apps/immich/src/api-v1/server-info/response-dto/server-info-response.dto.ts index e0a5f5c2d..444292091 100644 --- a/server/apps/immich/src/api-v1/server-info/response-dto/server-info-response.dto.ts +++ b/server/apps/immich/src/api-v1/server-info/response-dto/server-info-response.dto.ts @@ -1,9 +1,19 @@ +import { ApiProperty } from '@nestjs/swagger'; + export class ServerInfoResponseDto { diskSize!: string; diskUse!: string; diskAvailable!: string; + + @ApiProperty({ type: 'integer' }) diskSizeRaw!: number; + + @ApiProperty({ type: 'integer' }) diskUseRaw!: number; + + @ApiProperty({ type: 'integer' }) diskAvailableRaw!: number; + + @ApiProperty({ type: 'number', format: 'float' }) diskUsagePercentage!: number; } diff --git a/server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts b/server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts index d054d9b3c..812f3b071 100644 --- a/server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts +++ b/server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts @@ -1,8 +1,13 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IServerVersion } from 'apps/immich/src/constants/server_version.constant'; export class ServerVersionReponseDto implements IServerVersion { + @ApiProperty({ type: 'integer' }) major!: number; + @ApiProperty({ type: 'integer' }) minor!: number; + @ApiProperty({ type: 'integer' }) patch!: number; + @ApiProperty({ type: 'integer' }) build!: number; } diff --git a/server/apps/immich/src/api-v1/server-info/server-info.service.ts b/server/apps/immich/src/api-v1/server-info/server-info.service.ts index 606161aa7..23de4123e 100644 --- a/server/apps/immich/src/api-v1/server-info/server-info.service.ts +++ b/server/apps/immich/src/api-v1/server-info/server-info.service.ts @@ -5,7 +5,7 @@ import { APP_UPLOAD_LOCATION } from '../../constants/upload_location.constant'; @Injectable() export class ServerInfoService { - async getServerInfo() { + async getServerInfo(): Promise { const diskInfo = await diskusage.check(APP_UPLOAD_LOCATION); const usagePercentage = (((diskInfo.total - diskInfo.free) / diskInfo.total) * 100).toFixed(2); diff --git a/server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts b/server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts index a01f10f46..7b58ba5aa 100644 --- a/server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts +++ b/server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts @@ -1,6 +1,7 @@ import { ApiProperty } from '@nestjs/swagger'; +import { Express } from 'express'; export class CreateProfileImageDto { @ApiProperty({ type: 'string', format: 'binary' }) - file: any; + file!: Express.Multer.File; } diff --git a/server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts b/server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts index 63df37235..bcdc3a5b7 100644 --- a/server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts +++ b/server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts @@ -1,5 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger'; export class UserCountResponseDto { + @ApiProperty({ type: 'integer' }) userCount!: number; } @@ -7,4 +9,4 @@ export function mapUserCountResponse(count: number): UserCountResponseDto { return { userCount: count, }; -} \ No newline at end of file +} diff --git a/server/apps/immich/src/api-v1/user/user.controller.ts b/server/apps/immich/src/api-v1/user/user.controller.ts index 6ec543b1f..3700050a4 100644 --- a/server/apps/immich/src/api-v1/user/user.controller.ts +++ b/server/apps/immich/src/api-v1/user/user.controller.ts @@ -11,6 +11,7 @@ import { UseInterceptors, UploadedFile, Response, + Request, StreamableFile, ParseBoolPipe, } from '@nestjs/common'; @@ -22,7 +23,7 @@ import { AdminRolesGuard } from '../../middlewares/admin-role-guard.middleware'; import { UpdateUserDto } from './dto/update-user.dto'; import { FileInterceptor } from '@nestjs/platform-express'; import { profileImageUploadOption } from '../../config/profile-image-upload.config'; -import { Response as Res } from 'express'; +import { Response as Res, Request as Req } from 'express'; import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger'; import { UserResponseDto } from './response-dto/user-response.dto'; import { UserCountResponseDto } from './response-dto/user-count-response.dto'; @@ -76,13 +77,16 @@ export class UserController { @ApiBearerAuth() @ApiConsumes('multipart/form-data') @ApiBody({ + description: 'A new avatar for the user', type: CreateProfileImageDto, }) @Post('/profile-image') async createProfileImage( @GetAuthUser() authUser: AuthUserDto, @UploadedFile() fileInfo: Express.Multer.File, + @Request() req: Req, ): Promise { + console.log(req.body, req.file); return await this.userService.createProfileImage(authUser, fileInfo); } diff --git a/server/immich-openapi-specs.json b/server/immich-openapi-specs.json index fadc2b713..a70db8f2c 100644 --- a/server/immich-openapi-specs.json +++ b/server/immich-openapi-specs.json @@ -1 +1 @@ -{"openapi":"3.0.0","paths":{"/user":{"get":{"operationId":"getAllUsers","parameters":[{"name":"isAll","required":true,"in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseDto"}}}}}},"tags":["User"],"security":[{"bearer":[]}]},"post":{"operationId":"createUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]},"put":{"operationId":"updateUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/me":{"get":{"operationId":"getMyUserInfo","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/count":{"get":{"operationId":"getUserCount","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCountResponseDto"}}}}},"tags":["User"]}},"/user/profile-image":{"post":{"operationId":"createProfileImage","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateProfileImageDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProfileImageResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/profile-image/{userId}":{"get":{"operationId":"getProfileImage","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["User"]}},"/asset/upload":{"post":{"operationId":"uploadFile","parameters":[],"requestBody":{"required":true,"description":"Asset Upload Information","content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/AssetFileUploadDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetFileUploadResponseDto"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/download":{"get":{"operationId":"downloadFile","parameters":[{"name":"aid","required":true,"in":"query","schema":{"title":"Device Asset ID","type":"string"}},{"name":"did","required":true,"in":"query","schema":{"title":"Device ID","type":"string"}},{"name":"isThumb","required":false,"in":"query","schema":{"title":"Is serve thumbnail (resize) file","type":"boolean"}},{"name":"isWeb","required":false,"in":"query","schema":{"title":"Is request made from web","type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/file":{"get":{"operationId":"serveFile","parameters":[{"name":"aid","required":true,"in":"query","schema":{"title":"Device Asset ID","type":"string"}},{"name":"did","required":true,"in":"query","schema":{"title":"Device ID","type":"string"}},{"name":"isThumb","required":false,"in":"query","schema":{"title":"Is serve thumbnail (resize) file","type":"boolean"}},{"name":"isWeb","required":false,"in":"query","schema":{"title":"Is request made from web","type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/thumbnail/{assetId}":{"get":{"operationId":"getAssetThumbnail","parameters":[{"name":"assetId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/allObjects":{"get":{"operationId":"getCuratedObjects","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CuratedObjectsResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/allLocation":{"get":{"operationId":"getCuratedLocations","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CuratedLocationsResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/searchTerm":{"get":{"operationId":"getAssetSearchTerms","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/search":{"post":{"operationId":"searchAsset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchAssetDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset":{"get":{"operationId":"getAllAssets","summary":"","description":"Get all AssetEntity belong to the user","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]},"delete":{"operationId":"deleteAsset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAssetDto"}}}},"responses":{"200":{"description":""}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/{deviceId}":{"get":{"operationId":"getUserAssetsByDeviceId","summary":"","description":"Get all asset of a device that are in the database, ID only.","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/assetById/{assetId}":{"get":{"operationId":"getAssetById","summary":"","description":"Get a single asset's information","parameters":[{"name":"assetId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponseDto"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/check":{"post":{"operationId":"checkDuplicateAsset","summary":"","description":"Check duplicated asset before uploading - for Web upload used","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckDuplicateAssetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckDuplicateAssetResponseDto"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/auth/login":{"post":{"operationId":"login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginCredentialDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"tags":["Authentication"]}},"/auth/admin-sign-up":{"post":{"operationId":"adminSignUp","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignUpDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSignupResponseDto"}}}},"400":{"description":"The server already has an admin"}},"tags":["Authentication"]}},"/auth/validateToken":{"post":{"operationId":"validateAccessToken","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateAccessTokenResponseDto"}}}}},"tags":["Authentication"],"security":[{"bearer":[]}]}},"/device-info":{"post":{"operationId":"createDeviceInfo","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeviceInfoDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceInfoResponseDto"}}}}},"tags":["Device Info"],"security":[{"bearer":[]}]},"patch":{"operationId":"updateDeviceInfo","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceInfoDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceInfoResponseDto"}}}}},"tags":["Device Info"],"security":[{"bearer":[]}]}},"/server-info":{"get":{"operationId":"getServerInfo","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerInfoResponseDto"}}}}},"tags":["Server Info"]}},"/server-info/ping":{"get":{"operationId":"pingServer","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerPingResponse"}}}}},"tags":["Server Info"]}},"/server-info/version":{"get":{"operationId":"getServerVersion","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerVersionReponseDto"}}}}},"tags":["Server Info"]}},"/album":{"post":{"operationId":"createAlbum","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAlbumDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"get":{"operationId":"getAllAlbums","parameters":[{"name":"shared","required":false,"in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/users":{"put":{"operationId":"addUsersToAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddUsersDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/assets":{"put":{"operationId":"addAssetsToAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddAssetsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"delete":{"operationId":"removeAssetFromAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveAssetsDto"}}}},"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}":{"get":{"operationId":"getAlbumInfo","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"delete":{"operationId":"deleteAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]},"patch":{"operationId":"updateAlbumInfo","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlbumDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/user/{userId}":{"delete":{"operationId":"removeUserFromAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]}}},"info":{"title":"Immich","description":"Immich API","version":"1.17.0","contact":{}},"tags":[],"servers":[{"url":"/api"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http","name":"JWT","description":"Enter JWT token","in":"header"}},"schemas":{"UserResponseDto":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"createdAt":{"type":"string"},"profileImagePath":{"type":"string"},"shouldChangePassword":{"type":"boolean"},"isAdmin":{"type":"boolean"}},"required":["id","email","firstName","lastName","createdAt","profileImagePath","shouldChangePassword","isAdmin"]},"CreateUserDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"},"firstName":{"type":"string","example":"John"},"lastName":{"type":"string","example":"Doe"}},"required":["email","password","firstName","lastName"]},"UserCountResponseDto":{"type":"object","properties":{"userCount":{"type":"number"}},"required":["userCount"]},"UpdateUserDto":{"type":"object","properties":{"id":{"type":"string"},"password":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"isAdmin":{"type":"boolean"},"shouldChangePassword":{"type":"boolean"},"profileImagePath":{"type":"string"}},"required":["id"]},"CreateProfileImageDto":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]},"CreateProfileImageResponseDto":{"type":"object","properties":{"userId":{"type":"string"},"profileImagePath":{"type":"string"}},"required":["userId","profileImagePath"]},"AssetFileUploadDto":{"type":"object","properties":{"assetData":{"type":"string","format":"binary"}},"required":["assetData"]},"AssetFileUploadResponseDto":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"CuratedObjectsResponseDto":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string"},"resizePath":{"type":"string"},"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["id","object","resizePath","deviceAssetId","deviceId"]},"CuratedLocationsResponseDto":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"resizePath":{"type":"string"},"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["id","city","resizePath","deviceAssetId","deviceId"]},"SearchAssetDto":{"type":"object","properties":{"searchTerm":{"type":"string"}},"required":["searchTerm"]},"ExifResponseDto":{"type":"object","properties":{"id":{"type":"string"},"make":{"type":"string","nullable":true,"default":null},"model":{"type":"string","nullable":true,"default":null},"imageName":{"type":"string","nullable":true,"default":null},"exifImageWidth":{"type":"number","nullable":true,"default":null},"exifImageHeight":{"type":"number","nullable":true,"default":null},"fileSizeInByte":{"type":"number","nullable":true,"default":null},"orientation":{"type":"string","nullable":true,"default":null},"dateTimeOriginal":{"format":"date-time","type":"string","nullable":true,"default":null},"modifyDate":{"format":"date-time","type":"string","nullable":true,"default":null},"lensModel":{"type":"string","nullable":true,"default":null},"fNumber":{"type":"number","nullable":true,"default":null},"focalLength":{"type":"number","nullable":true,"default":null},"iso":{"type":"number","nullable":true,"default":null},"exposureTime":{"type":"number","nullable":true,"default":null},"latitude":{"type":"number","nullable":true,"default":null},"longitude":{"type":"number","nullable":true,"default":null},"city":{"type":"string","nullable":true,"default":null},"state":{"type":"string","nullable":true,"default":null},"country":{"type":"string","nullable":true,"default":null}},"required":["id","make","model","imageName","exifImageWidth","exifImageHeight","fileSizeInByte","orientation","dateTimeOriginal","modifyDate","lensModel","fNumber","focalLength","iso","exposureTime","latitude","longitude","city","state","country"]},"SmartInfoResponseDto":{"type":"object","properties":{"id":{"type":"string"},"tags":{"nullable":true,"type":"array","items":{"type":"string"}},"objects":{"nullable":true,"type":"array","items":{"type":"string"}}}},"AssetResponseDto":{"type":"object","properties":{"id":{"type":"string"},"deviceAssetId":{"type":"string"},"ownerId":{"type":"string"},"deviceId":{"type":"string"},"type":{"enum":["IMAGE","VIDEO","AUDIO","OTHER"],"type":"string"},"originalPath":{"type":"string"},"resizePath":{"type":"string","nullable":true},"createdAt":{"type":"string"},"modifiedAt":{"type":"string"},"isFavorite":{"type":"boolean"},"mimeType":{"type":"string","nullable":true},"duration":{"type":"string"},"webpPath":{"type":"string","nullable":true},"encodedVideoPath":{"type":"string","nullable":true},"exifInfo":{"$ref":"#/components/schemas/ExifResponseDto"},"smartInfo":{"$ref":"#/components/schemas/SmartInfoResponseDto"}},"required":["id","deviceAssetId","ownerId","deviceId","type","originalPath","resizePath","createdAt","modifiedAt","isFavorite","mimeType","duration","webpPath","encodedVideoPath"]},"DeleteAssetDto":{"type":"object","properties":{"ids":{"title":"Array of asset IDs to delete","example":["bf973405-3f2a-48d2-a687-2ed4167164be","dd41870b-5d00-46d2-924e-1d8489a0aa0f","fad77c3f-deef-4e7e-9608-14c1aa4e559a"],"type":"array","items":{"type":"string"}}},"required":["ids"]},"CheckDuplicateAssetDto":{"type":"object","properties":{"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["deviceAssetId","deviceId"]},"CheckDuplicateAssetResponseDto":{"type":"object","properties":{"isExist":{"type":"boolean"}},"required":["isExist"]},"LoginCredentialDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"}},"required":["email","password"]},"LoginResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","readOnly":true},"userId":{"type":"string","readOnly":true},"userEmail":{"type":"string","readOnly":true},"firstName":{"type":"string","readOnly":true},"lastName":{"type":"string","readOnly":true},"profileImagePath":{"type":"string","readOnly":true},"isAdmin":{"type":"boolean","readOnly":true},"shouldChangePassword":{"type":"boolean","readOnly":true}},"required":["accessToken","userId","userEmail","firstName","lastName","profileImagePath","isAdmin","shouldChangePassword"]},"SignUpDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"},"firstName":{"type":"string","example":"Admin"},"lastName":{"type":"string","example":"Doe"}},"required":["email","password","firstName","lastName"]},"AdminSignupResponseDto":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","email","firstName","lastName","createdAt"]},"ValidateAccessTokenResponseDto":{"type":"object","properties":{}},"CreateDeviceInfoDto":{"type":"object","properties":{"deviceId":{"type":"string"},"deviceType":{"type":"string","enum":["IOS","ANDROID","WEB"]},"isAutoBackup":{"type":"boolean"}},"required":["deviceId","deviceType"]},"DeviceInfoResponseDto":{"type":"object","properties":{"id":{"type":"number"},"userId":{"type":"string"},"deviceId":{"type":"string"},"deviceType":{"enum":["IOS","ANDROID","WEB"],"type":"string"},"notificationToken":{"type":"string","nullable":true},"createdAt":{"type":"string"},"isAutoBackup":{"type":"boolean"}},"required":["id","userId","deviceId","deviceType","notificationToken","createdAt","isAutoBackup"]},"UpdateDeviceInfoDto":{"type":"object","properties":{}},"ServerInfoResponseDto":{"type":"object","properties":{"diskSize":{"type":"string"},"diskUse":{"type":"string"},"diskAvailable":{"type":"string"},"diskSizeRaw":{"type":"number"},"diskUseRaw":{"type":"number"},"diskAvailableRaw":{"type":"number"},"diskUsagePercentage":{"type":"number"}},"required":["diskSize","diskUse","diskAvailable","diskSizeRaw","diskUseRaw","diskAvailableRaw","diskUsagePercentage"]},"ServerPingResponse":{"type":"object","properties":{"res":{"type":"string","readOnly":true,"example":"pong"}},"required":["res"]},"ServerVersionReponseDto":{"type":"object","properties":{"major":{"type":"number"},"minor":{"type":"number"},"patch":{"type":"number"},"build":{"type":"number"}},"required":["major","minor","patch","build"]},"CreateAlbumDto":{"type":"object","properties":{"albumName":{"type":"string"},"sharedWithUserIds":{"type":"array","items":{"type":"string"}},"assetIds":{"type":"array","items":{"type":"string"}}},"required":["albumName"]},"AlbumResponseDto":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"type":"string"},"albumName":{"type":"string"},"createdAt":{"type":"string"},"albumThumbnailAssetId":{"type":"string","nullable":true},"shared":{"type":"boolean"},"sharedUsers":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseDto"}},"assets":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}},"required":["id","ownerId","albumName","createdAt","albumThumbnailAssetId","shared","sharedUsers","assets"]},"AddUsersDto":{"type":"object","properties":{"sharedUserIds":{"type":"array","items":{"type":"string"}}},"required":["sharedUserIds"]},"AddAssetsDto":{"type":"object","properties":{"assetIds":{"type":"array","items":{"type":"string"}}},"required":["assetIds"]},"RemoveAssetsDto":{"type":"object","properties":{"assetIds":{"type":"array","items":{"type":"string"}}},"required":["assetIds"]},"UpdateAlbumDto":{"type":"object","properties":{"albumName":{"type":"string"},"ownerId":{"type":"string"}},"required":["albumName","ownerId"]}}}} \ No newline at end of file +{"openapi":"3.0.0","paths":{"/user":{"get":{"operationId":"getAllUsers","parameters":[{"name":"isAll","required":true,"in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseDto"}}}}}},"tags":["User"],"security":[{"bearer":[]}]},"post":{"operationId":"createUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]},"put":{"operationId":"updateUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/me":{"get":{"operationId":"getMyUserInfo","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/count":{"get":{"operationId":"getUserCount","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCountResponseDto"}}}}},"tags":["User"]}},"/user/profile-image":{"post":{"operationId":"createProfileImage","parameters":[],"requestBody":{"required":true,"description":"A new avatar for the user","content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateProfileImageDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProfileImageResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/profile-image/{userId}":{"get":{"operationId":"getProfileImage","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["User"]}},"/asset/upload":{"post":{"operationId":"uploadFile","parameters":[],"requestBody":{"required":true,"description":"Asset Upload Information","content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/AssetFileUploadDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetFileUploadResponseDto"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/download":{"get":{"operationId":"downloadFile","parameters":[{"name":"aid","required":true,"in":"query","schema":{"title":"Device Asset ID","type":"string"}},{"name":"did","required":true,"in":"query","schema":{"title":"Device ID","type":"string"}},{"name":"isThumb","required":false,"in":"query","schema":{"title":"Is serve thumbnail (resize) file","type":"boolean"}},{"name":"isWeb","required":false,"in":"query","schema":{"title":"Is request made from web","type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/file":{"get":{"operationId":"serveFile","parameters":[{"name":"aid","required":true,"in":"query","schema":{"title":"Device Asset ID","type":"string"}},{"name":"did","required":true,"in":"query","schema":{"title":"Device ID","type":"string"}},{"name":"isThumb","required":false,"in":"query","schema":{"title":"Is serve thumbnail (resize) file","type":"boolean"}},{"name":"isWeb","required":false,"in":"query","schema":{"title":"Is request made from web","type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/thumbnail/{assetId}":{"get":{"operationId":"getAssetThumbnail","parameters":[{"name":"assetId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/allObjects":{"get":{"operationId":"getCuratedObjects","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CuratedObjectsResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/allLocation":{"get":{"operationId":"getCuratedLocations","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CuratedLocationsResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/searchTerm":{"get":{"operationId":"getAssetSearchTerms","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/search":{"post":{"operationId":"searchAsset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchAssetDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset":{"get":{"operationId":"getAllAssets","summary":"","description":"Get all AssetEntity belong to the user","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]},"delete":{"operationId":"deleteAsset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAssetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeleteAssetResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/{deviceId}":{"get":{"operationId":"getUserAssetsByDeviceId","summary":"","description":"Get all asset of a device that are in the database, ID only.","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/assetById/{assetId}":{"get":{"operationId":"getAssetById","summary":"","description":"Get a single asset's information","parameters":[{"name":"assetId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponseDto"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/check":{"post":{"operationId":"checkDuplicateAsset","summary":"","description":"Check duplicated asset before uploading - for Web upload used","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckDuplicateAssetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckDuplicateAssetResponseDto"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/auth/login":{"post":{"operationId":"login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginCredentialDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"tags":["Authentication"]}},"/auth/admin-sign-up":{"post":{"operationId":"adminSignUp","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignUpDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSignupResponseDto"}}}},"400":{"description":"The server already has an admin"}},"tags":["Authentication"]}},"/auth/validateToken":{"post":{"operationId":"validateAccessToken","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateAccessTokenResponseDto"}}}}},"tags":["Authentication"],"security":[{"bearer":[]}]}},"/device-info":{"post":{"operationId":"createDeviceInfo","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeviceInfoDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceInfoResponseDto"}}}}},"tags":["Device Info"],"security":[{"bearer":[]}]},"patch":{"operationId":"updateDeviceInfo","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceInfoDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceInfoResponseDto"}}}}},"tags":["Device Info"],"security":[{"bearer":[]}]}},"/server-info":{"get":{"operationId":"getServerInfo","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerInfoResponseDto"}}}}},"tags":["Server Info"]}},"/server-info/ping":{"get":{"operationId":"pingServer","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerPingResponse"}}}}},"tags":["Server Info"]}},"/server-info/version":{"get":{"operationId":"getServerVersion","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerVersionReponseDto"}}}}},"tags":["Server Info"]}},"/album":{"post":{"operationId":"createAlbum","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAlbumDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"get":{"operationId":"getAllAlbums","parameters":[{"name":"shared","required":false,"in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/users":{"put":{"operationId":"addUsersToAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddUsersDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/assets":{"put":{"operationId":"addAssetsToAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddAssetsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"delete":{"operationId":"removeAssetFromAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveAssetsDto"}}}},"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}":{"get":{"operationId":"getAlbumInfo","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"delete":{"operationId":"deleteAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]},"patch":{"operationId":"updateAlbumInfo","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlbumDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/user/{userId}":{"delete":{"operationId":"removeUserFromAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]}}},"info":{"title":"Immich","description":"Immich API","version":"1.17.0","contact":{}},"tags":[],"servers":[{"url":"/api"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http","name":"JWT","description":"Enter JWT token","in":"header"}},"schemas":{"UserResponseDto":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"createdAt":{"type":"string"},"profileImagePath":{"type":"string"},"shouldChangePassword":{"type":"boolean"},"isAdmin":{"type":"boolean"}},"required":["id","email","firstName","lastName","createdAt","profileImagePath","shouldChangePassword","isAdmin"]},"CreateUserDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"},"firstName":{"type":"string","example":"John"},"lastName":{"type":"string","example":"Doe"}},"required":["email","password","firstName","lastName"]},"UserCountResponseDto":{"type":"object","properties":{"userCount":{"type":"integer"}},"required":["userCount"]},"UpdateUserDto":{"type":"object","properties":{"id":{"type":"string"},"password":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"isAdmin":{"type":"boolean"},"shouldChangePassword":{"type":"boolean"},"profileImagePath":{"type":"string"}},"required":["id"]},"CreateProfileImageDto":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]},"CreateProfileImageResponseDto":{"type":"object","properties":{"userId":{"type":"string"},"profileImagePath":{"type":"string"}},"required":["userId","profileImagePath"]},"AssetFileUploadDto":{"type":"object","properties":{"assetData":{"type":"string","format":"binary"}},"required":["assetData"]},"AssetFileUploadResponseDto":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"CuratedObjectsResponseDto":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string"},"resizePath":{"type":"string"},"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["id","object","resizePath","deviceAssetId","deviceId"]},"CuratedLocationsResponseDto":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"resizePath":{"type":"string"},"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["id","city","resizePath","deviceAssetId","deviceId"]},"SearchAssetDto":{"type":"object","properties":{"searchTerm":{"type":"string"}},"required":["searchTerm"]},"AssetTypeEnum":{"type":"string","enum":["IMAGE","VIDEO","AUDIO","OTHER"]},"ExifResponseDto":{"type":"object","properties":{"id":{"type":"string","nullable":true,"default":null},"make":{"type":"string","nullable":true,"default":null},"model":{"type":"string","nullable":true,"default":null},"imageName":{"type":"string","nullable":true,"default":null},"exifImageWidth":{"type":"number","nullable":true,"default":null},"exifImageHeight":{"type":"number","nullable":true,"default":null},"fileSizeInByte":{"type":"number","nullable":true,"default":null},"orientation":{"type":"string","nullable":true,"default":null},"dateTimeOriginal":{"format":"date-time","type":"string","nullable":true,"default":null},"modifyDate":{"format":"date-time","type":"string","nullable":true,"default":null},"lensModel":{"type":"string","nullable":true,"default":null},"fNumber":{"type":"number","nullable":true,"default":null},"focalLength":{"type":"number","nullable":true,"default":null},"iso":{"type":"number","nullable":true,"default":null},"exposureTime":{"type":"number","nullable":true,"default":null},"latitude":{"type":"number","nullable":true,"default":null},"longitude":{"type":"number","nullable":true,"default":null},"city":{"type":"string","nullable":true,"default":null},"state":{"type":"string","nullable":true,"default":null},"country":{"type":"string","nullable":true,"default":null}}},"SmartInfoResponseDto":{"type":"object","properties":{"id":{"type":"string"},"tags":{"nullable":true,"type":"array","items":{"type":"string"}},"objects":{"nullable":true,"type":"array","items":{"type":"string"}}}},"AssetResponseDto":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/AssetTypeEnum"},"id":{"type":"string"},"deviceAssetId":{"type":"string"},"ownerId":{"type":"string"},"deviceId":{"type":"string"},"originalPath":{"type":"string"},"resizePath":{"type":"string","nullable":true},"createdAt":{"type":"string"},"modifiedAt":{"type":"string"},"isFavorite":{"type":"boolean"},"mimeType":{"type":"string","nullable":true},"duration":{"type":"string"},"webpPath":{"type":"string","nullable":true},"encodedVideoPath":{"type":"string","nullable":true},"exifInfo":{"$ref":"#/components/schemas/ExifResponseDto"},"smartInfo":{"$ref":"#/components/schemas/SmartInfoResponseDto"}},"required":["type","id","deviceAssetId","ownerId","deviceId","originalPath","resizePath","createdAt","modifiedAt","isFavorite","mimeType","duration","webpPath","encodedVideoPath"]},"DeleteAssetDto":{"type":"object","properties":{"ids":{"title":"Array of asset IDs to delete","example":["bf973405-3f2a-48d2-a687-2ed4167164be","dd41870b-5d00-46d2-924e-1d8489a0aa0f","fad77c3f-deef-4e7e-9608-14c1aa4e559a"],"type":"array","items":{"type":"string"}}},"required":["ids"]},"DeleteAssetStatus":{"type":"string","enum":["SUCCESS","FAILED"]},"DeleteAssetResponseDto":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/DeleteAssetStatus"},"id":{"type":"string"}},"required":["status","id"]},"CheckDuplicateAssetDto":{"type":"object","properties":{"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["deviceAssetId","deviceId"]},"CheckDuplicateAssetResponseDto":{"type":"object","properties":{"isExist":{"type":"boolean"}},"required":["isExist"]},"LoginCredentialDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"}},"required":["email","password"]},"LoginResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","readOnly":true},"userId":{"type":"string","readOnly":true},"userEmail":{"type":"string","readOnly":true},"firstName":{"type":"string","readOnly":true},"lastName":{"type":"string","readOnly":true},"profileImagePath":{"type":"string","readOnly":true},"isAdmin":{"type":"boolean","readOnly":true},"shouldChangePassword":{"type":"boolean","readOnly":true}},"required":["accessToken","userId","userEmail","firstName","lastName","profileImagePath","isAdmin","shouldChangePassword"]},"SignUpDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"},"firstName":{"type":"string","example":"Admin"},"lastName":{"type":"string","example":"Doe"}},"required":["email","password","firstName","lastName"]},"AdminSignupResponseDto":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","email","firstName","lastName","createdAt"]},"ValidateAccessTokenResponseDto":{"type":"object","properties":{"authStatus":{"type":"boolean"}},"required":["authStatus"]},"DeviceTypeEnum":{"type":"string","enum":["IOS","ANDROID","WEB"]},"CreateDeviceInfoDto":{"type":"object","properties":{"deviceType":{"$ref":"#/components/schemas/DeviceTypeEnum"},"deviceId":{"type":"string"},"isAutoBackup":{"type":"boolean"}},"required":["deviceType","deviceId"]},"DeviceInfoResponseDto":{"type":"object","properties":{"id":{"type":"integer"},"deviceType":{"$ref":"#/components/schemas/DeviceTypeEnum"},"userId":{"type":"string"},"deviceId":{"type":"string"},"createdAt":{"type":"string"},"isAutoBackup":{"type":"boolean"}},"required":["id","deviceType","userId","deviceId","createdAt","isAutoBackup"]},"UpdateDeviceInfoDto":{"type":"object","properties":{"deviceType":{"$ref":"#/components/schemas/DeviceTypeEnum"},"deviceId":{"type":"string"},"isAutoBackup":{"type":"boolean"}},"required":["deviceType","deviceId"]},"ServerInfoResponseDto":{"type":"object","properties":{"diskSizeRaw":{"type":"integer"},"diskUseRaw":{"type":"integer"},"diskAvailableRaw":{"type":"integer"},"diskUsagePercentage":{"type":"number","format":"float"},"diskSize":{"type":"string"},"diskUse":{"type":"string"},"diskAvailable":{"type":"string"}},"required":["diskSizeRaw","diskUseRaw","diskAvailableRaw","diskUsagePercentage","diskSize","diskUse","diskAvailable"]},"ServerPingResponse":{"type":"object","properties":{"res":{"type":"string","readOnly":true,"example":"pong"}},"required":["res"]},"ServerVersionReponseDto":{"type":"object","properties":{"major":{"type":"integer"},"minor":{"type":"integer"},"patch":{"type":"integer"},"build":{"type":"integer"}},"required":["major","minor","patch","build"]},"CreateAlbumDto":{"type":"object","properties":{"albumName":{"type":"string"},"sharedWithUserIds":{"type":"array","items":{"type":"string"}},"assetIds":{"type":"array","items":{"type":"string"}}},"required":["albumName"]},"AlbumResponseDto":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"type":"string"},"albumName":{"type":"string"},"createdAt":{"type":"string"},"albumThumbnailAssetId":{"type":"string","nullable":true},"shared":{"type":"boolean"},"sharedUsers":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseDto"}},"assets":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}},"required":["id","ownerId","albumName","createdAt","albumThumbnailAssetId","shared","sharedUsers","assets"]},"AddUsersDto":{"type":"object","properties":{"sharedUserIds":{"type":"array","items":{"type":"string"}}},"required":["sharedUserIds"]},"AddAssetsDto":{"type":"object","properties":{"assetIds":{"type":"array","items":{"type":"string"}}},"required":["assetIds"]},"RemoveAssetsDto":{"type":"object","properties":{"assetIds":{"type":"array","items":{"type":"string"}}},"required":["assetIds"]},"UpdateAlbumDto":{"type":"object","properties":{"albumName":{"type":"string"},"ownerId":{"type":"string"}},"required":["albumName","ownerId"]}}}} \ No newline at end of file diff --git a/server/package.json b/server/package.json index ab0910ac9..7eccabdd0 100644 --- a/server/package.json +++ b/server/package.json @@ -23,7 +23,9 @@ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./apps/immich/test/jest-e2e.json", "typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js", - "api:generate-typescript": "rm -rf ../web/src/api/open-api && npx openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ../web/src/api/open-api" + "api:typescript": "rm -rf ../web/src/api/open-api && npx openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ../web/src/api/open-api", + "api:dart": "npx openapi-generator-cli generate -g dart -i ./immich-openapi-specs.json -o ../mobile/openapi", + "api:generate": "npm run api:typescript && npm run api:dart" }, "dependencies": { "@mapbox/mapbox-sdk": "^0.13.3", diff --git a/web/src/api/open-api/api.ts b/web/src/api/open-api/api.ts index c94ef1437..b61c24d1b 100644 --- a/web/src/api/open-api/api.ts +++ b/web/src/api/open-api/api.ts @@ -158,6 +158,12 @@ export interface AssetFileUploadResponseDto { * @interface AssetResponseDto */ export interface AssetResponseDto { + /** + * + * @type {AssetTypeEnum} + * @memberof AssetResponseDto + */ + 'type': AssetTypeEnum; /** * * @type {string} @@ -182,12 +188,6 @@ export interface AssetResponseDto { * @memberof AssetResponseDto */ 'deviceId': string; - /** - * - * @type {string} - * @memberof AssetResponseDto - */ - 'type': AssetResponseDtoTypeEnum; /** * * @type {string} @@ -255,15 +255,21 @@ export interface AssetResponseDto { */ 'smartInfo'?: SmartInfoResponseDto; } +/** + * + * @export + * @enum {string} + */ -export const AssetResponseDtoTypeEnum = { +export const AssetTypeEnum = { Image: 'IMAGE', Video: 'VIDEO', Audio: 'AUDIO', Other: 'OTHER' } as const; -export type AssetResponseDtoTypeEnum = typeof AssetResponseDtoTypeEnum[keyof typeof AssetResponseDtoTypeEnum]; +export type AssetTypeEnum = typeof AssetTypeEnum[keyof typeof AssetTypeEnum]; + /** * @@ -330,16 +336,16 @@ export interface CreateAlbumDto { export interface CreateDeviceInfoDto { /** * - * @type {string} + * @type {DeviceTypeEnum} * @memberof CreateDeviceInfoDto */ - 'deviceId': string; + 'deviceType': DeviceTypeEnum; /** * * @type {string} * @memberof CreateDeviceInfoDto */ - 'deviceType': CreateDeviceInfoDtoDeviceTypeEnum; + 'deviceId': string; /** * * @type {boolean} @@ -347,15 +353,6 @@ export interface CreateDeviceInfoDto { */ 'isAutoBackup'?: boolean; } - -export const CreateDeviceInfoDtoDeviceTypeEnum = { - Ios: 'IOS', - Android: 'ANDROID', - Web: 'WEB' -} as const; - -export type CreateDeviceInfoDtoDeviceTypeEnum = typeof CreateDeviceInfoDtoDeviceTypeEnum[keyof typeof CreateDeviceInfoDtoDeviceTypeEnum]; - /** * * @export @@ -493,6 +490,39 @@ export interface DeleteAssetDto { */ 'ids': Array; } +/** + * + * @export + * @interface DeleteAssetResponseDto + */ +export interface DeleteAssetResponseDto { + /** + * + * @type {DeleteAssetStatus} + * @memberof DeleteAssetResponseDto + */ + 'status': DeleteAssetStatus; + /** + * + * @type {string} + * @memberof DeleteAssetResponseDto + */ + 'id': string; +} +/** + * + * @export + * @enum {string} + */ + +export const DeleteAssetStatus = { + Success: 'SUCCESS', + Failed: 'FAILED' +} as const; + +export type DeleteAssetStatus = typeof DeleteAssetStatus[keyof typeof DeleteAssetStatus]; + + /** * * @export @@ -505,6 +535,12 @@ export interface DeviceInfoResponseDto { * @memberof DeviceInfoResponseDto */ 'id': number; + /** + * + * @type {DeviceTypeEnum} + * @memberof DeviceInfoResponseDto + */ + 'deviceType': DeviceTypeEnum; /** * * @type {string} @@ -517,18 +553,6 @@ export interface DeviceInfoResponseDto { * @memberof DeviceInfoResponseDto */ 'deviceId': string; - /** - * - * @type {string} - * @memberof DeviceInfoResponseDto - */ - 'deviceType': DeviceInfoResponseDtoDeviceTypeEnum; - /** - * - * @type {string} - * @memberof DeviceInfoResponseDto - */ - 'notificationToken': string | null; /** * * @type {string} @@ -542,14 +566,20 @@ export interface DeviceInfoResponseDto { */ 'isAutoBackup': boolean; } +/** + * + * @export + * @enum {string} + */ -export const DeviceInfoResponseDtoDeviceTypeEnum = { +export const DeviceTypeEnum = { Ios: 'IOS', Android: 'ANDROID', Web: 'WEB' } as const; -export type DeviceInfoResponseDtoDeviceTypeEnum = typeof DeviceInfoResponseDtoDeviceTypeEnum[keyof typeof DeviceInfoResponseDtoDeviceTypeEnum]; +export type DeviceTypeEnum = typeof DeviceTypeEnum[keyof typeof DeviceTypeEnum]; + /** * @@ -562,121 +592,121 @@ export interface ExifResponseDto { * @type {string} * @memberof ExifResponseDto */ - 'id': string; + 'id'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'make': string | null; + 'make'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'model': string | null; + 'model'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'imageName': string | null; + 'imageName'?: string | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'exifImageWidth': number | null; + 'exifImageWidth'?: number | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'exifImageHeight': number | null; + 'exifImageHeight'?: number | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'fileSizeInByte': number | null; + 'fileSizeInByte'?: number | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'orientation': string | null; + 'orientation'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'dateTimeOriginal': string | null; + 'dateTimeOriginal'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'modifyDate': string | null; + 'modifyDate'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'lensModel': string | null; + 'lensModel'?: string | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'fNumber': number | null; + 'fNumber'?: number | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'focalLength': number | null; + 'focalLength'?: number | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'iso': number | null; + 'iso'?: number | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'exposureTime': number | null; + 'exposureTime'?: number | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'latitude': number | null; + 'latitude'?: number | null; /** * * @type {number} * @memberof ExifResponseDto */ - 'longitude': number | null; + 'longitude'?: number | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'city': string | null; + 'city'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'state': string | null; + 'state'?: string | null; /** * * @type {string} * @memberof ExifResponseDto */ - 'country': string | null; + 'country'?: string | null; } /** * @@ -784,24 +814,6 @@ export interface SearchAssetDto { * @interface ServerInfoResponseDto */ export interface ServerInfoResponseDto { - /** - * - * @type {string} - * @memberof ServerInfoResponseDto - */ - 'diskSize': string; - /** - * - * @type {string} - * @memberof ServerInfoResponseDto - */ - 'diskUse': string; - /** - * - * @type {string} - * @memberof ServerInfoResponseDto - */ - 'diskAvailable': string; /** * * @type {number} @@ -826,6 +838,24 @@ export interface ServerInfoResponseDto { * @memberof ServerInfoResponseDto */ 'diskUsagePercentage': number; + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + 'diskSize': string; + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + 'diskUse': string; + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + 'diskAvailable': string; } /** * @@ -946,6 +976,31 @@ export interface UpdateAlbumDto { */ 'ownerId': string; } +/** + * + * @export + * @interface UpdateDeviceInfoDto + */ +export interface UpdateDeviceInfoDto { + /** + * + * @type {DeviceTypeEnum} + * @memberof UpdateDeviceInfoDto + */ + 'deviceType': DeviceTypeEnum; + /** + * + * @type {string} + * @memberof UpdateDeviceInfoDto + */ + 'deviceId': string; + /** + * + * @type {boolean} + * @memberof UpdateDeviceInfoDto + */ + 'isAutoBackup'?: boolean; +} /** * * @export @@ -1063,6 +1118,19 @@ export interface UserResponseDto { */ 'isAdmin': boolean; } +/** + * + * @export + * @interface ValidateAccessTokenResponseDto + */ +export interface ValidateAccessTokenResponseDto { + /** + * + * @type {boolean} + * @memberof ValidateAccessTokenResponseDto + */ + 'authStatus': boolean; +} /** * AlbumApi - axios parameter creator @@ -2306,7 +2374,7 @@ export const AssetApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async deleteAsset(deleteAssetDto: DeleteAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async deleteAsset(deleteAssetDto: DeleteAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { const localVarAxiosArgs = await localVarAxiosParamCreator.deleteAsset(deleteAssetDto, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, @@ -2349,7 +2417,7 @@ export const AssetApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getAssetSearchTerms(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + async getAssetSearchTerms(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetSearchTerms(options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, @@ -2451,7 +2519,7 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath * @param {*} [options] Override http request option. * @throws {RequiredError} */ - deleteAsset(deleteAssetDto: DeleteAssetDto, options?: any): AxiosPromise { + deleteAsset(deleteAssetDto: DeleteAssetDto, options?: any): AxiosPromise> { return localVarFp.deleteAsset(deleteAssetDto, options).then((request) => request(axios, basePath)); }, /** @@ -2490,7 +2558,7 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getAssetSearchTerms(options?: any): AxiosPromise> { + getAssetSearchTerms(options?: any): AxiosPromise> { return localVarFp.getAssetSearchTerms(options).then((request) => request(axios, basePath)); }, /** @@ -2863,7 +2931,7 @@ export const AuthenticationApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async validateAccessToken(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async validateAccessToken(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.validateAccessToken(options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, @@ -2900,7 +2968,7 @@ export const AuthenticationApiFactory = function (configuration?: Configuration, * @param {*} [options] Override http request option. * @throws {RequiredError} */ - validateAccessToken(options?: any): AxiosPromise { + validateAccessToken(options?: any): AxiosPromise { return localVarFp.validateAccessToken(options).then((request) => request(axios, basePath)); }, }; @@ -2994,13 +3062,13 @@ export const DeviceInfoApiAxiosParamCreator = function (configuration?: Configur }, /** * - * @param {object} body + * @param {UpdateDeviceInfoDto} updateDeviceInfoDto * @param {*} [options] Override http request option. * @throws {RequiredError} */ - updateDeviceInfo: async (body: object, options: AxiosRequestConfig = {}): Promise => { - // verify required parameter 'body' is not null or undefined - assertParamExists('updateDeviceInfo', 'body', body) + updateDeviceInfo: async (updateDeviceInfoDto: UpdateDeviceInfoDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'updateDeviceInfoDto' is not null or undefined + assertParamExists('updateDeviceInfo', 'updateDeviceInfoDto', updateDeviceInfoDto) const localVarPath = `/device-info`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -3024,7 +3092,7 @@ export const DeviceInfoApiAxiosParamCreator = function (configuration?: Configur setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(body, localVarRequestOptions, configuration) + localVarRequestOptions.data = serializeDataIfNeeded(updateDeviceInfoDto, localVarRequestOptions, configuration) return { url: toPathString(localVarUrlObj), @@ -3053,12 +3121,12 @@ export const DeviceInfoApiFp = function(configuration?: Configuration) { }, /** * - * @param {object} body + * @param {UpdateDeviceInfoDto} updateDeviceInfoDto * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async updateDeviceInfo(body: object, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.updateDeviceInfo(body, options); + async updateDeviceInfo(updateDeviceInfoDto: UpdateDeviceInfoDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateDeviceInfo(updateDeviceInfoDto, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, } @@ -3082,12 +3150,12 @@ export const DeviceInfoApiFactory = function (configuration?: Configuration, bas }, /** * - * @param {object} body + * @param {UpdateDeviceInfoDto} updateDeviceInfoDto * @param {*} [options] Override http request option. * @throws {RequiredError} */ - updateDeviceInfo(body: object, options?: any): AxiosPromise { - return localVarFp.updateDeviceInfo(body, options).then((request) => request(axios, basePath)); + updateDeviceInfo(updateDeviceInfoDto: UpdateDeviceInfoDto, options?: any): AxiosPromise { + return localVarFp.updateDeviceInfo(updateDeviceInfoDto, options).then((request) => request(axios, basePath)); }, }; }; @@ -3112,13 +3180,13 @@ export class DeviceInfoApi extends BaseAPI { /** * - * @param {object} body + * @param {UpdateDeviceInfoDto} updateDeviceInfoDto * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DeviceInfoApi */ - public updateDeviceInfo(body: object, options?: AxiosRequestConfig) { - return DeviceInfoApiFp(this.configuration).updateDeviceInfo(body, options).then((request) => request(this.axios, this.basePath)); + public updateDeviceInfo(updateDeviceInfoDto: UpdateDeviceInfoDto, options?: AxiosRequestConfig) { + return DeviceInfoApiFp(this.configuration).updateDeviceInfo(updateDeviceInfoDto, options).then((request) => request(this.axios, this.basePath)); } } diff --git a/web/src/lib/components/forms/login-form.svelte b/web/src/lib/components/forms/login-form.svelte index 7b20c4402..b0934fb5d 100644 --- a/web/src/lib/components/forms/login-form.svelte +++ b/web/src/lib/components/forms/login-form.svelte @@ -45,10 +45,6 @@ {#if loginPageMessage} - -

{@html loginPageMessage}