feat(mobile): Manual asset upload (#3445)

* fix: exclude albums filter in backup provider

* refactor: Separate builder methods for Top Control App Bar buttons

* fix: Show download button only for Remote only assets

* fix(mobile): Force Refresh duration is too low to trigger it consistently

* feat(mobile): Make Buttons dynamic in Home Selection DraggableScrollableSheet

* feat(mobile): Manual Asset upload

* refactor(mobile): Replace _showToast with ImmichToast calls

* refactor(mobile): home_page selectionAssetState handling

* chore(mobile): min and initial size of DraggableScrollState increased

This is to prevent the buttons in the bottom sheet getting clipped behind the 3 way navigation buttons
in the default density of Android devices

* feat(mobile): notifications for manual upload progress

* wording

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
shalong-tanwen
2023-08-06 02:40:50 +00:00
committed by GitHub
parent f1b92718d5
commit deaf81e2a4
27 changed files with 887 additions and 163 deletions

View File

@@ -13,11 +13,13 @@ class TopControlAppBar extends HookConsumerWidget {
required this.onToggleMotionVideo,
required this.isPlayingMotionVideo,
required this.onFavorite,
required this.onUploadPressed,
required this.isFavorite,
}) : super(key: key);
final Asset asset;
final Function onMoreInfoPressed;
final VoidCallback? onUploadPressed;
final VoidCallback? onDownloadPressed;
final VoidCallback onToggleMotionVideo;
final VoidCallback onAddToAlbumPressed;
@@ -39,10 +41,69 @@ class TopControlAppBar extends HookConsumerWidget {
);
}
return AppBar(
foregroundColor: Colors.grey[100],
backgroundColor: Colors.transparent,
leading: IconButton(
Widget buildLivePhotoButton() {
return IconButton(
onPressed: () {
onToggleMotionVideo();
},
icon: isPlayingMotionVideo
? Icon(
Icons.motion_photos_pause_outlined,
color: Colors.grey[200],
)
: Icon(
Icons.play_circle_outline_rounded,
color: Colors.grey[200],
),
);
}
Widget buildMoreInfoButton() {
return IconButton(
onPressed: () {
onMoreInfoPressed();
},
icon: Icon(
Icons.info_outline_rounded,
color: Colors.grey[200],
),
);
}
Widget buildDownloadButton() {
return IconButton(
onPressed: onDownloadPressed,
icon: Icon(
Icons.cloud_download_outlined,
color: Colors.grey[200],
),
);
}
Widget buildAddToAlbumButtom() {
return IconButton(
onPressed: () {
onAddToAlbumPressed();
},
icon: Icon(
Icons.add,
color: Colors.grey[200],
),
);
}
Widget buildUploadButton() {
return IconButton(
onPressed: onUploadPressed,
icon: Icon(
Icons.backup_outlined,
color: Colors.grey[200],
),
);
}
Widget buildBackButton() {
return IconButton(
onPressed: () {
AutoRouter.of(context).pop();
},
@@ -51,54 +112,23 @@ class TopControlAppBar extends HookConsumerWidget {
size: 20.0,
color: Colors.grey[200],
),
),
);
}
return AppBar(
foregroundColor: Colors.grey[100],
backgroundColor: Colors.transparent,
leading: buildBackButton(),
actionsIconTheme: const IconThemeData(
size: iconSize,
),
actions: [
if (asset.isRemote) buildFavoriteButton(),
if (asset.livePhotoVideoId != null)
IconButton(
onPressed: () {
onToggleMotionVideo();
},
icon: isPlayingMotionVideo
? Icon(
Icons.motion_photos_pause_outlined,
color: Colors.grey[200],
)
: Icon(
Icons.play_circle_outline_rounded,
color: Colors.grey[200],
),
),
if (asset.storage == AssetState.remote)
IconButton(
onPressed: onDownloadPressed,
icon: Icon(
Icons.cloud_download_outlined,
color: Colors.grey[200],
),
),
if (asset.isRemote)
IconButton(
onPressed: () {
onAddToAlbumPressed();
},
icon: Icon(
Icons.add,
color: Colors.grey[200],
),
),
IconButton(
onPressed: () {
onMoreInfoPressed();
},
icon: Icon(
Icons.info_outline_rounded,
color: Colors.grey[200],
),
),
if (asset.livePhotoVideoId != null) buildLivePhotoButton(),
if (asset.isLocal && !asset.isRemote) buildUploadButton(),
if (asset.isRemote && !asset.isLocal) buildDownloadButton(),
if (asset.isRemote) buildAddToAlbumButtom(),
buildMoreInfoButton()
],
);
}

View File

@@ -16,6 +16,8 @@ import 'package:immich_mobile/modules/asset_viewer/ui/advanced_bottom_sheet.dart
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/asset_viewer/views/video_viewer_page.dart';
import 'package:immich_mobile/modules/backup/providers/manual_upload.provider.dart';
import 'package:immich_mobile/modules/home/ui/upload_dialog.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/modules/home/ui/delete_dialog.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
@@ -276,6 +278,21 @@ class GalleryViewerPage extends HookConsumerWidget {
AutoRouter.of(context).pop();
}
handleUpload(Asset asset) {
showDialog(
context: context,
builder: (BuildContext _) {
return UploadDialog(
onUpload: () {
ref
.read(manualUploadProvider.notifier)
.uploadAssets(context, [asset]);
},
);
},
);
}
buildAppBar() {
return IgnorePointer(
ignoring: !ref.watch(showControlsProvider),
@@ -291,6 +308,8 @@ class GalleryViewerPage extends HookConsumerWidget {
onMoreInfoPressed: showInfo,
onFavorite:
asset().isRemote ? () => toggleFavorite(asset()) : null,
onUploadPressed:
asset().isLocal ? () => handleUpload(asset()) : null,
onDownloadPressed: asset().isLocal
? null
: () => ref