mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-29 21:15:19 +00:00
Compare commits
42 Commits
toger5/fit
...
toger5/js-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94bf6cfae1 | ||
|
|
cfb0aa5793 | ||
|
|
30b3ba302e | ||
|
|
f613b17824 | ||
|
|
11457da794 | ||
|
|
b811c34805 | ||
|
|
e4b012440b | ||
|
|
6539c15177 | ||
|
|
e7b93680af | ||
|
|
87df439020 | ||
|
|
d8385c2f6e | ||
|
|
a0c40d250b | ||
|
|
ebdda59b86 | ||
|
|
68b4714516 | ||
|
|
8cec85bafb | ||
|
|
a88357a0ae | ||
|
|
cace73bad7 | ||
|
|
f8ff5d83cd | ||
|
|
cdfa1c2bcb | ||
|
|
b8325611a0 | ||
|
|
f0af7e4c52 | ||
|
|
30151435ea | ||
|
|
439fdaad74 | ||
|
|
9d27f07414 | ||
|
|
21e3c606bf | ||
|
|
c4075f736f | ||
|
|
1dfe378700 | ||
|
|
457941edac | ||
|
|
541830f11f | ||
|
|
7c9be03a7d | ||
|
|
160063e29a | ||
|
|
ddc4def65f | ||
|
|
f56d2cfbf4 | ||
|
|
d801360f28 | ||
|
|
0f244c12de | ||
|
|
38ceb381d4 | ||
|
|
997284b89a | ||
|
|
353b243686 | ||
|
|
11948449d1 | ||
|
|
5502f588eb | ||
|
|
7345665589 | ||
|
|
7f571b695e |
@@ -199,3 +199,23 @@ If set to false, the widget will show a blank page after leaving the call.
|
||||
```
|
||||
returnToLobby: boolean; (default: false)
|
||||
```
|
||||
|
||||
**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.
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
```
|
||||
homeserver: string; (default: undefined)
|
||||
```
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@juggle/resize-observer": "^3.3.1",
|
||||
"@livekit/components-core": "^0.8.0",
|
||||
"@livekit/components-react": "^1.1.0",
|
||||
"@livekit/components-core": "^0.9.0",
|
||||
"@livekit/components-react": "^2.0.0",
|
||||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz",
|
||||
"@opentelemetry/api": "^1.4.0",
|
||||
"@opentelemetry/context-zone": "^1.9.1",
|
||||
@@ -60,9 +60,9 @@
|
||||
"i18next": "^23.0.0",
|
||||
"i18next-browser-languagedetector": "^7.0.0",
|
||||
"i18next-http-backend": "^2.0.0",
|
||||
"livekit-client": "1.15.12",
|
||||
"livekit-client": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#99600e87f193508ad56325baf2bb134110f3905a",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#8123e9a3f1142a7619758c0a238172b007e3a06a",
|
||||
"matrix-widget-api": "^1.3.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pako": "^2.0.4",
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"unmute_microphone_button_label": "Unmute microphone",
|
||||
"version": "Version: {{version}}",
|
||||
"video_tile": {
|
||||
"change_fit_contain": "Crop to fit",
|
||||
"change_fit_contain": "Fit to frame",
|
||||
"exit_full_screen": "Exit full screen",
|
||||
"full_screen": "Full screen",
|
||||
"mute_for_me": "Mute for me",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"semanticCommits": "disabled",
|
||||
"ignoreDeps": [
|
||||
"@react-aria/button",
|
||||
"@react-aria/focus",
|
||||
@@ -20,6 +21,7 @@
|
||||
"@react-stately/collections",
|
||||
"@react-stately/select",
|
||||
"@react-stately/tooltip",
|
||||
"@react-stately/tree"
|
||||
"@react-stately/tree",
|
||||
"@react-types/dialog"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -130,6 +130,20 @@ export interface UrlParams {
|
||||
* This is useful for video rooms.
|
||||
*/
|
||||
returnToLobby: boolean;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
viaServers: string | null;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
homeserver: string | null;
|
||||
}
|
||||
|
||||
// This is here as a stopgap, but what would be far nicer is a function that
|
||||
@@ -229,6 +243,8 @@ export const getUrlParams = (
|
||||
perParticipantE2EE: parser.getFlagParam("perParticipantE2EE"),
|
||||
skipLobby: parser.getFlagParam("skipLobby"),
|
||||
returnToLobby: parser.getFlagParam("returnToLobby"),
|
||||
viaServers: parser.getParam("viaServers"),
|
||||
homeserver: parser.getParam("homeserver"),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import { useClient } from "../ClientContext";
|
||||
import { useInteractiveRegistration } from "../auth/useInteractiveRegistration";
|
||||
import { generateRandomName } from "../auth/generateRandomName";
|
||||
import { useRecaptcha } from "../auth/useRecaptcha";
|
||||
import { widget } from "../widget";
|
||||
|
||||
interface UseRegisterPasswordlessUserType {
|
||||
privacyPolicyUrl?: string;
|
||||
@@ -39,6 +40,11 @@ export function useRegisterPasswordlessUser(): UseRegisterPasswordlessUserType {
|
||||
if (!setClient) {
|
||||
throw new Error("No client context");
|
||||
}
|
||||
if (widget) {
|
||||
throw new Error(
|
||||
"Registration was skipped: We should never try to register password-less user in embedded mode.",
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const recaptchaResponse = await execute();
|
||||
|
||||
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { getUrlParams } from "../UrlParams";
|
||||
import {
|
||||
DEFAULT_CONFIG,
|
||||
ConfigOptions,
|
||||
@@ -45,10 +46,18 @@ export class Config {
|
||||
|
||||
// Convenience accessors
|
||||
public static defaultHomeserverUrl(): string | undefined {
|
||||
return Config.get().default_server_config?.["m.homeserver"].base_url;
|
||||
return (
|
||||
getUrlParams().homeserver ??
|
||||
Config.get().default_server_config?.["m.homeserver"].base_url
|
||||
);
|
||||
}
|
||||
|
||||
public static defaultServerName(): string | undefined {
|
||||
const homeserver = getUrlParams().homeserver;
|
||||
if (homeserver) {
|
||||
const url = new URL(homeserver);
|
||||
return url.hostname;
|
||||
}
|
||||
return Config.get().default_server_config?.["m.homeserver"].server_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,5 +59,4 @@ export const defaultLiveKitOptions: RoomOptions = {
|
||||
stopLocalTrackOnUnpublish: true,
|
||||
reconnectPolicy: new DefaultReconnectPolicy(),
|
||||
disconnectOnPageLeave: true,
|
||||
expWebAudioMix: false,
|
||||
};
|
||||
|
||||
@@ -61,7 +61,9 @@ async function doConnect(
|
||||
// doesn't publish it until you unmute. We want to publish it from the start so we're
|
||||
// always capturing audio: it helps keep bluetooth headsets in the right mode and
|
||||
// mobile browsers to know we're doing a call.
|
||||
if (livekitRoom!.localParticipant.getTrack(Track.Source.Microphone)) {
|
||||
if (
|
||||
livekitRoom!.localParticipant.getTrackPublication(Track.Source.Microphone)
|
||||
) {
|
||||
logger.warn(
|
||||
"Pre-creating audio track but participant already appears to have an microphone track: this shouldn't happen!",
|
||||
);
|
||||
@@ -90,7 +92,9 @@ async function doConnect(
|
||||
if (!audioEnabled) await preCreatedAudioTrack?.mute();
|
||||
|
||||
// check again having awaited for the track to create
|
||||
if (livekitRoom!.localParticipant.getTrack(Track.Source.Microphone)) {
|
||||
if (
|
||||
livekitRoom!.localParticipant.getTrackPublication(Track.Source.Microphone)
|
||||
) {
|
||||
logger.warn(
|
||||
"Pre-created audio track but participant already appears to have an microphone track: this shouldn't happen!",
|
||||
);
|
||||
@@ -174,7 +178,7 @@ export function useECConnectionState(
|
||||
|
||||
const doFocusSwitch = useCallback(async (): Promise<void> => {
|
||||
const screenshareTracks: MediaStreamTrack[] = [];
|
||||
for (const t of livekitRoom!.localParticipant.videoTracks.values()) {
|
||||
for (const t of livekitRoom!.localParticipant.videoTrackPublications.values()) {
|
||||
if (t.track && t.source == Track.Source.ScreenShare) {
|
||||
const newTrack = t.track.mediaStreamTrack.clone();
|
||||
newTrack.enabled = true;
|
||||
|
||||
@@ -291,7 +291,7 @@ export function useLiveKit(
|
||||
room.options.audioCaptureDefaults?.deviceId === "default"
|
||||
) {
|
||||
const activeMicTrack = Array.from(
|
||||
room.localParticipant.audioTracks.values(),
|
||||
room.localParticipant.audioTrackPublications.values(),
|
||||
).find((d) => d.source === Track.Source.Microphone)?.track;
|
||||
|
||||
const defaultDevice = device.available.find(
|
||||
@@ -313,7 +313,7 @@ export function useLiveKit(
|
||||
// Note that room.switchActiveDevice() won't work: Livekit will ignore it because
|
||||
// the deviceId hasn't changed (was & still is default).
|
||||
room.localParticipant
|
||||
.getTrack(Track.Source.Microphone)
|
||||
.getTrackPublication(Track.Source.Microphone)
|
||||
?.audioTrack?.restartTrack();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -188,16 +188,9 @@ export async function initClient(
|
||||
await client.store.startup();
|
||||
}
|
||||
|
||||
if (client.initCrypto) {
|
||||
await client.initCrypto();
|
||||
}
|
||||
|
||||
await client.startClient({
|
||||
// dirty hack to reduce chance of gappy syncs
|
||||
// should be fixed by spotting gaps and backpaginating
|
||||
initialSyncLimit: 50,
|
||||
});
|
||||
|
||||
await client.initCrypto();
|
||||
client.setGlobalErrorOnUnknownDevices(false);
|
||||
await client.startClient();
|
||||
await waitForSync(client);
|
||||
|
||||
return client;
|
||||
|
||||
@@ -29,6 +29,7 @@ import { useOptInAnalytics } from "../settings/useSetting";
|
||||
import { HomePage } from "../home/HomePage";
|
||||
import { platform } from "../Platform";
|
||||
import { AppSelectionModal } from "./AppSelectionModal";
|
||||
import { widget } from "../widget";
|
||||
|
||||
export const RoomPage: FC = () => {
|
||||
const {
|
||||
@@ -62,7 +63,7 @@ export const RoomPage: FC = () => {
|
||||
useEffect(() => {
|
||||
// If we've finished loading, are not already authed and we've been given a display name as
|
||||
// a URL param, automatically register a passwordless user
|
||||
if (!loading && !authenticated && displayName) {
|
||||
if (!loading && !authenticated && displayName && !widget) {
|
||||
setIsRegistering(true);
|
||||
registerPasswordlessUser(displayName).finally(() => {
|
||||
setIsRegistering(false);
|
||||
|
||||
@@ -30,13 +30,6 @@ function getActiveFocus(
|
||||
const oldestMembership = rtcSession.getOldestMembership();
|
||||
const focus = oldestMembership?.getActiveFoci()[0] as LivekitFocus;
|
||||
|
||||
if (focus) {
|
||||
logger.info(
|
||||
`Got active focus for call from ${oldestMembership?.sender}/${oldestMembership?.deviceId}`,
|
||||
focus,
|
||||
);
|
||||
}
|
||||
|
||||
return focus;
|
||||
}
|
||||
|
||||
@@ -56,6 +49,11 @@ export function useActiveFocus(
|
||||
const newActiveFocus = getActiveFocus(rtcSession);
|
||||
|
||||
if (!deepCompare(activeFocus, newActiveFocus)) {
|
||||
const oldestMembership = rtcSession.getOldestMembership();
|
||||
logger.warn(
|
||||
`Got new active focus from membership: ${oldestMembership?.sender}/${oldestMembership?.deviceId}.
|
||||
Updating focus (focus switch) from ${activeFocus} to ${newActiveFocus}`,
|
||||
);
|
||||
setActiveFocus(newActiveFocus);
|
||||
}
|
||||
}, [activeFocus, rtcSession]);
|
||||
|
||||
@@ -82,10 +82,7 @@ export const useLoadGroupCall = (
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// room IDs we just try to join by their ID, which will not work in the
|
||||
// general case without providing some servers to join via. We could provide
|
||||
// our own server, but in practice that is implicit.
|
||||
room = await client.joinRoom(roomIdOrAlias);
|
||||
room = await client.joinRoom(roomIdOrAlias, { viaServers });
|
||||
}
|
||||
|
||||
logger.info(
|
||||
|
||||
@@ -56,7 +56,7 @@ function observeTrackReference(
|
||||
observeParticipantMedia(participant).pipe(
|
||||
map(() => ({
|
||||
participant,
|
||||
publication: participant.getTrack(source),
|
||||
publication: participant.getTrackPublication(source),
|
||||
source,
|
||||
})),
|
||||
distinctUntilKeyChanged("publication"),
|
||||
|
||||
Reference in New Issue
Block a user