Skip to content

Commit d7824ce

Browse files
authored
Backport: Add ring notification to UserIntent.StartNewCallDM (#3498)
* Add ring notification to UserIntent.StartNewCallDM Signed-off-by: Timo K <[email protected]> * Add more tests (refactor to compute + get) Signed-off-by: Timo K <[email protected]> --------- Signed-off-by: Timo K <[email protected]>
1 parent db5c7cf commit d7824ce

File tree

2 files changed

+108
-41
lines changed

2 files changed

+108
-41
lines changed

src/UrlParams.test.ts

Lines changed: 89 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
55
Please see LICENSE in the repository root for full details.
66
*/
77

8-
import { describe, expect, it } from "vitest";
8+
import { describe, expect, it, onTestFinished, vi } from "vitest";
9+
import { logger } from "matrix-js-sdk/lib/logger";
910

11+
import * as PlatformMod from "../src/Platform";
1012
import {
1113
getRoomIdentifierFromUrl,
12-
getUrlParams,
14+
computeUrlParams,
1315
HeaderStyle,
16+
getUrlParams,
1417
} from "../src/UrlParams";
1518

1619
const ROOM_NAME = "roomNameHere";
@@ -103,16 +106,16 @@ describe("UrlParams", () => {
103106

104107
describe("preload", () => {
105108
it("defaults to false", () => {
106-
expect(getUrlParams().preload).toBe(false);
109+
expect(computeUrlParams().preload).toBe(false);
107110
});
108111

109112
it("ignored in SPA mode", () => {
110-
expect(getUrlParams("?preload=true").preload).toBe(false);
113+
expect(computeUrlParams("?preload=true").preload).toBe(false);
111114
});
112115

113116
it("respected in widget mode", () => {
114117
expect(
115-
getUrlParams(
118+
computeUrlParams(
116119
"?preload=true&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
117120
).preload,
118121
).toBe(true);
@@ -121,19 +124,20 @@ describe("UrlParams", () => {
121124

122125
describe("returnToLobby", () => {
123126
it("is false in SPA mode", () => {
124-
expect(getUrlParams("?returnToLobby=true").returnToLobby).toBe(false);
127+
expect(computeUrlParams("?returnToLobby=true").returnToLobby).toBe(false);
125128
});
126129

127130
it("defaults to false in widget mode", () => {
128131
expect(
129-
getUrlParams("?widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo")
130-
.returnToLobby,
132+
computeUrlParams(
133+
"?widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
134+
).returnToLobby,
131135
).toBe(false);
132136
});
133137

134138
it("respected in widget mode", () => {
135139
expect(
136-
getUrlParams(
140+
computeUrlParams(
137141
"?returnToLobby=true&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
138142
).returnToLobby,
139143
).toBe(true);
@@ -142,12 +146,12 @@ describe("UrlParams", () => {
142146

143147
describe("userId", () => {
144148
it("is ignored in SPA mode", () => {
145-
expect(getUrlParams("?userId=asd").userId).toBe(null);
149+
expect(computeUrlParams("?userId=asd").userId).toBe(null);
146150
});
147151

148152
it("is parsed in widget mode", () => {
149153
expect(
150-
getUrlParams(
154+
computeUrlParams(
151155
"?userId=asd&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
152156
).userId,
153157
).toBe("asd");
@@ -156,12 +160,12 @@ describe("UrlParams", () => {
156160

157161
describe("deviceId", () => {
158162
it("is ignored in SPA mode", () => {
159-
expect(getUrlParams("?deviceId=asd").deviceId).toBe(null);
163+
expect(computeUrlParams("?deviceId=asd").deviceId).toBe(null);
160164
});
161165

162166
it("is parsed in widget mode", () => {
163167
expect(
164-
getUrlParams(
168+
computeUrlParams(
165169
"?deviceId=asd&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
166170
).deviceId,
167171
).toBe("asd");
@@ -170,12 +174,12 @@ describe("UrlParams", () => {
170174

171175
describe("baseUrl", () => {
172176
it("is ignored in SPA mode", () => {
173-
expect(getUrlParams("?baseUrl=asd").baseUrl).toBe(null);
177+
expect(computeUrlParams("?baseUrl=asd").baseUrl).toBe(null);
174178
});
175179

176180
it("is parsed in widget mode", () => {
177181
expect(
178-
getUrlParams(
182+
computeUrlParams(
179183
"?baseUrl=asd&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
180184
).baseUrl,
181185
).toBe("asd");
@@ -185,28 +189,28 @@ describe("UrlParams", () => {
185189
describe("viaServers", () => {
186190
it("is ignored in widget mode", () => {
187191
expect(
188-
getUrlParams(
192+
computeUrlParams(
189193
"?viaServers=asd&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
190194
).viaServers,
191195
).toBe(null);
192196
});
193197

194198
it("is parsed in SPA mode", () => {
195-
expect(getUrlParams("?viaServers=asd").viaServers).toBe("asd");
199+
expect(computeUrlParams("?viaServers=asd").viaServers).toBe("asd");
196200
});
197201
});
198202

199203
describe("homeserver", () => {
200204
it("is ignored in widget mode", () => {
201205
expect(
202-
getUrlParams(
206+
computeUrlParams(
203207
"?homeserver=asd&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
204208
).homeserver,
205209
).toBe(null);
206210
});
207211

208212
it("is parsed in SPA mode", () => {
209-
expect(getUrlParams("?homeserver=asd").homeserver).toBe("asd");
213+
expect(computeUrlParams("?homeserver=asd").homeserver).toBe("asd");
210214
});
211215
});
212216

@@ -237,7 +241,7 @@ describe("UrlParams", () => {
237241
controlledAudioDevices: platform === "desktop" ? false : true,
238242
skipLobby: true,
239243
returnToLobby: false,
240-
sendNotificationType: "notification",
244+
sendNotificationType: platform === "desktop" ? "notification" : "ring",
241245
});
242246
const joinExistingCallDefaults = (platform: string): object => ({
243247
confineToRoom: true,
@@ -252,24 +256,55 @@ describe("UrlParams", () => {
252256
skipLobby: false,
253257
returnToLobby: false,
254258
sendNotificationType: "notification",
259+
defaultAudioEnabled: true,
260+
defaultVideoEnabled: true,
255261
});
256262
it("use no-intent-defaults with unknown intent", () => {
257-
expect(getUrlParams()).toMatchObject(noIntentDefaults);
263+
expect(computeUrlParams()).toMatchObject(noIntentDefaults);
258264
});
259265

260266
it("ignores intent if it is not a valid value", () => {
261-
expect(getUrlParams("?intent=foo")).toMatchObject(noIntentDefaults);
267+
expect(computeUrlParams("?intent=foo")).toMatchObject(noIntentDefaults);
262268
});
263269

264270
it("accepts start_call", () => {
265271
expect(
266-
getUrlParams("?intent=start_call&widgetId=1234&parentUrl=parent.org"),
272+
computeUrlParams(
273+
"?intent=start_call&widgetId=1234&parentUrl=parent.org",
274+
),
267275
).toMatchObject(startNewCallDefaults("desktop"));
268276
});
269277

278+
it("accepts start_call_dm mobile", () => {
279+
vi.spyOn(PlatformMod, "platform", "get").mockReturnValue("android");
280+
onTestFinished(() => {
281+
vi.spyOn(PlatformMod, "platform", "get").mockReturnValue("desktop");
282+
});
283+
expect(
284+
computeUrlParams(
285+
"?intent=start_call_dm&widgetId=1234&parentUrl=parent.org",
286+
),
287+
).toMatchObject(startNewCallDefaults("android"));
288+
});
289+
290+
it("accepts start_call_dm mobile and prioritizes overwritten params", () => {
291+
vi.spyOn(PlatformMod, "platform", "get").mockReturnValue("android");
292+
onTestFinished(() => {
293+
vi.spyOn(PlatformMod, "platform", "get").mockReturnValue("desktop");
294+
});
295+
expect(
296+
computeUrlParams(
297+
"?intent=start_call_dm&widgetId=1234&parentUrl=parent.org&sendNotificationType=notification",
298+
),
299+
).toMatchObject({
300+
...startNewCallDefaults("android"),
301+
sendNotificationType: "notification",
302+
});
303+
});
304+
270305
it("accepts join_existing", () => {
271306
expect(
272-
getUrlParams(
307+
computeUrlParams(
273308
"?intent=join_existing&widgetId=1234&parentUrl=parent.org",
274309
),
275310
).toMatchObject(joinExistingCallDefaults("desktop"));
@@ -278,31 +313,55 @@ describe("UrlParams", () => {
278313

279314
describe("skipLobby", () => {
280315
it("defaults to false", () => {
281-
expect(getUrlParams().skipLobby).toBe(false);
316+
expect(computeUrlParams().skipLobby).toBe(false);
282317
});
283318

284319
it("defaults to false if intent is start_call in SPA mode", () => {
285-
expect(getUrlParams("?intent=start_call").skipLobby).toBe(false);
320+
expect(computeUrlParams("?intent=start_call").skipLobby).toBe(false);
286321
});
287322

288323
it("defaults to true if intent is start_call in widget mode", () => {
289324
expect(
290-
getUrlParams(
325+
computeUrlParams(
291326
"?intent=start_call&widgetId=12345&parentUrl=https%3A%2F%2Flocalhost%2Ffoo",
292327
).skipLobby,
293328
).toBe(true);
294329
});
295330

296331
it("default to false if intent is join_existing", () => {
297-
expect(getUrlParams("?intent=join_existing").skipLobby).toBe(false);
332+
expect(computeUrlParams("?intent=join_existing").skipLobby).toBe(false);
298333
});
299334
});
300335
describe("header", () => {
301336
it("uses header if provided", () => {
302-
expect(getUrlParams("?header=app_bar&hideHeader=true").header).toBe(
337+
expect(computeUrlParams("?header=app_bar&hideHeader=true").header).toBe(
303338
"app_bar",
304339
);
305-
expect(getUrlParams("?header=none&hideHeader=false").header).toBe("none");
340+
expect(computeUrlParams("?header=none&hideHeader=false").header).toBe(
341+
"none",
342+
);
343+
});
344+
});
345+
describe("getUrlParams", () => {
346+
it("uses cached values", () => {
347+
const spy = vi.spyOn(logger, "info");
348+
// call get once
349+
const params = getUrlParams("?header=app_bar&hideHeader=true", "");
350+
// call get twice
351+
expect(getUrlParams("?header=app_bar&hideHeader=true", "")).toBe(params);
352+
// expect compute to only be called once
353+
// it will only log when it is computing the values
354+
expect(spy).toHaveBeenCalledExactlyOnceWith(
355+
"UrlParams: final set of url params\n",
356+
"intent:",
357+
"unknown",
358+
"\nproperties:",
359+
expect.any(Object),
360+
"configuration:",
361+
expect.any(Object),
362+
"intentAndPlatformDerivedConfiguration:",
363+
{},
364+
);
306365
});
307366
});
308367
});

src/UrlParams.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,27 +322,37 @@ let urlParamCache: {
322322
hash?: string;
323323
params?: UrlParams;
324324
} = {};
325+
325326
/**
326-
* Gets the app parameters for the current URL.
327+
* Gets the url params and loads them from a cache if already computed.
327328
* @param search The URL search string
328329
* @param hash The URL hash
329330
* @returns The app parameters encoded in the URL
330331
*/
331332
export const getUrlParams = (
332333
search = window.location.search,
333334
hash = window.location.hash,
334-
/** Skipping the cache might be needed in tests, to allow recomputing based on mocked platform changes. */
335-
skipCache = false,
336335
): UrlParams => {
337-
// Only run the param configuration if we do not yet have it cached for this url.
338336
if (
339337
urlParamCache.search === search &&
340338
urlParamCache.hash === hash &&
341-
urlParamCache.params &&
342-
!skipCache
339+
urlParamCache.params
343340
) {
344341
return urlParamCache.params;
345342
}
343+
const params = computeUrlParams(search, hash);
344+
urlParamCache = { search, hash, params };
345+
346+
return params;
347+
};
348+
349+
/**
350+
* Gets the app parameters for the current URL.
351+
* @param search The URL search string
352+
* @param hash The URL hash
353+
* @returns The app parameters encoded in the URL
354+
*/
355+
export const computeUrlParams = (search = "", hash = ""): UrlParams => {
346356
const parser = new ParamParser(search, hash);
347357

348358
const fontScale = parseFloat(parser.getParam("fontScale") ?? "");
@@ -378,7 +388,7 @@ export const getUrlParams = (
378388
controlledAudioDevices: platform === "desktop" ? false : true,
379389
skipLobby: true,
380390
returnToLobby: false,
381-
sendNotificationType: "notification" as RTCNotificationType,
391+
sendNotificationType: "notification",
382392
autoLeaveWhenOthersLeft: false,
383393
waitForCallPickup: false,
384394
};
@@ -392,6 +402,7 @@ export const getUrlParams = (
392402
break;
393403
case UserIntent.StartNewCallDM:
394404
intentPreset.skipLobby = true;
405+
intentPreset.sendNotificationType = "ring";
395406
intentPreset.autoLeaveWhenOthersLeft = true;
396407
intentPreset.waitForCallPickup = true;
397408

@@ -505,15 +516,12 @@ export const getUrlParams = (
505516
intentAndPlatformDerivedConfiguration,
506517
);
507518

508-
const params = {
519+
return {
509520
...properties,
510521
...intentPreset,
511522
...pickBy(configuration, (v?: unknown) => v !== undefined),
512523
...intentAndPlatformDerivedConfiguration,
513524
};
514-
urlParamCache = { search, hash, params };
515-
516-
return params;
517525
};
518526

519527
/**

0 commit comments

Comments
 (0)