Skip to content

Commit 3d3b1c1

Browse files
chrisbobbegnprice
authored andcommitted
action_sheet: Show topic in topic action sheet
Fixes #1533.
1 parent 536aa99 commit 3d3b1c1

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

lib/widgets/action_sheet.dart

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,20 @@ void showTopicActionSheet(BuildContext context, {
785785
narrow: TopicNarrow(channelId, topic, with_: someMessageIdInTopic),
786786
pageContext: context));
787787

788-
_showActionSheet(pageContext, buttonSections: [optionButtons]);
788+
final header = BottomSheetHeader(
789+
buildTitle: (baseStyle) => Text.rich(
790+
style: baseStyle,
791+
channelTopicLabelSpan(
792+
context: context,
793+
channelId: channelId,
794+
topic: topic,
795+
fontSize: baseStyle.fontSize!,
796+
color: baseStyle.color!)));
797+
798+
_showActionSheet(pageContext,
799+
header: header,
800+
headerScrollable: false,
801+
buttonSections: [optionButtons]);
789802
}
790803

791804
class UserTopicUpdateButton extends ActionSheetMenuItemButton {

lib/widgets/text.dart

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
44
import 'package:flutter/gestures.dart';
55
import 'package:flutter/material.dart';
66

7+
import '../api/model/model.dart';
78
import '../generated/l10n/zulip_localizations.dart';
89
import 'icons.dart';
910
import 'store.dart';
@@ -582,6 +583,11 @@ class InlineIconGeometryData {
582583
sizeFactor: 0.8,
583584
alphabeticBaselineFactor: 1 / 16,
584585
paddingFactor: 1 / 4),
586+
587+
ZulipIcons.chevron_right: InlineIconGeometryData._(
588+
sizeFactor: 1,
589+
alphabeticBaselineFactor: 5 / 24,
590+
paddingFactor: 0),
585591
};
586592

587593
static final _defaultGeometry = InlineIconGeometryData._(
@@ -637,14 +643,16 @@ WidgetSpan iconWidgetSpan({
637643
child: child);
638644
}
639645

640-
/// An [InlineSpan] with a channel privacy icon and channel name.
646+
/// An [InlineSpan] with a channel privacy icon, channel name,
647+
/// and optionally a chevron-right icon plus topic.
641648
///
642649
/// Pass this to [Text.rich], which can be styled arbitrarily.
643-
/// Pass the [fontSize] of surrounding text
644-
/// so that the icon is sized appropriately.
650+
/// Pass the [fontSize] and [color] of surrounding text
651+
/// so that the icons are sized and colored appropriately.
645652
InlineSpan channelTopicLabelSpan({
646653
required BuildContext context,
647654
required int channelId,
655+
TopicName? topic,
648656
required double fontSize,
649657
required Color color,
650658
}) {
@@ -670,5 +678,20 @@ InlineSpan channelTopicLabelSpan({
670678
TextSpan(
671679
style: TextStyle(fontStyle: FontStyle.italic),
672680
text: zulipLocalizations.unknownChannelName),
681+
if (topic != null) ...[
682+
iconWidgetSpan(
683+
icon: ZulipIcons.chevron_right,
684+
fontSize: fontSize,
685+
baselineType: baselineType,
686+
color: color,
687+
padBefore: true,
688+
padAfter: true),
689+
if (topic.displayName != null)
690+
TextSpan(text: topic.displayName)
691+
else
692+
TextSpan(
693+
style: TextStyle(fontStyle: FontStyle.italic),
694+
text: store.realmEmptyTopicDisplayName),
695+
],
673696
]);
674697
}

test/widgets/action_sheet_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,38 @@ void main() {
805805
checkButton('Copy link to topic');
806806
}
807807

808+
group('header', () {
809+
final findHeader = find.descendant(
810+
of: actionSheetFinder,
811+
matching: find.byType(BottomSheetHeader));
812+
813+
Finder findInHeader(Finder finder) =>
814+
find.descendant(of: findHeader, matching: finder);
815+
816+
testWidgets('with topic', (tester) async {
817+
await prepare();
818+
check(store.streams[someChannel.streamId]).isNotNull()
819+
..inviteOnly.isFalse()..isWebPublic.isFalse();
820+
await showFromAppBar(tester);
821+
check(findInHeader(find.byIcon(ZulipIcons.hash_sign))).findsOne();
822+
check(findInHeader(find.textContaining(someChannel.name))).findsOne();
823+
check(findInHeader(find.textContaining(someTopic))).findsOne();
824+
});
825+
826+
testWidgets('without topic (general chat)', (tester) async {
827+
await prepare(topic: '');
828+
check(store.streams[someChannel.streamId]).isNotNull()
829+
..inviteOnly.isFalse()..isWebPublic.isFalse();
830+
final message = eg.streamMessage(
831+
stream: someChannel, topic: '', sender: eg.otherUser);
832+
await showFromAppBar(tester, messages: [message], topic: eg.t(''));
833+
check(findInHeader(find.byIcon(ZulipIcons.hash_sign))).findsOne();
834+
check(findInHeader(find.textContaining(someChannel.name))).findsOne();
835+
check(findInHeader(find.textContaining(store.realmEmptyTopicDisplayName)))
836+
.findsOne();
837+
});
838+
});
839+
808840
testWidgets('show from inbox; message in Unreads but not in MessageStore', (tester) async {
809841
await prepare(unreadMsgs: eg.unreadMsgs(count: 1,
810842
channels: [eg.unreadChannelMsgs(

0 commit comments

Comments
 (0)