Add avatar-menu navigation style and inline Android search bar
- New Settings > Appearance > "Navigation menu" toggle (SettingsController.navMenuStyle, NooNavMenuStyle.drawer/avatarMenu): the hamburger-opens-a-Drawer pattern stays the default, or the avatar button opens a full-width dropdown (showAvatarMenu) instead, holding the same hidden-tabs + Settings content the drawer does. Removes one of the two top-corner targets the shell asks a thumb to reach, with no permanent chrome added. - NooTopBar gains androidTitleReplacement so Android's top bar can swap its title for an inline search-field-styled launcher (ShellSearchLauncher) when search isn't in the bottom bar, instead of a bare search icon beside it. - ShellAvatarButton's onTap/label are now overridable so AppTopBar can repoint it per the new setting without this file depending on avatar_menu.dart (which already depends on it for shared helpers). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -212,13 +212,31 @@ class _AccountSwitchRow extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// The current user's avatar in the mobile top bar. Tap opens the accounts
|
||||
/// sheet ([showAccountSwitcher]); swiping up/down on it cycles to the
|
||||
/// next/previous saved account immediately, with no confirmation - a
|
||||
/// shortcut alongside the full switcher.
|
||||
/// sheet ([showAccountSwitcher]) by default - or [onTap], when the caller
|
||||
/// overrides it (`AppTopBar` does this for
|
||||
/// `SettingsController.navMenuStyle`'s `avatarMenu` option, which
|
||||
/// repurposes this same button to open `showAvatarMenu` instead; avoids
|
||||
/// this file importing `widgets/avatar_menu.dart`, which itself imports
|
||||
/// this file for `openSettings`/`accountInitial`/`serverHost`). Swiping
|
||||
/// up/down on it cycles to the next/previous saved account immediately,
|
||||
/// with no confirmation, regardless of [onTap] - a shortcut that stays
|
||||
/// available either way.
|
||||
class ShellAvatarButton extends StatelessWidget {
|
||||
final double hitBox;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const ShellAvatarButton({super.key, this.hitBox = 48});
|
||||
/// Describes whatever [onTap] actually does - defaults to "Accounts"
|
||||
/// (the account switcher), but a caller overriding [onTap] should
|
||||
/// override this too so the tooltip/semantics describe the real action
|
||||
/// instead of a stale default.
|
||||
final String label;
|
||||
|
||||
const ShellAvatarButton({
|
||||
super.key,
|
||||
this.hitBox = 48,
|
||||
this.onTap,
|
||||
this.label = 'Accounts',
|
||||
});
|
||||
|
||||
Future<void> _handleVerticalSwipe(
|
||||
BuildContext context,
|
||||
@@ -246,17 +264,17 @@ class ShellAvatarButton extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final session = context.watch<SessionController>();
|
||||
return Tooltip(
|
||||
message: 'Accounts',
|
||||
message: label,
|
||||
child: Semantics(
|
||||
button: true,
|
||||
label: 'Accounts',
|
||||
label: label,
|
||||
child: GestureDetector(
|
||||
onVerticalDragEnd: (details) =>
|
||||
_handleVerticalSwipe(context, details),
|
||||
child: SizedBox.square(
|
||||
dimension: hitBox,
|
||||
child: InkResponse(
|
||||
onTap: () => showAccountSwitcher(context),
|
||||
onTap: onTap ?? () => showAccountSwitcher(context),
|
||||
radius: hitBox / 2,
|
||||
child: Center(
|
||||
child: NooAvatar(
|
||||
|
||||
Reference in New Issue
Block a user