Skip to content

Commit e2e2eab

Browse files
committed
internal_link [nfc]: Add ApiIsNarrow.
This replaces ApiNarrowIsMentioned and ApiNarrowIsUnread with the generic ApiNarrowIs element. This does not change the internal links behavior, hence the nfc. This is also why this commit hasn't introduced new tests yet. We convert the IsOperand value into a String when constructing ApiNarrowIs, so that we don't need to mingle with ApiNarrowElement.toJson to take care of the enum. Signed-off-by: Zixuan James Li <[email protected]>
1 parent d77baa8 commit e2e2eab

File tree

7 files changed

+59
-20
lines changed

7 files changed

+59
-20
lines changed

lib/api/model/narrow.dart

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import '../../model/internal_link.dart';
2+
13
typedef ApiNarrow = List<ApiNarrowElement>;
24

35
/// Resolve any [ApiNarrowDm] elements appropriately.
@@ -114,19 +116,17 @@ class ApiNarrowPmWith extends ApiNarrowDm {
114116
ApiNarrowPmWith._(super.operand, {super.negated});
115117
}
116118

117-
// TODO: generalize into ApiNarrowIs
118-
class ApiNarrowIsMentioned extends ApiNarrowElement {
119+
class ApiNarrowIs extends ApiNarrowElement {
119120
@override String get operator => 'is';
120-
@override String get operand => 'mentioned';
121121

122-
ApiNarrowIsMentioned({super.negated});
123-
}
122+
@override final String operand;
124123

125-
class ApiNarrowIsUnread extends ApiNarrowElement {
126-
@override String get operator => 'is';
127-
@override String get operand => 'unread';
124+
ApiNarrowIs(IsOperand operand, {super.negated}) : operand = operand.toString();
128125

129-
ApiNarrowIsUnread({super.negated});
126+
factory ApiNarrowIs.fromJson(Map<String, dynamic> json) => ApiNarrowIs(
127+
IsOperand.fromRawString(json['operand'] as String),
128+
negated: json['negated'] as bool? ?? false,
129+
);
130130
}
131131

132132
class ApiNarrowMessageId extends ApiNarrowElement {

lib/model/internal_link.dart

+28-5
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ Uri narrowLink(PerAccountStore store, Narrow narrow, {int? nearMessageId}) {
8585
fragment.write('${element.operand.join(',')}-$suffix');
8686
case ApiNarrowDm():
8787
assert(false, 'ApiNarrowDm should have been resolved');
88-
case ApiNarrowIsMentioned():
89-
fragment.write(element.operand.toString());
90-
case ApiNarrowIsUnread():
88+
case ApiNarrowIs():
9189
fragment.write(element.operand.toString());
9290
case ApiNarrowMessageId():
9391
fragment.write(element.operand.toString());
@@ -154,7 +152,7 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
154152
ApiNarrowStream? streamElement;
155153
ApiNarrowTopic? topicElement;
156154
ApiNarrowDm? dmElement;
157-
ApiNarrowIsMentioned? isMentionedElement;
155+
ApiNarrowIs? isMentionedElement;
158156

159157
for (var i = 0; i < segments.length; i += 2) {
160158
final (operator, negated) = _parseOperator(segments[i]);
@@ -184,7 +182,7 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
184182

185183
case _NarrowOperator.is_:
186184
if (isMentionedElement != null) return null;
187-
if (operand == 'mentioned') isMentionedElement = ApiNarrowIsMentioned();
185+
if (operand == 'mentioned') isMentionedElement = ApiNarrowIs(IsOperand.mentioned);
188186
return null;
189187

190188
case _NarrowOperator.near: // TODO(#82): support for near
@@ -293,3 +291,28 @@ List<int>? _parseDmOperand(String operand) {
293291
return null;
294292
}
295293
}
294+
295+
/// An operand value of "is" operator.
296+
///
297+
/// See also:
298+
/// - https://zulip.com/api/construct-narrow
299+
/// - https://zulip.com/help/search-for-messages#search-your-important-messages
300+
/// - https://zulip.com/help/search-for-messages#search-by-message-status
301+
@JsonEnum(alwaysCreate: true)
302+
enum IsOperand {
303+
dm,
304+
private, // This is deprecated in FL 177 and equivalent to [dm].
305+
alerted,
306+
mentioned,
307+
starred,
308+
followed,
309+
resolved,
310+
unread,
311+
unknown;
312+
313+
static IsOperand fromRawString(String raw) => $enumDecode(
314+
_$IsOperandEnumMap, raw, unknownValue: unknown);
315+
316+
@override
317+
String toString() => _$IsOperandEnumMap[this]!;
318+
}

lib/model/internal_link.g.dart

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/model/narrow.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import '../api/model/model.dart';
55
import '../api/model/narrow.dart';
66
import '../api/route/messages.dart';
77
import 'algorithms.dart';
8+
import 'internal_link.dart';
89

910
/// A Zulip narrow.
1011
sealed class Narrow {
@@ -309,7 +310,7 @@ class MentionsNarrow extends Narrow {
309310
}
310311

311312
@override
312-
ApiNarrow apiEncode() => [ApiNarrowIsMentioned()];
313+
ApiNarrow apiEncode() => [ApiNarrowIs(IsOperand.mentioned)];
313314

314315
@override
315316
bool operator ==(Object other) {

lib/widgets/actions.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
1212
import '../api/model/model.dart';
1313
import '../api/model/narrow.dart';
1414
import '../api/route/messages.dart';
15+
import '../model/internal_link.dart';
1516
import '../model/narrow.dart';
1617
import 'dialog.dart';
1718
import 'store.dart';
@@ -44,7 +45,7 @@ Future<void> markNarrowAsRead(
4445
// The server applies the same optimization within the (deprecated)
4546
// specialized endpoints for marking messages as read; see
4647
// `do_mark_stream_messages_as_read` in `zulip:zerver/actions/message_flags.py`.
47-
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread());
48+
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread));
4849

4950
while (true) {
5051
final result = await updateMessageFlagsForNarrow(connection,

test/widgets/actions_test.dart

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:zulip/api/model/initial_snapshot.dart';
88
import 'package:zulip/api/model/model.dart';
99
import 'package:zulip/api/model/narrow.dart';
1010
import 'package:zulip/api/route/messages.dart';
11+
import 'package:zulip/model/internal_link.dart';
1112
import 'package:zulip/model/localizations.dart';
1213
import 'package:zulip/model/narrow.dart';
1314
import 'package:zulip/model/store.dart';
@@ -54,7 +55,7 @@ void main() {
5455
foundOldest: true, foundNewest: true).toJson());
5556
markNarrowAsRead(context, narrow, false);
5657
await tester.pump(Duration.zero);
57-
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread());
58+
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread));
5859
check(connection.lastRequest).isA<http.Request>()
5960
..method.equals('POST')
6061
..url.path.equals('/api/v1/messages/flags/narrow')
@@ -104,7 +105,7 @@ void main() {
104105
firstProcessedId: 1, lastProcessedId: 1989,
105106
foundOldest: true, foundNewest: false).toJson());
106107
markNarrowAsRead(context, narrow, false);
107-
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread());
108+
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread));
108109
check(connection.lastRequest).isA<http.Request>()
109110
..method.equals('POST')
110111
..url.path.equals('/api/v1/messages/flags/narrow')
@@ -164,7 +165,7 @@ void main() {
164165
foundOldest: true, foundNewest: false).toJson());
165166
markNarrowAsRead(context, narrow, false);
166167
await tester.pump(Duration.zero);
167-
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread());
168+
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread));
168169
check(connection.lastRequest).isA<http.Request>()
169170
..method.equals('POST')
170171
..url.path.equals('/api/v1/messages/flags/narrow')

test/widgets/message_list_test.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:zulip/api/model/initial_snapshot.dart';
1111
import 'package:zulip/api/model/model.dart';
1212
import 'package:zulip/api/model/narrow.dart';
1313
import 'package:zulip/api/route/messages.dart';
14+
import 'package:zulip/model/internal_link.dart';
1415
import 'package:zulip/model/localizations.dart';
1516
import 'package:zulip/model/narrow.dart';
1617
import 'package:zulip/model/store.dart';
@@ -540,7 +541,7 @@ void main() {
540541
firstProcessedId: null, lastProcessedId: null,
541542
foundOldest: true, foundNewest: true).toJson());
542543
await tester.tap(find.byType(MarkAsReadWidget));
543-
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread());
544+
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread));
544545
check(connection.lastRequest).isA<http.Request>()
545546
..method.equals('POST')
546547
..url.path.equals('/api/v1/messages/flags/narrow')

0 commit comments

Comments
 (0)