From 8da38d173add53cef20aae45bd90cc619fdb9745 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 22 Nov 2024 18:12:29 +0000 Subject: [PATCH 01/11] Remove .well-known files from build process (#2830) These don't get included in the docker images anyhow (due to them being excluded by defautl by https://github.com/actions/upload-artifact#uploading-hidden-files). We need to inject the right values into our managed deployments elsewhere. --- public/.well-known/apple-app-site-association | 26 --------------- public/.well-known/assetlinks.json | 32 ------------------- 2 files changed, 58 deletions(-) delete mode 100644 public/.well-known/apple-app-site-association delete mode 100644 public/.well-known/assetlinks.json diff --git a/public/.well-known/apple-app-site-association b/public/.well-known/apple-app-site-association deleted file mode 100644 index 088a1a04..00000000 --- a/public/.well-known/apple-app-site-association +++ /dev/null @@ -1,26 +0,0 @@ -{ - "applinks": { - "details": [ - { - "appIDs": [ - "7J4U792NQT.io.element.elementx", - "7J4U792NQT.io.element.elementx.nightly", - "7J4U792NQT.io.element.elementx.pr" - ], - "components": [ - { - "?": { - "no_universal_links": "?*" - }, - "exclude": true, - "comment": "Opt out of universal links" - }, - { - "/": "/*", - "comment": "Matches any URL" - } - ] - } - ] - } -} diff --git a/public/.well-known/assetlinks.json b/public/.well-known/assetlinks.json deleted file mode 100644 index 6f64bcc5..00000000 --- a/public/.well-known/assetlinks.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "relation": ["delegate_permission/common.handle_all_urls"], - "target": { - "namespace": "android_app", - "package_name": "io.element.android.x.debug", - "sha256_cert_fingerprints": [ - "B0:B0:51:DC:56:5C:81:2F:E1:7F:6F:3E:94:5B:4D:79:04:71:23:AB:0D:A6:12:86:76:9E:B2:94:91:97:13:0E" - ] - } - }, - { - "relation": ["delegate_permission/common.handle_all_urls"], - "target": { - "namespace": "android_app", - "package_name": "io.element.android.x.nightly", - "sha256_cert_fingerprints": [ - "CA:D3:85:16:84:3A:05:CC:EB:00:AB:7B:D3:80:0F:01:BA:8F:E0:4B:38:86:F3:97:D8:F7:9A:1B:C4:54:E4:0F" - ] - } - }, - { - "relation": ["delegate_permission/common.handle_all_urls"], - "target": { - "namespace": "android_app", - "package_name": "io.element.android.x", - "sha256_cert_fingerprints": [ - "C6:DB:9B:9C:8C:BD:D6:5D:16:E8:EC:8C:8B:91:C8:31:B9:EF:C9:5C:BF:98:AE:41:F6:A9:D8:35:15:1A:7E:16" - ] - } - } -] From 51e4a3b14bf0cce77071d459caf2dda3161ac0b3 Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 22 Nov 2024 13:17:05 -0500 Subject: [PATCH 02/11] Don't trigger keyboard shortcuts if modifiers are held None of these keyboard shortcuts expect modifier keys, so they should in fact expect the absence of modifiers. --- src/useCallViewKeyboardShortcuts.test.tsx | 10 ++++++++++ src/useCallViewKeyboardShortcuts.ts | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/useCallViewKeyboardShortcuts.test.tsx b/src/useCallViewKeyboardShortcuts.test.tsx index 9b8d45e7..fdf7ed85 100644 --- a/src/useCallViewKeyboardShortcuts.test.tsx +++ b/src/useCallViewKeyboardShortcuts.test.tsx @@ -93,6 +93,16 @@ test("reactions can be sent via keyboard presses", async () => { } }); +test("reaction is not sent when modifier key is held", async () => { + const user = userEvent.setup(); + + const sendReaction = vi.fn(); + render(); + + await user.keyboard("{Meta>}1{/Meta}"); + expect(sendReaction).not.toHaveBeenCalled(); +}); + test("raised hand can be sent via keyboard presses", async () => { const user = userEvent.setup(); diff --git a/src/useCallViewKeyboardShortcuts.ts b/src/useCallViewKeyboardShortcuts.ts index 7c27e1e2..77028a27 100644 --- a/src/useCallViewKeyboardShortcuts.ts +++ b/src/useCallViewKeyboardShortcuts.ts @@ -43,6 +43,8 @@ export function useCallViewKeyboardShortcuts( (event: KeyboardEvent) => { if (focusElement.current === null) return; if (!mayReceiveKeyEvents(focusElement.current)) return; + if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) + return; if (event.key === "m") { event.preventDefault(); From 44e1c136dfd3336c2b75ca35cc651ffef4afa484 Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 22 Nov 2024 13:45:39 -0500 Subject: [PATCH 03/11] Fix a singular string using the plural form --- locales/en-GB/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en-GB/app.json b/locales/en-GB/app.json index 0b9142d2..6340d160 100644 --- a/locales/en-GB/app.json +++ b/locales/en-GB/app.json @@ -171,7 +171,7 @@ "preferences_tab_show_hand_raised_timer_label": "Show hand raise duration", "speaker_device_selection_label": "Speaker" }, - "star_rating_input_label_one": "{{count}} stars", + "star_rating_input_label_one": "{{count}} star", "star_rating_input_label_other": "{{count}} stars", "start_new_call": "Start new call", "start_video_button_label": "Start video", From 9ce16b68e9900b2a5c92e524aacc266d6df0415f Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sat, 23 Nov 2024 08:51:27 +0000 Subject: [PATCH 04/11] Refactor URL parameters into table (#2827) * Refactor URL parameters into table This is for readability and ahead of some possible changes * Whitespace * Lint * Cleanup and correct fontScale --- docs/url-params.md | 254 ++++++--------------------------------------- 1 file changed, 31 insertions(+), 223 deletions(-) diff --git a/docs/url-params.md b/docs/url-params.md index c45c2610..267c65f6 100644 --- a/docs/url-params.md +++ b/docs/url-params.md @@ -25,230 +25,38 @@ There are two formats for Element Call urls. ``` With this format the livekit alias that will be used is the ``. - All ppl connecting to this url will end up in the same unencrypted room. + All people connecting to this URL will end up in the same unencrypted room. This does not scale, is super unsecure - (ppl could end up in the same room by accident) and it also is not really + (people could end up in the same room by accident) and it also is not really possible to support encryption. - The url parameters are spit into two categories: **general** and **widget related**. -## Widget related params +## Parameters -**widgetId** -The id used by the widget. The presence of this parameter implies that element -call will not connect to a homeserver directly and instead tries to establish -postMessage communication via the `parentUrl`. - -```ts -widgetId: string | null; -``` - -**parentUrl** -The url used to send widget action postMessages. This should be the domain of -the client or the webview the widget is hosted in. (in case the widget is not -in an Iframe but in a dedicated webview we send the postMessages same webview -the widget lives in. Filtering is done in the widget so it ignores the messages -it receives from itself) - -```ts -parentUrl: string | null; -``` - -**userId** -The user's ID (only used in matryoshka mode). - -```ts -userId: string | null; -``` - -**deviceId** -The device's ID (only used in matryoshka mode). - -```ts -deviceId: string | null; -``` - -**baseUrl** -The base URL of the homeserver to use for media lookups in matryoshka mode. - -```ts -baseUrl: string | null; -``` - -### General url parameters - -**roomId** -Anything about what room we're pointed to should be from useRoomIdentifier which -parses the path and resolves alias with respect to the default server name, however -roomId is an exception as we need the room ID in embedded (matroyska) mode, and not -the room alias (or even the via params because we are not trying to join it). This -is also not validated, where it is in useRoomIdentifier(). - -```ts -roomId: string | null; -``` - -**confineToRoom** -Whether the app should keep the user confined to the current call/room. - -```ts -confineToRoom: boolean; (default: false) -``` - -**appPrompt** -Whether upon entering a room, the user should be prompted to launch the -native mobile app. (Affects only Android and iOS.) - -The app prompt must also be enabled in the config for this to take effect. - -```ts -appPrompt: boolean; (default: true) -``` - -**preload** -Whether the app should pause before joining the call until it sees an -io.element.join widget action, allowing it to be preloaded. - -```ts -preload: boolean; (default: false) -``` - -**hideHeader** -Whether to hide the room header when in a call. - -```ts -hideHeader: boolean; (default: false) -``` - -**showControls** -Whether to show the buttons to mute, screen-share, invite, hangup are shown -when in a call. - -```ts -showControls: boolean; (default: true) -``` - -**hideScreensharing** -Whether to hide the screen-sharing button. - -```ts -hideScreensharing: boolean; (default: false) -``` - -**enableE2EE** (Deprecated) -Whether to use end-to-end encryption. This is a legacy flag for the full mesh branch. -It is not used on the livekit branch and has no impact there! - -```ts -enableE2EE: boolean; (default: true) -``` - -**perParticipantE2EE** -Whether to use per participant encryption. -Keys will be exchanged over encrypted matrix room messages. - -```ts -perParticipantE2EE: boolean; (default: false) -``` - -**password** -E2EE password when using a shared secret. -(For individual sender keys in embedded mode this is not required.) - -```ts -password: string | null; -``` - -**displayName** -The display name to use for auto-registration. - -```ts -displayName: string | null; -``` - -**lang** -The BCP 47 code of the language the app should use. - -```ts -lang: string | null; -``` - -**fonts** -The font/fonts which the interface should use. -There can be multiple font url parameters: `?font=font-one&font=font-two...` - -```ts -font: string; -font: string; -... -``` - -**fontScale** -The factor by which to scale the interface's font size. - -```ts -fontScale: number | null; -``` - -**analyticsID** -The Posthog analytics ID. It is only available if the user has given consent for -sharing telemetry in element web. - -```ts -analyticsID: string | null; -``` - -**allowIceFallback** -Whether the app is allowed to use fallback STUN servers for ICE in case the -user's homeserver doesn't provide any. - -```ts -allowIceFallback: boolean; (default: false) -``` - -**skipLobby** -Setting this flag skips the lobby and brings you in the call directly. -In the widget this can be combined with preload to pass the device settings -with the join widget action. - -```ts -skipLobby: boolean; (default: false) -``` - -**returnToLobby** -Setting this flag makes element call show the lobby in widget mode after leaving -a call. -This is useful for video rooms. -If set to false, the widget will show a blank page after leaving the call. - -```ts -returnToLobby: boolean; (default: false) -``` - -**theme** -The theme to use for element call. -can be "light", "dark", "light-high-contrast" or "dark-high-contrast". -If not set element call will use the dark theme. - -```ts -theme: string | null; -``` - -**viaServers** -This defines the homeserver that is going to be used when joining a room. -It has to be set to a non default value for links to rooms -that are not on the default homeserver, -that is in use for the current user. - -```ts -viaServers: string; (default: undefined) -``` - -**homeserver** -This defines the homeserver that is going to be used when registering -a new (guest) user. -This can be user to configure a non default guest user server when -creating a spa link. - -```ts -homeserver: string; (default: undefined) -``` +| Name | Values | Required for widget | Required for SPA | Description | +| ------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `allowIceFallback` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Allows use of fallback STUN servers for ICE if the user's homeserver doesn’t provide any. | +| `analyticsID` | Posthog analytics ID | No | No | Available only with user's consent for sharing telemetry in Element Web. | +| `appPrompt` | `true` or `false` | No, defaults to `true` | No, defaults to `true` | Prompts the user to launch the native mobile app upon entering a room, applicable only on Android and iOS, and must be enabled in config. | +| `baseUrl` | | Yes | Not applicable | The base URL of the homeserver to use for media lookups. | +| `confineToRoom` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Keeps the user confined to the current call/room. | +| `deviceId` | Matrix device ID | Yes | Not applicable | The Matrix device ID for the widget host. | +| `displayName` | | No | No | Display name used for auto-registration. | +| `enableE2EE` (deprecated) | `true` or `false` | No, defaults to `true` | No, defaults to `true` | Legacy flag to enable end-to-end encryption, not used in the `livekit` branch. | +| `fontScale` | A decimal number such as `0.9` | No | No | Factor by which to scale the interface's font size. | +| `fonts` | | No | No | Defines the font(s) used by the interface. Multiple font parameters can be specified: `?font=font-one&font=font-two...`. | +| `hideHeader` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Hides the room header when in a call. | +| `hideScreensharing` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Hides the screen-sharing button. | +| `homeserver` | | Not applicable | No | Homeserver for registering a new (guest) user, configures non-default guest user server when creating a spa link. | +| `lang` | [BCP 47](https://www.rfc-editor.org/info/bcp47) code | No | No | The language the app should use. | +| `parentUrl` | | Yes | Not applicable | The url used to send widget action postMessages. This should be the domain of the client or the webview the widget is hosted in. (in case the widget is not in an Iframe but in a dedicated webview we send the postMessages same WebView the widget lives in. Filtering is done in the widget so it ignores the messages it receives from itself) | +| `password` | | No | No | E2EE password when using a shared secret. (For individual sender keys in embedded mode this is not required.) | +| `perParticipantE2EE` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Enables per participant encryption with Keys exchanged over encrypted matrix room messages. | +| `preload` | `true` or `false` | No, defaults to `false` | Not applicable | Pauses app before joining a call until an `io.element.join` widget action is seen, allowing preloading. | +| `returnToLobby` | `true` or `false` | No, defaults to `false` | Not applicable | Displays the lobby in widget mode after leaving a call; shows a blank page if set to `false`. Useful for video rooms. | +| `roomId` | [Matrix Room ID](https://spec.matrix.org/v1.12/appendices/#room-ids) | Yes | No | Anything about what room we're pointed to should be from useRoomIdentifier which parses the path and resolves alias with respect to the default server name, however roomId is an exception as we need the room ID in embedded widget mode, and not the room alias (or even the via params because we are not trying to join it). This is also not validated, where it is in `useRoomIdentifier()`. | +| `showControls` | `true` or `false` | No, defaults to `true` | No, defaults to `true` | Displays controls like mute, screen-share, invite, and hangup buttons during a call. | +| `skipLobby` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Skips the lobby to join a call directly, can be combined with preload in widget. | +| `theme` | One of: `light`, `dark`, `light-high-contrast`, `dark-high-contrast` | No, defaults to `dark` | No, defaults to `dark` | UI theme to use. | +| `userId` | [Matrix User Identifier](https://spec.matrix.org/v1.12/appendices/#user-identifiers) | Yes | Not applicable | The Matrix user ID. | +| `viaServers` | Comma separated list of [Matrix Server Names](https://spec.matrix.org/v1.12/appendices/#server-name) | Not applicable | No | Homeserver for joining a room, non-empty value required for rooms not on the user’s default homeserver. | +| `widgetId` | [MSC2774](https://github.com/matrix-org/matrix-spec-proposals/pull/2774) format widget ID | Yes | Not applicable | The id used by the widget. The presence of this parameter implies that element call will not connect to a homeserver directly and instead tries to establish postMessage communication via the `parentUrl`. | From 5c18868aa46861519ebffead338b32f44ea09d85 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sat, 23 Nov 2024 08:55:03 +0000 Subject: [PATCH 05/11] The preload URL param shouldn't be used in SPA mode, so ignore it if not in widget (#2832) * Refactor URL parameters into table This is for readability and ahead of some possible changes * Whitespace * Lint * The preload URL param shouldn't be used in SPA mode, so ignore it --- src/UrlParams.test.ts | 16 +++++++++++++++- src/UrlParams.ts | 7 +++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/UrlParams.test.ts b/src/UrlParams.test.ts index 2bf12a6b..47428ac6 100644 --- a/src/UrlParams.test.ts +++ b/src/UrlParams.test.ts @@ -7,7 +7,7 @@ Please see LICENSE in the repository root for full details. import { describe, expect, it } from "vitest"; -import { getRoomIdentifierFromUrl } from "../src/UrlParams"; +import { getRoomIdentifierFromUrl, getUrlParams } from "../src/UrlParams"; const ROOM_NAME = "roomNameHere"; const ROOM_ID = "!d45f138fsd"; @@ -86,4 +86,18 @@ describe("UrlParams", () => { .roomAlias, ).toBeFalsy(); }); + + describe("preload", () => { + it("defaults to false", () => { + expect(getUrlParams().preload).toBe(false); + }); + + it("ignored in SPA mode", () => { + expect(getUrlParams("?preload=true").preload).toBe(false); + }); + + it("respected in widget mode", () => { + expect(getUrlParams("?preload=true&widgetId=12345").preload).toBe(true); + }); + }); }); diff --git a/src/UrlParams.ts b/src/UrlParams.ts index b4f6ca28..c87b79cc 100644 --- a/src/UrlParams.ts +++ b/src/UrlParams.ts @@ -211,8 +211,11 @@ export const getUrlParams = ( const fontScale = parseFloat(parser.getParam("fontScale") ?? ""); + const widgetId = parser.getParam("widgetId"); + const isWidget = !!widgetId; + return { - widgetId: parser.getParam("widgetId"), + widgetId, parentUrl: parser.getParam("parentUrl"), // NB. we don't validate roomId here as we do in getRoomIdentifierFromUrl: @@ -224,7 +227,7 @@ export const getUrlParams = ( confineToRoom: parser.getFlagParam("confineToRoom") || parser.getFlagParam("embed"), appPrompt: parser.getFlagParam("appPrompt", true), - preload: parser.getFlagParam("preload"), + preload: isWidget ? parser.getFlagParam("preload") : false, hideHeader: parser.getFlagParam("hideHeader"), showControls: parser.getFlagParam("showControls", true), hideScreensharing: parser.getFlagParam("hideScreensharing"), From 4e1b4fae19b5dacbcb0ba366bd87ff063f51c547 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sat, 23 Nov 2024 08:59:15 +0000 Subject: [PATCH 06/11] Refactor the speaker detection logic into observeSpeaker and add tests (#2814) * Refactor the speaker detection logic into observeSpeaker and add tests @robintown the tests pass, but some of the values were off by 1ms from what I was expecting. Please can you sanity check them? * Extra test cases and clean up * Make distinctUntilChanged part of the observable itself * More suggestions from code review --- src/state/CallViewModel.ts | 19 +---- src/state/observeSpeaker.test.ts | 119 +++++++++++++++++++++++++++++++ src/state/observeSpeaker.ts | 36 ++++++++++ 3 files changed, 157 insertions(+), 17 deletions(-) create mode 100644 src/state/observeSpeaker.test.ts create mode 100644 src/state/observeSpeaker.ts diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index 8999dc89..83ccd48c 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -27,7 +27,6 @@ import { EMPTY, Observable, Subject, - audit, combineLatest, concat, distinctUntilChanged, @@ -76,6 +75,7 @@ import { spotlightExpandedLayout } from "./SpotlightExpandedLayout"; import { oneOnOneLayout } from "./OneOnOneLayout"; import { pipLayout } from "./PipLayout"; import { EncryptionSystem } from "../e2ee/sharedKeyManagement"; +import { observeSpeaker } from "./observeSpeaker"; // How long we wait after a focus switch before showing the real participant // list again @@ -248,22 +248,7 @@ class UserMedia { livekitRoom, ); - this.speaker = this.vm.speaking.pipe( - // Require 1 s of continuous speaking to become a speaker, and 60 s of - // continuous silence to stop being considered a speaker - audit((s) => - merge( - timer(s ? 1000 : 60000), - // If the speaking flag resets to its original value during this time, - // end the silencing window to stick with that original value - this.vm.speaking.pipe(filter((s1) => s1 !== s)), - ), - ), - startWith(false), - // Make this Observable hot so that the timers don't reset when you - // resubscribe - this.scope.state(), - ); + this.speaker = observeSpeaker(this.vm.speaking).pipe(this.scope.state()); this.presenter = observeParticipantEvents( participant, diff --git a/src/state/observeSpeaker.test.ts b/src/state/observeSpeaker.test.ts new file mode 100644 index 00000000..daa5f033 --- /dev/null +++ b/src/state/observeSpeaker.test.ts @@ -0,0 +1,119 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. +*/ + +import { describe, test } from "vitest"; + +import { withTestScheduler } from "../utils/test"; +import { observeSpeaker } from "./observeSpeaker"; + +const yesNo = { + y: true, + n: false, +}; + +describe("observeSpeaker", () => { + describe("does not activate", () => { + const expectedOutputMarbles = "n"; + test("starts correctly", () => { + // should default to false when no input is given + const speakingInputMarbles = ""; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + + test("after no speaking", () => { + const speakingInputMarbles = "n"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + + test("with speaking for 1ms", () => { + const speakingInputMarbles = "y n"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + + test("with speaking for 999ms", () => { + const speakingInputMarbles = "y 999ms n"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + + test("with speaking intermittently", () => { + const speakingInputMarbles = + "y 199ms n 199ms y 199ms n 199ms y 199ms n 199ms y 199ms n 199ms y 199ms n 199ms y 199ms n 199ms y 199ms n 199ms y 199ms n"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + + test("with consecutive speaking then stops speaking", () => { + const speakingInputMarbles = "y y y y y y y y y y n"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + }); + + describe("activates", () => { + test("after 1s", () => { + // this will active after 1s as no `n` follows it: + const speakingInputMarbles = " y"; + const expectedOutputMarbles = "n 999ms y"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + + test("speaking for 1001ms activates for 60s", () => { + const speakingInputMarbles = " y 1s n "; + const expectedOutputMarbles = "n 999ms y 60s n"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + + test("speaking for 5s activates for 64s", () => { + const speakingInputMarbles = " y 5s n "; + const expectedOutputMarbles = "n 999ms y 64s n"; + withTestScheduler(({ hot, expectObservable }) => { + expectObservable(observeSpeaker(hot(speakingInputMarbles, yesNo))).toBe( + expectedOutputMarbles, + yesNo, + ); + }); + }); + }); +}); diff --git a/src/state/observeSpeaker.ts b/src/state/observeSpeaker.ts new file mode 100644 index 00000000..d32fbdaa --- /dev/null +++ b/src/state/observeSpeaker.ts @@ -0,0 +1,36 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. +*/ +import { + Observable, + audit, + merge, + timer, + filter, + startWith, + distinctUntilChanged, +} from "rxjs"; + +/** + * Require 1 second of continuous speaking to become a speaker, and 60 second of + * continuous silence to stop being considered a speaker + */ +export function observeSpeaker( + isSpeakingObservable: Observable, +): Observable { + const distinct = isSpeakingObservable.pipe(distinctUntilChanged()); + + return distinct.pipe( + // Either change to the new value after the timer or re-emit the same value if it toggles back + // (audit will return the latest (toggled back) value) before the timeout. + audit((s) => + merge(timer(s ? 1000 : 60000), distinct.pipe(filter((s1) => s1 !== s))), + ), + // Filter the re-emissions (marked as: | ) that happen if we toggle quickly (<1s) from false->true->false|->.. + startWith(false), + distinctUntilChanged(), + ); +} From fc8da6ef5844a0dd6dc01b1f36ca6fba86586641 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sat, 23 Nov 2024 08:59:33 +0000 Subject: [PATCH 07/11] Use hot marbles for speaker tests (#2815) * Refactor the speaker detection logic into observeSpeaker and add tests @robintown the tests pass, but some of the values were off by 1ms from what I was expecting. Please can you sanity check them? * Extra test cases and clean up * Make distinctUntilChanged part of the observable itself * More suggestions from code review * Use hot marbles for speaker tests This was originally part of https://github.com/element-hq/element-call/pull/2810 * Only feed speaking mocks to observables that ask for IsSpeakingChanged --- src/state/CallViewModel.test.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/state/CallViewModel.test.ts b/src/state/CallViewModel.test.ts index aa49f048..9b2e5ee7 100644 --- a/src/state/CallViewModel.test.ts +++ b/src/state/CallViewModel.test.ts @@ -20,6 +20,7 @@ import { ConnectionState, LocalParticipant, Participant, + ParticipantEvent, RemoteParticipant, } from "livekit-client"; import * as ComponentsCore from "@livekit/components-core"; @@ -188,11 +189,15 @@ function withCallViewModel( ); const eventsSpy = vi .spyOn(ComponentsCore, "observeParticipantEvents") - .mockImplementation((p) => - (speaking.get(p) ?? of(false)).pipe( - map((s) => ({ ...p, isSpeaking: s }) as Participant), - ), - ); + .mockImplementation((p, ...eventTypes) => { + if (eventTypes.includes(ParticipantEvent.IsSpeakingChanged)) { + return (speaking.get(p) ?? of(false)).pipe( + map((s) => ({ ...p, isSpeaking: s }) as Participant), + ); + } else { + return of(p); + } + }); const roomEventSelectorSpy = vi .spyOn(ComponentsCore, "roomEventSelector") @@ -407,7 +412,7 @@ test("participants stay in the same order unless to appear/disappear", () => { }); test("spotlight speakers swap places", () => { - withTestScheduler(({ cold, schedule, expectObservable }) => { + withTestScheduler(({ hot, schedule, expectObservable }) => { // Go immediately into spotlight mode for the test const modeInputMarbles = " s"; // First Bob speaks, then Dave, then Alice @@ -424,9 +429,9 @@ test("spotlight speakers swap places", () => { of([aliceParticipant, bobParticipant, daveParticipant]), of(ConnectionState.Connected), new Map([ - [aliceParticipant, cold(aSpeakingInputMarbles, { y: true, n: false })], - [bobParticipant, cold(bSpeakingInputMarbles, { y: true, n: false })], - [daveParticipant, cold(dSpeakingInputMarbles, { y: true, n: false })], + [aliceParticipant, hot(aSpeakingInputMarbles, { y: true, n: false })], + [bobParticipant, hot(bSpeakingInputMarbles, { y: true, n: false })], + [daveParticipant, hot(dSpeakingInputMarbles, { y: true, n: false })], ]), (vm) => { schedule(modeInputMarbles, { s: () => vm.setGridMode("spotlight") }); From 0469d8ef568a8c543d05af54dfcb6d997b65ec66 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Sat, 23 Nov 2024 09:00:43 +0000 Subject: [PATCH 08/11] Add explicit code split on matrix-sdk-crypto-wasm to allow caching between deploys (#2823) * Add explicit code split on matrix-sdk-crypto-wasm to allow caching between deploys * Comment on removing once https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/167 lands --- vite.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vite.config.js b/vite.config.js index b8072577..1feb7d66 100644 --- a/vite.config.js +++ b/vite.config.js @@ -82,6 +82,10 @@ export default defineConfig(({ mode }) => { // Default naming fallback return "assets/[name]-[hash][extname]"; }, + manualChunks: { + // we should be able to remove this one https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/167 lands + "matrix-sdk-crypto-wasm": ["@matrix-org/matrix-sdk-crypto-wasm"], + }, }, }, }, From e36029c9c0a75a91670a14ab84616d32130aa59c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:46:30 +0100 Subject: [PATCH 09/11] Update all non-major dependencies (#2835) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 440 ++++++++++++++++++++++++++------------------------- 2 files changed, 225 insertions(+), 217 deletions(-) diff --git a/package.json b/package.json index d6df23cf..46a86b45 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@livekit/components-react": "^2.0.0", "@opentelemetry/api": "^1.4.0", "@opentelemetry/core": "^1.25.1", - "@opentelemetry/exporter-trace-otlp-http": "^0.54.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.55.0", "@opentelemetry/resources": "^1.25.1", "@opentelemetry/sdk-trace-base": "^1.25.1", "@opentelemetry/sdk-trace-web": "^1.9.1", diff --git a/yarn.lock b/yarn.lock index 33d8910f..96ee1ae4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1944,10 +1944,10 @@ dependencies: "@octokit/openapi-types" "^22.2.0" -"@opentelemetry/api-logs@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.54.2.tgz#bb8aa11cdc69b327b58d7e10cc2bc26bf540421f" - integrity sha512-4MTVwwmLgUh5QrJnZpYo6YRO5IBLAggf2h8gWDblwRagDStY13aEvt7gGk3jewrMaPlHiF83fENhIx0HO97/cQ== +"@opentelemetry/api-logs@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.55.0.tgz#5cd7461820d864600250deb3803c32367a6bb2d2" + integrity sha512-3cpa+qI45VHYcA5c0bHM6VHo9gicv3p5mlLHNG3rLyjQU8b7e0st1rWtrUn3JbZ3DwwCfhKop4eQ9UuYlC6Pkg== dependencies: "@opentelemetry/api" "^1.3.0" @@ -1956,93 +1956,98 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== -"@opentelemetry/core@1.27.0", "@opentelemetry/core@^1.25.1": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.27.0.tgz#9f1701a654ab01abcebb12931b418f3393b94b75" - integrity sha512-yQPKnK5e+76XuiqUH/gKyS8wv/7qITd5ln56QkBTf3uggr0VkXOXfcaAuG330UfdYu83wsyoBwqwxigpIG+Jkg== +"@opentelemetry/core@1.28.0", "@opentelemetry/core@^1.25.1": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.28.0.tgz#e97290a3e36c59480ffb2287fe2713c66749274c" + integrity sha512-ZLwRMV+fNDpVmF2WYUdBHlq0eOWtEaUJSusrzjGnBt7iSRvfjFE3RXYUZJrqou/wIDWV0DwQ5KIfYe9WXg9Xqw== dependencies: "@opentelemetry/semantic-conventions" "1.27.0" -"@opentelemetry/exporter-trace-otlp-http@^0.54.0": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.54.2.tgz#e6fab84405b95ece2977a80e4cec907e568ef0f3" - integrity sha512-BgWKKyD/h2zpISdmYHN/sapwTjvt1P4p5yx4xeBV8XAEqh4OQUhOtSGFG80+nPQ1F8of3mKOT1DDoDbJp1u25w== +"@opentelemetry/exporter-trace-otlp-http@^0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.55.0.tgz#275e458aa3bd33c52d77f4357706bcfa53d27f28" + integrity sha512-lMiNic63EVHpW+eChmLD2CieDmwQBFi72+LFbh8+5hY0ShrDGrsGP/zuT5MRh7M/vM/UZYO/2A/FYd7CMQGR7A== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/otlp-exporter-base" "0.54.2" - "@opentelemetry/otlp-transformer" "0.54.2" - "@opentelemetry/resources" "1.27.0" - "@opentelemetry/sdk-trace-base" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/otlp-exporter-base" "0.55.0" + "@opentelemetry/otlp-transformer" "0.55.0" + "@opentelemetry/resources" "1.28.0" + "@opentelemetry/sdk-trace-base" "1.28.0" -"@opentelemetry/otlp-exporter-base@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.54.2.tgz#fb2361665baec9e9600c5408747fc03124889f0a" - integrity sha512-NrNyxu6R/bGAwanhz1HI0aJWKR6xUED4TjCH4iWMlAfyRukGbI9Kt/Akd2sYLwRKNhfS+sKetKGCUQPMDyYYMA== +"@opentelemetry/otlp-exporter-base@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.55.0.tgz#db17332497e4a97e4ca85d394fb91cbbcfd76d84" + integrity sha512-iHQI0Zzq3h1T6xUJTVFwmFl5Dt5y1es+fl4kM+k5T/3YvmVyeYkSiF+wHCg6oKrlUAJfk+t55kaAu3sYmt7ZYA== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/otlp-transformer" "0.54.2" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/otlp-transformer" "0.55.0" -"@opentelemetry/otlp-transformer@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.54.2.tgz#5952072cf37a7d5da0ac5491426126459c13c839" - integrity sha512-2tIjahJlMRRUz0A2SeE+qBkeBXBFkSjR0wqJ08kuOqaL8HNGan5iZf+A8cfrfmZzPUuMKCyY9I+okzFuFs6gKQ== +"@opentelemetry/otlp-transformer@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.55.0.tgz#316b9325983e660cb4f18cb76fa84ce1c0cdad42" + integrity sha512-kVqEfxtp6mSN2Dhpy0REo1ghP4PYhC1kMHQJ2qVlO99Pc+aigELjZDfg7/YKmL71gR6wVGIeJfiql/eXL7sQPA== dependencies: - "@opentelemetry/api-logs" "0.54.2" - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" - "@opentelemetry/sdk-logs" "0.54.2" - "@opentelemetry/sdk-metrics" "1.27.0" - "@opentelemetry/sdk-trace-base" "1.27.0" + "@opentelemetry/api-logs" "0.55.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" + "@opentelemetry/sdk-logs" "0.55.0" + "@opentelemetry/sdk-metrics" "1.28.0" + "@opentelemetry/sdk-trace-base" "1.28.0" protobufjs "^7.3.0" -"@opentelemetry/resources@1.27.0", "@opentelemetry/resources@^1.25.1": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.27.0.tgz#1f91c270eb95be32f3511e9e6624c1c0f993c4ac" - integrity sha512-jOwt2VJ/lUD5BLc+PMNymDrUCpm5PKi1E9oSVYAvz01U/VdndGmrtV3DU1pG4AwlYhJRHbHfOUIlpBeXCPw6QQ== +"@opentelemetry/resources@1.28.0", "@opentelemetry/resources@^1.25.1": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.28.0.tgz#c8c27ae7559c817f9d117f1bf96d76f893fb29f5" + integrity sha512-cIyXSVJjGeTICENN40YSvLDAq4Y2502hGK3iN7tfdynQLKWb3XWZQEkPc+eSx47kiy11YeFAlYkEfXwR1w8kfw== dependencies: - "@opentelemetry/core" "1.27.0" + "@opentelemetry/core" "1.28.0" "@opentelemetry/semantic-conventions" "1.27.0" -"@opentelemetry/sdk-logs@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.54.2.tgz#07cc61135b5acb09affa8cd290966027ee8c886a" - integrity sha512-yIbYqDLS/AtBbPjCjh6eSToGNRMqW2VR8RrKEy+G+J7dFG7pKoptTH5T+XlKPleP9NY8JZYIpgJBlI+Osi0rFw== +"@opentelemetry/sdk-logs@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.55.0.tgz#78844e502167723a258c75a6b4f3de3900c13ea3" + integrity sha512-TSx+Yg/d48uWW6HtjS1AD5x6WPfLhDWLl/WxC7I2fMevaiBuKCuraxTB8MDXieCNnBI24bw9ytyXrDCswFfWgA== dependencies: - "@opentelemetry/api-logs" "0.54.2" - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" + "@opentelemetry/api-logs" "0.55.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" -"@opentelemetry/sdk-metrics@1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.27.0.tgz#fb4f55017dc95a95ee00260262952b18e3e7c25c" - integrity sha512-JzWgzlutoXCydhHWIbLg+r76m+m3ncqvkCcsswXAQ4gqKS+LOHKhq+t6fx1zNytvLuaOUBur7EvWxECc4jPQKg== +"@opentelemetry/sdk-metrics@1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.28.0.tgz#257b5295bbe9de1ad31c5e8cb43a660c25911d20" + integrity sha512-43tqMK/0BcKTyOvm15/WQ3HLr0Vu/ucAl/D84NO7iSlv6O4eOprxSHa3sUtmYkaZWHqdDJV0AHVz/R6u4JALVQ== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" -"@opentelemetry/sdk-trace-base@1.27.0", "@opentelemetry/sdk-trace-base@^1.25.1": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.27.0.tgz#2276e4cd0d701a8faba77382b2938853a0907b54" - integrity sha512-btz6XTQzwsyJjombpeqCX6LhiMQYpzt2pIYNPnw0IPO/3AhT6yjnf8Mnv3ZC2A4eRYOjqrg+bfaXg9XHDRJDWQ== +"@opentelemetry/sdk-trace-base@1.28.0", "@opentelemetry/sdk-trace-base@^1.25.1": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.28.0.tgz#6195dc8cd78bd74394cf54c67c5cbd8d1528516c" + integrity sha512-ceUVWuCpIao7Y5xE02Xs3nQi0tOGmMea17ecBdwtCvdo9ekmO+ijc9RFDgfifMl7XCBf41zne/1POM3LqSTZDA== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" "@opentelemetry/semantic-conventions" "1.27.0" "@opentelemetry/sdk-trace-web@^1.9.1": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.27.0.tgz#cdc9b43aab44b12741e408fb70b2bc0e941f0c7c" - integrity sha512-ORZfG8Sm5IkJeI+P8MyW8v4m5OcmjEtD7VsjBghv5sDKH3f5p2mQpEEoJWlCr5GiW50Y1MaI2R4uFGIsxmDE9A== + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.28.0.tgz#0b8652a05ded13308c7afd162ca2ba55ff204efd" + integrity sha512-/QOIrJc/A/caKbA9voLua4isf///cjQKB6gomEzX2fL18TBqZhIkm9k2DpjlbtrQoYCJDZ9x7Phrec22aQGpQw== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/sdk-trace-base" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/sdk-trace-base" "1.28.0" "@opentelemetry/semantic-conventions" "1.27.0" -"@opentelemetry/semantic-conventions@1.27.0", "@opentelemetry/semantic-conventions@^1.25.1": +"@opentelemetry/semantic-conventions@1.27.0": version "1.27.0" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz#1a857dcc95a5ab30122e04417148211e6f945e6c" integrity sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg== +"@opentelemetry/semantic-conventions@^1.25.1": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz#337fb2bca0453d0726696e745f50064411f646d6" + integrity sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA== + "@parcel/watcher-android-arm64@2.5.0": version "2.5.0" resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz#e32d3dda6647791ee930556aee206fcd5ea0fb7a" @@ -2654,61 +2659,56 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@sentry-internal/browser-utils@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/browser-utils/-/browser-utils-8.38.0.tgz#d7f6d398778906efb0c017e63d3c59d3203dfa7d" - integrity sha512-5QMVcssrAcmjKT0NdFYcX0b0wwZovGAZ9L2GajErXtHkBenjI2sgR2+5J7n+QZGuk2SC1qhGmT1O9i3p3UEwew== +"@sentry-internal/browser-utils@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/browser-utils/-/browser-utils-8.40.0.tgz#972925a9d600723dd1a022297100e97e92f4c903" + integrity sha512-tx7gb/PWMbTEyil/XPETVeRUeS3nKHIvQY2omyebw30TbhyLnibPZsUmXJiaIysL5PcY3k9maub3W/o0Y37T7Q== dependencies: - "@sentry/core" "8.38.0" - "@sentry/types" "8.38.0" - "@sentry/utils" "8.38.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" -"@sentry-internal/feedback@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-8.38.0.tgz#726661a01f7ff40b93c8ee05c985fd0436a1c033" - integrity sha512-AW5HCCAlc3T1jcSuNhbFVNO1CHyJ5g5tsGKEP4VKgu+D1Gg2kZ5S2eFatLBUP/BD5JYb1A7p6XPuzYp1XfMq0A== +"@sentry-internal/feedback@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-8.40.0.tgz#5549f73d32b9a2509ffb0a07bf462ed8085178ec" + integrity sha512-1O9F3z80HNE0VfepKS+v+dixdatNqWlrlwgvvWl4BGzzoA+XhqvZo+HWxiOt7yx7+k1TuZNrB6Gy3u/QvpozXA== dependencies: - "@sentry/core" "8.38.0" - "@sentry/types" "8.38.0" - "@sentry/utils" "8.38.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" -"@sentry-internal/replay-canvas@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-8.38.0.tgz#26e9bc937dab73e1a26d57dc1015b7ff1f2d76c5" - integrity sha512-OxmlWzK9J8mRM+KxdSnQ5xuxq+p7TiBzTz70FT3HltxmeugvDkyp6803UcFqHOPHR35OYeVLOalym+FmvNn9kw== +"@sentry-internal/replay-canvas@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-8.40.0.tgz#6de0d67ee2fe3e503c6f85faeefab5df742a3ebe" + integrity sha512-Zr+m/le0SH4RowZB7rBCM0aRnvH3wZTaOFhwUk03/oGf2BRcgKuDCUMjnXKC9MyOpmey7UYXkzb8ro+81R6Q8w== dependencies: - "@sentry-internal/replay" "8.38.0" - "@sentry/core" "8.38.0" - "@sentry/types" "8.38.0" - "@sentry/utils" "8.38.0" + "@sentry-internal/replay" "8.40.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" -"@sentry-internal/replay@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/replay/-/replay-8.38.0.tgz#9a9b945a3c066f5610a363774e3c99420c3f4fce" - integrity sha512-mQPShKnIab7oKwkwrRxP/D8fZYHSkDY+cvqORzgi+wAwgnunytJQjz9g6Ww2lJu98rHEkr5SH4V4rs6PZYZmnQ== +"@sentry-internal/replay@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay/-/replay-8.40.0.tgz#54c7f1e3d115f9324f34e1b8875a95463a23049f" + integrity sha512-0SaDsBCSWxNVgNmPKu23frrHEXzN/MKl0hIkfuO55vL5TgjLTwpgkf0Ne4rNvaZQ5omIKk9Qd63HuQP3PHAMaw== dependencies: - "@sentry-internal/browser-utils" "8.38.0" - "@sentry/core" "8.38.0" - "@sentry/types" "8.38.0" - "@sentry/utils" "8.38.0" + "@sentry-internal/browser-utils" "8.40.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" "@sentry/babel-plugin-component-annotate@2.22.6": version "2.22.6" resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.22.6.tgz#829d6caf2c95c1c46108336de4e1049e6521435e" integrity sha512-V2g1Y1I5eSe7dtUVMBvAJr8BaLRr4CLrgNgtPaZyMT4Rnps82SrZ5zqmEkLXPumlXhLUWR6qzoMNN2u+RXVXfQ== -"@sentry/browser@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-8.38.0.tgz#c562accdc2bbe0b0074d98bfe7ff460e39ce3109" - integrity sha512-AZR+b0EteNZEGv6JSdBD22S9VhQ7nrljKsSnzxobBULf3BpwmhmCzTbDrqWszKDAIDYmL+yQJIR2glxbknneWQ== +"@sentry/browser@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-8.40.0.tgz#de7b4531be2ac4667755e9e1b5da3808851392ae" + integrity sha512-m/Yor6IDBeDHtQochu8n6z4HXrXkrPhu6+o5Ouve0Zi3ptthSoK1FOGvJxVBat3nRq0ydQyuuPuTB6WfdWbwHQ== dependencies: - "@sentry-internal/browser-utils" "8.38.0" - "@sentry-internal/feedback" "8.38.0" - "@sentry-internal/replay" "8.38.0" - "@sentry-internal/replay-canvas" "8.38.0" - "@sentry/core" "8.38.0" - "@sentry/types" "8.38.0" - "@sentry/utils" "8.38.0" + "@sentry-internal/browser-utils" "8.40.0" + "@sentry-internal/feedback" "8.40.0" + "@sentry-internal/replay" "8.40.0" + "@sentry-internal/replay-canvas" "8.40.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" "@sentry/bundler-plugin-core@2.22.6": version "2.22.6" @@ -2778,36 +2778,27 @@ "@sentry/cli-win32-i686" "2.38.1" "@sentry/cli-win32-x64" "2.38.1" -"@sentry/core@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.38.0.tgz#5d1b74770c79e489e786018a3e514cddeb777bcb" - integrity sha512-sGD+5TEHU9G7X7zpyaoJxpOtwjTjvOd1f/MKBrWW2vf9UbYK+GUJrOzLhMoSWp/pHSYgvObkJkDb/HwieQjvhQ== +"@sentry/core@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.40.0.tgz#cb5c02d12e29070bf88692c64cfd7db7700be4ea" + integrity sha512-u/U2CJpG/+SmTR2bPM4ZZoPYTJAOUuxzj/0IURnvI0v9+rNu939J/fzrO9huA5IJVxS5TiYykhQm7o6I3Zuo3Q== dependencies: - "@sentry/types" "8.38.0" - "@sentry/utils" "8.38.0" + "@sentry/types" "8.40.0" "@sentry/react@^8.0.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-8.38.0.tgz#513cbd9ba35bb0258d10b74d272800cbc5f05631" - integrity sha512-5396tewO00wbJFHUkmU+ikmp4A+wuBpStNc7UDyAm642jfbPajj51+GWld/ZYNFiQaZ/8I9tvvpHqVLnUh21gg== + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-8.40.0.tgz#9dfbbeaaeb8731103292d771c52b3d06b7e1500b" + integrity sha512-Ohq/po83r9sh/DCO6VAxx4xU+1ztvFzmXTl3fUnAEc+2bFJK1MsRt6BWfG37XxjQN//mfmyS9KEBgsOpOyd4LQ== dependencies: - "@sentry/browser" "8.38.0" - "@sentry/core" "8.38.0" - "@sentry/types" "8.38.0" - "@sentry/utils" "8.38.0" + "@sentry/browser" "8.40.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" hoist-non-react-statics "^3.3.2" -"@sentry/types@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-8.38.0.tgz#9c48734a8b4055bfd553a0141efec78e9680ed09" - integrity sha512-fP5H9ZX01W4Z/EYctk3mkSHi7d06cLcX2/UWqwdWbyPWI+pL2QpUPICeO/C+8SnmYx//wFj3qWDhyPCh1PdFAA== - -"@sentry/utils@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-8.38.0.tgz#2f91ca7d044f6e17b993c866ca02a981c4c1bc25" - integrity sha512-3X7MgIKIx+2q5Al7QkhaRB4wV6DvzYsaeIwdqKUzGLuRjXmNgJrLoU87TAwQRmZ6Wr3IoEpThZZMNrzYPXxArw== - dependencies: - "@sentry/types" "8.38.0" +"@sentry/types@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-8.40.0.tgz#a98d2bcc48adbc066b403713688ded3ac5eb1cec" + integrity sha512-nuCf3U3deolPM9BjNnwCc33UtFl9ec15/r74ngAkNccn+A2JXdIAsDkGJMO/9mgSFykLe1QyeJ0pQFRisCGOiA== "@sentry/vite-plugin@^2.0.0": version "2.22.6" @@ -3057,9 +3048,9 @@ undici-types "~6.19.8" "@types/node@^20.0.0": - version "20.17.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.6.tgz#6e4073230c180d3579e8c60141f99efdf5df0081" - integrity sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ== + version "20.17.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.7.tgz#790151a28c5a172773d95d53a0c23d3c59a883c4" + integrity sha512-sZXXnpBFMKbao30dUAvzKbdwA2JM1fwUtVEq/kxKuPI5mMwZiRElCpTXb0Biq/LMEVpXDZL5G5V0RPnxKeyaYg== dependencies: undici-types "~6.19.2" @@ -3160,15 +3151,15 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^8.0.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz#7dc0e419c87beadc8f554bf5a42e5009ed3748dc" - integrity sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w== + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz#c95c6521e70c8b095a684d884d96c0c1c63747d2" + integrity sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.14.0" - "@typescript-eslint/type-utils" "8.14.0" - "@typescript-eslint/utils" "8.14.0" - "@typescript-eslint/visitor-keys" "8.14.0" + "@typescript-eslint/scope-manager" "8.15.0" + "@typescript-eslint/type-utils" "8.15.0" + "@typescript-eslint/utils" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" @@ -3182,14 +3173,14 @@ "@typescript-eslint/utils" "5.62.0" "@typescript-eslint/parser@^8.0.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.14.0.tgz#0a7e9dbc11bc07716ab2d7b1226217e9f6b51fc8" - integrity sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA== + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.15.0.tgz#92610da2b3af702cfbc02a46e2a2daa6260a9045" + integrity sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A== dependencies: - "@typescript-eslint/scope-manager" "8.14.0" - "@typescript-eslint/types" "8.14.0" - "@typescript-eslint/typescript-estree" "8.14.0" - "@typescript-eslint/visitor-keys" "8.14.0" + "@typescript-eslint/scope-manager" "8.15.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/typescript-estree" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" debug "^4.3.4" "@typescript-eslint/scope-manager@5.62.0": @@ -3200,21 +3191,21 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/scope-manager@8.14.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz#01f37c147a735cd78f0ff355e033b9457da1f373" - integrity sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw== +"@typescript-eslint/scope-manager@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz#28a1a0f13038f382424f45a988961acaca38f7c6" + integrity sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA== dependencies: - "@typescript-eslint/types" "8.14.0" - "@typescript-eslint/visitor-keys" "8.14.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" -"@typescript-eslint/type-utils@8.14.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.14.0.tgz#455c6af30c336b24a1af28bc4f81b8dd5d74d94d" - integrity sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ== +"@typescript-eslint/type-utils@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz#a6da0f93aef879a68cc66c73fe42256cb7426c72" + integrity sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw== dependencies: - "@typescript-eslint/typescript-estree" "8.14.0" - "@typescript-eslint/utils" "8.14.0" + "@typescript-eslint/typescript-estree" "8.15.0" + "@typescript-eslint/utils" "8.15.0" debug "^4.3.4" ts-api-utils "^1.3.0" @@ -3223,10 +3214,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/types@8.14.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.14.0.tgz#0d33d8d0b08479c424e7d654855fddf2c71e4021" - integrity sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g== +"@typescript-eslint/types@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.15.0.tgz#4958edf3d83e97f77005f794452e595aaf6430fc" + integrity sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ== "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" @@ -3241,13 +3232,13 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@8.14.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz#a7a3a5a53a6c09313e12fb4531d4ff582ee3c312" - integrity sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ== +"@typescript-eslint/typescript-estree@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz#915c94e387892b114a2a2cc0df2d7f19412c8ba7" + integrity sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg== dependencies: - "@typescript-eslint/types" "8.14.0" - "@typescript-eslint/visitor-keys" "8.14.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -3269,15 +3260,15 @@ eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/utils@8.14.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.14.0.tgz#ac2506875e03aba24e602364e43b2dfa45529dbd" - integrity sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA== +"@typescript-eslint/utils@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.15.0.tgz#ac04679ad19252776b38b81954b8e5a65567cef6" + integrity sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.14.0" - "@typescript-eslint/types" "8.14.0" - "@typescript-eslint/typescript-estree" "8.14.0" + "@typescript-eslint/scope-manager" "8.15.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/typescript-estree" "8.15.0" "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" @@ -3287,13 +3278,13 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@8.14.0": - version "8.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz#2418d5a54669af9658986ade4e6cfb7767d815ad" - integrity sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ== +"@typescript-eslint/visitor-keys@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz#9ea5a85eb25401d2aa74ec8a478af4e97899ea12" + integrity sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q== dependencies: - "@typescript-eslint/types" "8.14.0" - eslint-visitor-keys "^3.4.3" + "@typescript-eslint/types" "8.15.0" + eslint-visitor-keys "^4.2.0" "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -3828,7 +3819,7 @@ broccoli-plugin@^4.0.7: rimraf "^3.0.2" symlink-or-copy "^1.3.1" -browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.24.0: +browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.24.0, browserslist@^4.24.2: version "4.24.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== @@ -3894,11 +3885,16 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001669: +caniuse-lite@^1.0.30001646: version "1.0.30001680" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz#5380ede637a33b9f9f1fc6045ea99bd142f3da5e" integrity sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA== +caniuse-lite@^1.0.30001669: + version "1.0.30001684" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz#0eca437bab7d5f03452ff0ef9de8299be6b08e16" + integrity sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -3994,9 +3990,9 @@ chokidar@^4.0.0: readdirp "^4.0.1" ci-info@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.0.0.tgz#65466f8b280fc019b9f50a5388115d17a63a44f2" - integrity sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg== + version "4.1.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.1.0.tgz#92319d2fa29d2620180ea5afed31f589bc98cf83" + integrity sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A== classnames@^2.3.1, classnames@^2.5.1: version "2.5.1" @@ -4126,13 +4122,20 @@ copy-to-clipboard@^3.3.1: dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.38.0, core-js-compat@^3.38.1: +core-js-compat@^3.38.0: version "3.38.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.1.tgz#2bc7a298746ca5a7bcb9c164bcb120f2ebc09a09" integrity sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw== dependencies: browserslist "^4.23.3" +core-js-compat@^3.38.1: + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.39.0.tgz#b12dccb495f2601dc860bdbe7b4e3ffa8ba63f61" + integrity sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw== + dependencies: + browserslist "^4.24.2" + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -4455,9 +4458,9 @@ easy-table@1.2.0: wcwidth "^1.0.1" electron-to-chromium@^1.5.41: - version "1.5.62" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.62.tgz#8289468414b0b0b3e9180ef619a763555debe612" - integrity sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg== + version "1.5.64" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.64.tgz#ac8c4c89075d35a1514b620f47dfe48a71ec3697" + integrity sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ== emoji-regex@^8.0.0: version "8.0.0" @@ -4838,9 +4841,9 @@ eslint-plugin-rxjs@^5.0.3: tsutils-etc "^1.4.1" eslint-plugin-unicorn@^56.0.0: - version "56.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.0.tgz#9fd3ebe6f478571734541fa745026b743175b59e" - integrity sha512-aXpddVz/PQMmd69uxO98PA4iidiVNvA0xOtbpUoz1WhBd4RxOQQYqN618v68drY0hmy5uU2jy1bheKEVWBjlPw== + version "56.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz#d10a3df69ba885939075bdc95a65a0c872e940d4" + integrity sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog== dependencies: "@babel/helper-validator-identifier" "^7.24.7" "@eslint-community/eslint-utils" "^4.4.0" @@ -4880,6 +4883,11 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + eslint@^8.14.0: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" @@ -5293,9 +5301,9 @@ globals@^13.19.0: type-fest "^0.20.2" globals@^15.9.0: - version "15.11.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-15.11.0.tgz#b96ed4c6998540c6fb824b24b5499216d2438d6e" - integrity sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw== + version "15.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.12.0.tgz#1811872883ad8f41055b61457a130221297de5b5" + integrity sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ== globalthis@^1.0.3, globalthis@^1.0.4: version "1.0.4" @@ -5510,9 +5518,9 @@ i18next-parser@^9.0.0: vinyl-fs "^4.0.0" i18next@^23.0.0, i18next@^23.5.1: - version "23.16.5" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.16.5.tgz#53d48ae9f985fd73fc1fcb96e6c7d90ababf0831" - integrity sha512-KTlhE3EP9x6pPTAW7dy0WKIhoCpfOGhRQlO+jttQLgzVaoOjWwBWramu7Pp0i+8wDNduuzXfe3kkVbzrKyrbTA== + version "23.16.8" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.16.8.tgz#3ae1373d344c2393f465556f394aba5a9233b93a" + integrity sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg== dependencies: "@babel/runtime" "^7.23.2" @@ -6010,9 +6018,9 @@ kleur@^3.0.3: integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== knip@^5.27.2: - version "5.37.1" - resolved "https://registry.yarnpkg.com/knip/-/knip-5.37.1.tgz#3c3e91c425dfb35be68b4d12cc0b9ee3cde794e8" - integrity sha512-69gjKj5lLsLXcIPXlHyFfX5AOHgRdh/iXH8gUqvmsHtjqoWhOATeXZDjvvemmgw7KxbWbUzxBNbpjhtJWzgqGA== + version "5.37.2" + resolved "https://registry.yarnpkg.com/knip/-/knip-5.37.2.tgz#e218afae3bf28ec10fa3be419cf6d89fd20fd63b" + integrity sha512-Rs9HHTgmUacyKxchP4kRwG8idi0tzVHVpSyo4EM9sNGDSrPq20lhKXOWMFmShGCV6CH2352393Ok/qG1NblCMw== dependencies: "@nodelib/fs.walk" "1.2.8" "@snyk/github-codeowners" "1.1.0" @@ -7665,9 +7673,9 @@ slash@^3.0.0: integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== smol-toml@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/smol-toml/-/smol-toml-1.3.0.tgz#5200e251fffadbb72570c84e9776d2a3eca48143" - integrity sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA== + version "1.3.1" + resolved "https://registry.yarnpkg.com/smol-toml/-/smol-toml-1.3.1.tgz#d9084a9e212142e3cab27ef4e2b8e8ba620bfe15" + integrity sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ== snake-case@^3.0.4: version "3.0.4" @@ -7698,9 +7706,9 @@ spdx-correct@^3.0.0: spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz#c07a4ede25b16e4f78e6707bbd84b15a45c19c1b" - integrity sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw== + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== spdx-expression-parse@^3.0.0: version "3.0.1" @@ -7711,9 +7719,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.16" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" - integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + version "3.0.20" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz#e44ed19ed318dd1e5888f93325cee800f0f51b89" + integrity sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw== sprintf-js@^1.1.1: version "1.1.3" @@ -8064,9 +8072,9 @@ tr46@~0.0.3: integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-api-utils@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.0.tgz#709c6f2076e511a81557f3d07a0cbd566ae8195c" - integrity sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ== + version "1.4.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.1.tgz#7c0a304cd446d9a497c24c960b8abbf0bc1611ae" + integrity sha512-5RU2/lxTA3YUZxju61HO2U6EoZLvBLtmV2mbTvqyu4a/7s7RmJPT+1YekhMVsQhznRWk/czIwDUg+V8Q9ZuG4w== ts-debounce@^4.0.0: version "4.0.0" @@ -8202,9 +8210,9 @@ typescript-eslint-language-service@^5.0.5: integrity sha512-b7gWXpwSTqMVKpPX3WttNZEyVAMKs/2jsHKF79H+qaD6mjzCyU5jboJe/lOZgLJD+QRsXCr0GjIVxvl5kI1NMw== typescript@^5.0.4, typescript@^5.1.6: - version "5.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" - integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== + version "5.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" + integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg== unbox-primitive@^1.0.2: version "1.0.2" From cf174261c9fcae99c5312d01cd5c3c662d8dc02b Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 25 Nov 2024 20:22:02 +0000 Subject: [PATCH 10/11] Some simple initial tests for MediaView (#2813) * Some simple tests for MediaView * Use jest-dom assertions * Add tests for videoMuted * Add test case for placeholder video track * Revert yarn.lock changes * More revert * Deduplicate test case logic and improve names * Use role and label --- package.json | 1 + src/Avatar.tsx | 7 +- src/tile/MediaView.module.css | 9 --- src/tile/MediaView.test.tsx | 117 ++++++++++++++++++++++++++++++++++ src/tile/MediaView.tsx | 14 +++- src/vitest.setup.ts | 1 + yarn.lock | 51 ++++++++++++++- 7 files changed, 187 insertions(+), 13 deletions(-) create mode 100644 src/tile/MediaView.test.tsx diff --git a/package.json b/package.json index 46a86b45..6d5fca42 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@sentry/react": "^8.0.0", "@sentry/vite-plugin": "^2.0.0", "@testing-library/dom": "^10.1.0", + "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.0.0", "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^14.5.1", diff --git a/src/Avatar.tsx b/src/Avatar.tsx index a0ae1483..29ab5236 100644 --- a/src/Avatar.tsx +++ b/src/Avatar.tsx @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only Please see LICENSE in the repository root for full details. */ -import { useMemo, FC } from "react"; +import { useMemo, FC, CSSProperties } from "react"; import { Avatar as CompoundAvatar } from "@vector-im/compound-web"; import { getAvatarUrl } from "./utils/matrix"; @@ -33,6 +33,7 @@ interface Props { className?: string; src?: string; size?: Size | number; + style?: CSSProperties; } export const Avatar: FC = ({ @@ -41,6 +42,8 @@ export const Avatar: FC = ({ name, src, size = Size.MD, + style, + ...props }) => { const { client } = useClient(); @@ -64,6 +67,8 @@ export const Avatar: FC = ({ name={name} size={`${sizePx}px`} src={resolvedSrc} + style={style} + {...props} /> ); }; diff --git a/src/tile/MediaView.module.css b/src/tile/MediaView.module.css index 3ed6c83d..4594c284 100644 --- a/src/tile/MediaView.module.css +++ b/src/tile/MediaView.module.css @@ -34,10 +34,6 @@ Please see LICENSE in the repository root for full details. object-fit: contain; } -.media.videoMuted video { - display: none; -} - .bg { background-color: var(--cpd-color-bg-subtle-secondary); inline-size: 100%; @@ -47,7 +43,6 @@ Please see LICENSE in the repository root for full details. } .avatar { - display: none; position: absolute; top: 50%; left: 50%; @@ -55,10 +50,6 @@ Please see LICENSE in the repository root for full details. pointer-events: none; } -.media.videoMuted .avatar { - display: initial; -} - /* CSS makes us put a condition here, even though all we want to do is unconditionally select the container so we can use cqmin units */ @container mediaView (width > 0) { diff --git a/src/tile/MediaView.test.tsx b/src/tile/MediaView.test.tsx new file mode 100644 index 00000000..238ffdd1 --- /dev/null +++ b/src/tile/MediaView.test.tsx @@ -0,0 +1,117 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. +*/ + +import { describe, expect, test } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { axe } from "vitest-axe"; +import { TooltipProvider } from "@vector-im/compound-web"; +import { + TrackReference, + TrackReferencePlaceholder, +} from "@livekit/components-core"; +import { Track, TrackPublication } from "livekit-client"; +import { type ComponentProps } from "react"; + +import { MediaView } from "./MediaView"; +import { EncryptionStatus } from "../state/MediaViewModel"; +import { mockLocalParticipant } from "../utils/test"; + +describe("MediaView", () => { + const participant = mockLocalParticipant({}); + const trackReferencePlaceholder: TrackReferencePlaceholder = { + participant, + source: Track.Source.Camera, + }; + const trackReference: TrackReference = { + ...trackReferencePlaceholder, + publication: new TrackPublication(Track.Kind.Video, "id", "name"), + }; + + const baseProps: ComponentProps = { + displayName: "some name", + videoEnabled: true, + videoFit: "contain", + targetWidth: 300, + targetHeight: 200, + encryptionStatus: EncryptionStatus.Connecting, + mirror: false, + unencryptedWarning: false, + video: trackReference, + member: undefined, + }; + + test("is accessible", async () => { + const { container } = render(); + expect(await axe(container)).toHaveNoViolations(); + }); + + describe("placeholder track", () => { + test("neither video nor avatar are shown", () => { + render(); + expect(screen.queryByTestId("video")).toBeNull(); + expect(screen.queryAllByRole("img", { name: "some name" }).length).toBe( + 0, + ); + }); + }); + + describe("name tag", () => { + test("is shown with name", () => { + render(); + expect(screen.getByTestId("name_tag")).toHaveTextContent("Bob"); + }); + }); + + describe("unencryptedWarning", () => { + test("is shown and accessible", async () => { + const { container } = render( + + + , + ); + expect(await axe(container)).toHaveNoViolations(); + expect( + screen.getByRole("img", { name: "common.unencrypted" }), + ).toBeTruthy(); + }); + + test("is not shown", () => { + render( + + + , + ); + expect( + screen.queryAllByRole("img", { name: "common.unencrypted" }).length, + ).toBe(0); + }); + }); + + describe("videoEnabled", () => { + test("just video is visible", () => { + render( + + + , + ); + expect(screen.getByTestId("video")).toBeVisible(); + expect(screen.queryAllByRole("img", { name: "some name" }).length).toBe( + 0, + ); + }); + + test("just avatar is visible", () => { + render( + + + , + ); + expect(screen.getByRole("img", { name: "some name" })).toBeVisible(); + expect(screen.getByTestId("video")).not.toBeVisible(); + }); + }); +}); diff --git a/src/tile/MediaView.tsx b/src/tile/MediaView.tsx index 9707e707..4e69bf41 100644 --- a/src/tile/MediaView.tsx +++ b/src/tile/MediaView.tsx @@ -76,7 +76,6 @@ export const MediaView = forwardRef( ( size={avatarSize} src={member?.getMxcAvatarUrl()} className={styles.avatar} + style={{ display: videoEnabled ? "none" : "initial" }} /> {video.publication !== undefined && ( ( // There's no reason for this to be focusable tabIndex={-1} disablePictureInPicture + style={{ display: videoEnabled ? "block" : "none" }} + data-testid="video" /> )} @@ -133,7 +135,13 @@ export const MediaView = forwardRef( )*/}
{nameTagLeadingIcon} - + {displayName} {unencryptedWarning && ( @@ -146,6 +154,8 @@ export const MediaView = forwardRef( width={20} height={20} className={styles.errorIcon} + role="img" + aria-label={t("common.unencrypted")} /> )} diff --git a/src/vitest.setup.ts b/src/vitest.setup.ts index 421ec663..38b8704e 100644 --- a/src/vitest.setup.ts +++ b/src/vitest.setup.ts @@ -15,6 +15,7 @@ import { afterEach } from "vitest"; import { cleanup } from "@testing-library/react"; import "vitest-axe/extend-expect"; import { logger } from "matrix-js-sdk/src/logger"; +import "@testing-library/jest-dom/vitest"; import EN_GB from "../locales/en-GB/app.json"; import { Config } from "./config/Config"; diff --git a/yarn.lock b/yarn.lock index 96ee1ae4..06f07543 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40,6 +40,11 @@ resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.1.3.tgz#4cdb6254da7962b07473ff5c335f3da485d94d71" integrity sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q== +"@adobe/css-tools@^4.4.0": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.1.tgz#2447a230bfe072c1659e6815129c03cf170710e3" + integrity sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ== + "@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" @@ -2914,6 +2919,19 @@ lz-string "^1.5.0" pretty-format "^27.0.2" +"@testing-library/jest-dom@^6.6.3": + version "6.6.3" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz#26ba906cf928c0f8172e182c6fe214eb4f9f2bd2" + integrity sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA== + dependencies: + "@adobe/css-tools" "^4.4.0" + aria-query "^5.0.0" + chalk "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.6.3" + lodash "^4.17.21" + redent "^3.0.0" + "@testing-library/react-hooks@^8.0.1": version "8.0.1" resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12" @@ -3527,7 +3545,7 @@ aria-query@5.3.0: dependencies: dequal "^2.0.3" -aria-query@^5.3.2: +aria-query@^5.0.0, aria-query@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== @@ -3928,6 +3946,14 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" @@ -4206,6 +4232,11 @@ css-what@^6.1.0: resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== + cssdb@^8.2.1: version "8.2.1" resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.2.1.tgz#62a5d9a41e2c86f1d7c35981098fc5ce47c5766c" @@ -4400,6 +4431,11 @@ dom-accessibility-api@^0.5.9: resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== +dom-accessibility-api@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" + integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== + dom-serializer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" @@ -6118,6 +6154,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + loglevel@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.1.tgz#d63976ac9bcd03c7c873116d41c2a85bafff1be7" @@ -7269,6 +7310,14 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + reflect.getprototypeof@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz#3ab04c32a8390b770712b7a8633972702d278859" From f7c7f41afdec0e6d4da81751bcb1f7b66fabedb7 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 27 Nov 2024 20:43:56 +0000 Subject: [PATCH 11/11] Upgrade js-sdk to develop with MSC4222 state_after support (#2841) Diff https://github.com/matrix-org/matrix-js-sdk/compare/2210255d6ffc909c574fb8ef16f92140b2fb7797...8fc77c595aa651db9f402df798b868ed076590e3 --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 6d5fca42..ebaa59ff 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "livekit-client": "^2.5.7", "lodash-es": "^4.17.21", "loglevel": "^1.9.1", - "matrix-js-sdk": "matrix-org/matrix-js-sdk#2210255d6ffc909c574fb8ef16f92140b2fb7797", + "matrix-js-sdk": "matrix-org/matrix-js-sdk#develop", "matrix-widget-api": "^1.10.0", "normalize.css": "^8.0.1", "observable-hooks": "^4.2.3", diff --git a/yarn.lock b/yarn.lock index 06f07543..759a021d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6258,9 +6258,9 @@ matrix-events-sdk@0.0.1: resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd" integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA== -matrix-js-sdk@matrix-org/matrix-js-sdk#2210255d6ffc909c574fb8ef16f92140b2fb7797: +matrix-js-sdk@matrix-org/matrix-js-sdk#develop: version "34.12.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/2210255d6ffc909c574fb8ef16f92140b2fb7797" + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/8fc77c595aa651db9f402df798b868ed076590e3" dependencies: "@babel/runtime" "^7.12.5" "@matrix-org/matrix-sdk-crypto-wasm" "^9.0.0"