Skip to content

Commit

Permalink
inbox: Add label for archived channels in headers
Browse files Browse the repository at this point in the history
Fixes #800
  • Loading branch information
chimnayajith committed Feb 28, 2025
1 parent d5b5a80 commit 2760c82
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 17 deletions.
4 changes: 4 additions & 0 deletions assets/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,10 @@
"@unknownChannelName": {
"description": "Replacement name for channel when it cannot be found in the store."
},
"channelArchivedLabel": "(archived)",
"@channelArchivedLabel": {
"description": "Label shown next to an archived channel's name in headers."
},
"composeBoxTopicHintText": "Topic",
"@composeBoxTopicHintText": {
"description": "Hint text for topic input widget in compose box."
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 @@ -585,6 +585,12 @@ abstract class ZulipLocalizations {
/// **'(unknown channel)'**
String get unknownChannelName;

/// Label shown next to an archived channel's name in headers.
///
/// In en, this message translates to:
/// **'(archived)'**
String get channelArchivedLabel;

/// Hint text for topic input widget in compose box.
///
/// 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 @@ -286,6 +286,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
@override
String get unknownChannelName => '(unknown channel)';

@override
String get channelArchivedLabel => '(archived)';

@override
String get composeBoxTopicHintText => 'Topic';

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 @@ -286,6 +286,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
@override
String get unknownChannelName => '(unknown channel)';

@override
String get channelArchivedLabel => '(archived)';

@override
String get composeBoxTopicHintText => 'Topic';

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 @@ -286,6 +286,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
@override
String get unknownChannelName => '(unknown channel)';

@override
String get channelArchivedLabel => '(archived)';

@override
String get composeBoxTopicHintText => 'Topic';

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 @@ -286,6 +286,9 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
@override
String get unknownChannelName => '(unknown channel)';

@override
String get channelArchivedLabel => '(archived)';

@override
String get composeBoxTopicHintText => 'Topic';

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 @@ -286,6 +286,9 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
@override
String get unknownChannelName => '(nieznany kanał)';

@override
String get channelArchivedLabel => '(archived)';

@override
String get composeBoxTopicHintText => 'Wątek';

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 @@ -286,6 +286,9 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
@override
String get unknownChannelName => '(unknown channel)';

@override
String get channelArchivedLabel => '(archived)';

@override
String get composeBoxTopicHintText => 'Тема';

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 @@ -286,6 +286,9 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
@override
String get unknownChannelName => '(unknown channel)';

@override
String get channelArchivedLabel => '(archived)';

@override
String get composeBoxTopicHintText => 'Topic';

Expand Down
36 changes: 28 additions & 8 deletions lib/widgets/inbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ abstract class _HeaderItem extends StatelessWidget {
final _InboxPageState pageState;
final int count;
final bool hasMention;
final bool isArchived;

/// A build context within the [_StreamSection] or [_AllDmsSection].
///
Expand All @@ -236,6 +237,7 @@ abstract class _HeaderItem extends StatelessWidget {
required this.count,
required this.hasMention,
required this.sectionContext,
this.isArchived = false,
});

String title(ZulipLocalizations zulipLocalizations);
Expand Down Expand Up @@ -284,16 +286,32 @@ abstract class _HeaderItem extends StatelessWidget {
const SizedBox(width: 5),
Expanded(child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Text(
style: TextStyle(
fontSize: 17,
height: (20 / 17),
// TODO(design) check if this is the right variable
color: designVariables.labelMenuButton,
).merge(weightVariableTextStyle(context, wght: 600)),
child: RichText(
maxLines: 1,
overflow: TextOverflow.ellipsis,
title(zulipLocalizations)))),
text: TextSpan(
children: [
TextSpan(
text: title(zulipLocalizations),
style: TextStyle(
fontSize: 17,
height: 20 / 17,
// TODO(design) check if this is the right variable
color: designVariables.labelMenuButton,
).merge(weightVariableTextStyle(context, wght: 600))),
if (isArchived)
// TODO(#1285): Avoid concatenating translated strings
WidgetSpan(
child: Padding(
padding: EdgeInsetsDirectional.only(start: 4),
child: Text(
' ${zulipLocalizations.channelArchivedLabel}',
style: TextStyle(
fontSize: 17,
height: 20 / 17,
color: MessageListTheme.of(context).streamRecipientHeaderChevronRight,
fontStyle: FontStyle.italic)))),
])))),
const SizedBox(width: 12),
if (hasMention) const _IconMarker(icon: ZulipIcons.at_sign),
Padding(padding: const EdgeInsetsDirectional.only(end: 16),
Expand Down Expand Up @@ -441,6 +459,7 @@ class _StreamHeaderItem extends _HeaderItem {
required super.count,
required super.hasMention,
required super.sectionContext,
required super.isArchived,
});

@override String title(ZulipLocalizations zulipLocalizations) =>
Expand Down Expand Up @@ -487,6 +506,7 @@ class _StreamSection extends StatelessWidget {
collapsed: collapsed,
pageState: pageState,
sectionContext: context,
isArchived: subscription.isArchived,
);
return StickyHeaderItem(
header: header,
Expand Down
20 changes: 20 additions & 0 deletions lib/widgets/message_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ class MessageListAppBarTitle extends StatelessWidget {
ZulipStream? stream,
}) {
final zulipLocalizations = ZulipLocalizations.of(context);
final messageListTheme = MessageListTheme.of(context);
// A null [Icon.icon] makes a blank space.
final icon = stream != null ? iconDataForStream(stream) : null;
return Row(
Expand All @@ -351,6 +352,15 @@ class MessageListAppBarTitle extends StatelessWidget {
const SizedBox(width: 4),
Flexible(child: Text(
stream?.name ?? zulipLocalizations.unknownChannelName)),
if (stream?.isArchived ?? false)
Padding(
padding: EdgeInsetsDirectional.fromSTEB(4, 4, 0, 4),
child: Text(
' ${zulipLocalizations.channelArchivedLabel}',
style: TextStyle(
fontSize: 18,
color: messageListTheme.streamRecipientHeaderChevronRight,
fontStyle: FontStyle.italic))),
]);
}

Expand Down Expand Up @@ -1101,6 +1111,16 @@ class StreamMessageRecipientHeader extends StatelessWidget {
style: recipientHeaderTextStyle(context),
overflow: TextOverflow.ellipsis),
),
if (stream?.isArchived ?? false)
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(4, 4, 0, 4),
child: Text(
' ${zulipLocalizations.channelArchivedLabel}',
style: recipientHeaderTextStyle(context).copyWith(
color: messageListTheme.streamRecipientHeaderChevronRight,
fontStyle: FontStyle.italic),
overflow: TextOverflow.ellipsis,
maxLines: 1)),
Padding(
// Figma has 5px horizontal padding around an 8px wide icon.
// Icon is 16px wide here so horizontal padding is 1px.
Expand Down
62 changes: 53 additions & 9 deletions test/widgets/inbox_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,29 @@ void main() {

/// Find a row with the given label.
Widget? findRowByLabel(WidgetTester tester, String label) {
final rowLabel = tester.widgetList(
find.text(label),
).firstOrNull;
if (rowLabel == null) {
return null;
final textFinder = find.text(label);
if (textFinder.evaluate().isNotEmpty) {
return tester.widget(
find.ancestor(
of: textFinder.first,
matching: find.byType(Row))
);
}

return tester.widget(
find.ancestor(
of: find.byWidget(rowLabel),
matching: find.byType(Row)));
final richTextFinder = find.byWidgetPredicate((widget) =>
widget is RichText &&
widget.text.toPlainText().contains(label)
);

if (richTextFinder.evaluate().isNotEmpty) {
return tester.widget(
find.ancestor(
of: richTextFinder.first,
matching: find.byType(Row))
);
}

return null;
}

/// Find the all-DMs header element.
Expand Down Expand Up @@ -595,6 +607,38 @@ void main() {
check(rectAfterTap).equals(rectBeforeTap);
});

testWidgets('shows archived label for archived streams', (tester) async {
final stream = eg.stream(streamId: 1, isArchived: true);
final subscription = eg.subscription(stream);
await setupPage(tester,
streams: [stream],
subscriptions: [subscription],
unreadMessages: [eg.streamMessage(stream: stream)]);
await tester.pumpAndSettle();

final headerRowFinder = findStreamHeaderRow(tester, stream.streamId);
check(headerRowFinder).isNotNull();

final richTextFinder = find.descendant(
of: find.byWidget(headerRowFinder!),
matching: find.byWidgetPredicate((widget) =>
widget is RichText &&
widget.text.toPlainText().contains(stream.name)
),
);
expect(richTextFinder, findsOneWidget);

final archivedLabelFinder = find.descendant(
of: find.byWidget(headerRowFinder),
matching: find.text(' (archived)')
);
expect(archivedLabelFinder, findsOneWidget);

// Check that the Text widget has italic style
final archivedLabelText = tester.widget<Text>(archivedLabelFinder);
expect(archivedLabelText.style?.fontStyle, FontStyle.italic);
});

// TODO check it remains collapsed even if you scroll far away and back

// TODO check that it's always uncollapsed when it appears after being
Expand Down
22 changes: 22 additions & 0 deletions test/widgets/message_list_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,28 @@ void main() {
await tester.pump();
check(pushedRoutes).isEmpty();
});

testWidgets('shows archived label for archived streams', (tester) async {
final stream = eg.stream(streamId: 1, name: 'stream name', isArchived: true);
final message = eg.streamMessage(stream: stream, topic: 'topic');

await setupMessageListPage(tester,
narrow: const CombinedFeedNarrow(),
messages: [message],
streams: [stream],
subscriptions: [eg.subscription(stream)]);
await tester.pump();

check(findInMessageList('stream name')).length.equals(1);
check(findInMessageList(" (archived)")).length.equals(1);

final archivedLabelFinder = find.descendant(
of: find.byType(MessageList),
matching: find.text(" (archived)"),
);
final textWidget = tester.widget<Text>(archivedLabelFinder);
expect(textWidget.style?.fontStyle, FontStyle.italic);
});
});

group('DmRecipientHeader', () {
Expand Down

0 comments on commit 2760c82

Please sign in to comment.