From 53f1b25745ab5bc96037dab50a03ae27e1b5a13f Mon Sep 17 00:00:00 2001 From: chungwwei Date: Tue, 11 Nov 2025 09:48:10 -0500 Subject: [PATCH 1/2] compose_box: Add BuildContext context arg to buildTopicInput --- lib/widgets/compose_box.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/widgets/compose_box.dart b/lib/widgets/compose_box.dart index 6e83356042..c9ad6cca09 100644 --- a/lib/widgets/compose_box.dart +++ b/lib/widgets/compose_box.dart @@ -1435,7 +1435,7 @@ abstract class _ComposeBoxBody extends StatelessWidget { ComposeBoxController get controller; - Widget? buildTopicInput(); + Widget? buildTopicInput(BuildContext context); Widget buildContentInput(); bool getComposeButtonsEnabled(BuildContext context); Widget? buildSendButton(); @@ -1471,7 +1471,7 @@ abstract class _ComposeBoxBody extends StatelessWidget { _AttachFromCameraButton(controller: controller, enabled: composeButtonsEnabled), ]; - final topicInput = buildTopicInput(); + final topicInput = buildTopicInput(context); final sendButton = buildSendButton(); return Column(children: [ Padding( @@ -1509,7 +1509,7 @@ class _StreamComposeBoxBody extends _ComposeBoxBody { @override final StreamComposeBoxController controller; - @override Widget buildTopicInput() => _TopicInput( + @override Widget? buildTopicInput(BuildContext context) => _TopicInput( streamId: narrow.streamId, controller: controller, ); @@ -1537,7 +1537,7 @@ class _FixedDestinationComposeBoxBody extends _ComposeBoxBody { @override final FixedDestinationComposeBoxController controller; - @override Widget? buildTopicInput() => null; + @override Widget? buildTopicInput(BuildContext context) => null; @override Widget buildContentInput() => _FixedDestinationContentInput( narrow: narrow, @@ -1562,7 +1562,7 @@ class _EditMessageComposeBoxBody extends _ComposeBoxBody { @override final EditMessageComposeBoxController controller; - @override Widget? buildTopicInput() => null; + @override Widget? buildTopicInput(BuildContext context) => null; @override Widget buildContentInput() => _EditMessageContentInput( narrow: narrow, From d714978dbc4a91c47d5e6e56724c1c48500b0d2e Mon Sep 17 00:00:00 2001 From: chungwwei Date: Tue, 11 Nov 2025 10:02:13 -0500 Subject: [PATCH 2/2] compose_box: Hide topic input on a general chat only channel Closes: #1604 Fixes: #1843 --- lib/widgets/compose_box.dart | 19 +++++++++++++++---- test/widgets/compose_box_test.dart | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/widgets/compose_box.dart b/lib/widgets/compose_box.dart index c9ad6cca09..925ec17d98 100644 --- a/lib/widgets/compose_box.dart +++ b/lib/widgets/compose_box.dart @@ -1509,10 +1509,21 @@ class _StreamComposeBoxBody extends _ComposeBoxBody { @override final StreamComposeBoxController controller; - @override Widget? buildTopicInput(BuildContext context) => _TopicInput( - streamId: narrow.streamId, - controller: controller, - ); + @override + Widget? buildTopicInput(BuildContext context) { + final store = PerAccountStoreWidget.of(context); + final stream = store.streams[narrow.streamId]; + final topicsPolicy = stream?.topicsPolicy; + + if (topicsPolicy == TopicsPolicy.emptyTopicOnly) { + return null; + } + + return _TopicInput( + streamId: narrow.streamId, + controller: controller, + ); + } @override Widget buildContentInput() => _StreamContentInput( narrow: narrow, diff --git a/test/widgets/compose_box_test.dart b/test/widgets/compose_box_test.dart index d27e374e3b..ff1a0012d7 100644 --- a/test/widgets/compose_box_test.dart +++ b/test/widgets/compose_box_test.dart @@ -2360,6 +2360,30 @@ void main() { // testCancel(narrow: topicNarrow, start: _EditInteractionStart.restoreFailedEdit); // testCancel(narrow: dmNarrow, start: _EditInteractionStart.restoreFailedEdit); }); + + group('compose box inputs visibility by topic policy', () { + void testComposeBoxWidgetVisibility({required TopicsPolicy topicsPolicy, required bool shouldShowTopicInput}) { + final description = shouldShowTopicInput ? + 'show topic input when topic policy is $topicsPolicy': + 'hide topic input when topic policy is $topicsPolicy'; + + testWidgets(description, (tester) async { + final channel = eg.stream(topicsPolicy: topicsPolicy); + + await prepareComposeBox(tester, narrow: ChannelNarrow(channel.streamId), streams: [channel]); + + check(contentInputFinder).findsOne(); + shouldShowTopicInput ? + check(topicInputFinder).findsOne(): + check(topicInputFinder).findsNothing(); + }); + } + + testComposeBoxWidgetVisibility(topicsPolicy: TopicsPolicy.inherit, shouldShowTopicInput: true); + testComposeBoxWidgetVisibility(topicsPolicy: TopicsPolicy.allowEmptyTopic, shouldShowTopicInput: true); + testComposeBoxWidgetVisibility(topicsPolicy: TopicsPolicy.disableEmptyTopic, shouldShowTopicInput: true); + testComposeBoxWidgetVisibility(topicsPolicy: TopicsPolicy.emptyTopicOnly, shouldShowTopicInput: false); + }); } /// How the edit interaction is started: