Skip to content

Commit 9562778

Browse files
committed
msglist: Handle topic permalinks (/with/<id>) just as we do /near/ links
Explanation in a comment, which quotes Greg in #5866. Fixes: #5866
1 parent d30f94e commit 9562778

File tree

3 files changed

+86
-5
lines changed

3 files changed

+86
-5
lines changed

src/message/__tests__/messageActions-test.js

+15
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ describe('messageActions', () => {
6868
pmNarrowFromUsersUnsafe([user1, user2]),
6969
);
7070
});
71+
72+
test('handles /with/ links', async () => {
73+
const stream = eg.makeStream({ stream_id: 1, name: 'test' });
74+
const user1 = eg.makeUser({ user_id: 1, full_name: 'user 1' });
75+
const user2 = eg.makeUser({ user_id: 2, full_name: 'user 2' });
76+
const { store } = prepare({ streams: [stream], users: [user1, user2] });
77+
78+
await checkLink(store, '#narrow/stream/1-test/topic/hello/with/1', topicNarrow(1, 'hello'));
79+
await checkLink(store, '#narrow/dm/1-user-1/with/1', pmNarrowFromUsersUnsafe([user1]));
80+
await checkLink(
81+
store,
82+
'#narrow/dm/1,2-group/with/1',
83+
pmNarrowFromUsersUnsafe([user1, user2]),
84+
);
85+
});
7186
});
7287

7388
describe('doNarrow', () => {

src/utils/__tests__/internalLinks-test.js

+57
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,10 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
194194
[
195195
'/#narrow/channel/1-jest/topic/test',
196196
'/#narrow/channel/4-mobile/subject/topic/near/378333',
197+
'/#narrow/channel/4-mobile/subject/topic/with/378333',
197198
'/#narrow/channel/4-mobile/topic/topic/',
198199
'/#narrow/channel/3-stream/topic/topic/near/1',
200+
'/#narrow/channel/3-stream/topic/topic/with/1',
199201
].forEach(hash => check(hash));
200202
});
201203

@@ -204,9 +206,12 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
204206
[
205207
'/#narrow/stream/jest/topic/test',
206208
'/#narrow/stream/mobile/subject/topic/near/378333',
209+
'/#narrow/stream/mobile/subject/topic/with/378333',
207210
'/#narrow/stream/mobile/topic/topic/',
208211
'/#narrow/stream/stream/topic/topic/near/1',
212+
'/#narrow/stream/stream/topic/topic/with/1',
209213
'/#narrow/stream/stream/subject/topic/near/1',
214+
'/#narrow/stream/stream/subject/topic/with/1',
210215
'/#narrow/stream/stream/subject/topic',
211216
].forEach(hash => check(hash));
212217
});
@@ -216,7 +221,9 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
216221
[
217222
'/#narrow/dm/1,2-group',
218223
'/#narrow/dm/1,2-group/near/1',
224+
'/#narrow/dm/1,2-group/with/1',
219225
'/#narrow/dm/a.40b.2Ecom.2Ec.2Ed.2Ecom/near/3',
226+
'/#narrow/dm/a.40b.2Ecom.2Ec.2Ed.2Ecom/with/3',
220227
].forEach(hash => check(hash));
221228
});
222229

@@ -225,7 +232,9 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
225232
[
226233
'/#narrow/pm-with/1,2-group',
227234
'/#narrow/pm-with/1,2-group/near/1',
235+
'/#narrow/pm-with/1,2-group/with/1',
228236
'/#narrow/pm-with/a.40b.2Ecom.2Ec.2Ed.2Ecom/near/3',
237+
'/#narrow/pm-with/a.40b.2Ecom.2Ec.2Ed.2Ecom/with/3',
229238
].forEach(hash => check(hash));
230239
});
231240

@@ -245,6 +254,9 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
245254
// `near` with no operand
246255
'/#narrow/channel/stream/topic/topic/near/',
247256

257+
// `with` with no operand
258+
'/#narrow/channel/stream/topic/topic/with/',
259+
248260
// `is` with invalid operand
249261
'/#narrow/is/men',
250262
'/#narrow/is/men/channel',
@@ -472,6 +484,31 @@ describe('getNarrowFromNarrowLink (part 2)', () => {
472484
get(`https://example.com/#narrow/stream/${eg.stream.name}/subject/test/near/1`, [eg.stream]),
473485
).toEqual(topicNarrow(eg.stream.stream_id, 'test'));
474486
});
487+
488+
test('on a /with/ link', () => {
489+
const ids = `${userB.user_id},${userC.user_id}`;
490+
expect(get(`https://example.com/#narrow/dm/${ids}-group/with/2`, [])).toEqual(
491+
pmNarrowFromUsersUnsafe([userB, userC]),
492+
);
493+
expect(get(`https://example.com/#narrow/pm-with/${ids}-group/with/2`, [])).toEqual(
494+
pmNarrowFromUsersUnsafe([userB, userC]),
495+
);
496+
497+
expect(
498+
get(
499+
`https://example.com/#narrow/channel/${eg.stream.stream_id}-${eg.stream.name}/topic/test/with/1`,
500+
[eg.stream],
501+
),
502+
).toEqual(topicNarrow(eg.stream.stream_id, 'test'));
503+
504+
expect(
505+
get(`https://example.com/#narrow/stream/${eg.stream.name}/topic/test/with/1`, [eg.stream]),
506+
).toEqual(topicNarrow(eg.stream.stream_id, 'test'));
507+
508+
expect(
509+
get(`https://example.com/#narrow/stream/${eg.stream.name}/subject/test/with/1`, [eg.stream]),
510+
).toEqual(topicNarrow(eg.stream.stream_id, 'test'));
511+
});
475512
});
476513

477514
describe('getNearOperandFromLink', () => {
@@ -485,13 +522,24 @@ describe('getNearOperandFromLink', () => {
485522
expect(getNearOperandFromLink(new URL('/#narrow/near/1', realm), realm)).toBe(1);
486523
});
487524

525+
test('`with` is the only operator', () => {
526+
expect(getNearOperandFromLink(new URL('/#narrow/with/1', realm), realm)).toBe(1);
527+
});
528+
488529
test('when link is a group link, return anchor message id', () => {
489530
expect(getNearOperandFromLink(new URL('/#narrow/dm/1,3-group/near/1/', realm), realm)).toBe(1);
490531
expect(
491532
getNearOperandFromLink(new URL('/#narrow/pm-with/1,3-group/near/1/', realm), realm),
492533
).toBe(1);
493534
});
494535

536+
test('when link is a group link with /with/, return anchor message id', () => {
537+
expect(getNearOperandFromLink(new URL('/#narrow/dm/1,3-group/with/1/', realm), realm)).toBe(1);
538+
expect(
539+
getNearOperandFromLink(new URL('/#narrow/pm-with/1,3-group/with/1/', realm), realm),
540+
).toBe(1);
541+
});
542+
495543
test('when link is a topic link, return anchor message id', () => {
496544
expect(
497545
getNearOperandFromLink(new URL('/#narrow/channel/1-jest/topic/test/near/1', realm), realm),
@@ -500,4 +548,13 @@ describe('getNearOperandFromLink', () => {
500548
getNearOperandFromLink(new URL('/#narrow/stream/jest/topic/test/near/1', realm), realm),
501549
).toBe(1);
502550
});
551+
552+
test('when link is a topic link with /with/, return anchor message id', () => {
553+
expect(
554+
getNearOperandFromLink(new URL('/#narrow/channel/1-jest/topic/test/with/1', realm), realm),
555+
).toBe(1);
556+
expect(
557+
getNearOperandFromLink(new URL('/#narrow/stream/jest/topic/test/with/1', realm), realm),
558+
).toBe(1);
559+
});
503560
});

src/utils/internalLinks.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export const getNarrowFromNarrowLink = (
148148
(hashSegments.length === 2 && (hashSegments[0] === 'pm-with' || hashSegments[0] === 'dm'))
149149
|| (hashSegments.length === 4
150150
&& (hashSegments[0] === 'pm-with' || hashSegments[0] === 'dm')
151-
&& hashSegments[2] === 'near')
151+
&& (hashSegments[2] === 'near' || hashSegments[2] === 'with'))
152152
) {
153153
// TODO: This case is pretty useless in practice, due to basically a
154154
// bug in the webapp: the URL that appears in the location bar for a
@@ -167,7 +167,7 @@ export const getNarrowFromNarrowLink = (
167167
|| (hashSegments.length === 6
168168
&& (hashSegments[0] === 'stream' || hashSegments[0] === 'channel')
169169
&& (hashSegments[2] === 'subject' || hashSegments[2] === 'topic')
170-
&& hashSegments[4] === 'near')
170+
&& (hashSegments[4] === 'near' || hashSegments[4] === 'with'))
171171
) {
172172
const streamId = parseStreamOperand(hashSegments[1], streamsById, streamsByName);
173173
return streamId != null ? topicNarrow(streamId, parseTopicOperand(hashSegments[3])) : null;
@@ -219,9 +219,18 @@ export const getNearOperandFromLink = (url: URL, realm: URL): number | null => {
219219
(str, i) =>
220220
// This is a segment where we expect an operator to be specified.
221221
i % 2 === 0
222-
// The operator is 'near' and its meaning is not negated (`str` does
223-
// not start with "-").
224-
&& str === 'near',
222+
// The operator is 'near' or 'with' and its meaning is not negated
223+
// (`str` does not start with "-").
224+
//
225+
// Quoting Greg from #5866:
226+
// > Currently the app doesn't interpret the "anchor" meaning of
227+
// > `/near/` links at all (that's #3604) — we already effectively
228+
// > give `/near/` links exactly the meaning that the upcoming
229+
// > `/with/` links will have. So to handle the new links, we just
230+
// > need to parse them and then handle them the way we already handle
231+
// > `/near/` links.
232+
// Which makes sense for this legacy codebase.
233+
&& (str === 'near' || str === 'with'),
225234
);
226235
if (nearOperatorIndex < 0) {
227236
return null;

0 commit comments

Comments
 (0)