fix(ui): present the library switcher and profile menu as bottom sheets on mobile
Both anchored popups were small tap targets on phones. AppMenuButton gains an opt-in adaptiveSheet flag that routes through showAdaptiveAppMenu: full-width, untitled sheet rows on touch platforms (phones plus Android TV / tvOS), the same anchored popup on desktop.
This commit is contained in:
@@ -664,6 +664,7 @@ class _DiscoverScreenState extends State<DiscoverScreen>
|
||||
? ProfileAvatar(profile: active, size: 32, avatarUrl: activeProvider.avatarUrlFor(active.id))
|
||||
: const AppIcon(Symbols.account_circle_rounded, fill: 1, size: 32, color: Colors.white),
|
||||
tooltip: t.profiles.sectionTitle,
|
||||
adaptiveSheet: true,
|
||||
anchorAlignment: AppMenuAnchorAlignment.end,
|
||||
onSelected: (value) => unawaited(_handleUserMenuAction(context, value)),
|
||||
entriesBuilder: (context) =>
|
||||
|
||||
@@ -634,6 +634,7 @@ class _LibrariesScreenState extends State<LibrariesScreen>
|
||||
return AppMenuButton<String>(
|
||||
key: _libraryDropdownKey,
|
||||
tooltip: t.libraries.selectLibrary,
|
||||
adaptiveSheet: true,
|
||||
onSelected: (libraryGlobalKey) {
|
||||
_loadLibraryContent(libraryGlobalKey);
|
||||
},
|
||||
|
||||
@@ -160,6 +160,12 @@ class AppMenuButton<T> extends StatefulWidget {
|
||||
final Widget? icon;
|
||||
final Widget? child;
|
||||
final String? tooltip;
|
||||
|
||||
/// When true, iOS/Android (phones plus Android TV / tvOS) present the menu
|
||||
/// as an untitled bottom sheet — just the drag handle and rows — via
|
||||
/// [showAdaptiveAppMenu]; desktop keeps the anchored popup. False keeps the
|
||||
/// anchored popup on every platform.
|
||||
final bool adaptiveSheet;
|
||||
final bool enabled;
|
||||
final AppMenuEntryBuilder<T> entriesBuilder;
|
||||
final ValueChanged<T>? onSelected;
|
||||
@@ -170,6 +176,7 @@ class AppMenuButton<T> extends StatefulWidget {
|
||||
this.icon,
|
||||
this.child,
|
||||
this.tooltip,
|
||||
this.adaptiveSheet = false,
|
||||
this.enabled = true,
|
||||
required this.entriesBuilder,
|
||||
this.onSelected,
|
||||
@@ -189,13 +196,21 @@ class AppMenuButtonState<T> extends State<AppMenuButton<T>> {
|
||||
|
||||
final topLeft = renderBox.localToGlobal(Offset.zero);
|
||||
final anchorRect = Rect.fromLTWH(topLeft.dx, topLeft.dy, renderBox.size.width, renderBox.size.height);
|
||||
final selected = await showAppMenu<T>(
|
||||
context,
|
||||
entries: widget.entriesBuilder(context),
|
||||
anchorRect: anchorRect,
|
||||
anchorAlignment: widget.anchorAlignment,
|
||||
focusFirstItem: focusFirstItem,
|
||||
);
|
||||
final selected = widget.adaptiveSheet
|
||||
? await showAdaptiveAppMenu<T>(
|
||||
context,
|
||||
entries: widget.entriesBuilder(context),
|
||||
anchorRect: anchorRect,
|
||||
anchorAlignment: widget.anchorAlignment,
|
||||
focusFirstItem: focusFirstItem,
|
||||
)
|
||||
: await showAppMenu<T>(
|
||||
context,
|
||||
entries: widget.entriesBuilder(context),
|
||||
anchorRect: anchorRect,
|
||||
anchorAlignment: widget.anchorAlignment,
|
||||
focusFirstItem: focusFirstItem,
|
||||
);
|
||||
if (!mounted || selected == null) return selected;
|
||||
widget.onSelected?.call(selected);
|
||||
return selected;
|
||||
|
||||
Reference in New Issue
Block a user