Skip to content
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 @@ -1247,6 +1247,10 @@
"@wildcardMentionTopicDescription": {
"description": "Description for \"@topic\" wildcard-mention autocomplete options when writing a channel message."
},
"navBarMenuLabel": "Menu",
"@navBarMenuLabel": {
"description": "Label for the Menu button on the bottom navigation bar."
},
Comment on lines +1250 to +1253
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we add entries to this file, we do it in the same commit that uses them. That way it's easier to see them together, and make sure they're used as intended.

"messageIsEditedLabel": "EDITED",
"@messageIsEditedLabel": {
"description": "Label for an edited message. (Use ALL CAPS for cased alphabets: Latin, Greek, Cyrillic, etc.)"
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 @@ -1823,6 +1823,12 @@ abstract class ZulipLocalizations {
/// **'Notify topic'**
String get wildcardMentionTopicDescription;

/// Label for the Menu button on the bottom navigation bar.
///
/// In en, this message translates to:
/// **'Menu'**
String get navBarMenuLabel;

/// Label for an edited message. (Use ALL CAPS for cased alphabets: Latin, Greek, Cyrillic, etc.)
///
/// 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 @@ -1041,6 +1041,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'إخطار الموضوع';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

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 @@ -1065,6 +1065,9 @@ class ZulipLocalizationsDe extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Thema benachrichtigen';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'BEARBEITET';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_el.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,9 @@ class ZulipLocalizationsEl extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

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 @@ -1041,6 +1041,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_es.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,9 @@ class ZulipLocalizationsEs extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

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 @@ -1057,6 +1057,9 @@ class ZulipLocalizationsFr extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_he.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,9 @@ class ZulipLocalizationsHe extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

Expand Down
3 changes: 3 additions & 0 deletions lib/generated/l10n/zulip_localizations_hu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,9 @@ class ZulipLocalizationsHu extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

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 @@ -1060,6 +1060,9 @@ class ZulipLocalizationsIt extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notifica argomento';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'MODIFICATO';

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 @@ -1020,6 +1020,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'トピック参加者に通知';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => '編集済み';

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 @@ -1041,6 +1041,9 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

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 @@ -1056,6 +1056,9 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Powiadom w wątku';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'ZMIENIONO';

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 @@ -1068,6 +1068,9 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Оповестить тему';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'ИЗМЕНЕНО';

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 @@ -1043,6 +1043,9 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'UPRAVENÉ';

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 @@ -1078,6 +1078,9 @@ class ZulipLocalizationsSl extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Obvesti udeležence teme';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'UREJENO';

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 @@ -1057,6 +1057,9 @@ class ZulipLocalizationsUk extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Повідомити канал';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'РЕДАГОВАНО';

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 @@ -1041,6 +1041,9 @@ class ZulipLocalizationsZh extends ZulipLocalizations {
@override
String get wildcardMentionTopicDescription => 'Notify topic';

@override
String get navBarMenuLabel => 'Menu';

@override
String get messageIsEditedLabel => 'EDITED';

Expand Down
79 changes: 49 additions & 30 deletions lib/widgets/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,35 +86,43 @@ class _HomePageState extends State<HomePage> {

@override
Widget build(BuildContext context) {
final zulipLocalizations = ZulipLocalizations.of(context);

const pageBodies = [
(_HomePageTab.inbox, InboxPageBody()),
(_HomePageTab.channels, SubscriptionListPageBody()),
// TODO(#1094): Users
(_HomePageTab.directMessages, RecentDmConversationsPageBody()),
];

_NavigationBarButton button(_HomePageTab tab, IconData icon) {
_NavigationBarButton button(_HomePageTab tab, IconData icon, String label) {
return _NavigationBarButton(icon: icon,
selected: _tab.value == tab,
onPressed: () {
_tab.value = tab;
});
},
label: label);
}

// TODO(a11y): add tooltips for these buttons
final navigationBarButtons = [
button(_HomePageTab.inbox, ZulipIcons.inbox),
button(_HomePageTab.inbox, ZulipIcons.inbox,
zulipLocalizations.inboxPageTitle),
_NavigationBarButton( icon: ZulipIcons.message_feed,
selected: false,
onPressed: () => Navigator.push(context,
MessageListPage.buildRoute(context: context,
narrow: const CombinedFeedNarrow()))),
button(_HomePageTab.channels, ZulipIcons.hash_italic),
narrow: const CombinedFeedNarrow())),
label: zulipLocalizations.combinedFeedPageTitle),
button(_HomePageTab.channels, ZulipIcons.hash_italic,
zulipLocalizations.channelsPageTitle),
// TODO(#1094): Users
button(_HomePageTab.directMessages, ZulipIcons.two_person),
button(_HomePageTab.directMessages, ZulipIcons.two_person,
zulipLocalizations.recentDmConversationsPageTitle),
_NavigationBarButton( icon: ZulipIcons.menu,
selected: false,
onPressed: () => _showMainMenu(context, tabNotifier: _tab)),
onPressed: () => _showMainMenu(context, tabNotifier: _tab),
label: zulipLocalizations.navBarMenuLabel),
];

final designVariables = DesignVariables.of(context);
Expand All @@ -134,17 +142,15 @@ class _HomePageState extends State<HomePage> {
border: Border(top: BorderSide(color: designVariables.borderBar)),
color: designVariables.bgBotBar),
child: SafeArea(
child: SizedBox(height: 48,
child: Center(
child: ConstrainedBox(
// TODO(design): determine a suitable max width for bottom nav bar
constraints: const BoxConstraints(maxWidth: 600),
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
for (final navigationBarButton in navigationBarButtons)
Expanded(child: navigationBarButton),
])))))));
child: ConstrainedBox(
// TODO(design): determine a suitable max width for bottom nav bar
constraints: const BoxConstraints(maxWidth: 600, minHeight: 48),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (final navigationBarButton in navigationBarButtons)
Expanded(child: navigationBarButton),
])))));
}
}

Expand Down Expand Up @@ -231,35 +237,48 @@ class _NavigationBarButton extends StatelessWidget {
required this.icon,
required this.selected,
required this.onPressed,
required this.label,
});

final IconData icon;
final bool selected;
final void Function() onPressed;
final String label;

@override
Widget build(BuildContext context) {
final designVariables = DesignVariables.of(context);

final iconColor = WidgetStateColor.fromMap({
WidgetState.pressed: designVariables.iconSelected,
~WidgetState.pressed: selected ? designVariables.iconSelected
: designVariables.icon,
});
final color = selected ? designVariables.iconSelected : designVariables.icon;

return AnimatedScaleOnTap(
scaleEnd: 0.875,
duration: const Duration(milliseconds: 100),
child: IconButton(
icon: Icon(icon, size: 24),
onPressed: onPressed,
style: IconButton.styleFrom(
child: Material(
type: MaterialType.transparency,
child: InkWell(
borderRadius: BorderRadius.all(Radius.circular(4)),
// TODO(#417): Disable splash effects for all buttons globally.
splashFactory: NoSplash.splashFactory,
highlightColor: designVariables.navigationButtonBg,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4))),
).copyWith(foregroundColor: iconColor)));
onTap: onPressed,
child: Padding(
// (Added 3px horizontal padding not present in Figma, to make the
// text wrap before getting too close to the button's edge, which is
// visible on tap-down.)
padding: const EdgeInsets.fromLTRB(3, 6, 3, 3),
child: Column(
spacing: 3,
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 24, color: color),
Flexible(
child: Text(
label,
style: TextStyle(fontSize: 12, color: color, height: 12 / 12),
textAlign: TextAlign.center,
textScaler: MediaQuery.textScalerOf(context).clamp(maxScaleFactor: 1.5))),
])))));
}
}

Expand Down
34 changes: 34 additions & 0 deletions test/widgets/home_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ void main () {
}

group('bottom nav navigation', () {
final findBottomNavDecoratedBox = find.byWidgetPredicate((widget) {
if (widget is! DecoratedBox) return false;

final decoration = widget.decoration;
if (decoration is! BoxDecoration) return false;

final expectedBorderTop = BorderSide(color: Colors.black.withValues(alpha: 0.2));
return decoration.border == Border(top: expectedBorderTop);
});

// Finds a widget within the bottom navbar's decorated box subtree.
Finder findInBottomNav(Finder finder) =>
find.descendant(of: findBottomNavDecoratedBox, matching: finder);

testWidgets('preserve states when switching between views', (tester) async {
await prepare(tester);
await store.addUser(eg.otherUser);
Expand Down Expand Up @@ -131,6 +145,26 @@ void main () {
matching: find.text('Direct messages'))).findsOne();
});

testWidgets("view switches when labels are tapped", (tester) async {
await prepare(tester);

check(find.descendant(
of: find.byType(ZulipAppBar),
matching: find.text('Inbox'))).findsOne();

await tester.tap(findInBottomNav(find.text('Channels')));
await tester.pump();
check(find.descendant(
of: find.byType(ZulipAppBar),
matching: find.text('Channels'))).findsOne();

await tester.tap(findInBottomNav(find.text('Direct messages')));
await tester.pump();
check(find.descendant(
of: find.byType(ZulipAppBar),
matching: find.text('Direct messages'))).findsOne();
});

testWidgets('combined feed', (tester) async {
await prepare(tester);
pushedRoutes.clear();
Expand Down
2 changes: 1 addition & 1 deletion test/widgets/recent_dm_conversations_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Future<void> setupPage(WidgetTester tester, {

// Switch to direct messages tab.
await tester.tap(find.descendant(
of: find.byType(Center),
of: find.byType(DecoratedBox),
matching: find.byIcon(ZulipIcons.two_person)));
await tester.pump();
}
Expand Down