Skip to content

Commit 23a3cf1

Browse files
committed
Merge remote-tracking branch 'pr/1517'
2 parents 77ab930 + 0960ebc commit 23a3cf1

File tree

10 files changed

+1184
-288
lines changed

10 files changed

+1184
-288
lines changed

lib/model/internal_link.dart

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,23 @@ Uri narrowLink(PerAccountStore store, Narrow narrow, {int? nearMessageId}) {
109109
return result;
110110
}
111111

112+
/// The result of parsing some URL within a Zulip realm,
113+
/// when the URL corresponds to some page in this app.
114+
sealed class InternalLink {
115+
InternalLink({required this.realmUrl});
116+
117+
final Uri realmUrl;
118+
}
119+
120+
/// The result of parsing some URL that points to a narrow on a Zulip realm,
121+
/// when the narrow is of a type that this app understands.
122+
class NarrowLink extends InternalLink {
123+
NarrowLink(this.narrow, this.nearMessageId, {required super.realmUrl});
124+
125+
final Narrow narrow;
126+
final int? nearMessageId;
127+
}
128+
112129
/// A [Narrow] from a given URL, on `store`'s realm.
113130
///
114131
/// `url` must already be a result from [PerAccountStore.tryResolveUrl]
@@ -124,7 +141,7 @@ Uri narrowLink(PerAccountStore store, Narrow narrow, {int? nearMessageId}) {
124141
/// better, but some kinds will be rare, even unheard-of:
125142
/// #narrow/stream/1-announce/stream/1-announce (duplicated operator)
126143
// TODO(#252): handle all valid narrow links, returning a search narrow
127-
Narrow? parseInternalLink(Uri url, PerAccountStore store) {
144+
InternalLink? parseInternalLink(Uri url, PerAccountStore store) {
128145
if (!_isInternalLink(url, store.realmUrl)) return null;
129146

130147
final (category, segments) = _getCategoryAndSegmentsFromFragment(url.fragment);
@@ -155,7 +172,7 @@ bool _isInternalLink(Uri url, Uri realmUrl) {
155172
return (category, segments);
156173
}
157174

158-
Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
175+
NarrowLink? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
159176
assert(segments.isNotEmpty);
160177
assert(segments.length.isEven);
161178

@@ -164,6 +181,7 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
164181
ApiNarrowDm? dmElement;
165182
ApiNarrowWith? withElement;
166183
Set<IsOperand> isElementOperands = {};
184+
int? nearMessageId;
167185

168186
for (var i = 0; i < segments.length; i += 2) {
169187
final (operator, negated) = _parseOperator(segments[i]);
@@ -201,24 +219,26 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
201219
// It is fine to have duplicates of the same [IsOperand].
202220
isElementOperands.add(IsOperand.fromRawString(operand));
203221

204-
case _NarrowOperator.near: // TODO(#82): support for near
205-
continue;
222+
case _NarrowOperator.near:
223+
if (nearMessageId != null) return null;
224+
nearMessageId = int.tryParse(operand, radix: 10);
206225

207226
case _NarrowOperator.unknown:
208227
return null;
209228
}
210229
}
211230

231+
final Narrow? narrow;
212232
if (isElementOperands.isNotEmpty) {
213233
if (streamElement != null || topicElement != null || dmElement != null || withElement != null) {
214234
return null;
215235
}
216236
if (isElementOperands.length > 1) return null;
217237
switch (isElementOperands.single) {
218238
case IsOperand.mentioned:
219-
return const MentionsNarrow();
239+
narrow = const MentionsNarrow();
220240
case IsOperand.starred:
221-
return const StarredMessagesNarrow();
241+
narrow = const StarredMessagesNarrow();
222242
case IsOperand.dm:
223243
case IsOperand.private:
224244
case IsOperand.alerted:
@@ -230,17 +250,20 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
230250
}
231251
} else if (dmElement != null) {
232252
if (streamElement != null || topicElement != null || withElement != null) return null;
233-
return DmNarrow.withUsers(dmElement.operand, selfUserId: store.selfUserId);
253+
narrow = DmNarrow.withUsers(dmElement.operand, selfUserId: store.selfUserId);
234254
} else if (streamElement != null) {
235255
final streamId = streamElement.operand;
236256
if (topicElement != null) {
237-
return TopicNarrow(streamId, topicElement.operand, with_: withElement?.operand);
257+
narrow = TopicNarrow(streamId, topicElement.operand, with_: withElement?.operand);
238258
} else {
239259
if (withElement != null) return null;
240-
return ChannelNarrow(streamId);
260+
narrow = ChannelNarrow(streamId);
241261
}
262+
} else {
263+
return null;
242264
}
243-
return null;
265+
266+
return NarrowLink(narrow, nearMessageId, realmUrl: store.realmUrl);
244267
}
245268

246269
@JsonEnum(fieldRename: FieldRename.kebab, alwaysCreate: true)

0 commit comments

Comments
 (0)