Skip to content

share: Support choosing an account, if there are multiple #1816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,10 @@
"@sharePageTitle": {
"description": "Title for the page about sharing content received from other apps."
},
"shareChooseAccountLabel": "Choose account",
"@shareChooseAccountLabel": {
"description": "Label for the page about selecting an account to share content received from other apps."
},
"mainMenuMyProfile": "My profile",
"@mainMenuMyProfile": {
"description": "Label for main-menu button leading to the user's own profile."
Expand Down
6 changes: 6 additions & 0 deletions lib/generated/l10n/zulip_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,12 @@ abstract class ZulipLocalizations {
/// **'Share'**
String get sharePageTitle;

/// Label for the page about selecting an account to share content received from other apps.
///
/// In en, this message translates to:
/// **'Choose account'**
String get shareChooseAccountLabel;

/// Label for main-menu button leading to the user's own profile.
///
/// In en, this message translates to:
Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'My profile';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_de.dart
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,9 @@ class ZulipLocalizationsDe extends ZulipLocalizations {
@override
String get sharePageTitle => 'Teilen';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'Mein Profil';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'My profile';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_fr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,9 @@ class ZulipLocalizationsFr extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'My profile';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_it.dart
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,9 @@ class ZulipLocalizationsIt extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'Il mio profilo';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_ja.dart
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
@override
String get sharePageTitle => '共有';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => '自分のプロフィール';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_nb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,9 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'My profile';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_pl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,9 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
@override
String get sharePageTitle => 'Udostępnij';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'Mój profil';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_ru.dart
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,9 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
@override
String get sharePageTitle => 'Поделиться';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'Мой профиль';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_sk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,9 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'Môj profil';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_sl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,9 @@ class ZulipLocalizationsSl extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'Moj profil';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_uk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,9 @@ class ZulipLocalizationsUk extends ZulipLocalizations {
@override
String get sharePageTitle => 'Поділитися';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'Мій профіль';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_zh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,9 @@ class ZulipLocalizationsZh extends ZulipLocalizations {
@override
String get sharePageTitle => 'Share';

@override
String get shareChooseAccountLabel => 'Choose account';

@override
String get mainMenuMyProfile => 'My profile';

Expand Down
121 changes: 68 additions & 53 deletions lib/widgets/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,72 @@ class _PreventEmptyStack extends NavigatorObserver {
class ChooseAccountPage extends StatelessWidget {
const ChooseAccountPage({super.key});

Widget _buildAccountItem(
BuildContext context, {
required int accountId,
required Widget title,
Widget? subtitle,
}) {
@override
Widget build(BuildContext context) {
final colorScheme = ColorScheme.of(context);
final zulipLocalizations = ZulipLocalizations.of(context);
assert(!PerAccountStoreWidget.debugExistsOf(context));
final globalStore = GlobalStoreWidget.of(context);

// Borrowed from [AppBar.build].
// See documentation on [ModalRoute.impliesAppBarDismissal]:
// > Whether an [AppBar] in the route should automatically add a back button or
// > close button.
final hasBackButton = ModalRoute.of(context)?.impliesAppBarDismissal ?? false;

return MenuButtonTheme(
data: MenuButtonThemeData(style: MenuItemButton.styleFrom(
backgroundColor: colorScheme.secondaryContainer,
foregroundColor: colorScheme.onSecondaryContainer)),
child: Scaffold(
appBar: AppBar(
titleSpacing: hasBackButton ? null : 16,
title: Text(zulipLocalizations.chooseAccountPageTitle),
actions: const [ChooseAccountPageOverflowButton()]),
body: SafeArea(
minimum: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Flexible(child: SingleChildScrollView(
padding: const EdgeInsets.only(top: 8),
child: Column(mainAxisSize: MainAxisSize.min, children: [
for (final (:accountId, :account) in globalStore.accountEntries)
ChooseAccountListItem(
accountId: accountId,
title: Text(account.realmUrl.toString()),
subtitle: Text(account.email),
showLogoutMenu: true,
onTap: () => HomePage.navigate(context, accountId: accountId)),
]))),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () => Navigator.push(context,
AddAccountPage.buildRoute()),
child: Text(zulipLocalizations.chooseAccountButtonAddAnAccount)),
]))))));
}
}

class ChooseAccountListItem extends StatelessWidget {
const ChooseAccountListItem({
super.key,
required this.accountId,
required this.title,
required this.subtitle,
required this.showLogoutMenu,
required this.onTap,
});

final int accountId;
final Widget title;
final Widget? subtitle;
final bool showLogoutMenu;
final VoidCallback onTap;

@override
Widget build(BuildContext context) {
final colorScheme = ColorScheme.of(context);
final designVariables = DesignVariables.of(context);
final zulipLocalizations = ZulipLocalizations.of(context);
Expand All @@ -325,7 +385,7 @@ class ChooseAccountPage extends StatelessWidget {
subtitle: subtitle,
tileColor: colorScheme.secondaryContainer,
textColor: colorScheme.onSecondaryContainer,
trailing: MenuAnchor(
trailing: !showLogoutMenu ? null : MenuAnchor(
menuChildren: [
MenuItemButton(
onPressed: () async {
Expand Down Expand Up @@ -357,52 +417,7 @@ class ChooseAccountPage extends StatelessWidget {
// The default trailing padding with M3 is 24px. Decrease by 12 because
// IconButton (the "…" button) comes with 12px padding on all sides.
contentPadding: const EdgeInsetsDirectional.only(start: 16, end: 12),
onTap: () => HomePage.navigate(context, accountId: accountId)));
}

@override
Widget build(BuildContext context) {
final colorScheme = ColorScheme.of(context);
final zulipLocalizations = ZulipLocalizations.of(context);
assert(!PerAccountStoreWidget.debugExistsOf(context));
final globalStore = GlobalStoreWidget.of(context);

// Borrowed from [AppBar.build].
// See documentation on [ModalRoute.impliesAppBarDismissal]:
// > Whether an [AppBar] in the route should automatically add a back button or
// > close button.
final hasBackButton = ModalRoute.of(context)?.impliesAppBarDismissal ?? false;

return MenuButtonTheme(
data: MenuButtonThemeData(style: MenuItemButton.styleFrom(
backgroundColor: colorScheme.secondaryContainer,
foregroundColor: colorScheme.onSecondaryContainer)),
child: Scaffold(
appBar: AppBar(
titleSpacing: hasBackButton ? null : 16,
title: Text(zulipLocalizations.chooseAccountPageTitle),
actions: const [ChooseAccountPageOverflowButton()]),
body: SafeArea(
minimum: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Flexible(child: SingleChildScrollView(
padding: const EdgeInsets.only(top: 8),
child: Column(mainAxisSize: MainAxisSize.min, children: [
for (final (:accountId, :account) in globalStore.accountEntries)
_buildAccountItem(context,
accountId: accountId,
title: Text(account.realmUrl.toString()),
subtitle: Text(account.email)),
]))),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () => Navigator.push(context,
AddAccountPage.buildRoute()),
child: Text(zulipLocalizations.chooseAccountButtonAddAnAccount)),
]))))));
onTap: onTap));
}
}

Expand Down
21 changes: 18 additions & 3 deletions lib/widgets/button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import 'theme.dart';
/// The Figma uses this for the "Cancel" and "Save" buttons in the compose box
/// for editing an already-sent message.
///
/// The icon is optional;
/// to provide one, pass [icon] or [buildIcon] but not both.
///
/// See Figma:
/// * Component: https://www.figma.com/design/msWyAJ8cnMHgOMPxi7BUvA/Zulip-Web-UI-kit?node-id=1-2780&t=Wia0D0i1I0GXdD9z-0
/// * Edit-message compose box: https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3988-38201&m=dev
Expand All @@ -22,14 +25,16 @@ class ZulipWebUiKitButton extends StatelessWidget {
this.size = ZulipWebUiKitButtonSize.normal,
required this.label,
this.icon,
this.buildIcon,
required this.onPressed,
});
}) : assert(icon == null || buildIcon == null);

final ZulipWebUiKitButtonAttention attention;
final ZulipWebUiKitButtonIntent intent;
final ZulipWebUiKitButtonSize size;
final String label;
final IconData? icon;
final Widget Function(double size)? buildIcon;
final VoidCallback onPressed;

WidgetStateColor _backgroundColor(DesignVariables designVariables) {
Expand Down Expand Up @@ -141,14 +146,24 @@ class ZulipWebUiKitButton extends StatelessWidget {

final labelColor = _labelColor(designVariables);

final iconSize = 16.0;

Widget? effectiveIcon;
if (icon != null) {
effectiveIcon = Icon(icon); // (size is set in TextButton.styleFrom)
}
if (buildIcon != null) {
effectiveIcon = buildIcon!(iconSize);
}

return AnimatedScaleOnTap(
scaleEnd: 0.96,
duration: Duration(milliseconds: 100),
child: TextButton.icon(
// TODO the gap between the icon and label should be 6px, not 8px
icon: icon != null ? Icon(icon) : null,
icon: effectiveIcon,
style: TextButton.styleFrom(
iconSize: 16,
iconSize: iconSize,
iconColor: labelColor,
padding: EdgeInsets.symmetric(
horizontal: _forSize(6, 10),
Expand Down
Loading
Loading