Skip to content

Commit b10a8ba

Browse files
feat(mobile): move buttons in the bottom sheet to the kebabu menu (#24175)
* refactor: remove bottom sheet buttons * feat: add iconOnly and menuItem parameters to action buttons * feat: enhance action button context and kebab menu integration * feat: use ActionButtonContext * fix: add missing options in some cases --------- Co-authored-by: Alex <[email protected]>
1 parent 7792638 commit b10a8ba

19 files changed

+274
-158
lines changed

mobile/lib/presentation/widgets/action_buttons/advanced_info_action_button.widget.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import 'package:immich_mobile/providers/infrastructure/action.provider.dart';
99

1010
class AdvancedInfoActionButton extends ConsumerWidget {
1111
final ActionSource source;
12+
final bool iconOnly;
13+
final bool menuItem;
1214

13-
const AdvancedInfoActionButton({super.key, required this.source});
15+
const AdvancedInfoActionButton({super.key, required this.source, this.iconOnly = false, this.menuItem = false});
1416

1517
void _onTap(BuildContext context, WidgetRef ref) async {
1618
if (!context.mounted) {
@@ -26,6 +28,8 @@ class AdvancedInfoActionButton extends ConsumerWidget {
2628
maxWidth: 115.0,
2729
iconData: Icons.help_outline_rounded,
2830
label: "troubleshoot".t(context: context),
31+
iconOnly: iconOnly,
32+
menuItem: menuItem,
2933
onPressed: () => _onTap(context, ref),
3034
);
3135
}

mobile/lib/presentation/widgets/action_buttons/archive_action_button.widget.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ Future<void> performArchiveAction(BuildContext context, WidgetRef ref, {required
3535

3636
class ArchiveActionButton extends ConsumerWidget {
3737
final ActionSource source;
38+
final bool iconOnly;
39+
final bool menuItem;
3840

39-
const ArchiveActionButton({super.key, required this.source});
41+
const ArchiveActionButton({super.key, required this.source, this.iconOnly = false, this.menuItem = false});
4042

4143
Future<void> _onTap(BuildContext context, WidgetRef ref) async {
4244
await performArchiveAction(context, ref, source: source);
@@ -47,6 +49,8 @@ class ArchiveActionButton extends ConsumerWidget {
4749
return BaseActionButton(
4850
iconData: Icons.archive_outlined,
4951
label: "to_archive".t(context: context),
52+
iconOnly: iconOnly,
53+
menuItem: menuItem,
5054
onPressed: () => _onTap(context, ref),
5155
);
5256
}

mobile/lib/presentation/widgets/action_buttons/delete_action_button.widget.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart';
1818
class DeleteActionButton extends ConsumerWidget {
1919
final ActionSource source;
2020
final bool showConfirmation;
21-
const DeleteActionButton({super.key, required this.source, this.showConfirmation = false});
21+
final bool iconOnly;
22+
final bool menuItem;
23+
const DeleteActionButton({
24+
super.key,
25+
required this.source,
26+
this.showConfirmation = false,
27+
this.iconOnly = false,
28+
this.menuItem = false,
29+
});
2230

2331
void _onTap(BuildContext context, WidgetRef ref) async {
2432
if (!context.mounted) {
@@ -74,6 +82,8 @@ class DeleteActionButton extends ConsumerWidget {
7482
maxWidth: 110.0,
7583
iconData: Icons.delete_sweep_outlined,
7684
label: "delete".t(context: context),
85+
iconOnly: iconOnly,
86+
menuItem: menuItem,
7787
onPressed: () => _onTap(context, ref),
7888
);
7989
}

mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart';
1414
/// - Prompt to delete the asset locally
1515
class DeleteLocalActionButton extends ConsumerWidget {
1616
final ActionSource source;
17+
final bool iconOnly;
18+
final bool menuItem;
1719

18-
const DeleteLocalActionButton({super.key, required this.source});
20+
const DeleteLocalActionButton({super.key, required this.source, this.iconOnly = false, this.menuItem = false});
1921

2022
void _onTap(BuildContext context, WidgetRef ref) async {
2123
if (!context.mounted) {
@@ -55,6 +57,8 @@ class DeleteLocalActionButton extends ConsumerWidget {
5557
maxWidth: 95.0,
5658
iconData: Icons.no_cell_outlined,
5759
label: "control_bottom_app_bar_delete_from_local".t(context: context),
60+
iconOnly: iconOnly,
61+
menuItem: menuItem,
5862
onPressed: () => _onTap(context, ref),
5963
);
6064
}

mobile/lib/presentation/widgets/action_buttons/delete_permanent_action_button.widget.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart';
1515
/// - Prompt to delete the asset locally
1616
class DeletePermanentActionButton extends ConsumerWidget {
1717
final ActionSource source;
18+
final bool iconOnly;
19+
final bool menuItem;
1820

19-
const DeletePermanentActionButton({super.key, required this.source});
21+
const DeletePermanentActionButton({super.key, required this.source, this.iconOnly = false, this.menuItem = false});
2022

2123
void _onTap(BuildContext context, WidgetRef ref) async {
2224
if (!context.mounted) {
@@ -51,6 +53,8 @@ class DeletePermanentActionButton extends ConsumerWidget {
5153
maxWidth: 110.0,
5254
iconData: Icons.delete_forever,
5355
label: "delete_permanently".t(context: context),
56+
iconOnly: iconOnly,
57+
menuItem: menuItem,
5458
onPressed: () => _onTap(context, ref),
5559
);
5660
}

mobile/lib/presentation/widgets/action_buttons/move_to_lock_folder_action_button.widget.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ Future<void> performMoveToLockFolderAction(BuildContext context, WidgetRef ref,
3838

3939
class MoveToLockFolderActionButton extends ConsumerWidget {
4040
final ActionSource source;
41+
final bool iconOnly;
42+
final bool menuItem;
4143

42-
const MoveToLockFolderActionButton({super.key, required this.source});
44+
const MoveToLockFolderActionButton({super.key, required this.source, this.iconOnly = false, this.menuItem = false});
4345

4446
Future<void> _onTap(BuildContext context, WidgetRef ref) async {
4547
await performMoveToLockFolderAction(context, ref, source: source);
@@ -51,6 +53,8 @@ class MoveToLockFolderActionButton extends ConsumerWidget {
5153
maxWidth: 115.0,
5254
iconData: Icons.lock_outline_rounded,
5355
label: "move_to_locked_folder".t(context: context),
56+
iconOnly: iconOnly,
57+
menuItem: menuItem,
5458
onPressed: () => _onTap(context, ref),
5559
);
5660
}

mobile/lib/presentation/widgets/action_buttons/remove_from_album_action_button.widget.dart

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
22
import 'package:fluttertoast/fluttertoast.dart';
33
import 'package:hooks_riverpod/hooks_riverpod.dart';
44
import 'package:immich_mobile/constants/enums.dart';
5+
import 'package:immich_mobile/domain/models/events.model.dart';
6+
import 'package:immich_mobile/domain/utils/event_stream.dart';
57
import 'package:immich_mobile/extensions/translate_extensions.dart';
68
import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart';
79
import 'package:immich_mobile/providers/infrastructure/action.provider.dart';
@@ -11,8 +13,16 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart';
1113
class RemoveFromAlbumActionButton extends ConsumerWidget {
1214
final String albumId;
1315
final ActionSource source;
16+
final bool iconOnly;
17+
final bool menuItem;
1418

15-
const RemoveFromAlbumActionButton({super.key, required this.albumId, required this.source});
19+
const RemoveFromAlbumActionButton({
20+
super.key,
21+
required this.albumId,
22+
required this.source,
23+
this.iconOnly = false,
24+
this.menuItem = false,
25+
});
1626

1727
void _onTap(BuildContext context, WidgetRef ref) async {
1828
if (!context.mounted) {
@@ -22,6 +32,10 @@ class RemoveFromAlbumActionButton extends ConsumerWidget {
2232
final result = await ref.read(actionProvider.notifier).removeFromAlbum(source, albumId);
2333
ref.read(multiSelectProvider.notifier).reset();
2434

35+
if (source == ActionSource.viewer) {
36+
EventStream.shared.emit(const ViewerReloadAssetEvent());
37+
}
38+
2539
final successMessage = 'remove_from_album_action_prompt'.t(
2640
context: context,
2741
args: {'count': result.count.toString()},
@@ -42,6 +56,8 @@ class RemoveFromAlbumActionButton extends ConsumerWidget {
4256
return BaseActionButton(
4357
iconData: Icons.remove_circle_outline,
4458
label: "remove_from_album".t(context: context),
59+
iconOnly: iconOnly,
60+
menuItem: menuItem,
4561
onPressed: () => _onTap(context, ref),
4662
maxWidth: 100,
4763
);

mobile/lib/presentation/widgets/action_buttons/remove_from_lock_folder_action_button.widget.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart';
1010

1111
class RemoveFromLockFolderActionButton extends ConsumerWidget {
1212
final ActionSource source;
13+
final bool iconOnly;
14+
final bool menuItem;
1315

14-
const RemoveFromLockFolderActionButton({super.key, required this.source});
16+
const RemoveFromLockFolderActionButton({
17+
super.key,
18+
required this.source,
19+
this.iconOnly = false,
20+
this.menuItem = false,
21+
});
1522

1623
void _onTap(BuildContext context, WidgetRef ref) async {
1724
if (!context.mounted) {
@@ -42,6 +49,8 @@ class RemoveFromLockFolderActionButton extends ConsumerWidget {
4249
maxWidth: 100.0,
4350
iconData: Icons.lock_open_rounded,
4451
label: "remove_from_locked_folder".t(context: context),
52+
iconOnly: iconOnly,
53+
menuItem: menuItem,
4554
onPressed: () => _onTap(context, ref),
4655
);
4756
}

mobile/lib/presentation/widgets/action_buttons/share_action_button.widget.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ class _SharePreparingDialog extends StatelessWidget {
3131

3232
class ShareActionButton extends ConsumerWidget {
3333
final ActionSource source;
34+
final bool iconOnly;
35+
final bool menuItem;
3436

35-
const ShareActionButton({super.key, required this.source});
37+
const ShareActionButton({super.key, required this.source, this.iconOnly = false, this.menuItem = false});
3638

3739
void _onTap(BuildContext context, WidgetRef ref) async {
3840
if (!context.mounted) {
@@ -74,6 +76,8 @@ class ShareActionButton extends ConsumerWidget {
7476
return BaseActionButton(
7577
iconData: Platform.isAndroid ? Icons.share_rounded : Icons.ios_share_rounded,
7678
label: 'share'.t(context: context),
79+
iconOnly: iconOnly,
80+
menuItem: menuItem,
7781
onPressed: () => _onTap(context, ref),
7882
);
7983
}

mobile/lib/presentation/widgets/action_buttons/share_link_action_button.widget.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import 'package:immich_mobile/providers/infrastructure/action.provider.dart';
77

88
class ShareLinkActionButton extends ConsumerWidget {
99
final ActionSource source;
10+
final bool iconOnly;
11+
final bool menuItem;
1012

11-
const ShareLinkActionButton({super.key, required this.source});
13+
const ShareLinkActionButton({super.key, required this.source, this.iconOnly = false, this.menuItem = false});
1214

1315
_onTap(BuildContext context, WidgetRef ref) async {
1416
if (!context.mounted) {
@@ -23,6 +25,8 @@ class ShareLinkActionButton extends ConsumerWidget {
2325
return BaseActionButton(
2426
iconData: Icons.link_rounded,
2527
label: "share_link".t(context: context),
28+
iconOnly: iconOnly,
29+
menuItem: menuItem,
2630
onPressed: () => _onTap(context, ref),
2731
);
2832
}

0 commit comments

Comments
 (0)