mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
Merge branch 'main' into feature/add-live-wallpaper-option-to-android-app
This commit is contained in:
commit
b4d09d0219
14 changed files with 184 additions and 61 deletions
|
|
@ -36,7 +36,7 @@ class UnStackActionButton extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return BaseActionButton(
|
return BaseActionButton(
|
||||||
iconData: Icons.filter_none_rounded,
|
iconData: Icons.layers_clear_outlined,
|
||||||
label: "unstack".t(context: context),
|
label: "unstack".t(context: context),
|
||||||
onPressed: () => _onTap(context, ref),
|
onPressed: () => _onTap(context, ref),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ class AssetDetailBottomSheet extends ConsumerWidget {
|
||||||
isArchived: isArchived,
|
isArchived: isArchived,
|
||||||
isTrashEnabled: isTrashEnable,
|
isTrashEnabled: isTrashEnable,
|
||||||
isInLockedView: isInLockedView,
|
isInLockedView: isInLockedView,
|
||||||
|
isStacked: asset.hasRemote && (asset as RemoteAsset).stackId != null,
|
||||||
currentAlbum: currentAlbum,
|
currentAlbum: currentAlbum,
|
||||||
advancedTroubleshooting: advancedTroubleshooting,
|
advancedTroubleshooting: advancedTroubleshooting,
|
||||||
source: ActionSource.viewer,
|
source: ActionSource.viewer,
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget {
|
||||||
final isCasting = ref.watch(castProvider.select((c) => c.isCasting));
|
final isCasting = ref.watch(castProvider.select((c) => c.isCasting));
|
||||||
|
|
||||||
final actions = <Widget>[
|
final actions = <Widget>[
|
||||||
if (asset.hasRemote) const DownloadActionButton(source: ActionSource.viewer, menuItem: true),
|
if (asset.isRemoteOnly) const DownloadActionButton(source: ActionSource.viewer, menuItem: true),
|
||||||
if (isCasting || (asset.hasRemote)) const CastActionButton(menuItem: true),
|
if (isCasting || (asset.hasRemote)) const CastActionButton(menuItem: true),
|
||||||
if (album != null && album.isActivityEnabled && album.isShared)
|
if (album != null && album.isActivityEnabled && album.isShared)
|
||||||
IconButton(
|
IconButton(
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_act
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/unarchive_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unarchive_action_button.widget.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
||||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
import 'package:immich_mobile/providers/server_info.provider.dart';
|
||||||
|
|
@ -44,6 +45,7 @@ class ArchiveBottomSheet extends ConsumerWidget {
|
||||||
const EditLocationActionButton(source: ActionSource.timeline),
|
const EditLocationActionButton(source: ActionSource.timeline),
|
||||||
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
||||||
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
||||||
|
if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline),
|
||||||
],
|
],
|
||||||
if (multiselect.hasLocal) ...[
|
if (multiselect.hasLocal) ...[
|
||||||
const DeleteLocalActionButton(source: ActionSource.timeline),
|
const DeleteLocalActionButton(source: ActionSource.timeline),
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_act
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
||||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
import 'package:immich_mobile/providers/server_info.provider.dart';
|
||||||
|
|
@ -44,6 +45,7 @@ class FavoriteBottomSheet extends ConsumerWidget {
|
||||||
const EditLocationActionButton(source: ActionSource.timeline),
|
const EditLocationActionButton(source: ActionSource.timeline),
|
||||||
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
||||||
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
||||||
|
if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline),
|
||||||
],
|
],
|
||||||
if (multiselect.hasLocal) ...[
|
if (multiselect.hasLocal) ...[
|
||||||
const DeleteLocalActionButton(source: ActionSource.timeline),
|
const DeleteLocalActionButton(source: ActionSource.timeline),
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_action_b
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/album/album_selector.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/album/album_selector.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
||||||
|
|
@ -117,6 +118,7 @@ class _GeneralBottomSheetState extends ConsumerState<GeneralBottomSheet> {
|
||||||
const EditLocationActionButton(source: ActionSource.timeline),
|
const EditLocationActionButton(source: ActionSource.timeline),
|
||||||
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
||||||
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
||||||
|
if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline),
|
||||||
const DeleteActionButton(source: ActionSource.timeline),
|
const DeleteActionButton(source: ActionSource.timeline),
|
||||||
],
|
],
|
||||||
if (multiselect.hasLocal || multiselect.hasMerged) const DeleteLocalActionButton(source: ActionSource.timeline),
|
if (multiselect.hasLocal || multiselect.hasMerged) const DeleteLocalActionButton(source: ActionSource.timeline),
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_action_b
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/album/album_selector.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/album/album_selector.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
||||||
|
|
@ -102,6 +103,7 @@ class _RemoteAlbumBottomSheetState extends ConsumerState<RemoteAlbumBottomSheet>
|
||||||
const EditLocationActionButton(source: ActionSource.timeline),
|
const EditLocationActionButton(source: ActionSource.timeline),
|
||||||
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
const MoveToLockFolderActionButton(source: ActionSource.timeline),
|
||||||
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline),
|
||||||
|
if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline),
|
||||||
],
|
],
|
||||||
if (multiselect.hasLocal) ...[
|
if (multiselect.hasLocal) ...[
|
||||||
const DeleteLocalActionButton(source: ActionSource.timeline),
|
const DeleteLocalActionButton(source: ActionSource.timeline),
|
||||||
|
|
|
||||||
|
|
@ -123,28 +123,14 @@ ImageProvider getFullImageProvider(BaseAsset asset, {Size size = const Size(1080
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageProvider getThumbnailImageProvider({BaseAsset? asset, String? remoteId, Size size = kThumbnailResolution}) {
|
ImageProvider? getThumbnailImageProvider(BaseAsset asset, {Size size = kThumbnailResolution}) {
|
||||||
assert(asset != null || remoteId != null, 'Either asset or remoteId must be provided');
|
if (_shouldUseLocalAsset(asset)) {
|
||||||
|
|
||||||
if (remoteId != null) {
|
|
||||||
return RemoteThumbProvider(assetId: remoteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_shouldUseLocalAsset(asset!)) {
|
|
||||||
final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).localId!;
|
final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).localId!;
|
||||||
return LocalThumbProvider(id: id, size: size, assetType: asset.type);
|
return LocalThumbProvider(id: id, size: size, assetType: asset.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String assetId;
|
final assetId = asset is RemoteAsset ? asset.id : (asset as LocalAsset).remoteId;
|
||||||
if (asset is LocalAsset && asset.hasRemote) {
|
return assetId != null ? RemoteThumbProvider(assetId: assetId) : null;
|
||||||
assetId = asset.remoteId!;
|
|
||||||
} else if (asset is RemoteAsset) {
|
|
||||||
assetId = asset.id;
|
|
||||||
} else {
|
|
||||||
throw ArgumentError("Unsupported asset type: ${asset.runtimeType}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return RemoteThumbProvider(assetId: assetId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _shouldUseLocalAsset(BaseAsset asset) =>
|
bool _shouldUseLocalAsset(BaseAsset asset) =>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/local_image_provider.dart';
|
|
||||||
import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart';
|
import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/thumb_hash_provider.dart';
|
import 'package:immich_mobile/presentation/widgets/images/thumb_hash_provider.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/timeline/constants.dart';
|
import 'package:immich_mobile/presentation/widgets/timeline/constants.dart';
|
||||||
|
|
@ -39,14 +38,7 @@ class Thumbnail extends StatefulWidget {
|
||||||
),
|
),
|
||||||
_ => null,
|
_ => null,
|
||||||
},
|
},
|
||||||
imageProvider = switch (asset) {
|
imageProvider = asset == null ? null : getThumbnailImageProvider(asset, size: size);
|
||||||
RemoteAsset() =>
|
|
||||||
asset.localId == null
|
|
||||||
? RemoteThumbProvider(assetId: asset.id)
|
|
||||||
: LocalThumbProvider(id: asset.localId!, size: size, assetType: asset.type),
|
|
||||||
LocalAsset() => LocalThumbProvider(id: asset.id, size: size, assetType: asset.type),
|
|
||||||
_ => null,
|
|
||||||
};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<Thumbnail> createState() => _ThumbnailState();
|
State<Thumbnail> createState() => _ThumbnailState();
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,6 @@ class ThumbnailTile extends ConsumerWidget {
|
||||||
)
|
)
|
||||||
: const BoxDecoration();
|
: const BoxDecoration();
|
||||||
|
|
||||||
final hasStack = asset is RemoteAsset && asset.stackId != null;
|
|
||||||
|
|
||||||
final bool storageIndicator =
|
final bool storageIndicator =
|
||||||
showStorageIndicator ?? ref.watch(settingsProvider.select((s) => s.get(Setting.showStorageIndicator)));
|
showStorageIndicator ?? ref.watch(settingsProvider.select((s) => s.get(Setting.showStorageIndicator)));
|
||||||
|
|
||||||
|
|
@ -77,21 +75,10 @@ class ThumbnailTile extends ConsumerWidget {
|
||||||
child: Thumbnail.fromAsset(asset: asset, size: size),
|
child: Thumbnail.fromAsset(asset: asset, size: size),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (hasStack)
|
if (asset != null)
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topRight,
|
||||||
child: Padding(
|
child: _AssetTypeIcons(asset: asset),
|
||||||
padding: EdgeInsets.only(right: 10.0, top: asset.isVideo ? 24.0 : 6.0),
|
|
||||||
child: const _TileOverlayIcon(Icons.burst_mode_rounded),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (asset != null && asset.isVideo)
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.topRight,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 10.0, top: 6.0),
|
|
||||||
child: _VideoIndicator(asset.duration),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (storageIndicator && asset != null)
|
if (storageIndicator && asset != null)
|
||||||
switch (asset.storage) {
|
switch (asset.storage) {
|
||||||
|
|
@ -214,3 +201,34 @@ class _TileOverlayIcon extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _AssetTypeIcons extends StatelessWidget {
|
||||||
|
final BaseAsset asset;
|
||||||
|
|
||||||
|
const _AssetTypeIcons({required this.asset});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final hasStack = asset is RemoteAsset && (asset as RemoteAsset).stackId != null;
|
||||||
|
final isLivePhoto = asset is RemoteAsset && asset.livePhotoVideoId != null;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
if (asset.isVideo)
|
||||||
|
Padding(padding: const EdgeInsets.only(right: 10.0, top: 6.0), child: _VideoIndicator(asset.duration)),
|
||||||
|
if (hasStack)
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(right: 10.0, top: 6.0),
|
||||||
|
child: _TileOverlayIcon(Icons.burst_mode_rounded),
|
||||||
|
),
|
||||||
|
if (isLivePhoto)
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(right: 10.0, top: 6.0),
|
||||||
|
child: _TileOverlayIcon(Icons.motion_photos_on_rounded),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ import 'package:background_downloader/background_downloader.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:immich_mobile/constants/enums.dart';
|
import 'package:immich_mobile/constants/enums.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
|
import 'package:immich_mobile/domain/services/asset.service.dart';
|
||||||
import 'package:immich_mobile/models/download/livephotos_medatada.model.dart';
|
import 'package:immich_mobile/models/download/livephotos_medatada.model.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
||||||
import 'package:immich_mobile/providers/user.provider.dart';
|
import 'package:immich_mobile/providers/user.provider.dart';
|
||||||
|
|
@ -36,6 +39,7 @@ class ActionNotifier extends Notifier<void> {
|
||||||
late ActionService _service;
|
late ActionService _service;
|
||||||
late UploadService _uploadService;
|
late UploadService _uploadService;
|
||||||
late DownloadService _downloadService;
|
late DownloadService _downloadService;
|
||||||
|
late AssetService _assetService;
|
||||||
|
|
||||||
ActionNotifier() : super();
|
ActionNotifier() : super();
|
||||||
|
|
||||||
|
|
@ -43,6 +47,7 @@ class ActionNotifier extends Notifier<void> {
|
||||||
void build() {
|
void build() {
|
||||||
_uploadService = ref.watch(uploadServiceProvider);
|
_uploadService = ref.watch(uploadServiceProvider);
|
||||||
_service = ref.watch(actionServiceProvider);
|
_service = ref.watch(actionServiceProvider);
|
||||||
|
_assetService = ref.watch(assetServiceProvider);
|
||||||
_downloadService = ref.watch(downloadServiceProvider);
|
_downloadService = ref.watch(downloadServiceProvider);
|
||||||
_downloadService.onImageDownloadStatus = _downloadImageCallback;
|
_downloadService.onImageDownloadStatus = _downloadImageCallback;
|
||||||
_downloadService.onVideoDownloadStatus = _downloadVideoCallback;
|
_downloadService.onVideoDownloadStatus = _downloadVideoCallback;
|
||||||
|
|
@ -335,6 +340,14 @@ class ActionNotifier extends Notifier<void> {
|
||||||
final assets = _getOwnedRemoteAssetsForSource(source);
|
final assets = _getOwnedRemoteAssetsForSource(source);
|
||||||
try {
|
try {
|
||||||
await _service.unStack(assets.map((e) => e.stackId).nonNulls.toList());
|
await _service.unStack(assets.map((e) => e.stackId).nonNulls.toList());
|
||||||
|
if (source == ActionSource.viewer) {
|
||||||
|
final updatedParent = await _assetService.getRemoteAsset(assets.first.id);
|
||||||
|
if (updatedParent != null) {
|
||||||
|
ref.read(currentAssetNotifier.notifier).setAsset(updatedParent);
|
||||||
|
ref.read(assetViewerProvider.notifier).setAsset(updatedParent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ActionResult(count: assets.length, success: true);
|
return ActionResult(count: assets.length, success: true);
|
||||||
} catch (error, stack) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Failed to unstack assets', error, stack);
|
_logger.severe('Failed to unstack assets', error, stack);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ class MultiSelectState {
|
||||||
bool get hasRemote =>
|
bool get hasRemote =>
|
||||||
selectedAssets.any((asset) => asset.storage == AssetState.remote || asset.storage == AssetState.merged);
|
selectedAssets.any((asset) => asset.storage == AssetState.remote || asset.storage == AssetState.merged);
|
||||||
|
|
||||||
|
bool get hasStacked => selectedAssets.any((asset) => asset is RemoteAsset && asset.stackId != null);
|
||||||
|
|
||||||
bool get hasLocal => selectedAssets.any((asset) => asset.storage == AssetState.local);
|
bool get hasLocal => selectedAssets.any((asset) => asset.storage == AssetState.local);
|
||||||
|
|
||||||
bool get hasMerged => selectedAssets.any((asset) => asset.storage == AssetState.merged);
|
bool get hasMerged => selectedAssets.any((asset) => asset.storage == AssetState.merged);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_action_b
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/unarchive_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unarchive_action_button.widget.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart';
|
||||||
|
|
||||||
class ActionButtonContext {
|
class ActionButtonContext {
|
||||||
|
|
@ -24,6 +25,7 @@ class ActionButtonContext {
|
||||||
final bool isArchived;
|
final bool isArchived;
|
||||||
final bool isTrashEnabled;
|
final bool isTrashEnabled;
|
||||||
final bool isInLockedView;
|
final bool isInLockedView;
|
||||||
|
final bool isStacked;
|
||||||
final RemoteAlbum? currentAlbum;
|
final RemoteAlbum? currentAlbum;
|
||||||
final bool advancedTroubleshooting;
|
final bool advancedTroubleshooting;
|
||||||
final ActionSource source;
|
final ActionSource source;
|
||||||
|
|
@ -33,6 +35,7 @@ class ActionButtonContext {
|
||||||
required this.isOwner,
|
required this.isOwner,
|
||||||
required this.isArchived,
|
required this.isArchived,
|
||||||
required this.isTrashEnabled,
|
required this.isTrashEnabled,
|
||||||
|
required this.isStacked,
|
||||||
required this.isInLockedView,
|
required this.isInLockedView,
|
||||||
required this.currentAlbum,
|
required this.currentAlbum,
|
||||||
required this.advancedTroubleshooting,
|
required this.advancedTroubleshooting,
|
||||||
|
|
@ -55,6 +58,7 @@ enum ActionButtonType {
|
||||||
deleteLocal,
|
deleteLocal,
|
||||||
upload,
|
upload,
|
||||||
removeFromAlbum,
|
removeFromAlbum,
|
||||||
|
unstack,
|
||||||
likeActivity;
|
likeActivity;
|
||||||
|
|
||||||
bool shouldShow(ActionButtonContext context) {
|
bool shouldShow(ActionButtonContext context) {
|
||||||
|
|
@ -110,6 +114,10 @@ enum ActionButtonType {
|
||||||
context.isOwner && //
|
context.isOwner && //
|
||||||
!context.isInLockedView && //
|
!context.isInLockedView && //
|
||||||
context.currentAlbum != null,
|
context.currentAlbum != null,
|
||||||
|
ActionButtonType.unstack =>
|
||||||
|
context.isOwner && //
|
||||||
|
!context.isInLockedView && //
|
||||||
|
context.isStacked,
|
||||||
ActionButtonType.likeActivity =>
|
ActionButtonType.likeActivity =>
|
||||||
!context.isInLockedView &&
|
!context.isInLockedView &&
|
||||||
context.currentAlbum != null &&
|
context.currentAlbum != null &&
|
||||||
|
|
@ -138,28 +146,13 @@ enum ActionButtonType {
|
||||||
source: context.source,
|
source: context.source,
|
||||||
),
|
),
|
||||||
ActionButtonType.likeActivity => const LikeActivityActionButton(),
|
ActionButtonType.likeActivity => const LikeActivityActionButton(),
|
||||||
|
ActionButtonType.unstack => UnStackActionButton(source: context.source),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ActionButtonBuilder {
|
class ActionButtonBuilder {
|
||||||
static const List<ActionButtonType> _actionTypes = [
|
static const List<ActionButtonType> _actionTypes = ActionButtonType.values;
|
||||||
ActionButtonType.advancedInfo,
|
|
||||||
ActionButtonType.share,
|
|
||||||
ActionButtonType.shareLink,
|
|
||||||
ActionButtonType.likeActivity,
|
|
||||||
ActionButtonType.archive,
|
|
||||||
ActionButtonType.unarchive,
|
|
||||||
ActionButtonType.download,
|
|
||||||
ActionButtonType.trash,
|
|
||||||
ActionButtonType.deletePermanent,
|
|
||||||
ActionButtonType.delete,
|
|
||||||
ActionButtonType.moveToLockFolder,
|
|
||||||
ActionButtonType.removeFromLockFolder,
|
|
||||||
ActionButtonType.deleteLocal,
|
|
||||||
ActionButtonType.upload,
|
|
||||||
ActionButtonType.removeFromAlbum,
|
|
||||||
];
|
|
||||||
|
|
||||||
static List<Widget> build(ActionButtonContext context) {
|
static List<Widget> build(ActionButtonContext context) {
|
||||||
return _actionTypes.where((type) => type.shouldShow(context)).map((type) => type.buildButton(context)).toList();
|
return _actionTypes.where((type) => type.shouldShow(context)).map((type) => type.buildButton(context)).toList();
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -112,6 +113,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -127,6 +129,7 @@ void main() {
|
||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -145,6 +148,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -161,6 +165,7 @@ void main() {
|
||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -177,6 +182,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -195,6 +201,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -211,6 +218,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -227,6 +235,7 @@ void main() {
|
||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -243,6 +252,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -259,6 +269,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -277,6 +288,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -293,6 +305,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -309,6 +322,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -327,6 +341,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -343,6 +358,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -359,6 +375,7 @@ void main() {
|
||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -377,6 +394,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -393,6 +411,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -411,6 +430,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -427,6 +447,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -445,6 +466,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -463,6 +485,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -481,6 +504,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -497,6 +521,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -512,6 +537,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -530,6 +556,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -548,6 +575,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -563,6 +591,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -581,6 +610,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -597,6 +627,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -613,6 +644,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -628,6 +660,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -645,6 +678,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: true,
|
advancedTroubleshooting: true,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -660,6 +694,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -668,6 +703,59 @@ void main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('unstack button', () {
|
||||||
|
test('should show when owner, not locked, has remote, and is stacked', () {
|
||||||
|
final remoteAsset = createRemoteAsset();
|
||||||
|
final context = ActionButtonContext(
|
||||||
|
asset: remoteAsset,
|
||||||
|
isOwner: true,
|
||||||
|
isArchived: false,
|
||||||
|
isTrashEnabled: true,
|
||||||
|
isInLockedView: false,
|
||||||
|
currentAlbum: null,
|
||||||
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: true,
|
||||||
|
source: ActionSource.timeline,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(ActionButtonType.unstack.shouldShow(context), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not show when not stacked', () {
|
||||||
|
final remoteAsset = createRemoteAsset();
|
||||||
|
final context = ActionButtonContext(
|
||||||
|
asset: remoteAsset,
|
||||||
|
isOwner: true,
|
||||||
|
isArchived: false,
|
||||||
|
isTrashEnabled: true,
|
||||||
|
isInLockedView: false,
|
||||||
|
currentAlbum: null,
|
||||||
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
|
source: ActionSource.timeline,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(ActionButtonType.unstack.shouldShow(context), isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not show when not owner', () {
|
||||||
|
final remoteAsset = createRemoteAsset();
|
||||||
|
final context = ActionButtonContext(
|
||||||
|
asset: remoteAsset,
|
||||||
|
isOwner: false,
|
||||||
|
isArchived: true,
|
||||||
|
isTrashEnabled: true,
|
||||||
|
isInLockedView: false,
|
||||||
|
currentAlbum: null,
|
||||||
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
|
source: ActionSource.timeline,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(ActionButtonType.unstack.shouldShow(context), isFalse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
group('ActionButtonType.buildButton', () {
|
group('ActionButtonType.buildButton', () {
|
||||||
late BaseAsset asset;
|
late BaseAsset asset;
|
||||||
late ActionButtonContext context;
|
late ActionButtonContext context;
|
||||||
|
|
@ -682,6 +770,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -698,6 +787,22 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
|
source: ActionSource.timeline,
|
||||||
|
);
|
||||||
|
final widget = buttonType.buildButton(contextWithAlbum);
|
||||||
|
expect(widget, isA<Widget>());
|
||||||
|
} else if (buttonType == ActionButtonType.unstack) {
|
||||||
|
final album = createRemoteAlbum();
|
||||||
|
final contextWithAlbum = ActionButtonContext(
|
||||||
|
asset: asset,
|
||||||
|
isOwner: true,
|
||||||
|
isArchived: false,
|
||||||
|
isTrashEnabled: true,
|
||||||
|
isInLockedView: false,
|
||||||
|
currentAlbum: album,
|
||||||
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: true,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
final widget = buttonType.buildButton(contextWithAlbum);
|
final widget = buttonType.buildButton(contextWithAlbum);
|
||||||
|
|
@ -721,6 +826,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -741,6 +847,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -759,6 +866,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -778,6 +886,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -791,6 +900,7 @@ void main() {
|
||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
|
isStacked: false,
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue