Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 277eb5b1aa |
@@ -1037,7 +1037,6 @@
|
|||||||
"exif_bottom_sheet_description_error": "Error updating description",
|
"exif_bottom_sheet_description_error": "Error updating description",
|
||||||
"exif_bottom_sheet_details": "DETAILS",
|
"exif_bottom_sheet_details": "DETAILS",
|
||||||
"exif_bottom_sheet_location": "LOCATION",
|
"exif_bottom_sheet_location": "LOCATION",
|
||||||
"exif_bottom_sheet_no_description": "No description",
|
|
||||||
"exif_bottom_sheet_people": "PEOPLE",
|
"exif_bottom_sheet_people": "PEOPLE",
|
||||||
"exif_bottom_sheet_person_add_person": "Add name",
|
"exif_bottom_sheet_person_add_person": "Add name",
|
||||||
"exit_slideshow": "Exit Slideshow",
|
"exit_slideshow": "Exit Slideshow",
|
||||||
|
|||||||
@@ -120,10 +120,6 @@ class RemoteAlbumService {
|
|||||||
return _repository.getSharedUsers(albumId);
|
return _repository.getSharedUsers(albumId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AlbumUserRole?> getUserRole(String albumId, String userId) {
|
|
||||||
return _repository.getUserRole(albumId, userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<RemoteAsset>> getAssets(String albumId) {
|
Future<List<RemoteAsset>> getAssets(String albumId) {
|
||||||
return _repository.getAssets(albumId);
|
return _repository.getAssets(albumId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,15 +221,6 @@ class DriftRemoteAlbumRepository extends DriftDatabaseRepository {
|
|||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AlbumUserRole?> getUserRole(String albumId, String userId) async {
|
|
||||||
final query = _db.remoteAlbumUserEntity.select()
|
|
||||||
..where((row) => row.albumId.equals(albumId) & row.userId.equals(userId))
|
|
||||||
..limit(1);
|
|
||||||
|
|
||||||
final result = await query.getSingleOrNull();
|
|
||||||
return result?.role;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<RemoteAsset>> getAssets(String albumId) {
|
Future<List<RemoteAsset>> getAssets(String albumId) {
|
||||||
final query = _db.remoteAlbumAssetEntity.select().join([
|
final query = _db.remoteAlbumAssetEntity.select().join([
|
||||||
innerJoin(_db.remoteAssetEntity, _db.remoteAssetEntity.id.equalsExp(_db.remoteAlbumAssetEntity.assetId)),
|
innerJoin(_db.remoteAssetEntity, _db.remoteAssetEntity.id.equalsExp(_db.remoteAlbumAssetEntity.assetId)),
|
||||||
|
|||||||
@@ -169,11 +169,9 @@ class _RemoteAlbumPageState extends ConsumerState<RemoteAlbumPage> {
|
|||||||
context.pushRoute(const DriftActivitiesRoute());
|
context.pushRoute(const DriftActivitiesRoute());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> showOptionSheet(BuildContext context) async {
|
void showOptionSheet(BuildContext context) {
|
||||||
final user = ref.watch(currentUserProvider);
|
final user = ref.watch(currentUserProvider);
|
||||||
final isOwner = user != null ? user.id == _album.ownerId : false;
|
final isOwner = user != null ? user.id == _album.ownerId : false;
|
||||||
final canAddPhotos =
|
|
||||||
await ref.read(remoteAlbumServiceProvider).getUserRole(_album.id, user?.id ?? '') == AlbumUserRole.editor;
|
|
||||||
|
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -195,30 +193,22 @@ class _RemoteAlbumPageState extends ConsumerState<RemoteAlbumPage> {
|
|||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
onAddPhotos: isOwner || canAddPhotos
|
onAddPhotos: () async {
|
||||||
? () async {
|
await addAssets(context);
|
||||||
await addAssets(context);
|
context.pop();
|
||||||
context.pop();
|
},
|
||||||
}
|
onToggleAlbumOrder: () async {
|
||||||
: null,
|
await toggleAlbumOrder();
|
||||||
onToggleAlbumOrder: isOwner
|
context.pop();
|
||||||
? () async {
|
},
|
||||||
await toggleAlbumOrder();
|
onEditAlbum: () async {
|
||||||
context.pop();
|
context.pop();
|
||||||
}
|
await showEditTitleAndDescription(context);
|
||||||
: null,
|
},
|
||||||
onEditAlbum: isOwner
|
onCreateSharedLink: () async {
|
||||||
? () async {
|
context.pop();
|
||||||
context.pop();
|
context.pushRoute(SharedLinkEditRoute(albumId: _album.id));
|
||||||
await showEditTitleAndDescription(context);
|
},
|
||||||
}
|
|
||||||
: null,
|
|
||||||
onCreateSharedLink: isOwner
|
|
||||||
? () async {
|
|
||||||
context.pop();
|
|
||||||
context.pushRoute(SharedLinkEditRoute(albumId: _album.id));
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
onShowOptions: () {
|
onShowOptions: () {
|
||||||
context.pop();
|
context.pop();
|
||||||
context.pushRoute(const DriftAlbumOptionsRoute());
|
context.pushRoute(const DriftAlbumOptionsRoute());
|
||||||
@@ -230,9 +220,6 @@ class _RemoteAlbumPageState extends ConsumerState<RemoteAlbumPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final user = ref.watch(currentUserProvider);
|
|
||||||
final isOwner = user != null ? user.id == _album.ownerId : false;
|
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
onPopInvokedWithResult: (didPop, _) {
|
onPopInvokedWithResult: (didPop, _) {
|
||||||
if (didPop) {
|
if (didPop) {
|
||||||
@@ -256,8 +243,8 @@ class _RemoteAlbumPageState extends ConsumerState<RemoteAlbumPage> {
|
|||||||
appBar: RemoteAlbumSliverAppBar(
|
appBar: RemoteAlbumSliverAppBar(
|
||||||
icon: Icons.photo_album_outlined,
|
icon: Icons.photo_album_outlined,
|
||||||
onShowOptions: () => showOptionSheet(context),
|
onShowOptions: () => showOptionSheet(context),
|
||||||
onToggleAlbumOrder: isOwner ? () => toggleAlbumOrder() : null,
|
onToggleAlbumOrder: () => toggleAlbumOrder(),
|
||||||
onEditTitle: isOwner ? () => showEditTitleAndDescription(context) : null,
|
onEditTitle: () => showEditTitleAndDescription(context),
|
||||||
onActivity: () => showActivity(context),
|
onActivity: () => showActivity(context),
|
||||||
),
|
),
|
||||||
bottomSheet: RemoteAlbumBottomSheet(album: _album),
|
bottomSheet: RemoteAlbumBottomSheet(album: _album),
|
||||||
|
|||||||
@@ -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.layers_clear_outlined,
|
iconData: Icons.filter_none_rounded,
|
||||||
label: "unstack".t(context: context),
|
label: "unstack".t(context: context),
|
||||||
onPressed: () => _onTap(context, ref),
|
onPressed: () => _onTap(context, ref),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class ViewerBottomBar extends ConsumerWidget {
|
|||||||
final actions = <Widget>[
|
final actions = <Widget>[
|
||||||
const ShareActionButton(source: ActionSource.viewer),
|
const ShareActionButton(source: ActionSource.viewer),
|
||||||
if (asset.isLocalOnly) const UploadActionButton(source: ActionSource.viewer),
|
if (asset.isLocalOnly) const UploadActionButton(source: ActionSource.viewer),
|
||||||
if (asset.type == AssetType.image && isOwner) const EditImageActionButton(),
|
if (asset.type == AssetType.image) const EditImageActionButton(),
|
||||||
if (isOwner) ...[
|
if (isOwner) ...[
|
||||||
if (asset.hasRemote && isOwner && isArchived)
|
if (asset.hasRemote && isOwner && isArchived)
|
||||||
const UnArchiveActionButton(source: ActionSource.viewer)
|
const UnArchiveActionButton(source: ActionSource.viewer)
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ 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,
|
||||||
@@ -140,7 +139,6 @@ class _AssetDetailBottomSheet extends ConsumerWidget {
|
|||||||
|
|
||||||
final exifInfo = ref.watch(currentAssetExifProvider).valueOrNull;
|
final exifInfo = ref.watch(currentAssetExifProvider).valueOrNull;
|
||||||
final cameraTitle = _getCameraInfoTitle(exifInfo);
|
final cameraTitle = _getCameraInfoTitle(exifInfo);
|
||||||
final isOwner = ref.watch(currentUserProvider)?.id == (asset is RemoteAsset ? asset.ownerId : null);
|
|
||||||
|
|
||||||
return SliverList.list(
|
return SliverList.list(
|
||||||
children: [
|
children: [
|
||||||
@@ -148,10 +146,10 @@ class _AssetDetailBottomSheet extends ConsumerWidget {
|
|||||||
_SheetTile(
|
_SheetTile(
|
||||||
title: _getDateTime(context, asset),
|
title: _getDateTime(context, asset),
|
||||||
titleStyle: context.textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w600),
|
titleStyle: context.textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w600),
|
||||||
trailing: asset.hasRemote && isOwner ? const Icon(Icons.edit, size: 18) : null,
|
trailing: asset.hasRemote ? const Icon(Icons.edit, size: 18) : null,
|
||||||
onTap: asset.hasRemote && isOwner ? () async => await _editDateTime(context, ref) : null,
|
onTap: asset.hasRemote ? () async => await _editDateTime(context, ref) : null,
|
||||||
),
|
),
|
||||||
if (exifInfo != null) _SheetAssetDescription(exif: exifInfo, isEditable: isOwner),
|
if (exifInfo != null) _SheetAssetDescription(exif: exifInfo),
|
||||||
const SheetPeopleDetails(),
|
const SheetPeopleDetails(),
|
||||||
const SheetLocationDetails(),
|
const SheetLocationDetails(),
|
||||||
// Details header
|
// Details header
|
||||||
@@ -265,9 +263,8 @@ class _SheetTile extends ConsumerWidget {
|
|||||||
|
|
||||||
class _SheetAssetDescription extends ConsumerStatefulWidget {
|
class _SheetAssetDescription extends ConsumerStatefulWidget {
|
||||||
final ExifInfo exif;
|
final ExifInfo exif;
|
||||||
final bool isEditable;
|
|
||||||
|
|
||||||
const _SheetAssetDescription({required this.exif, this.isEditable = true, super.key});
|
const _SheetAssetDescription({required this.exif});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<_SheetAssetDescription> createState() => _SheetAssetDescriptionState();
|
ConsumerState<_SheetAssetDescription> createState() => _SheetAssetDescriptionState();
|
||||||
@@ -313,33 +310,27 @@ class _SheetAssetDescriptionState extends ConsumerState<_SheetAssetDescription>
|
|||||||
|
|
||||||
// Update controller text when EXIF data changes
|
// Update controller text when EXIF data changes
|
||||||
final currentDescription = currentExifInfo?.description ?? '';
|
final currentDescription = currentExifInfo?.description ?? '';
|
||||||
final hintText = (widget.isEditable ? 'exif_bottom_sheet_description' : 'exif_bottom_sheet_no_description').t(
|
|
||||||
context: context,
|
|
||||||
);
|
|
||||||
if (_controller.text != currentDescription && !_descriptionFocus.hasFocus) {
|
if (_controller.text != currentDescription && !_descriptionFocus.hasFocus) {
|
||||||
_controller.text = currentDescription;
|
_controller.text = currentDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8),
|
||||||
child: IgnorePointer(
|
child: TextField(
|
||||||
ignoring: !widget.isEditable,
|
controller: _controller,
|
||||||
child: TextField(
|
keyboardType: TextInputType.multiline,
|
||||||
controller: _controller,
|
focusNode: _descriptionFocus,
|
||||||
keyboardType: TextInputType.multiline,
|
maxLines: null, // makes it grow as text is added
|
||||||
focusNode: _descriptionFocus,
|
decoration: InputDecoration(
|
||||||
maxLines: null, // makes it grow as text is added
|
hintText: 'exif_bottom_sheet_description'.t(context: context),
|
||||||
decoration: InputDecoration(
|
border: InputBorder.none,
|
||||||
hintText: hintText,
|
enabledBorder: InputBorder.none,
|
||||||
border: InputBorder.none,
|
focusedBorder: InputBorder.none,
|
||||||
enabledBorder: InputBorder.none,
|
disabledBorder: InputBorder.none,
|
||||||
focusedBorder: InputBorder.none,
|
errorBorder: InputBorder.none,
|
||||||
disabledBorder: InputBorder.none,
|
focusedErrorBorder: InputBorder.none,
|
||||||
errorBorder: InputBorder.none,
|
|
||||||
focusedErrorBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
onTapOutside: (_) => saveDescription(currentExifInfo?.description),
|
|
||||||
),
|
),
|
||||||
|
onTapOutside: (_) => saveDescription(currentExifInfo?.description),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget {
|
|||||||
final showViewInTimelineButton =
|
final showViewInTimelineButton =
|
||||||
(previousRouteName != TabShellRoute.name || tabRoute == TabEnum.search) &&
|
(previousRouteName != TabShellRoute.name || tabRoute == TabEnum.search) &&
|
||||||
previousRouteName != AssetViewerRoute.name &&
|
previousRouteName != AssetViewerRoute.name &&
|
||||||
previousRouteName != null &&
|
previousRouteName != null;
|
||||||
isOwner;
|
|
||||||
|
|
||||||
final isShowingSheet = ref.watch(assetViewerProvider.select((state) => state.showingBottomSheet));
|
final isShowingSheet = ref.watch(assetViewerProvider.select((state) => state.showingBottomSheet));
|
||||||
int opacity = ref.watch(assetViewerProvider.select((state) => state.backgroundOpacity));
|
int opacity = ref.watch(assetViewerProvider.select((state) => state.backgroundOpacity));
|
||||||
@@ -58,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.isRemoteOnly) const DownloadActionButton(source: ActionSource.viewer, menuItem: true),
|
if (asset.hasRemote) 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,7 +13,6 @@ 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';
|
||||||
@@ -45,7 +44,6 @@ 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,7 +13,6 @@ 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';
|
||||||
@@ -45,7 +44,6 @@ 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,7 +20,6 @@ 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';
|
||||||
@@ -118,7 +117,6 @@ 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),
|
||||||
|
|||||||
+14
-25
@@ -17,14 +17,12 @@ 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';
|
||||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
import 'package:immich_mobile/providers/server_info.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/widgets/common/immich_toast.dart';
|
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
||||||
|
|
||||||
class RemoteAlbumBottomSheet extends ConsumerStatefulWidget {
|
class RemoteAlbumBottomSheet extends ConsumerStatefulWidget {
|
||||||
@@ -54,7 +52,6 @@ class _RemoteAlbumBottomSheetState extends ConsumerState<RemoteAlbumBottomSheet>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final multiselect = ref.watch(multiSelectProvider);
|
final multiselect = ref.watch(multiSelectProvider);
|
||||||
final isTrashEnable = ref.watch(serverInfoProvider.select((state) => state.serverFeatures.trash));
|
final isTrashEnable = ref.watch(serverInfoProvider.select((state) => state.serverFeatures.trash));
|
||||||
final ownsAlbum = ref.watch(currentUserProvider)?.id == widget.album.ownerId;
|
|
||||||
|
|
||||||
Future<void> addAssetsToAlbum(RemoteAlbum album) async {
|
Future<void> addAssetsToAlbum(RemoteAlbum album) async {
|
||||||
final selectedAssets = multiselect.selectedAssets;
|
final selectedAssets = multiselect.selectedAssets;
|
||||||
@@ -95,35 +92,27 @@ class _RemoteAlbumBottomSheetState extends ConsumerState<RemoteAlbumBottomSheet>
|
|||||||
const ShareActionButton(source: ActionSource.timeline),
|
const ShareActionButton(source: ActionSource.timeline),
|
||||||
if (multiselect.hasRemote) ...[
|
if (multiselect.hasRemote) ...[
|
||||||
const ShareLinkActionButton(source: ActionSource.timeline),
|
const ShareLinkActionButton(source: ActionSource.timeline),
|
||||||
|
const ArchiveActionButton(source: ActionSource.timeline),
|
||||||
if (ownsAlbum) ...[
|
const FavoriteActionButton(source: ActionSource.timeline),
|
||||||
const ArchiveActionButton(source: ActionSource.timeline),
|
|
||||||
const FavoriteActionButton(source: ActionSource.timeline),
|
|
||||||
],
|
|
||||||
const DownloadActionButton(source: ActionSource.timeline),
|
const DownloadActionButton(source: ActionSource.timeline),
|
||||||
if (ownsAlbum) ...[
|
isTrashEnable
|
||||||
isTrashEnable
|
? const TrashActionButton(source: ActionSource.timeline)
|
||||||
? const TrashActionButton(source: ActionSource.timeline)
|
: const DeletePermanentActionButton(source: ActionSource.timeline),
|
||||||
: const DeletePermanentActionButton(source: ActionSource.timeline),
|
const EditDateTimeActionButton(source: ActionSource.timeline),
|
||||||
const EditDateTimeActionButton(source: ActionSource.timeline),
|
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),
|
||||||
const UploadActionButton(source: ActionSource.timeline),
|
const UploadActionButton(source: ActionSource.timeline),
|
||||||
],
|
],
|
||||||
if (ownsAlbum) RemoveFromAlbumActionButton(source: ActionSource.timeline, albumId: widget.album.id),
|
RemoveFromAlbumActionButton(source: ActionSource.timeline, albumId: widget.album.id),
|
||||||
|
],
|
||||||
|
slivers: [
|
||||||
|
const AddToAlbumHeader(),
|
||||||
|
AlbumSelector(onAlbumSelected: addAssetsToAlbum, onKeyboardExpanded: onKeyboardExpand),
|
||||||
],
|
],
|
||||||
slivers: ownsAlbum
|
|
||||||
? [
|
|
||||||
const AddToAlbumHeader(),
|
|
||||||
AlbumSelector(onAlbumSelected: addAssetsToAlbum, onKeyboardExpanded: onKeyboardExpand),
|
|
||||||
]
|
|
||||||
: null,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,14 +123,28 @@ ImageProvider getFullImageProvider(BaseAsset asset, {Size size = const Size(1080
|
|||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageProvider? getThumbnailImageProvider(BaseAsset asset, {Size size = kThumbnailResolution}) {
|
ImageProvider getThumbnailImageProvider({BaseAsset? asset, String? remoteId, Size size = kThumbnailResolution}) {
|
||||||
if (_shouldUseLocalAsset(asset)) {
|
assert(asset != null || remoteId != null, 'Either asset or remoteId must be provided');
|
||||||
|
|
||||||
|
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 assetId = asset is RemoteAsset ? asset.id : (asset as LocalAsset).remoteId;
|
final String assetId;
|
||||||
return assetId != null ? RemoteThumbProvider(assetId: assetId) : null;
|
if (asset is LocalAsset && asset.hasRemote) {
|
||||||
|
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,6 +5,7 @@ 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';
|
||||||
@@ -38,7 +39,14 @@ class Thumbnail extends StatefulWidget {
|
|||||||
),
|
),
|
||||||
_ => null,
|
_ => null,
|
||||||
},
|
},
|
||||||
imageProvider = asset == null ? null : getThumbnailImageProvider(asset, size: size);
|
imageProvider = switch (asset) {
|
||||||
|
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,6 +54,8 @@ 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)));
|
||||||
|
|
||||||
@@ -75,10 +77,21 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
child: Thumbnail.fromAsset(asset: asset, size: size),
|
child: Thumbnail.fromAsset(asset: asset, size: size),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (asset != null)
|
if (hasStack)
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topRight,
|
||||||
child: _AssetTypeIcons(asset: asset),
|
child: Padding(
|
||||||
|
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) {
|
||||||
@@ -201,34 +214,3 @@ 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,10 +3,7 @@ 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';
|
||||||
@@ -39,7 +36,6 @@ 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();
|
||||||
|
|
||||||
@@ -47,7 +43,6 @@ 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;
|
||||||
@@ -340,14 +335,6 @@ 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,8 +28,6 @@ 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,7 +16,6 @@ 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 {
|
||||||
@@ -25,7 +24,6 @@ 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;
|
||||||
@@ -35,7 +33,6 @@ 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,
|
||||||
@@ -58,7 +55,6 @@ enum ActionButtonType {
|
|||||||
deleteLocal,
|
deleteLocal,
|
||||||
upload,
|
upload,
|
||||||
removeFromAlbum,
|
removeFromAlbum,
|
||||||
unstack,
|
|
||||||
likeActivity;
|
likeActivity;
|
||||||
|
|
||||||
bool shouldShow(ActionButtonContext context) {
|
bool shouldShow(ActionButtonContext context) {
|
||||||
@@ -114,10 +110,6 @@ 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 &&
|
||||||
@@ -146,13 +138,28 @@ 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 = ActionButtonType.values;
|
static const List<ActionButtonType> _actionTypes = [
|
||||||
|
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,7 +82,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -113,7 +112,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -129,7 +127,6 @@ void main() {
|
|||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -148,7 +145,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -165,7 +161,6 @@ void main() {
|
|||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -182,7 +177,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -201,7 +195,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -218,7 +211,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -235,7 +227,6 @@ void main() {
|
|||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -252,7 +243,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -269,7 +259,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -288,7 +277,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -305,7 +293,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -322,7 +309,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -341,7 +327,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -358,7 +343,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -375,7 +359,6 @@ void main() {
|
|||||||
isInLockedView: true,
|
isInLockedView: true,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -394,7 +377,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -411,7 +393,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -430,7 +411,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -447,7 +427,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -466,7 +445,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -485,7 +463,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -504,7 +481,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -521,7 +497,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -537,7 +512,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -556,7 +530,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -575,7 +548,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -591,7 +563,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -610,7 +581,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -627,7 +597,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -644,7 +613,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -660,7 +628,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -678,7 +645,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: true,
|
advancedTroubleshooting: true,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -694,7 +660,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -703,59 +668,6 @@ 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;
|
||||||
@@ -770,7 +682,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -787,22 +698,6 @@ 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);
|
||||||
@@ -826,7 +721,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -847,7 +741,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: album,
|
currentAlbum: album,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -866,7 +759,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -886,7 +778,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -900,7 +791,6 @@ void main() {
|
|||||||
isInLockedView: false,
|
isInLockedView: false,
|
||||||
currentAlbum: null,
|
currentAlbum: null,
|
||||||
advancedTroubleshooting: false,
|
advancedTroubleshooting: false,
|
||||||
isStacked: false,
|
|
||||||
source: ActionSource.timeline,
|
source: ActionSource.timeline,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<div
|
<div
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
class="relative z-0 grid grid-cols-[--spacing(0)_auto] overflow-hidden sidebar:grid-cols-[--spacing(64)_auto]
|
class="relative z-0 grid grid-cols-[--spacing(0)_auto] overflow-hidden sidebar:grid-cols-[--spacing(64)_auto]
|
||||||
{hideNavbar ? 'h-dvh' : 'h-[calc(100dvh-var(--navbar-height))]'}
|
{hideNavbar ? 'h-dvh' : 'h-[calc(100dvh-var(--navbar-height))] max-md:h-[calc(100dvh-var(--navbar-height-md))]'}
|
||||||
{hideNavbar ? 'pt-(--navbar-height)' : ''}
|
{hideNavbar ? 'pt-(--navbar-height)' : ''}
|
||||||
{hideNavbar ? 'max-md:pt-(--navbar-height-md)' : ''}"
|
{hideNavbar ? 'max-md:pt-(--navbar-height-md)' : ''}"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user