feat(mobile): move top bar buttons into kebabu menu in AssetViewer (#24461)

* chore(mobile):  i18n: "open_asset_info" in viewer kebab menu

* feat(mobile): move some top buttons into kebabu menu

* refactor(mobile): viewer kebab menu to use context-based button generation

* feat(mobile): refactor action button and kebab menu to use ConsumerWidget for improved state management

* feat(mobile): pass original theme to ViewerKebabMenu for consistent styling

* chore: styling

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
idubnori
2025-12-10 03:26:28 +09:00
committed by GitHub
parent 01e39277e0
commit 7af99b8606
7 changed files with 156 additions and 58 deletions

View File

@@ -1,14 +1,17 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/events.model.dart';
import 'package:immich_mobile/domain/utils/event_stream.dart';
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart';
import 'package:immich_mobile/providers/cast.provider.dart';
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/utils/action_button.utils.dart';
class ViewerKebabMenu extends ConsumerWidget {
const ViewerKebabMenu({super.key});
const ViewerKebabMenu({super.key, this.originalTheme});
final ThemeData? originalTheme;
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -17,25 +20,42 @@ class ViewerKebabMenu extends ConsumerWidget {
return const SizedBox.shrink();
}
final menuChildren = <Widget>[
BaseActionButton(
label: 'about'.tr(),
iconData: Icons.info_outline,
menuItem: true,
onPressed: () => EventStream.shared.emit(const ViewerOpenBottomSheetEvent()),
),
];
final user = ref.watch(currentUserProvider);
final isOwner = asset is RemoteAsset && asset.ownerId == user?.id;
final isCasting = ref.watch(castProvider.select((c) => c.isCasting));
final timelineOrigin = ref.read(timelineServiceProvider).origin;
final kebabContext = ViewerKebabMenuButtonContext(
asset: asset,
isOwner: isOwner,
isCasting: isCasting,
timelineOrigin: timelineOrigin,
originalTheme: originalTheme,
);
final menuChildren = ViewerKebabMenuButtonBuilder.build(kebabContext, context, ref);
return MenuAnchor(
consumeOutsideTap: true,
style: MenuStyle(
backgroundColor: WidgetStatePropertyAll(context.themeData.scaffoldBackgroundColor),
surfaceTintColor: const WidgetStatePropertyAll(Colors.grey),
elevation: const WidgetStatePropertyAll(4),
shape: const WidgetStatePropertyAll(
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))),
),
padding: const WidgetStatePropertyAll(EdgeInsets.symmetric(vertical: 6)),
),
menuChildren: menuChildren,
menuChildren: [
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 150),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: menuChildren,
),
),
],
builder: (context, controller, child) {
return IconButton(
icon: const Icon(Icons.more_vert_rounded),