Merge remote-tracking branch 'origin/develop' into rav/edited_events
This commit is contained in:
commit
ad7c002f4d
62 changed files with 558 additions and 223 deletions
2
.github/workflows/cypress.yaml
vendored
2
.github/workflows/cypress.yaml
vendored
|
@ -111,7 +111,7 @@ jobs:
|
|||
path: webapp
|
||||
|
||||
- name: Run Cypress tests
|
||||
uses: cypress-io/github-action@v4.2.2
|
||||
uses: cypress-io/github-action@v5.0.2
|
||||
with:
|
||||
# The built-in Electron runner seems to grind to a halt trying
|
||||
# to run the tests, so use chrome.
|
||||
|
|
|
@ -28,6 +28,7 @@ class MockMap extends EventEmitter {
|
|||
}
|
||||
const MockMapInstance = new MockMap();
|
||||
|
||||
class MockAttributionControl {}
|
||||
class MockGeolocateControl extends EventEmitter {
|
||||
trigger = jest.fn();
|
||||
}
|
||||
|
@ -43,5 +44,5 @@ module.exports = {
|
|||
LngLat,
|
||||
LngLatBounds,
|
||||
NavigationControl,
|
||||
AttributionControl,
|
||||
AttributionControl: MockAttributionControl,
|
||||
};
|
||||
|
|
|
@ -158,8 +158,8 @@ describe("Cryptography", function () {
|
|||
cy.startSynapse("default")
|
||||
.as("synapse")
|
||||
.then((synapse: SynapseInstance) => {
|
||||
cy.initTestUser(synapse, "Alice");
|
||||
cy.getBot(synapse, { displayName: "Bob", autoAcceptInvites: false }).as("bob");
|
||||
cy.initTestUser(synapse, "Alice", undefined, "alice_");
|
||||
cy.getBot(synapse, { displayName: "Bob", autoAcceptInvites: false, userIdPrefix: "bob_" }).as("bob");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ describe("Device manager", () => {
|
|||
cy.get(".mx_Spinner").should("not.exist");
|
||||
|
||||
// session name updated in details
|
||||
cy.get(".mx_DeviceDetailHeading h3").should("have.text", sessionName);
|
||||
cy.get(".mx_DeviceDetailHeading h4").should("have.text", sessionName);
|
||||
// and main list item
|
||||
cy.get(".mx_DeviceTile h4").should("have.text", sessionName);
|
||||
|
||||
|
|
|
@ -22,6 +22,10 @@ import { Credentials } from "./synapse";
|
|||
import Chainable = Cypress.Chainable;
|
||||
|
||||
interface CreateBotOpts {
|
||||
/**
|
||||
* A prefix to use for the userid. If unspecified, "bot_" will be used.
|
||||
*/
|
||||
userIdPrefix?: string;
|
||||
/**
|
||||
* Whether the bot should automatically accept all invites.
|
||||
*/
|
||||
|
@ -41,6 +45,7 @@ interface CreateBotOpts {
|
|||
}
|
||||
|
||||
const defaultCreateBotOptions = {
|
||||
userIdPrefix: "bot_",
|
||||
autoAcceptInvites: true,
|
||||
startClient: true,
|
||||
bootstrapCrossSigning: true,
|
||||
|
@ -157,7 +162,7 @@ function setupBotClient(
|
|||
|
||||
Cypress.Commands.add("getBot", (synapse: SynapseInstance, opts: CreateBotOpts): Chainable<CypressBot> => {
|
||||
opts = Object.assign({}, defaultCreateBotOptions, opts);
|
||||
const username = Cypress._.uniqueId("userId_");
|
||||
const username = Cypress._.uniqueId(opts.userIdPrefix);
|
||||
const password = Cypress._.uniqueId("password_");
|
||||
return cy
|
||||
.registerUser(synapse, username, password, opts.displayName)
|
||||
|
|
|
@ -37,11 +37,14 @@ declare global {
|
|||
* @param synapse the synapse returned by startSynapse
|
||||
* @param displayName the displayName to give the test user
|
||||
* @param prelaunchFn optional function to run before the app is visited
|
||||
* @param userIdPrefix optional prefix to use for the generated user id. If unspecified, `user_` will be
|
||||
* useed.
|
||||
*/
|
||||
initTestUser(
|
||||
synapse: SynapseInstance,
|
||||
displayName: string,
|
||||
prelaunchFn?: () => void,
|
||||
userIdPrefix?: string,
|
||||
): Chainable<UserCredentials>;
|
||||
/**
|
||||
* Logs into synapse with the given username/password
|
||||
|
@ -91,7 +94,12 @@ Cypress.Commands.add(
|
|||
// eslint-disable-next-line max-len
|
||||
Cypress.Commands.add(
|
||||
"initTestUser",
|
||||
(synapse: SynapseInstance, displayName: string, prelaunchFn?: () => void): Chainable<UserCredentials> => {
|
||||
(
|
||||
synapse: SynapseInstance,
|
||||
displayName: string,
|
||||
prelaunchFn?: () => void,
|
||||
userIdPrefix = "user_",
|
||||
): Chainable<UserCredentials> => {
|
||||
// XXX: work around Cypress not clearing IDB between tests
|
||||
cy.window({ log: false }).then((win) => {
|
||||
win.indexedDB.databases()?.then((databases) => {
|
||||
|
@ -101,7 +109,7 @@ Cypress.Commands.add(
|
|||
});
|
||||
});
|
||||
|
||||
const username = Cypress._.uniqueId("userId_");
|
||||
const username = Cypress._.uniqueId(userIdPrefix);
|
||||
const password = Cypress._.uniqueId("password_");
|
||||
return cy
|
||||
.registerUser(synapse, username, password, displayName)
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
"linkify-string": "4.0.0-beta.4",
|
||||
"linkifyjs": "4.0.0-beta.4",
|
||||
"lodash": "^4.17.20",
|
||||
"maplibre-gl": "^1.15.2",
|
||||
"maplibre-gl": "^2.0.0",
|
||||
"matrix-encrypt-attachment": "^1.0.3",
|
||||
"matrix-events-sdk": "0.0.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
|
|
|
@ -20,24 +20,29 @@ limitations under the License.
|
|||
left: unset;
|
||||
right: -$spacing-12;
|
||||
width: 232px;
|
||||
padding: $spacing-12;
|
||||
|
||||
border: 1px solid $quinary-content;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0px 1px 3px rgba(23, 25, 28, 0.05);
|
||||
|
||||
.mx_Dropdown_option_highlight {
|
||||
background-color: $system;
|
||||
|
||||
.mx_Dropdown_option_highlight {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Dropdown_input {
|
||||
height: 24px;
|
||||
background-color: $quinary-content;
|
||||
border-color: $quinary-content;
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
color: $secondary-content;
|
||||
border-radius: 4px;
|
||||
|
||||
&:focus {
|
||||
&:focus,
|
||||
&:hover {
|
||||
background-color: $quinary-content;
|
||||
border-color: $quinary-content;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,18 +22,18 @@ limitations under the License.
|
|||
width: 100%;
|
||||
|
||||
margin-top: $spacing-16;
|
||||
padding: $spacing-16;
|
||||
padding: $spacing-24;
|
||||
border-radius: 8px;
|
||||
border: 1px solid $quinary-content;
|
||||
}
|
||||
|
||||
.mx_DeviceDetails_section {
|
||||
padding-bottom: $spacing-16;
|
||||
margin-bottom: $spacing-16;
|
||||
padding-bottom: $spacing-20;
|
||||
margin-bottom: $spacing-20;
|
||||
border-bottom: 1px solid $quinary-content;
|
||||
|
||||
display: grid;
|
||||
grid-gap: $spacing-16;
|
||||
grid-gap: $spacing-24;
|
||||
justify-content: left;
|
||||
grid-template-columns: 100%;
|
||||
|
||||
|
@ -52,6 +52,7 @@ limitations under the License.
|
|||
font-size: $font-12px;
|
||||
color: $secondary-content;
|
||||
line-height: $font-14px;
|
||||
margin-top: $spacing-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,17 +23,25 @@ limitations under the License.
|
|||
color: $secondary-content;
|
||||
|
||||
--icon-transform: rotate(-90deg);
|
||||
|
||||
&:hover {
|
||||
background: $quinary-content;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_DeviceExpandDetailsButton.mx_DeviceExpandDetailsButton_expanded {
|
||||
--icon-transform: rotate(0deg);
|
||||
|
||||
background: $system;
|
||||
|
||||
&:hover {
|
||||
background: $quinary-content;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_DeviceExpandDetailsButton_icon {
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
transition: all 0.3s;
|
||||
transform: var(--icon-transform);
|
||||
|
|
|
@ -55,7 +55,7 @@ limitations under the License.
|
|||
box-sizing: border-box;
|
||||
padding: $spacing-4;
|
||||
|
||||
border: 1px solid $system;
|
||||
border: 1px solid $quinary-content;
|
||||
border-radius: 50%;
|
||||
background-color: $background;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ limitations under the License.
|
|||
width: 100%;
|
||||
box-sizing: inherit;
|
||||
line-height: $font-24px;
|
||||
margin-bottom: $spacing-32;
|
||||
margin-bottom: $spacing-24;
|
||||
color: $secondary-content;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ limitations under the License.
|
|||
|
||||
&::after {
|
||||
mask-image: url("$(res)/img/e2e/warning.svg");
|
||||
background-color: $alert;
|
||||
background-color: $e2e-warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ limitations under the License.
|
|||
|
||||
&.mx_cryptoEvent_icon_warning::after {
|
||||
mask-image: url("$(res)/img/e2e/warning.svg");
|
||||
background-color: $alert;
|
||||
background-color: $e2e-warning-color;
|
||||
}
|
||||
|
||||
.mx_cryptoEvent_state,
|
||||
|
|
|
@ -75,14 +75,14 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomSummaryCard_e2ee_verified {
|
||||
background-color: #0dbd8b;
|
||||
background-color: #$e2e-verified-color;
|
||||
&::before {
|
||||
mask-image: url("$(res)/img/e2e/verified.svg");
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomSummaryCard_e2ee_warning {
|
||||
background-color: #ff5b55;
|
||||
background-color: $e2e-warning-color;
|
||||
&::before {
|
||||
mask-image: url("$(res)/img/e2e/warning.svg");
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ limitations under the License.
|
|||
width: 24px;
|
||||
height: 24px;
|
||||
mask-image: url("$(res)/img/e2e/decryption-failure.svg");
|
||||
background-color: $alert;
|
||||
background-color: $e2e-warning-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
|
|
|
@ -66,7 +66,7 @@ limitations under the License.
|
|||
|
||||
.mx_E2EIcon_warning::after {
|
||||
mask-image: url("$(res)/img/e2e/warning.svg");
|
||||
background-color: $alert;
|
||||
background-color: $e2e-warning-color;
|
||||
}
|
||||
|
||||
.mx_E2EIcon_normal::after {
|
||||
|
@ -76,5 +76,5 @@ limitations under the License.
|
|||
|
||||
.mx_E2EIcon_verified::after {
|
||||
mask-image: url("$(res)/img/e2e/verified.svg");
|
||||
background-color: $accent;
|
||||
background-color: $e2e-verified-color;
|
||||
}
|
||||
|
|
|
@ -678,7 +678,7 @@ $left-gutter: 64px;
|
|||
|
||||
&.mx_EventTile_e2eIcon_warning::after {
|
||||
mask-image: url("$(res)/img/e2e/warning.svg");
|
||||
background-color: $alert;
|
||||
background-color: $e2e-warning-color;
|
||||
}
|
||||
|
||||
&.mx_EventTile_e2eIcon_normal::after {
|
||||
|
|
|
@ -215,10 +215,10 @@ $event-timestamp-color: #acacac;
|
|||
$copy-button-url: "$(res)/img/element-icons/copy.svg";
|
||||
|
||||
/* e2e */
|
||||
$e2e-verified-color: #76cfa5; /* N.B. *NOT* the same as $accent */
|
||||
$e2e-verified-color: #0dbd8b;
|
||||
$e2e-unknown-color: #e8bf37;
|
||||
$e2e-unverified-color: #e8bf37;
|
||||
$e2e-warning-color: #ba6363;
|
||||
$e2e-warning-color: #ff5b55;
|
||||
$e2e-verified-color-light: rgba($e2e-verified-color, 0.06);
|
||||
$e2e-warning-color-light: rgba($e2e-warning-color, 0.06);
|
||||
|
||||
|
|
|
@ -183,10 +183,10 @@ $roomtile-default-badge-bg-color: $muted-fg-color;
|
|||
|
||||
/* e2e */
|
||||
/* ******************** */
|
||||
$e2e-verified-color: #76cfa5; /* N.B. *NOT* the same as $accent */
|
||||
$e2e-verified-color: #0dbd8b;
|
||||
$e2e-unknown-color: #e8bf37;
|
||||
$e2e-unverified-color: #e8bf37;
|
||||
$e2e-warning-color: #ba6363;
|
||||
$e2e-warning-color: #ff5b55;
|
||||
$e2e-verified-color-light: rgba($e2e-verified-color, 0.06);
|
||||
$e2e-warning-color-light: rgba($e2e-warning-color, 0.06);
|
||||
/* ******************** */
|
||||
|
|
|
@ -191,8 +191,6 @@ export interface IConfigOptions {
|
|||
description: string;
|
||||
show_once?: boolean;
|
||||
};
|
||||
|
||||
use_rust_crypto_sdk?: boolean;
|
||||
}
|
||||
|
||||
export interface ISsoRedirectOptions {
|
||||
|
|
|
@ -63,6 +63,8 @@ import { OpenInviteDialogPayload } from "./dispatcher/payloads/OpenInviteDialogP
|
|||
import { findDMForUser } from "./utils/dm/findDMForUser";
|
||||
import { getJoinedNonFunctionalMembers } from "./utils/room/getJoinedNonFunctionalMembers";
|
||||
import { localNotificationsAreSilenced } from "./utils/notifications";
|
||||
import { SdkContextClass } from "./contexts/SDKContext";
|
||||
import { showCantStartACallDialog } from "./voice-broadcast/utils/showCantStartACallDialog";
|
||||
|
||||
export const PROTOCOL_PSTN = "m.protocol.pstn";
|
||||
export const PROTOCOL_PSTN_PREFIXED = "im.vector.protocol.pstn";
|
||||
|
@ -932,6 +934,15 @@ export default class LegacyCallHandler extends EventEmitter {
|
|||
}
|
||||
|
||||
public async placeCall(roomId: string, type?: CallType, transferee?: MatrixCall): Promise<void> {
|
||||
// Pause current broadcast, if any
|
||||
SdkContextClass.instance.voiceBroadcastPlaybacksStore.getCurrent()?.pause();
|
||||
|
||||
if (SdkContextClass.instance.voiceBroadcastRecordingsStore.getCurrent()) {
|
||||
// Do not start a call, if recording a broadcast
|
||||
showCantStartACallDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
// We might be using managed hybrid widgets
|
||||
if (isManagedHybridWidgetEnabled()) {
|
||||
await addManagedHybridWidget(roomId);
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React, { ReactNode, useContext } from "react";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { Beacon, BeaconEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { LocationAssetType } from "matrix-js-sdk/src/@types/location";
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { Beacon, Room } from "matrix-js-sdk/src/matrix";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
|
||||
import { Icon as LiveLocationIcon } from "../../../../res/img/location/live-location.svg";
|
||||
import { useLiveBeacons } from "../../../utils/beacon/useLiveBeacons";
|
||||
|
|
|
@ -137,7 +137,7 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
|
|||
|
||||
private addMarkerToMap = () => {
|
||||
this.marker = new maplibregl.Marker({
|
||||
element: document.getElementById(this.getMarkerId()),
|
||||
element: document.getElementById(this.getMarkerId()) ?? undefined,
|
||||
anchor: "bottom",
|
||||
offset: [0, -1],
|
||||
})
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import React, { ReactNode, useContext, useEffect } from "react";
|
||||
import classNames from "classnames";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { ClientEvent, IClientWellKnown } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React, { ReactNode, useCallback, useEffect, useState } from "react";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { createMarker, parseGeoUri } from "../../../utils/location";
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
|
|
|
@ -115,7 +115,7 @@ const CurrentDeviceSection: React.FC<Props> = ({
|
|||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
/>
|
||||
</DeviceTile>
|
||||
{isExpanded && (
|
||||
{isExpanded ? (
|
||||
<DeviceDetails
|
||||
device={device}
|
||||
localNotificationSettings={localNotificationSettings}
|
||||
|
@ -125,11 +125,14 @@ const CurrentDeviceSection: React.FC<Props> = ({
|
|||
onSignOutDevice={onSignOutCurrentDevice}
|
||||
saveDeviceName={saveDeviceName}
|
||||
/>
|
||||
)}
|
||||
) : (
|
||||
<>
|
||||
<br />
|
||||
<DeviceVerificationStatusCard device={device} onVerifyDevice={onVerifyCurrentDevice} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</SettingsSubsection>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -134,7 +134,7 @@ export const DeviceDetailHeading: React.FC<Props> = ({ device, saveDeviceName })
|
|||
<DeviceNameEditor device={device} saveDeviceName={saveDeviceName} stopEditing={() => setIsEditing(false)} />
|
||||
) : (
|
||||
<div className="mx_DeviceDetailHeading" data-testid="device-detail-heading">
|
||||
<Heading size="h3">{device.display_name || device.device_id}</Heading>
|
||||
<Heading size="h4">{device.display_name || device.device_id}</Heading>
|
||||
<AccessibleButton
|
||||
kind="link_inline"
|
||||
onClick={() => setIsEditing(true)}
|
||||
|
|
|
@ -50,7 +50,7 @@ const FilteredDeviceListHeader: React.FC<Props> = ({
|
|||
</TooltipTarget>
|
||||
<span className="mx_FilteredDeviceListHeader_label">
|
||||
{selectedDeviceCount > 0
|
||||
? _t("%(selectedDeviceCount)s sessions selected", { selectedDeviceCount })
|
||||
? _t("%(count)s sessions selected", { count: selectedDeviceCount })
|
||||
: _t("Sessions")}
|
||||
</span>
|
||||
{children}
|
||||
|
|
|
@ -53,7 +53,7 @@ const SecurityRecommendations: React.FC<Props> = ({ devices, currentDeviceId, go
|
|||
return (
|
||||
<SettingsSubsection
|
||||
heading={_t("Security recommendations")}
|
||||
description={_t("Improve your account security by following these recommendations")}
|
||||
description={_t("Improve your account security by following these recommendations.")}
|
||||
data-testid="security-recommendations-section"
|
||||
>
|
||||
{!!unverifiedDevicesCount && (
|
||||
|
@ -89,7 +89,7 @@ const SecurityRecommendations: React.FC<Props> = ({ devices, currentDeviceId, go
|
|||
<>
|
||||
{_t(
|
||||
`Consider signing out from old sessions ` +
|
||||
`(%(inactiveAgeDays)s days or older) you don't use anymore`,
|
||||
`(%(inactiveAgeDays)s days or older) you don't use anymore.`,
|
||||
{ inactiveAgeDays },
|
||||
)}
|
||||
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Inactive} />
|
||||
|
|
|
@ -648,6 +648,8 @@
|
|||
"You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.": "You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.",
|
||||
"You don't have the required permissions to start a voice broadcast in this room. Contact a room administrator to upgrade your permissions.": "You don't have the required permissions to start a voice broadcast in this room. Contact a room administrator to upgrade your permissions.",
|
||||
"Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.": "Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.",
|
||||
"Can’t start a call": "Can’t start a call",
|
||||
"You can’t start a call as you are currently recording a live broadcast. Please end your live broadcast in order to start a call.": "You can’t start a call as you are currently recording a live broadcast. Please end your live broadcast in order to start a call.",
|
||||
"You ended a <a>voice broadcast</a>": "You ended a <a>voice broadcast</a>",
|
||||
"%(senderName)s ended a <a>voice broadcast</a>": "%(senderName)s ended a <a>voice broadcast</a>",
|
||||
"You ended a voice broadcast": "You ended a voice broadcast",
|
||||
|
@ -1005,8 +1007,6 @@
|
|||
"Enable URL previews by default for participants in this room": "Enable URL previews by default for participants in this room",
|
||||
"Enable widget screenshots on supported widgets": "Enable widget screenshots on supported widgets",
|
||||
"Prompt before sending invites to potentially invalid matrix IDs": "Prompt before sending invites to potentially invalid matrix IDs",
|
||||
"Order rooms by name": "Order rooms by name",
|
||||
"Show rooms with unread notifications first": "Show rooms with unread notifications first",
|
||||
"Show shortcuts to recently viewed rooms above the room list": "Show shortcuts to recently viewed rooms above the room list",
|
||||
"Show shortcut to welcome checklist above the room list": "Show shortcut to welcome checklist above the room list",
|
||||
"Show hidden events in timeline": "Show hidden events in timeline",
|
||||
|
@ -1835,14 +1835,14 @@
|
|||
"Inactive for %(inactiveAgeDays)s days or longer": "Inactive for %(inactiveAgeDays)s days or longer",
|
||||
"Filter devices": "Filter devices",
|
||||
"Show": "Show",
|
||||
"%(selectedDeviceCount)s sessions selected": "%(selectedDeviceCount)s sessions selected",
|
||||
"%(count)s sessions selected|other": "%(count)s sessions selected",
|
||||
"%(count)s sessions selected|one": "%(count)s session selected",
|
||||
"Sign in with QR code": "Sign in with QR code",
|
||||
"You can use this device to sign in a new device with a QR code. You will need to scan the QR code shown on this device with your device that's signed out.": "You can use this device to sign in a new device with a QR code. You will need to scan the QR code shown on this device with your device that's signed out.",
|
||||
"Show QR code": "Show QR code",
|
||||
"Security recommendations": "Security recommendations",
|
||||
"Improve your account security by following these recommendations": "Improve your account security by following these recommendations",
|
||||
"Improve your account security by following these recommendations.": "Improve your account security by following these recommendations.",
|
||||
"View all": "View all",
|
||||
"Consider signing out from old sessions (%(inactiveAgeDays)s days or older) you don't use anymore": "Consider signing out from old sessions (%(inactiveAgeDays)s days or older) you don't use anymore",
|
||||
"Failed to set pusher state": "Failed to set pusher state",
|
||||
"Unable to remove contact information": "Unable to remove contact information",
|
||||
"Remove %(email)s?": "Remove %(email)s?",
|
||||
|
|
|
@ -885,18 +885,6 @@ export const SETTINGS: { [setting: string]: ISetting } = {
|
|||
deny: [],
|
||||
},
|
||||
},
|
||||
// TODO: Remove setting: https://github.com/vector-im/element-web/issues/14373
|
||||
"RoomList.orderAlphabetically": {
|
||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||
displayName: _td("Order rooms by name"),
|
||||
default: false,
|
||||
},
|
||||
// TODO: Remove setting: https://github.com/vector-im/element-web/issues/14373
|
||||
"RoomList.orderByImportance": {
|
||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||
displayName: _td("Show rooms with unread notifications first"),
|
||||
default: true,
|
||||
},
|
||||
"breadcrumbs": {
|
||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||
displayName: _td("Show shortcuts to recently viewed rooms above the room list"),
|
||||
|
|
|
@ -56,6 +56,7 @@ import {
|
|||
doMaybeSetCurrentVoiceBroadcastPlayback,
|
||||
} from "../voice-broadcast";
|
||||
import { IRoomStateEventsActionPayload } from "../actions/MatrixActionCreators";
|
||||
import { showCantStartACallDialog } from "../voice-broadcast/utils/showCantStartACallDialog";
|
||||
|
||||
const NUM_JOIN_RETRY = 5;
|
||||
|
||||
|
@ -180,6 +181,16 @@ export class RoomViewStore extends EventEmitter {
|
|||
return;
|
||||
}
|
||||
|
||||
if (newState.viewingCall) {
|
||||
// Pause current broadcast, if any
|
||||
this.stores.voiceBroadcastPlaybacksStore.getCurrent()?.pause();
|
||||
|
||||
if (this.stores.voiceBroadcastRecordingsStore.getCurrent()) {
|
||||
showCantStartACallDialog();
|
||||
newState.viewingCall = false;
|
||||
}
|
||||
}
|
||||
|
||||
const lastRoomId = this.state.roomId;
|
||||
this.state = Object.assign(this.state, newState);
|
||||
if (lastRoomId !== this.state.roomId) {
|
||||
|
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
|
||||
|
@ -387,20 +386,15 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
|
|||
|
||||
// logic must match calculateListOrder
|
||||
private calculateTagSorting(tagId: TagID): SortAlgorithm {
|
||||
const isDefaultRecent = tagId === DefaultTagID.Invite || tagId === DefaultTagID.DM;
|
||||
const defaultSort = isDefaultRecent ? SortAlgorithm.Recent : SortAlgorithm.Alphabetic;
|
||||
const settingAlphabetical = SettingsStore.getValue("RoomList.orderAlphabetically", null, true);
|
||||
const definedSort = this.getTagSorting(tagId);
|
||||
const storedSort = this.getStoredTagSorting(tagId);
|
||||
|
||||
// We use the following order to determine which of the 4 flags to use:
|
||||
// Stored > Settings > Defined > Default
|
||||
|
||||
let tagSort = defaultSort;
|
||||
let tagSort = SortAlgorithm.Recent;
|
||||
if (storedSort) {
|
||||
tagSort = storedSort;
|
||||
} else if (!isNullOrUndefined(settingAlphabetical)) {
|
||||
tagSort = settingAlphabetical ? SortAlgorithm.Alphabetic : SortAlgorithm.Recent;
|
||||
} else if (definedSort) {
|
||||
tagSort = definedSort;
|
||||
} // else default (already set)
|
||||
|
@ -431,8 +425,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
|
|||
|
||||
// logic must match calculateTagSorting
|
||||
private calculateListOrder(tagId: TagID): ListAlgorithm {
|
||||
const defaultOrder = ListAlgorithm.Natural;
|
||||
const settingImportance = SettingsStore.getValue("RoomList.orderByImportance", null, true);
|
||||
const defaultOrder = ListAlgorithm.Importance;
|
||||
const definedOrder = this.getListOrder(tagId);
|
||||
const storedOrder = this.getStoredListOrder(tagId);
|
||||
|
||||
|
@ -442,8 +435,6 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
|
|||
let listOrder = defaultOrder;
|
||||
if (storedOrder) {
|
||||
listOrder = storedOrder;
|
||||
} else if (!isNullOrUndefined(settingImportance)) {
|
||||
listOrder = settingImportance ? ListAlgorithm.Importance : ListAlgorithm.Natural;
|
||||
} else if (definedOrder) {
|
||||
listOrder = definedOrder;
|
||||
} // else default (already set)
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { M_LOCATION } from "matrix-js-sdk/src/@types/location";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
|
|
@ -388,6 +388,7 @@ export class VoiceBroadcastPlayback
|
|||
|
||||
public stop(): void {
|
||||
this.setState(VoiceBroadcastPlaybackState.Stopped);
|
||||
this.getCurrentPlayback()?.stop();
|
||||
this.currentlyPlaying = null;
|
||||
this.setPosition(0);
|
||||
}
|
||||
|
@ -397,7 +398,6 @@ export class VoiceBroadcastPlayback
|
|||
if (this.getState() === VoiceBroadcastPlaybackState.Stopped) return;
|
||||
|
||||
this.setState(VoiceBroadcastPlaybackState.Paused);
|
||||
if (!this.currentlyPlaying) return;
|
||||
this.getCurrentPlayback()?.pause();
|
||||
}
|
||||
|
||||
|
|
36
src/voice-broadcast/utils/showCantStartACallDialog.tsx
Normal file
36
src/voice-broadcast/utils/showCantStartACallDialog.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import InfoDialog from "../../components/views/dialogs/InfoDialog";
|
||||
import { _t } from "../../languageHandler";
|
||||
import Modal from "../../Modal";
|
||||
|
||||
export const showCantStartACallDialog = () => {
|
||||
Modal.createDialog(InfoDialog, {
|
||||
title: _t("Can’t start a call"),
|
||||
description: (
|
||||
<p>
|
||||
{_t(
|
||||
"You can’t start a call as you are currently recording a live broadcast. " +
|
||||
"Please end your live broadcast in order to start a call.",
|
||||
)}
|
||||
</p>
|
||||
),
|
||||
hasCloseButton: true,
|
||||
});
|
||||
};
|
|
@ -19,6 +19,7 @@ import {
|
|||
LOCAL_NOTIFICATION_SETTINGS_PREFIX,
|
||||
MatrixEvent,
|
||||
PushRuleKind,
|
||||
Room,
|
||||
RuleId,
|
||||
TweakName,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
|
@ -43,6 +44,28 @@ import { Action } from "../src/dispatcher/actions";
|
|||
import { getFunctionalMembers } from "../src/utils/room/getFunctionalMembers";
|
||||
import SettingsStore from "../src/settings/SettingsStore";
|
||||
import { UIFeature } from "../src/settings/UIFeature";
|
||||
import { VoiceBroadcastInfoState, VoiceBroadcastPlayback, VoiceBroadcastRecording } from "../src/voice-broadcast";
|
||||
import { mkVoiceBroadcastInfoStateEvent } from "./voice-broadcast/utils/test-utils";
|
||||
import { SdkContextClass } from "../src/contexts/SDKContext";
|
||||
import Modal from "../src/Modal";
|
||||
|
||||
jest.mock("../src/Modal");
|
||||
|
||||
// mock VoiceRecording because it contains all the audio APIs
|
||||
jest.mock("../src/audio/VoiceRecording", () => ({
|
||||
VoiceRecording: jest.fn().mockReturnValue({
|
||||
disableMaxLength: jest.fn(),
|
||||
liveData: {
|
||||
onUpdate: jest.fn(),
|
||||
},
|
||||
off: jest.fn(),
|
||||
on: jest.fn(),
|
||||
start: jest.fn(),
|
||||
stop: jest.fn(),
|
||||
destroy: jest.fn(),
|
||||
contentType: "audio/ogg",
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock("../src/utils/room/getFunctionalMembers", () => ({
|
||||
getFunctionalMembers: jest.fn(),
|
||||
|
@ -71,7 +94,7 @@ const VIRTUAL_ROOM_BOB = "$virtual_bob_room:example.org";
|
|||
// Bob's phone number
|
||||
const BOB_PHONE_NUMBER = "01818118181";
|
||||
|
||||
function mkStubDM(roomId, userId) {
|
||||
function mkStubDM(roomId: string, userId: string) {
|
||||
const room = mkStubRoom(roomId, "room", MatrixClientPeg.get());
|
||||
room.getJoinedMembers = jest.fn().mockReturnValue([
|
||||
{
|
||||
|
@ -134,23 +157,24 @@ function untilCallHandlerEvent(callHandler: LegacyCallHandler, event: LegacyCall
|
|||
|
||||
describe("LegacyCallHandler", () => {
|
||||
let dmRoomMap;
|
||||
let callHandler;
|
||||
let callHandler: LegacyCallHandler;
|
||||
let audioElement: HTMLAudioElement;
|
||||
let fakeCall;
|
||||
let fakeCall: MatrixCall | null;
|
||||
|
||||
// what addresses the app has looked up via pstn and native lookup
|
||||
let pstnLookup: string;
|
||||
let nativeLookup: string;
|
||||
let pstnLookup: string | null;
|
||||
let nativeLookup: string | null;
|
||||
const deviceId = "my-device";
|
||||
|
||||
beforeEach(async () => {
|
||||
stubClient();
|
||||
MatrixClientPeg.get().createCall = (roomId) => {
|
||||
fakeCall = null;
|
||||
MatrixClientPeg.get().createCall = (roomId: string): MatrixCall | null => {
|
||||
if (fakeCall && fakeCall.roomId !== roomId) {
|
||||
throw new Error("Only one call is supported!");
|
||||
}
|
||||
fakeCall = new FakeCall(roomId);
|
||||
return fakeCall;
|
||||
fakeCall = new FakeCall(roomId) as unknown as MatrixCall;
|
||||
return fakeCall as unknown as MatrixCall;
|
||||
};
|
||||
MatrixClientPeg.get().deviceId = deviceId;
|
||||
|
||||
|
@ -172,7 +196,7 @@ describe("LegacyCallHandler", () => {
|
|||
const nativeRoomCharie = mkStubDM(NATIVE_ROOM_CHARLIE, NATIVE_CHARLIE);
|
||||
const virtualBobRoom = mkStubDM(VIRTUAL_ROOM_BOB, VIRTUAL_BOB);
|
||||
|
||||
MatrixClientPeg.get().getRoom = (roomId) => {
|
||||
MatrixClientPeg.get().getRoom = (roomId: string): Room | null => {
|
||||
switch (roomId) {
|
||||
case NATIVE_ROOM_ALICE:
|
||||
return nativeRoomAlice;
|
||||
|
@ -183,6 +207,8 @@ describe("LegacyCallHandler", () => {
|
|||
case VIRTUAL_ROOM_BOB:
|
||||
return virtualBobRoom;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
dmRoomMap = {
|
||||
|
@ -212,13 +238,13 @@ describe("LegacyCallHandler", () => {
|
|||
return [];
|
||||
}
|
||||
},
|
||||
};
|
||||
} as DMRoomMap;
|
||||
DMRoomMap.setShared(dmRoomMap);
|
||||
|
||||
pstnLookup = null;
|
||||
nativeLookup = null;
|
||||
|
||||
MatrixClientPeg.get().getThirdpartyUser = (proto, params) => {
|
||||
MatrixClientPeg.get().getThirdpartyUser = (proto: string, params: any) => {
|
||||
if ([PROTOCOL_PSTN, PROTOCOL_PSTN_PREFIXED].includes(proto)) {
|
||||
pstnLookup = params["m.id.phone"];
|
||||
return Promise.resolve([
|
||||
|
@ -261,6 +287,8 @@ describe("LegacyCallHandler", () => {
|
|||
}
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
|
||||
audioElement = document.createElement("audio");
|
||||
|
@ -270,10 +298,10 @@ describe("LegacyCallHandler", () => {
|
|||
|
||||
afterEach(() => {
|
||||
callHandler.stop();
|
||||
// @ts-ignore
|
||||
DMRoomMap.setShared(null);
|
||||
// @ts-ignore
|
||||
window.mxLegacyCallHandler = null;
|
||||
fakeCall = null;
|
||||
MatrixClientPeg.unset();
|
||||
|
||||
document.body.removeChild(audioElement);
|
||||
|
@ -292,25 +320,27 @@ describe("LegacyCallHandler", () => {
|
|||
|
||||
// Check that a call was started: its room on the protocol level
|
||||
// should be the virtual room
|
||||
expect(fakeCall.roomId).toEqual(VIRTUAL_ROOM_BOB);
|
||||
expect(fakeCall).not.toBeNull();
|
||||
expect(fakeCall?.roomId).toEqual(VIRTUAL_ROOM_BOB);
|
||||
|
||||
// but it should appear to the user to be in thw native room for Bob
|
||||
expect(callHandler.roomIdForCall(fakeCall)).toEqual(NATIVE_ROOM_BOB);
|
||||
expect(callHandler.roomIdForCall(fakeCall!)).toEqual(NATIVE_ROOM_BOB);
|
||||
});
|
||||
|
||||
it("should look up the correct user and start a call in the room when a call is transferred", async () => {
|
||||
// we can pass a very minimal object as as the call since we pass consultFirst=true:
|
||||
// we don't need to actually do any transferring
|
||||
const mockTransferreeCall = { type: CallType.Voice };
|
||||
const mockTransferreeCall = { type: CallType.Voice } as unknown as MatrixCall;
|
||||
await callHandler.startTransferToPhoneNumber(mockTransferreeCall, BOB_PHONE_NUMBER, true);
|
||||
|
||||
// same checks as above
|
||||
const viewRoomPayload = await untilDispatch(Action.ViewRoom);
|
||||
expect(viewRoomPayload.room_id).toEqual(NATIVE_ROOM_BOB);
|
||||
|
||||
expect(fakeCall.roomId).toEqual(VIRTUAL_ROOM_BOB);
|
||||
expect(fakeCall).not.toBeNull();
|
||||
expect(fakeCall!.roomId).toEqual(VIRTUAL_ROOM_BOB);
|
||||
|
||||
expect(callHandler.roomIdForCall(fakeCall)).toEqual(NATIVE_ROOM_BOB);
|
||||
expect(callHandler.roomIdForCall(fakeCall!)).toEqual(NATIVE_ROOM_BOB);
|
||||
});
|
||||
|
||||
it("should move calls between rooms when remote asserted identity changes", async () => {
|
||||
|
@ -331,10 +361,11 @@ describe("LegacyCallHandler", () => {
|
|||
|
||||
// Now emit an asserted identity for Bob: this should be ignored
|
||||
// because we haven't set the config option to obey asserted identity
|
||||
fakeCall.getRemoteAssertedIdentity = jest.fn().mockReturnValue({
|
||||
expect(fakeCall).not.toBeNull();
|
||||
fakeCall!.getRemoteAssertedIdentity = jest.fn().mockReturnValue({
|
||||
id: NATIVE_BOB,
|
||||
});
|
||||
fakeCall.emit(CallEvent.AssertedIdentityChanged);
|
||||
fakeCall!.emit(CallEvent.AssertedIdentityChanged);
|
||||
|
||||
// Now set the config option
|
||||
SdkConfig.add({
|
||||
|
@ -344,10 +375,10 @@ describe("LegacyCallHandler", () => {
|
|||
});
|
||||
|
||||
// ...and send another asserted identity event for a different user
|
||||
fakeCall.getRemoteAssertedIdentity = jest.fn().mockReturnValue({
|
||||
fakeCall!.getRemoteAssertedIdentity = jest.fn().mockReturnValue({
|
||||
id: NATIVE_CHARLIE,
|
||||
});
|
||||
fakeCall.emit(CallEvent.AssertedIdentityChanged);
|
||||
fakeCall!.emit(CallEvent.AssertedIdentityChanged);
|
||||
|
||||
await roomChangePromise;
|
||||
callHandler.removeAllListeners();
|
||||
|
@ -362,21 +393,68 @@ describe("LegacyCallHandler", () => {
|
|||
expect(callHandler.getCallForRoom(NATIVE_ROOM_BOB)).toBeNull();
|
||||
expect(callHandler.getCallForRoom(NATIVE_ROOM_CHARLIE)).toBe(fakeCall);
|
||||
});
|
||||
|
||||
describe("when listening to a voice broadcast", () => {
|
||||
let voiceBroadcastPlayback: VoiceBroadcastPlayback;
|
||||
|
||||
beforeEach(() => {
|
||||
voiceBroadcastPlayback = new VoiceBroadcastPlayback(
|
||||
mkVoiceBroadcastInfoStateEvent(
|
||||
"!room:example.com",
|
||||
VoiceBroadcastInfoState.Started,
|
||||
MatrixClientPeg.get().getSafeUserId(),
|
||||
"d42",
|
||||
),
|
||||
MatrixClientPeg.get(),
|
||||
);
|
||||
SdkContextClass.instance.voiceBroadcastPlaybacksStore.setCurrent(voiceBroadcastPlayback);
|
||||
jest.spyOn(voiceBroadcastPlayback, "pause").mockImplementation();
|
||||
});
|
||||
|
||||
it("and placing a call should pause the broadcast", async () => {
|
||||
callHandler.placeCall(NATIVE_ROOM_ALICE, CallType.Voice);
|
||||
await untilCallHandlerEvent(callHandler, LegacyCallHandlerEvent.CallState);
|
||||
|
||||
expect(voiceBroadcastPlayback.pause).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when recording a voice broadcast", () => {
|
||||
beforeEach(() => {
|
||||
SdkContextClass.instance.voiceBroadcastRecordingsStore.setCurrent(
|
||||
new VoiceBroadcastRecording(
|
||||
mkVoiceBroadcastInfoStateEvent(
|
||||
"!room:example.com",
|
||||
VoiceBroadcastInfoState.Started,
|
||||
MatrixClientPeg.get().getSafeUserId(),
|
||||
"d42",
|
||||
),
|
||||
MatrixClientPeg.get(),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("and placing a call should show the info dialog", async () => {
|
||||
callHandler.placeCall(NATIVE_ROOM_ALICE, CallType.Voice);
|
||||
expect(Modal.createDialog).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("LegacyCallHandler without third party protocols", () => {
|
||||
let dmRoomMap;
|
||||
let callHandler: LegacyCallHandler;
|
||||
let audioElement: HTMLAudioElement;
|
||||
let fakeCall;
|
||||
let fakeCall: MatrixCall | null;
|
||||
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
fakeCall = null;
|
||||
MatrixClientPeg.get().createCall = (roomId) => {
|
||||
if (fakeCall && fakeCall.roomId !== roomId) {
|
||||
throw new Error("Only one call is supported!");
|
||||
}
|
||||
fakeCall = new FakeCall(roomId);
|
||||
fakeCall = new FakeCall(roomId) as unknown as MatrixCall;
|
||||
return fakeCall;
|
||||
};
|
||||
|
||||
|
@ -389,11 +467,13 @@ describe("LegacyCallHandler without third party protocols", () => {
|
|||
|
||||
const nativeRoomAlice = mkStubDM(NATIVE_ROOM_ALICE, NATIVE_ALICE);
|
||||
|
||||
MatrixClientPeg.get().getRoom = (roomId) => {
|
||||
MatrixClientPeg.get().getRoom = (roomId: string): Room | null => {
|
||||
switch (roomId) {
|
||||
case NATIVE_ROOM_ALICE:
|
||||
return nativeRoomAlice;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
dmRoomMap = {
|
||||
|
@ -411,7 +491,7 @@ describe("LegacyCallHandler without third party protocols", () => {
|
|||
return [];
|
||||
}
|
||||
},
|
||||
};
|
||||
} as DMRoomMap;
|
||||
DMRoomMap.setShared(dmRoomMap);
|
||||
|
||||
MatrixClientPeg.get().getThirdpartyUser = (_proto, _params) => {
|
||||
|
@ -421,14 +501,17 @@ describe("LegacyCallHandler without third party protocols", () => {
|
|||
audioElement = document.createElement("audio");
|
||||
audioElement.id = "remoteAudio";
|
||||
document.body.appendChild(audioElement);
|
||||
|
||||
SdkContextClass.instance.voiceBroadcastPlaybacksStore.clearCurrent();
|
||||
SdkContextClass.instance.voiceBroadcastRecordingsStore.clearCurrent();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
callHandler.stop();
|
||||
// @ts-ignore
|
||||
DMRoomMap.setShared(null);
|
||||
// @ts-ignore
|
||||
window.mxLegacyCallHandler = null;
|
||||
fakeCall = null;
|
||||
MatrixClientPeg.unset();
|
||||
|
||||
document.body.removeChild(audioElement);
|
||||
|
@ -442,10 +525,11 @@ describe("LegacyCallHandler without third party protocols", () => {
|
|||
|
||||
// Check that a call was started: its room on the protocol level
|
||||
// should be the virtual room
|
||||
expect(fakeCall.roomId).toEqual(NATIVE_ROOM_ALICE);
|
||||
expect(fakeCall).not.toBeNull();
|
||||
expect(fakeCall!.roomId).toEqual(NATIVE_ROOM_ALICE);
|
||||
|
||||
// but it should appear to the user to be in thw native room for Bob
|
||||
expect(callHandler.roomIdForCall(fakeCall)).toEqual(NATIVE_ROOM_ALICE);
|
||||
expect(callHandler.roomIdForCall(fakeCall!)).toEqual(NATIVE_ROOM_ALICE);
|
||||
});
|
||||
|
||||
describe("incoming calls", () => {
|
||||
|
|
24
test/__snapshots__/LegacyCallHandler-test.ts.snap
Normal file
24
test/__snapshots__/LegacyCallHandler-test.ts.snap
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LegacyCallHandler when recording a voice broadcast and placing a call should show the info dialog 1`] = `
|
||||
[MockFunction] {
|
||||
"calls": [
|
||||
[
|
||||
[Function],
|
||||
{
|
||||
"description": <p>
|
||||
You can’t start a call as you are currently recording a live broadcast. Please end your live broadcast in order to start a call.
|
||||
</p>,
|
||||
"hasCloseButton": true,
|
||||
"title": "Can’t start a call",
|
||||
},
|
||||
],
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { Beacon, Room, RoomMember, MatrixEvent, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
|
@ -41,7 +41,8 @@ describe("<BeaconMarker />", () => {
|
|||
|
||||
const aliceMember = new RoomMember(roomId, aliceId);
|
||||
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
|
||||
const mockClient = getMockClientWithEventEmitter({
|
||||
getClientWellKnown: jest.fn().mockReturnValue({
|
||||
|
|
|
@ -19,7 +19,7 @@ import React from "react";
|
|||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { MatrixClient, MatrixEvent, Room, RoomMember, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
import BeaconViewDialog from "../../../../src/components/views/beacon/BeaconViewDialog";
|
||||
|
@ -58,7 +58,8 @@ describe("<BeaconViewDialog />", () => {
|
|||
getVisibleRooms: jest.fn().mockReturnValue([]),
|
||||
});
|
||||
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
|
||||
// make fresh rooms every time
|
||||
// as we update room state
|
||||
|
@ -91,10 +92,6 @@ describe("<BeaconViewDialog />", () => {
|
|||
component.setProps({});
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
maplibregl.AttributionControl = jest.fn();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(OwnBeaconStore.instance, "getLiveBeaconIds").mockRestore();
|
||||
jest.spyOn(OwnBeaconStore.instance, "getBeaconById").mockRestore();
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
@ -62,8 +62,9 @@ describe("LocationPicker", () => {
|
|||
wrappingComponentProps: { value: mockClient },
|
||||
});
|
||||
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mockGeolocate = new maplibregl.GeolocateControl();
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
const mockGeolocate = new maplibregl.GeolocateControl({});
|
||||
const mockMarker = new maplibregl.Marker();
|
||||
|
||||
const mockGeolocationPosition = {
|
||||
|
|
|
@ -19,7 +19,6 @@ import React from "react";
|
|||
import { mount } from "enzyme";
|
||||
import { RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
import { LocationAssetType } from "matrix-js-sdk/src/@types/location";
|
||||
import maplibregl from "maplibre-gl";
|
||||
|
||||
import LocationViewDialog from "../../../../src/components/views/location/LocationViewDialog";
|
||||
import { TILE_SERVER_WK_KEY } from "../../../../src/utils/WellKnownUtils";
|
||||
|
@ -42,10 +41,6 @@ describe("<LocationViewDialog />", () => {
|
|||
};
|
||||
const getComponent = (props = {}) => mount(<LocationViewDialog {...defaultProps} {...props} />);
|
||||
|
||||
beforeAll(() => {
|
||||
maplibregl.AttributionControl = jest.fn();
|
||||
});
|
||||
|
||||
it("renders map correctly", () => {
|
||||
const component = getComponent();
|
||||
expect(component.find("Map")).toMatchSnapshot();
|
||||
|
|
|
@ -18,7 +18,7 @@ import React from "react";
|
|||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { ClientEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
|
@ -45,10 +45,6 @@ describe("<Map />", () => {
|
|||
wrappingComponentProps: { value: matrixClient },
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
maplibregl.AttributionControl = jest.fn();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
matrixClient.getClientWellKnown.mockReturnValue({
|
||||
|
@ -58,7 +54,8 @@ describe("<Map />", () => {
|
|||
jest.spyOn(logger, "error").mockRestore();
|
||||
});
|
||||
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
|
||||
it("renders", () => {
|
||||
const component = getComponent();
|
||||
|
|
|
@ -18,7 +18,7 @@ import React from "react";
|
|||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { mocked } from "jest-mock";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
|
||||
import SmartMarker from "../../../../src/components/views/location/SmartMarker";
|
||||
|
||||
|
@ -27,7 +27,8 @@ jest.mock("../../../../src/utils/location/findMapStyleUrl", () => ({
|
|||
}));
|
||||
|
||||
describe("<SmartMarker />", () => {
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
const mockMarker = new maplibregl.Marker();
|
||||
|
||||
const defaultProps = {
|
||||
|
|
|
@ -17,14 +17,15 @@ limitations under the License.
|
|||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
||||
import ZoomButtons from "../../../../src/components/views/location/ZoomButtons";
|
||||
import { findByTestId } from "../../../test-utils";
|
||||
|
||||
describe("<ZoomButtons />", () => {
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
const defaultProps = {
|
||||
map: mockMap,
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@ exports[`<LocationViewDialog /> renders map correctly 1`] = `
|
|||
"addControl": [MockFunction] {
|
||||
"calls": [
|
||||
[
|
||||
mockConstructor {},
|
||||
MockAttributionControl {},
|
||||
"top-right",
|
||||
],
|
||||
],
|
||||
|
@ -94,7 +94,7 @@ exports[`<LocationViewDialog /> renders map correctly 1`] = `
|
|||
"addControl": [MockFunction] {
|
||||
"calls": [
|
||||
[
|
||||
mockConstructor {},
|
||||
MockAttributionControl {},
|
||||
"top-right",
|
||||
],
|
||||
],
|
||||
|
|
|
@ -18,7 +18,7 @@ import React from "react";
|
|||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { BeaconEvent, getBeaconInfoIdentifier, RelationType, MatrixEvent, EventType } from "matrix-js-sdk/src/matrix";
|
||||
import { Relations } from "matrix-js-sdk/src/models/relations";
|
||||
import { M_BEACON } from "matrix-js-sdk/src/@types/beacon";
|
||||
|
@ -48,7 +48,8 @@ describe("<MBeaconBody />", () => {
|
|||
const roomId = "!room:server";
|
||||
const aliceId = "@alice:server";
|
||||
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
const mockMarker = new maplibregl.Marker();
|
||||
|
||||
const mockClient = getMockClientWithEventEmitter({
|
||||
|
@ -81,10 +82,6 @@ describe("<MBeaconBody />", () => {
|
|||
|
||||
const modalSpy = jest.spyOn(Modal, "createDialog").mockReturnValue(undefined);
|
||||
|
||||
beforeAll(() => {
|
||||
maplibregl.AttributionControl = jest.fn();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@ import React from "react";
|
|||
import { mount } from "enzyme";
|
||||
import { LocationAssetType } from "matrix-js-sdk/src/@types/location";
|
||||
import { ClientEvent, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
import maplibregl from "maplibre-gl";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { SyncState } from "matrix-js-sdk/src/sync";
|
||||
|
@ -35,6 +35,7 @@ import { makeLocationEvent } from "../../../test-utils/location";
|
|||
import { getMockClientWithEventEmitter } from "../../../test-utils";
|
||||
|
||||
describe("MLocationBody", () => {
|
||||
const mapOptions = { container: {} as unknown as HTMLElement, style: "" };
|
||||
describe("<MLocationBody>", () => {
|
||||
const roomId = "!room:server";
|
||||
const userId = "@user:server";
|
||||
|
@ -60,7 +61,7 @@ describe("MLocationBody", () => {
|
|||
wrappingComponentProps: { value: mockClient },
|
||||
});
|
||||
const getMapErrorComponent = () => {
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
mockClient.getClientWellKnown.mockReturnValue({
|
||||
[TILE_SERVER_WK_KEY.name]: { map_style_url: "bad-tile-server.com" },
|
||||
});
|
||||
|
@ -73,10 +74,6 @@ describe("MLocationBody", () => {
|
|||
return component;
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
maplibregl.AttributionControl = jest.fn();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
@ -131,7 +128,7 @@ describe("MLocationBody", () => {
|
|||
});
|
||||
|
||||
it("renders map correctly", () => {
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
const component = getComponent();
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
|
@ -154,7 +151,7 @@ describe("MLocationBody", () => {
|
|||
});
|
||||
|
||||
it("renders marker correctly for a non-self share", () => {
|
||||
const mockMap = new maplibregl.Map();
|
||||
const mockMap = new maplibregl.Map(mapOptions);
|
||||
const component = getComponent();
|
||||
|
||||
expect(component.find("SmartMarker").at(0).props()).toEqual(
|
||||
|
|
|
@ -131,11 +131,11 @@ exports[`MLocationBody <MLocationBody> without error renders map correctly 1`] =
|
|||
"addControl": [MockFunction] {
|
||||
"calls": [
|
||||
[
|
||||
mockConstructor {},
|
||||
MockAttributionControl {},
|
||||
"top-right",
|
||||
],
|
||||
[
|
||||
mockConstructor {},
|
||||
MockAttributionControl {},
|
||||
"top-right",
|
||||
],
|
||||
],
|
||||
|
|
|
@ -13,11 +13,11 @@ HTMLCollection [
|
|||
class="mx_DeviceDetailHeading"
|
||||
data-testid="device-detail-heading"
|
||||
>
|
||||
<h3
|
||||
class="mx_Heading_h3"
|
||||
<h4
|
||||
class="mx_Heading_h4"
|
||||
>
|
||||
alices_device
|
||||
</h3>
|
||||
</h4>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_DeviceDetailHeading_renameCta mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
data-testid="device-heading-rename-cta"
|
||||
|
|
|
@ -78,11 +78,11 @@ exports[`<DeviceDetailHeading /> renders device name 1`] = `
|
|||
class="mx_DeviceDetailHeading"
|
||||
data-testid="device-detail-heading"
|
||||
>
|
||||
<h3
|
||||
class="mx_Heading_h3"
|
||||
<h4
|
||||
class="mx_Heading_h4"
|
||||
>
|
||||
My device
|
||||
</h3>
|
||||
</h4>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_DeviceDetailHeading_renameCta mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
data-testid="device-heading-rename-cta"
|
||||
|
|
|
@ -13,11 +13,11 @@ exports[`<DeviceDetails /> renders a verified device 1`] = `
|
|||
class="mx_DeviceDetailHeading"
|
||||
data-testid="device-detail-heading"
|
||||
>
|
||||
<h3
|
||||
class="mx_Heading_h3"
|
||||
<h4
|
||||
class="mx_Heading_h4"
|
||||
>
|
||||
my-device
|
||||
</h3>
|
||||
</h4>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_DeviceDetailHeading_renameCta mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
data-testid="device-heading-rename-cta"
|
||||
|
@ -122,11 +122,11 @@ exports[`<DeviceDetails /> renders device with metadata 1`] = `
|
|||
class="mx_DeviceDetailHeading"
|
||||
data-testid="device-detail-heading"
|
||||
>
|
||||
<h3
|
||||
class="mx_Heading_h3"
|
||||
<h4
|
||||
class="mx_Heading_h4"
|
||||
>
|
||||
My Device
|
||||
</h3>
|
||||
</h4>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_DeviceDetailHeading_renameCta mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
data-testid="device-heading-rename-cta"
|
||||
|
@ -331,11 +331,11 @@ exports[`<DeviceDetails /> renders device without metadata 1`] = `
|
|||
class="mx_DeviceDetailHeading"
|
||||
data-testid="device-detail-heading"
|
||||
>
|
||||
<h3
|
||||
class="mx_Heading_h3"
|
||||
<h4
|
||||
class="mx_Heading_h4"
|
||||
>
|
||||
my-device
|
||||
</h3>
|
||||
</h4>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_DeviceDetailHeading_renameCta mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
data-testid="device-heading-rename-cta"
|
||||
|
|
|
@ -18,7 +18,7 @@ exports[`<SecurityRecommendations /> renders both cards when user has both unver
|
|||
<div
|
||||
class="mx_SettingsSubsection_description"
|
||||
>
|
||||
Improve your account security by following these recommendations
|
||||
Improve your account security by following these recommendations.
|
||||
</div>
|
||||
<div
|
||||
class="mx_SettingsSubsection_content"
|
||||
|
@ -93,7 +93,7 @@ exports[`<SecurityRecommendations /> renders both cards when user has both unver
|
|||
<p
|
||||
class="mx_DeviceSecurityCard_description"
|
||||
>
|
||||
Consider signing out from old sessions (90 days or older) you don't use anymore
|
||||
Consider signing out from old sessions (90 days or older) you don't use anymore.
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
role="button"
|
||||
|
@ -139,7 +139,7 @@ exports[`<SecurityRecommendations /> renders inactive devices section when user
|
|||
<div
|
||||
class="mx_SettingsSubsection_description"
|
||||
>
|
||||
Improve your account security by following these recommendations
|
||||
Improve your account security by following these recommendations.
|
||||
</div>
|
||||
<div
|
||||
class="mx_SettingsSubsection_content"
|
||||
|
@ -214,7 +214,7 @@ exports[`<SecurityRecommendations /> renders inactive devices section when user
|
|||
<p
|
||||
class="mx_DeviceSecurityCard_description"
|
||||
>
|
||||
Consider signing out from old sessions (90 days or older) you don't use anymore
|
||||
Consider signing out from old sessions (90 days or older) you don't use anymore.
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
role="button"
|
||||
|
@ -260,7 +260,7 @@ exports[`<SecurityRecommendations /> renders unverified devices section when use
|
|||
<div
|
||||
class="mx_SettingsSubsection_description"
|
||||
>
|
||||
Improve your account security by following these recommendations
|
||||
Improve your account security by following these recommendations.
|
||||
</div>
|
||||
<div
|
||||
class="mx_SettingsSubsection_content"
|
||||
|
@ -335,7 +335,7 @@ exports[`<SecurityRecommendations /> renders unverified devices section when use
|
|||
<p
|
||||
class="mx_DeviceSecurityCard_description"
|
||||
>
|
||||
Consider signing out from old sessions (90 days or older) you don't use anymore
|
||||
Consider signing out from old sessions (90 days or older) you don't use anymore.
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
role="button"
|
||||
|
|
|
@ -420,6 +420,21 @@ describe("<SessionManagerTab />", () => {
|
|||
|
||||
expect(getByTestId("current-session-section")).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("expands current session details", async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
const { getByTestId } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromises();
|
||||
});
|
||||
|
||||
fireEvent.click(getByTestId("current-session-toggle-details"));
|
||||
|
||||
expect(getByTestId(`device-detail-${alicesDevice.device_id}`)).toBeTruthy();
|
||||
// only one security card rendered
|
||||
expect(getByTestId("current-session-section").querySelectorAll(".mx_DeviceSecurityCard").length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("device detail expansion", () => {
|
||||
|
|
|
@ -28,6 +28,17 @@ import { UPDATE_EVENT } from "../../src/stores/AsyncStore";
|
|||
import { ActiveRoomChangedPayload } from "../../src/dispatcher/payloads/ActiveRoomChangedPayload";
|
||||
import { SpaceStoreClass } from "../../src/stores/spaces/SpaceStore";
|
||||
import { TestSdkContext } from "../TestSdkContext";
|
||||
import { ViewRoomPayload } from "../../src/dispatcher/payloads/ViewRoomPayload";
|
||||
import {
|
||||
VoiceBroadcastInfoState,
|
||||
VoiceBroadcastPlayback,
|
||||
VoiceBroadcastPlaybacksStore,
|
||||
VoiceBroadcastRecording,
|
||||
} from "../../src/voice-broadcast";
|
||||
import { mkVoiceBroadcastInfoStateEvent } from "../voice-broadcast/utils/test-utils";
|
||||
import Modal from "../../src/Modal";
|
||||
|
||||
jest.mock("../../src/Modal");
|
||||
|
||||
// mock out the injected classes
|
||||
jest.mock("../../src/PosthogAnalytics");
|
||||
|
@ -37,6 +48,22 @@ const MockSlidingSyncManager = <jest.Mock<SlidingSyncManager>>(<unknown>SlidingS
|
|||
jest.mock("../../src/stores/spaces/SpaceStore");
|
||||
const MockSpaceStore = <jest.Mock<SpaceStoreClass>>(<unknown>SpaceStoreClass);
|
||||
|
||||
// mock VoiceRecording because it contains all the audio APIs
|
||||
jest.mock("../../src/audio/VoiceRecording", () => ({
|
||||
VoiceRecording: jest.fn().mockReturnValue({
|
||||
disableMaxLength: jest.fn(),
|
||||
liveData: {
|
||||
onUpdate: jest.fn(),
|
||||
},
|
||||
off: jest.fn(),
|
||||
on: jest.fn(),
|
||||
start: jest.fn(),
|
||||
stop: jest.fn(),
|
||||
destroy: jest.fn(),
|
||||
contentType: "audio/ogg",
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock("../../src/utils/DMRoomMap", () => {
|
||||
const mock = {
|
||||
getUserIdForRoomId: jest.fn(),
|
||||
|
@ -60,12 +87,24 @@ describe("RoomViewStore", function () {
|
|||
getRoom: jest.fn(),
|
||||
getRoomIdForAlias: jest.fn(),
|
||||
isGuest: jest.fn(),
|
||||
getSafeUserId: jest.fn(),
|
||||
});
|
||||
const room = new Room(roomId, mockClient, userId);
|
||||
|
||||
const viewCall = async (): Promise<void> => {
|
||||
dis.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: roomId,
|
||||
view_call: true,
|
||||
metricsTrigger: undefined,
|
||||
});
|
||||
await untilDispatch(Action.ViewRoom, dis);
|
||||
};
|
||||
|
||||
let roomViewStore: RoomViewStore;
|
||||
let slidingSyncManager: SlidingSyncManager;
|
||||
let dis: MatrixDispatcher;
|
||||
let stores: TestSdkContext;
|
||||
|
||||
beforeEach(function () {
|
||||
jest.clearAllMocks();
|
||||
|
@ -73,14 +112,16 @@ describe("RoomViewStore", function () {
|
|||
mockClient.joinRoom.mockResolvedValue(room);
|
||||
mockClient.getRoom.mockReturnValue(room);
|
||||
mockClient.isGuest.mockReturnValue(false);
|
||||
mockClient.getSafeUserId.mockReturnValue(userId);
|
||||
|
||||
// Make the RVS to test
|
||||
dis = new MatrixDispatcher();
|
||||
slidingSyncManager = new MockSlidingSyncManager();
|
||||
const stores = new TestSdkContext();
|
||||
stores = new TestSdkContext();
|
||||
stores._SlidingSyncManager = slidingSyncManager;
|
||||
stores._PosthogAnalytics = new MockPosthogAnalytics();
|
||||
stores._SpaceStore = new MockSpaceStore();
|
||||
stores._VoiceBroadcastPlaybacksStore = new VoiceBroadcastPlaybacksStore();
|
||||
roomViewStore = new RoomViewStore(dis, stores);
|
||||
stores._RoomViewStore = roomViewStore;
|
||||
});
|
||||
|
@ -206,6 +247,56 @@ describe("RoomViewStore", function () {
|
|||
expect(roomViewStore.getRoomId()).toBeNull();
|
||||
});
|
||||
|
||||
it("when viewing a call without a broadcast, it should not raise an error", async () => {
|
||||
await viewCall();
|
||||
});
|
||||
|
||||
describe("when listening to a voice broadcast", () => {
|
||||
let voiceBroadcastPlayback: VoiceBroadcastPlayback;
|
||||
|
||||
beforeEach(() => {
|
||||
voiceBroadcastPlayback = new VoiceBroadcastPlayback(
|
||||
mkVoiceBroadcastInfoStateEvent(
|
||||
roomId,
|
||||
VoiceBroadcastInfoState.Started,
|
||||
mockClient.getSafeUserId(),
|
||||
"d42",
|
||||
),
|
||||
mockClient,
|
||||
);
|
||||
stores.voiceBroadcastPlaybacksStore.setCurrent(voiceBroadcastPlayback);
|
||||
jest.spyOn(voiceBroadcastPlayback, "pause").mockImplementation();
|
||||
});
|
||||
|
||||
it("and viewing a call it should pause the current broadcast", async () => {
|
||||
await viewCall();
|
||||
expect(voiceBroadcastPlayback.pause).toHaveBeenCalled();
|
||||
expect(roomViewStore.isViewingCall()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when recording a voice broadcast", () => {
|
||||
beforeEach(() => {
|
||||
stores.voiceBroadcastRecordingsStore.setCurrent(
|
||||
new VoiceBroadcastRecording(
|
||||
mkVoiceBroadcastInfoStateEvent(
|
||||
roomId,
|
||||
VoiceBroadcastInfoState.Started,
|
||||
mockClient.getSafeUserId(),
|
||||
"d42",
|
||||
),
|
||||
mockClient,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("and trying to view a call, it should not actually view it and show the info dialog", async () => {
|
||||
await viewCall();
|
||||
expect(Modal.createDialog).toMatchSnapshot();
|
||||
expect(roomViewStore.isViewingCall()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sliding Sync", function () {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName, roomId, value) => {
|
||||
|
|
24
test/stores/__snapshots__/RoomViewStore-test.ts.snap
Normal file
24
test/stores/__snapshots__/RoomViewStore-test.ts.snap
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`RoomViewStore when recording a voice broadcast and trying to view a call, it should not actually view it and show the info dialog 1`] = `
|
||||
[MockFunction] {
|
||||
"calls": [
|
||||
[
|
||||
[Function],
|
||||
{
|
||||
"description": <p>
|
||||
You can’t start a call as you are currently recording a live broadcast. Please end your live broadcast in order to start a call.
|
||||
</p>,
|
||||
"hasCloseButton": true,
|
||||
"title": "Can’t start a call",
|
||||
},
|
||||
],
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
35
test/stores/room-list/RoomListStore-test.ts
Normal file
35
test/stores/room-list/RoomListStore-test.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { ListAlgorithm, SortAlgorithm } from "../../../src/stores/room-list/algorithms/models";
|
||||
import { OrderedDefaultTagIDs } from "../../../src/stores/room-list/models";
|
||||
import RoomListStore, { RoomListStoreClass } from "../../../src/stores/room-list/RoomListStore";
|
||||
import { stubClient } from "../../test-utils";
|
||||
|
||||
describe("RoomListStore", () => {
|
||||
beforeAll(async () => {
|
||||
const client = stubClient();
|
||||
await (RoomListStore.instance as RoomListStoreClass).makeReady(client);
|
||||
});
|
||||
|
||||
it.each(OrderedDefaultTagIDs)("defaults to importance ordering for %s=", (tagId) => {
|
||||
expect(RoomListStore.instance.getTagSorting(tagId)).toBe(SortAlgorithm.Recent);
|
||||
});
|
||||
|
||||
it.each(OrderedDefaultTagIDs)("defaults to activity ordering for %s=", (tagId) => {
|
||||
expect(RoomListStore.instance.getListOrder(tagId)).toBe(ListAlgorithm.Importance);
|
||||
});
|
||||
});
|
|
@ -411,6 +411,10 @@ describe("VoiceBroadcastPlayback", () => {
|
|||
stopPlayback();
|
||||
itShouldSetTheStateTo(VoiceBroadcastPlaybackState.Stopped);
|
||||
|
||||
it("should stop the playback", () => {
|
||||
expect(chunk1Playback.stop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("and skipping to somewhere in the middle of the first chunk", () => {
|
||||
beforeEach(async () => {
|
||||
mocked(chunk1Playback.play).mockClear();
|
||||
|
|
107
yarn.lock
107
yarn.lock
|
@ -1470,7 +1470,7 @@
|
|||
"@jridgewell/resolve-uri" "3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||
|
||||
"@mapbox/geojson-rewind@^0.5.0":
|
||||
"@mapbox/geojson-rewind@^0.5.2":
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz#591a5d71a9cd1da1a0bf3420b3bea31b0fc7946a"
|
||||
integrity sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==
|
||||
|
@ -1478,35 +1478,30 @@
|
|||
get-stream "^6.0.1"
|
||||
minimist "^1.2.6"
|
||||
|
||||
"@mapbox/geojson-types@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz#9aecf642cb00eab1080a57c4f949a65b4a5846d6"
|
||||
integrity sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw==
|
||||
|
||||
"@mapbox/jsonlint-lines-primitives@^2.0.2":
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234"
|
||||
integrity sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==
|
||||
|
||||
"@mapbox/mapbox-gl-supported@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz#f60b6a55a5d8e5ee908347d2ce4250b15103dc8e"
|
||||
integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg==
|
||||
"@mapbox/mapbox-gl-supported@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz#c15367178d8bfe4765e6b47b542fe821ce259c7b"
|
||||
integrity sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ==
|
||||
|
||||
"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2"
|
||||
integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==
|
||||
|
||||
"@mapbox/tiny-sdf@^1.1.1":
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz#424c620a96442b20402552be70a7f62a8407cc59"
|
||||
integrity sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw==
|
||||
"@mapbox/tiny-sdf@^2.0.5":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz#cdba698d3d65087643130f9af43a2b622ce0b372"
|
||||
integrity sha512-OhXt2lS//WpLdkqrzo/KwB7SRD8AiNTFFzuo9n14IBupzIMa67yGItcK7I2W9D8Ghpa4T04Sw9FWsKCJG50Bxw==
|
||||
|
||||
"@mapbox/unitbezier@^0.0.0":
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz#15651bd553a67b8581fb398810c98ad86a34524e"
|
||||
integrity sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==
|
||||
"@mapbox/unitbezier@^0.0.1":
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz#d32deb66c7177e9e9dfc3bbd697083e2e657ff01"
|
||||
integrity sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==
|
||||
|
||||
"@mapbox/vector-tile@^1.3.1":
|
||||
version "1.3.1"
|
||||
|
@ -2070,7 +2065,7 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/geojson@^7946.0.8":
|
||||
"@types/geojson@*", "@types/geojson@^7946.0.10", "@types/geojson@^7946.0.8":
|
||||
version "7946.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.10.tgz#6dfbf5ea17142f7f9a043809f1cd4c448cb68249"
|
||||
integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==
|
||||
|
@ -2146,6 +2141,20 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa"
|
||||
integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==
|
||||
|
||||
"@types/mapbox__point-geometry@*", "@types/mapbox__point-geometry@^0.1.2":
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz#488a9b76e8457d6792ea2504cdd4ecdd9860a27e"
|
||||
integrity sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA==
|
||||
|
||||
"@types/mapbox__vector-tile@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz#8fa1379dbaead1e1b639b8d96cfd174404c379d6"
|
||||
integrity sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==
|
||||
dependencies:
|
||||
"@types/geojson" "*"
|
||||
"@types/mapbox__point-geometry" "*"
|
||||
"@types/pbf" "*"
|
||||
|
||||
"@types/minimist@^1.2.0":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
|
||||
|
@ -2191,6 +2200,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
|
||||
integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==
|
||||
|
||||
"@types/pbf@*", "@types/pbf@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.2.tgz#8d291ad68b4b8c533e96c174a2e3e6399a59ed61"
|
||||
integrity sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==
|
||||
|
||||
"@types/prettier@^2.1.5":
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.1.tgz#dfd20e2dc35f027cdd6c1908e80a5ddc7499670e"
|
||||
|
@ -3783,7 +3797,7 @@ domutils@^3.0.1:
|
|||
domelementtype "^2.3.0"
|
||||
domhandler "^5.0.1"
|
||||
|
||||
earcut@^2.2.2:
|
||||
earcut@^2.2.4:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a"
|
||||
integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==
|
||||
|
@ -4787,7 +4801,7 @@ gfm.css@^1.1.2:
|
|||
resolved "https://registry.yarnpkg.com/gfm.css/-/gfm.css-1.1.2.tgz#94acfa600672663b9dd0fd4b6ee5d11c8dbc161e"
|
||||
integrity sha512-KhK3rqxMj+UTLRxWnfUA5n8XZYMWfHrrcCxtWResYR2B3hWIqBM6v9FPGZSlVuX+ScLewizOvNkjYXuPs95ThQ==
|
||||
|
||||
gl-matrix@^3.2.1:
|
||||
gl-matrix@^3.4.3:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9"
|
||||
integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==
|
||||
|
@ -4903,11 +4917,6 @@ grapheme-splitter@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
|
||||
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
|
||||
|
||||
grid-index@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7"
|
||||
integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==
|
||||
|
||||
hard-rejection@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
|
||||
|
@ -6341,34 +6350,35 @@ map-obj@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a"
|
||||
integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
|
||||
|
||||
maplibre-gl@^1.15.2:
|
||||
version "1.15.3"
|
||||
resolved "https://registry.yarnpkg.com/maplibre-gl/-/maplibre-gl-1.15.3.tgz#eebbdd6b4cba46c61a660d6fa1808fced126e24d"
|
||||
integrity sha512-ZuOhLCNgp7Yl1L9uyKgZeuo7kKdewP0iWtmEXsZ/snp0JiVkR1Kl+m1rsfKT/wpm/O4zZ7mUGxF16cYbMIFDRA==
|
||||
maplibre-gl@^2.0.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/maplibre-gl/-/maplibre-gl-2.4.0.tgz#2b53dbf526626bf4ee92ad4f33f13ef09e5af182"
|
||||
integrity sha512-csNFylzntPmHWidczfgCZpvbTSmhaWvLRj9e1ezUDBEPizGgshgm3ea1T5TCNEEBq0roauu7BPuRZjA3wO4KqA==
|
||||
dependencies:
|
||||
"@mapbox/geojson-rewind" "^0.5.0"
|
||||
"@mapbox/geojson-types" "^1.0.2"
|
||||
"@mapbox/geojson-rewind" "^0.5.2"
|
||||
"@mapbox/jsonlint-lines-primitives" "^2.0.2"
|
||||
"@mapbox/mapbox-gl-supported" "^1.5.0"
|
||||
"@mapbox/mapbox-gl-supported" "^2.0.1"
|
||||
"@mapbox/point-geometry" "^0.1.0"
|
||||
"@mapbox/tiny-sdf" "^1.1.1"
|
||||
"@mapbox/unitbezier" "^0.0.0"
|
||||
"@mapbox/tiny-sdf" "^2.0.5"
|
||||
"@mapbox/unitbezier" "^0.0.1"
|
||||
"@mapbox/vector-tile" "^1.3.1"
|
||||
"@mapbox/whoots-js" "^3.1.0"
|
||||
"@types/geojson" "^7946.0.10"
|
||||
"@types/mapbox__point-geometry" "^0.1.2"
|
||||
"@types/mapbox__vector-tile" "^1.3.0"
|
||||
"@types/pbf" "^3.0.2"
|
||||
csscolorparser "~1.0.3"
|
||||
earcut "^2.2.2"
|
||||
earcut "^2.2.4"
|
||||
geojson-vt "^3.2.1"
|
||||
gl-matrix "^3.2.1"
|
||||
grid-index "^1.1.0"
|
||||
minimist "^1.2.6"
|
||||
gl-matrix "^3.4.3"
|
||||
global-prefix "^3.0.0"
|
||||
murmurhash-js "^1.0.0"
|
||||
pbf "^3.2.1"
|
||||
potpack "^1.0.1"
|
||||
potpack "^1.0.2"
|
||||
quickselect "^2.0.0"
|
||||
rw "^1.3.3"
|
||||
supercluster "^7.1.0"
|
||||
supercluster "^7.1.5"
|
||||
tinyqueue "^2.0.3"
|
||||
vt-pbf "^3.1.1"
|
||||
vt-pbf "^3.1.3"
|
||||
|
||||
mathml-tag-names@^2.1.3:
|
||||
version "2.1.3"
|
||||
|
@ -7077,7 +7087,7 @@ posthog-js@1.36.0:
|
|||
fflate "^0.4.1"
|
||||
rrweb-snapshot "^1.1.14"
|
||||
|
||||
potpack@^1.0.1:
|
||||
potpack@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14"
|
||||
integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==
|
||||
|
@ -7672,11 +7682,6 @@ run-parallel@^1.1.9:
|
|||
dependencies:
|
||||
queue-microtask "^1.2.2"
|
||||
|
||||
rw@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
|
||||
integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==
|
||||
|
||||
rxjs@^7.5.1:
|
||||
version "7.5.7"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39"
|
||||
|
@ -8121,7 +8126,7 @@ stylelint@^14.9.1:
|
|||
v8-compile-cache "^2.3.0"
|
||||
write-file-atomic "^4.0.2"
|
||||
|
||||
supercluster@^7.1.0:
|
||||
supercluster@^7.1.5:
|
||||
version "7.1.5"
|
||||
resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.1.5.tgz#65a6ce4a037a972767740614c19051b64b8be5a3"
|
||||
integrity sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==
|
||||
|
@ -8576,7 +8581,7 @@ verror@1.10.0:
|
|||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
vt-pbf@^3.1.1:
|
||||
vt-pbf@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac"
|
||||
integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==
|
||||
|
|
Loading…
Reference in a new issue