Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
568c989ff7 | ||
|
|
8451296f3a | ||
|
|
606358c51b | ||
|
|
fd0956bbc5 | ||
|
|
c01e363639 | ||
|
|
0114db7d2d | ||
|
|
e93dfb54d2 | ||
|
|
f1ee3604de | ||
|
|
d270756443 |
@@ -53,7 +53,7 @@
|
|||||||
"i18next-browser-languagedetector": "^6.1.8",
|
"i18next-browser-languagedetector": "^6.1.8",
|
||||||
"i18next-http-backend": "^1.4.4",
|
"i18next-http-backend": "^1.4.4",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#fcbc195fbe4170251b87f03a69c8dc5bfccfd5ac",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#a7b1dcaf9514b2e424a387e266c6f383a5909927",
|
||||||
"matrix-widget-api": "^1.3.1",
|
"matrix-widget-api": "^1.3.1",
|
||||||
"mermaid": "^8.13.8",
|
"mermaid": "^8.13.8",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"More menu": "Menu \"więcej\"",
|
"More menu": "Menu \"więcej\"",
|
||||||
"Login": "Zaloguj się",
|
"Login": "Zaloguj się",
|
||||||
"Go": "Kontynuuj",
|
"Go": "Przejdź",
|
||||||
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "Klikając \"Kontynuuj\", wyrażasz zgodę na nasze <2>Warunki</2>",
|
"By clicking \"Go\", you agree to our <2>Terms and conditions</2>": "Klikając \"Kontynuuj\", wyrażasz zgodę na nasze <2>Zasady i warunki</2>",
|
||||||
"{{count}} people connected|other": "{{count}} osób połączonych",
|
"{{count}} people connected|other": "{{count}} osób połączonych",
|
||||||
"Your recent calls": "Twoje ostatnie połączenia",
|
"Your recent calls": "Twoje ostatnie połączenia",
|
||||||
"You can't talk at the same time": "Nie możesz mówić w tym samym czasie",
|
"You can't talk at the same time": "Nie możesz mówić w tym samym czasie",
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
"This call already exists, would you like to join?": "Te połączenie już istnieje, czy chcesz do niego dołączyć?",
|
"This call already exists, would you like to join?": "Te połączenie już istnieje, czy chcesz do niego dołączyć?",
|
||||||
"Thanks! We'll get right on it.": "Dziękujemy! Zaraz się tym zajmiemy.",
|
"Thanks! We'll get right on it.": "Dziękujemy! Zaraz się tym zajmiemy.",
|
||||||
"Talking…": "Mówienie…",
|
"Talking…": "Mówienie…",
|
||||||
"Take me Home": "Zabierz mnie do ekranu startowego",
|
"Take me Home": "Zabierz mnie do strony głównej",
|
||||||
"Submitting feedback…": "Przesyłanie opinii…",
|
"Submitting feedback…": "Przesyłanie opinii…",
|
||||||
"Submit feedback": "Prześlij opinię",
|
"Submit feedback": "Prześlij opinię",
|
||||||
"Stop sharing screen": "Zatrzymaj udostępnianie ekranu",
|
"Stop sharing screen": "Zatrzymaj udostępnianie ekranu",
|
||||||
@@ -45,10 +45,10 @@
|
|||||||
"Select an option": "Wybierz opcję",
|
"Select an option": "Wybierz opcję",
|
||||||
"Saving…": "Zapisywanie…",
|
"Saving…": "Zapisywanie…",
|
||||||
"Save": "Zapisz",
|
"Save": "Zapisz",
|
||||||
"Return to home screen": "Powróć do ekranu domowego",
|
"Return to home screen": "Powróć do strony głównej",
|
||||||
"Remove": "Usuń",
|
"Remove": "Usuń",
|
||||||
"Release to stop": "Puść przycisk, aby przestać",
|
"Release to stop": "Puść przycisk, aby zatrzymać",
|
||||||
"Release spacebar key to stop": "Puść spację, aby przestać",
|
"Release spacebar key to stop": "Puść spację, aby zatrzymać",
|
||||||
"Registering…": "Rejestrowanie…",
|
"Registering…": "Rejestrowanie…",
|
||||||
"Register": "Zarejestruj",
|
"Register": "Zarejestruj",
|
||||||
"Recaptcha not loaded": "Recaptcha nie została załadowana",
|
"Recaptcha not loaded": "Recaptcha nie została załadowana",
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
"Press and hold to talk": "Przytrzymaj, aby mówić",
|
"Press and hold to talk": "Przytrzymaj, aby mówić",
|
||||||
"Press and hold spacebar to talk over {{name}}": "Przytrzymaj spację, aby mówić wraz z {{name}}",
|
"Press and hold spacebar to talk over {{name}}": "Przytrzymaj spację, aby mówić wraz z {{name}}",
|
||||||
"Press and hold spacebar to talk": "Przytrzymaj spację, aby mówić",
|
"Press and hold spacebar to talk": "Przytrzymaj spację, aby mówić",
|
||||||
"Passwords must match": "Hasła muszą być identyczne",
|
"Passwords must match": "Hasła muszą pasować",
|
||||||
"Password": "Hasło",
|
"Password": "Hasło",
|
||||||
"Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}</1>": "Inni użytkownicy próbują dołączyć do tego połączenia przy użyciu niekompatybilnych wersji. Powinni oni upewnić się, że odświeżyli stronę w swoich przeglądarkach:<1>{userLis}</1>",
|
"Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}</1>": "Inni użytkownicy próbują dołączyć do tego połączenia przy użyciu niekompatybilnych wersji. Powinni oni upewnić się, że odświeżyli stronę w swoich przeglądarkach:<1>{userLis}</1>",
|
||||||
"Not registered yet? <2>Create an account</2>": "Nie masz konta? <2>Utwórz je</2>",
|
"Not registered yet? <2>Create an account</2>": "Nie masz konta? <2>Utwórz je</2>",
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"Microphone": "Mikrofon",
|
"Microphone": "Mikrofon",
|
||||||
"Login to your account": "Zaloguj się do swojego konta",
|
"Login to your account": "Zaloguj się do swojego konta",
|
||||||
"Logging in…": "Logowanie…",
|
"Logging in…": "Logowanie…",
|
||||||
"Local volume": "Lokalna głośność",
|
"Local volume": "Głośność lokalna",
|
||||||
"Loading…": "Ładowanie…",
|
"Loading…": "Ładowanie…",
|
||||||
"Leave": "Opuść",
|
"Leave": "Opuść",
|
||||||
"Join existing call?": "Dołączyć do istniejącego połączenia?",
|
"Join existing call?": "Dołączyć do istniejącego połączenia?",
|
||||||
@@ -86,15 +86,15 @@
|
|||||||
"Home": "Strona domowa",
|
"Home": "Strona domowa",
|
||||||
"Having trouble? Help us fix it.": "Masz problem? Pomóż nam go naprawić.",
|
"Having trouble? Help us fix it.": "Masz problem? Pomóż nam go naprawić.",
|
||||||
"Grid layout menu": "Menu układu siatki",
|
"Grid layout menu": "Menu układu siatki",
|
||||||
"Full screen": "Pełen ekran",
|
"Full screen": "Pełny ekran",
|
||||||
"Freedom": "Wolność",
|
"Freedom": "Wolność",
|
||||||
"Fetching group call timed out.": "Przekroczono limit czasu na uzyskanie połączenia grupowego.",
|
"Fetching group call timed out.": "Przekroczono limit czasu na uzyskanie połączenia grupowego.",
|
||||||
"Exit full screen": "Zamknij pełny ekran",
|
"Exit full screen": "Opuść pełny ekran",
|
||||||
"Download debug logs": "Pobierz dzienniki debugowania",
|
"Download debug logs": "Pobierz dzienniki debugowania",
|
||||||
"Display name": "Wyświetlana nazwa",
|
"Display name": "Nazwa wyświetlana",
|
||||||
"Developer": "Deweloper",
|
"Developer": "Programista",
|
||||||
"Details": "Szczegóły",
|
"Details": "Szczegóły",
|
||||||
"Description (optional)": "Opis (opcjonalny)",
|
"Description (optional)": "Opis (opcjonalne)",
|
||||||
"Debug log request": "Prośba o dzienniki debugowania",
|
"Debug log request": "Prośba o dzienniki debugowania",
|
||||||
"Debug log": "Dzienniki debugowania",
|
"Debug log": "Dzienniki debugowania",
|
||||||
"Create account": "Utwórz konto",
|
"Create account": "Utwórz konto",
|
||||||
@@ -104,20 +104,20 @@
|
|||||||
"Confirm password": "Potwierdź hasło",
|
"Confirm password": "Potwierdź hasło",
|
||||||
"Close": "Zamknij",
|
"Close": "Zamknij",
|
||||||
"Change layout": "Zmień układ",
|
"Change layout": "Zmień układ",
|
||||||
"Camera/microphone permissions needed to join the call.": "Aby dołączyć do tego połączenia, potrzebne są uprawnienia do kamery/mikrofonu.",
|
"Camera/microphone permissions needed to join the call.": "Wymagane są uprawnienia do kamery/mikrofonu, aby dołączyć do rozmowy.",
|
||||||
"Camera {{n}}": "Kamera {{n}}",
|
"Camera {{n}}": "Kamera {{n}}",
|
||||||
"Camera": "Kamera",
|
"Camera": "Kamera",
|
||||||
"Call type menu": "Menu rodzaju połączenia",
|
"Call type menu": "Menu typu połączenia",
|
||||||
"Call link copied": "Skopiowano link do połączenia",
|
"Call link copied": "Skopiowano link do połączenia",
|
||||||
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "Klikając \"Dołącz do rozmowy\", wyrażasz zgodę na nasze <2>Warunki</2>",
|
"By clicking \"Join call now\", you agree to our <2>Terms and conditions</2>": "Klikając \"Dołącz do rozmowy\", wyrażasz zgodę na nasze <2>Zasady i warunki</2>",
|
||||||
"Avatar": "Awatar",
|
"Avatar": "Awatar",
|
||||||
"Audio": "Dźwięk",
|
"Audio": "Dźwięk",
|
||||||
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "Inny użytkownik w tym połączeniu napotkał problem. Aby lepiej zdiagnozować tę usterkę, chcielibyśmy zebrać dzienniki debugowania.",
|
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "Inny użytkownik w tym połączeniu napotkał problem. Aby lepiej zdiagnozować tę usterkę, chcielibyśmy zebrać dzienniki debugowania.",
|
||||||
"Accept microphone permissions to join the call.": "Przyznaj uprawnienia do mikrofonu aby dołączyć do połączenia.",
|
"Accept microphone permissions to join the call.": "Akceptuj uprawnienia mikrofonu, aby dołączyć do połączenia.",
|
||||||
"Accept camera/microphone permissions to join the call.": "Przyznaj uprawnienia do kamery/mikrofonu aby dołączyć do połączenia.",
|
"Accept camera/microphone permissions to join the call.": "Akceptuj uprawnienia kamery/mikrofonu, aby dołączyć do połączenia.",
|
||||||
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Może zechcesz ustawić hasło, aby zachować swoje konto?</0><1>Będziesz w stanie utrzymać swoją nazwę i ustawić awatar do wyświetlania podczas połączeń w przyszłości</1>",
|
"<0>Why not finish by setting up a password to keep your account?</0><1>You'll be able to keep your name and set an avatar for use on future calls</1>": "<0>Może zechcesz ustawić hasło, aby zachować swoje konto?</0><1>Będziesz w stanie utrzymać swoją nazwę i ustawić awatar do wyświetlania podczas połączeń w przyszłości</1>",
|
||||||
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Utwórz konto</0> Albo <2>Dołącz jako gość</2>",
|
"<0>Create an account</0> Or <2>Access as a guest</2>": "<0>Utwórz konto</0> lub <2>Dołącz jako gość</2>",
|
||||||
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Masz już konto?</0><1><0>Zaloguj się</0> Albo <2>Dołącz jako gość</2></1>",
|
"<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>": "<0>Masz już konto?</0><1><0>Zaloguj się</0> lub <2>Dołącz jako gość</2></1>",
|
||||||
"{{roomName}} - Walkie-talkie call": "{{roomName}} - połączenie walkie-talkie",
|
"{{roomName}} - Walkie-talkie call": "{{roomName}} - połączenie walkie-talkie",
|
||||||
"{{names}}, {{name}}": "{{names}}, {{name}}",
|
"{{names}}, {{name}}": "{{names}}, {{name}}",
|
||||||
"{{name}} is talking…": "{{name}} mówi…",
|
"{{name}} is talking…": "{{name}} mówi…",
|
||||||
@@ -126,12 +126,12 @@
|
|||||||
"{{count}} people connected|one": "{{count}} osoba połączona",
|
"{{count}} people connected|one": "{{count}} osoba połączona",
|
||||||
"This feature is only supported on Firefox.": "Ta funkcjonalność jest dostępna tylko w Firefox.",
|
"This feature is only supported on Firefox.": "Ta funkcjonalność jest dostępna tylko w Firefox.",
|
||||||
"Copy": "Kopiuj",
|
"Copy": "Kopiuj",
|
||||||
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Wysłanie logów debuggowania pomoże nam ustalić przyczynę problemu.</0>",
|
"<0>Submitting debug logs will help us track down the problem.</0>": "<0>Wysłanie dzienników debuggowania pomoże nam ustalić przyczynę problemu.</0>",
|
||||||
"<0>Oops, something's gone wrong.</0>": "<0>Ojej, coś poszło nie tak.</0>",
|
"<0>Oops, something's gone wrong.</0>": "<0>Ojej, coś poszło nie tak.</0>",
|
||||||
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Dołącz do rozmowy już teraz</0><1>Or</1><2>Skopiuj link do rozmowy i dołącz później</2>",
|
"<0>Join call now</0><1>Or</1><2>Copy call link and join later</2>": "<0>Dołącz do rozmowy już teraz</0><1>lub</1><2>Skopiuj link do rozmowy i dołącz później</2>",
|
||||||
"{{name}} (Waiting for video...)": "{{name}} (Oczekiwanie na wideo...)",
|
"{{name}} (Waiting for video...)": "{{name}} (Oczekiwanie na wideo...)",
|
||||||
"{{name}} (Connecting...)": "{{name}} (Łączenie...)",
|
"{{name}} (Connecting...)": "{{name}} (Łączenie...)",
|
||||||
"Expose developer settings in the settings window.": "Wyświetlaj opcje programisty w oknie ustawień.",
|
"Expose developer settings in the settings window.": "Wyświetl opcje programisty w oknie ustawień.",
|
||||||
"Element Call Home": "Strona główna Element Call",
|
"Element Call Home": "Strona główna Element Call",
|
||||||
"Developer Settings": "Opcje programisty",
|
"Developer Settings": "Opcje programisty",
|
||||||
"Talk over speaker": "Rozmowa przez głośnik",
|
"Talk over speaker": "Rozmowa przez głośnik",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export async function findDeviceByName(
|
|||||||
*
|
*
|
||||||
* @return The available media devices
|
* @return The available media devices
|
||||||
*/
|
*/
|
||||||
export async function getDevices(): Promise<MediaDeviceInfo[]> {
|
export async function getNamedDevices(): Promise<MediaDeviceInfo[]> {
|
||||||
// First get the devices without their labels, to learn what kinds of streams
|
// First get the devices without their labels, to learn what kinds of streams
|
||||||
// we can request
|
// we can request
|
||||||
let devices: MediaDeviceInfo[];
|
let devices: MediaDeviceInfo[];
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import { useSentryGroupCallHandler } from "./useSentryGroupCallHandler";
|
|||||||
import { useLocationNavigation } from "../useLocationNavigation";
|
import { useLocationNavigation } from "../useLocationNavigation";
|
||||||
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
||||||
import { useMediaHandler } from "../settings/useMediaHandler";
|
import { useMediaHandler } from "../settings/useMediaHandler";
|
||||||
import { findDeviceByName, getDevices } from "../media-utils";
|
import { findDeviceByName, getNamedDevices } from "../media-utils";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@@ -102,7 +102,7 @@ export function GroupCallView({
|
|||||||
// Get the available devices so we can match the selected device
|
// Get the available devices so we can match the selected device
|
||||||
// to its ID. This involves getting a media stream (see docs on
|
// to its ID. This involves getting a media stream (see docs on
|
||||||
// the function) so we only do it once and re-use the result.
|
// the function) so we only do it once and re-use the result.
|
||||||
const devices = await getDevices();
|
const devices = await getNamedDevices();
|
||||||
|
|
||||||
const { audioInput, videoInput } = ev.detail
|
const { audioInput, videoInput } = ev.detail
|
||||||
.data as unknown as JoinCallData;
|
.data as unknown as JoinCallData;
|
||||||
|
|||||||
@@ -419,7 +419,9 @@ export function InCallView({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buttons.push(<HangupButton key="6" onPress={onLeave} />);
|
buttons.push(
|
||||||
|
<HangupButton key="6" onPress={onLeave} data-testid="incall_leave" />
|
||||||
|
);
|
||||||
footer = <div className={styles.footer}>{buttons}</div>;
|
footer = <div className={styles.footer}>{buttons}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,7 +453,7 @@ export function InCallView({
|
|||||||
otelGroupCallMembership={otelGroupCallMembership}
|
otelGroupCallMembership={otelGroupCallMembership}
|
||||||
show={showInspector}
|
show={showInspector}
|
||||||
/>
|
/>
|
||||||
{rageshakeRequestModalState.isOpen && (
|
{rageshakeRequestModalState.isOpen && !noControls && (
|
||||||
<RageshakeRequestModal
|
<RageshakeRequestModal
|
||||||
{...rageshakeRequestModalProps}
|
{...rageshakeRequestModalProps}
|
||||||
roomIdOrAlias={roomIdOrAlias}
|
roomIdOrAlias={roomIdOrAlias}
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ export const SettingsModal = (props: Props) => {
|
|||||||
audioOutput,
|
audioOutput,
|
||||||
audioOutputs,
|
audioOutputs,
|
||||||
setAudioOutput,
|
setAudioOutput,
|
||||||
|
useDeviceNames,
|
||||||
} = useMediaHandler();
|
} = useMediaHandler();
|
||||||
|
useDeviceNames();
|
||||||
|
|
||||||
const [spatialAudio, setSpatialAudio] = useSpatialAudio();
|
const [spatialAudio, setSpatialAudio] = useSpatialAudio();
|
||||||
const [showInspector, setShowInspector] = useShowInspector();
|
const [showInspector, setShowInspector] = useShowInspector();
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { MediaHandlerEvent } from "matrix-js-sdk/src/webrtc/mediaHandler";
|
|
||||||
import React, {
|
import React, {
|
||||||
useState,
|
useState,
|
||||||
useEffect,
|
useEffect,
|
||||||
@@ -41,18 +40,26 @@ import React, {
|
|||||||
useContext,
|
useContext,
|
||||||
createContext,
|
createContext,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
|
useRef,
|
||||||
} from "react";
|
} from "react";
|
||||||
|
|
||||||
|
import { getNamedDevices } from "../media-utils";
|
||||||
|
|
||||||
export interface MediaHandlerContextInterface {
|
export interface MediaHandlerContextInterface {
|
||||||
audioInput: string;
|
audioInput: string | undefined;
|
||||||
audioInputs: MediaDeviceInfo[];
|
audioInputs: MediaDeviceInfo[];
|
||||||
setAudioInput: (deviceId: string) => void;
|
setAudioInput: (deviceId: string) => void;
|
||||||
videoInput: string;
|
videoInput: string | undefined;
|
||||||
videoInputs: MediaDeviceInfo[];
|
videoInputs: MediaDeviceInfo[];
|
||||||
setVideoInput: (deviceId: string) => void;
|
setVideoInput: (deviceId: string) => void;
|
||||||
audioOutput: string;
|
audioOutput: string | undefined;
|
||||||
audioOutputs: MediaDeviceInfo[];
|
audioOutputs: MediaDeviceInfo[];
|
||||||
setAudioOutput: (deviceId: string) => void;
|
setAudioOutput: (deviceId: string) => void;
|
||||||
|
/**
|
||||||
|
* A hook which requests for devices to be named. This requires media
|
||||||
|
* permissions.
|
||||||
|
*/
|
||||||
|
useDeviceNames: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MediaHandlerContext =
|
const MediaHandlerContext =
|
||||||
@@ -70,10 +77,10 @@ function getMediaPreferences(): MediaPreferences {
|
|||||||
try {
|
try {
|
||||||
return JSON.parse(mediaPreferences);
|
return JSON.parse(mediaPreferences);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return undefined;
|
return {};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,112 +110,98 @@ export function MediaHandlerProvider({ client, children }: Props): JSX.Element {
|
|||||||
audioOutputs,
|
audioOutputs,
|
||||||
},
|
},
|
||||||
setState,
|
setState,
|
||||||
] = useState(() => {
|
] = useState(() => ({
|
||||||
const mediaPreferences = getMediaPreferences();
|
audioInput: undefined as string | undefined,
|
||||||
const mediaHandler = client.getMediaHandler();
|
videoInput: undefined as string | undefined,
|
||||||
|
audioOutput: undefined as string | undefined,
|
||||||
|
audioInputs: [] as MediaDeviceInfo[],
|
||||||
|
videoInputs: [] as MediaDeviceInfo[],
|
||||||
|
audioOutputs: [] as MediaDeviceInfo[],
|
||||||
|
}));
|
||||||
|
|
||||||
mediaHandler.restoreMediaSettings(
|
// A ref counting the number of components currently mounted that want
|
||||||
mediaPreferences?.audioInput,
|
// to know device names
|
||||||
mediaPreferences?.videoInput
|
const numComponentsWantingNames = useRef(0);
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
const updateDevices = useCallback(
|
||||||
// @ts-ignore, ignore that audioInput is a private members of mediaHandler
|
async (initial: boolean) => {
|
||||||
audioInput: mediaHandler.audioInput,
|
// Only request device names if components actually want them, because it
|
||||||
// @ts-ignore, ignore that videoInput is a private members of mediaHandler
|
// could trigger an extra permission pop-up
|
||||||
videoInput: mediaHandler.videoInput,
|
const devices = await (numComponentsWantingNames.current > 0
|
||||||
audioOutput: undefined,
|
? getNamedDevices()
|
||||||
audioInputs: [],
|
: navigator.mediaDevices.enumerateDevices());
|
||||||
videoInputs: [],
|
const mediaPreferences = getMediaPreferences();
|
||||||
audioOutputs: [],
|
|
||||||
};
|
const audioInputs = devices.filter((d) => d.kind === "audioinput");
|
||||||
});
|
const videoInputs = devices.filter((d) => d.kind === "videoinput");
|
||||||
|
const audioOutputs = devices.filter((d) => d.kind === "audiooutput");
|
||||||
|
|
||||||
|
const audioInput = (
|
||||||
|
mediaPreferences.audioInput === undefined
|
||||||
|
? audioInputs.at(0)
|
||||||
|
: audioInputs.find(
|
||||||
|
(d) => d.deviceId === mediaPreferences.audioInput
|
||||||
|
) ?? audioInputs.at(0)
|
||||||
|
)?.deviceId;
|
||||||
|
const videoInput = (
|
||||||
|
mediaPreferences.videoInput === undefined
|
||||||
|
? videoInputs.at(0)
|
||||||
|
: videoInputs.find(
|
||||||
|
(d) => d.deviceId === mediaPreferences.videoInput
|
||||||
|
) ?? videoInputs.at(0)
|
||||||
|
)?.deviceId;
|
||||||
|
const audioOutput =
|
||||||
|
mediaPreferences.audioOutput === undefined
|
||||||
|
? undefined
|
||||||
|
: audioOutputs.find(
|
||||||
|
(d) => d.deviceId === mediaPreferences.audioOutput
|
||||||
|
)?.deviceId;
|
||||||
|
|
||||||
|
updateMediaPreferences({ audioInput, videoInput, audioOutput });
|
||||||
|
setState({
|
||||||
|
audioInput,
|
||||||
|
videoInput,
|
||||||
|
audioOutput,
|
||||||
|
audioInputs,
|
||||||
|
videoInputs,
|
||||||
|
audioOutputs,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
initial ||
|
||||||
|
audioInput !== mediaPreferences.audioInput ||
|
||||||
|
videoInput !== mediaPreferences.videoInput
|
||||||
|
) {
|
||||||
|
client.getMediaHandler().setMediaInputs(audioInput, videoInput);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[client, setState]
|
||||||
|
);
|
||||||
|
|
||||||
|
const useDeviceNames = useCallback(() => {
|
||||||
|
// This is a little weird from React's perspective as it looks like a
|
||||||
|
// dynamic hook, but it works
|
||||||
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
|
useEffect(() => {
|
||||||
|
numComponentsWantingNames.current++;
|
||||||
|
if (numComponentsWantingNames.current === 1) updateDevices(false);
|
||||||
|
return () => void numComponentsWantingNames.current--;
|
||||||
|
}, []);
|
||||||
|
}, [updateDevices]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const mediaHandler = client.getMediaHandler();
|
updateDevices(true);
|
||||||
|
const onDeviceChange = () => updateDevices(false);
|
||||||
function updateDevices(): void {
|
navigator.mediaDevices.addEventListener("devicechange", onDeviceChange);
|
||||||
navigator.mediaDevices.enumerateDevices().then((devices) => {
|
|
||||||
const mediaPreferences = getMediaPreferences();
|
|
||||||
|
|
||||||
const audioInputs = devices.filter(
|
|
||||||
(device) => device.kind === "audioinput"
|
|
||||||
);
|
|
||||||
const audioConnected = audioInputs.some(
|
|
||||||
// @ts-ignore
|
|
||||||
(device) => device.deviceId === mediaHandler.audioInput
|
|
||||||
);
|
|
||||||
// @ts-ignore
|
|
||||||
let audioInput = mediaHandler.audioInput;
|
|
||||||
|
|
||||||
if (!audioConnected && audioInputs.length > 0) {
|
|
||||||
audioInput = audioInputs[0].deviceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
const videoInputs = devices.filter(
|
|
||||||
(device) => device.kind === "videoinput"
|
|
||||||
);
|
|
||||||
const videoConnected = videoInputs.some(
|
|
||||||
// @ts-ignore
|
|
||||||
(device) => device.deviceId === mediaHandler.videoInput
|
|
||||||
);
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
let videoInput = mediaHandler.videoInput;
|
|
||||||
|
|
||||||
if (!videoConnected && videoInputs.length > 0) {
|
|
||||||
videoInput = videoInputs[0].deviceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
const audioOutputs = devices.filter(
|
|
||||||
(device) => device.kind === "audiooutput"
|
|
||||||
);
|
|
||||||
let audioOutput = undefined;
|
|
||||||
|
|
||||||
if (
|
|
||||||
mediaPreferences &&
|
|
||||||
audioOutputs.some(
|
|
||||||
(device) => device.deviceId === mediaPreferences.audioOutput
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
audioOutput = mediaPreferences.audioOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
// @ts-ignore
|
|
||||||
(mediaHandler.videoInput && mediaHandler.videoInput !== videoInput) ||
|
|
||||||
// @ts-ignore
|
|
||||||
mediaHandler.audioInput !== audioInput
|
|
||||||
) {
|
|
||||||
mediaHandler.setMediaInputs(audioInput, videoInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateMediaPreferences({ audioInput, videoInput, audioOutput });
|
|
||||||
|
|
||||||
setState({
|
|
||||||
audioInput,
|
|
||||||
videoInput,
|
|
||||||
audioOutput,
|
|
||||||
audioInputs,
|
|
||||||
videoInputs,
|
|
||||||
audioOutputs,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
updateDevices();
|
|
||||||
|
|
||||||
mediaHandler.on(MediaHandlerEvent.LocalStreamsChanged, updateDevices);
|
|
||||||
navigator.mediaDevices.addEventListener("devicechange", updateDevices);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
mediaHandler.removeListener(
|
navigator.mediaDevices.removeEventListener(
|
||||||
MediaHandlerEvent.LocalStreamsChanged,
|
"devicechange",
|
||||||
updateDevices
|
onDeviceChange
|
||||||
);
|
);
|
||||||
navigator.mediaDevices.removeEventListener("devicechange", updateDevices);
|
client.getMediaHandler().stopAllStreams();
|
||||||
mediaHandler.stopAllStreams();
|
|
||||||
};
|
};
|
||||||
}, [client]);
|
}, [client, updateDevices]);
|
||||||
|
|
||||||
const setAudioInput: (deviceId: string) => void = useCallback(
|
const setAudioInput: (deviceId: string) => void = useCallback(
|
||||||
(deviceId: string) => {
|
(deviceId: string) => {
|
||||||
@@ -245,6 +238,7 @@ export function MediaHandlerProvider({ client, children }: Props): JSX.Element {
|
|||||||
audioOutput,
|
audioOutput,
|
||||||
audioOutputs,
|
audioOutputs,
|
||||||
setAudioOutput,
|
setAudioOutput,
|
||||||
|
useDeviceNames,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
audioInput,
|
audioInput,
|
||||||
@@ -256,6 +250,7 @@ export function MediaHandlerProvider({ client, children }: Props): JSX.Element {
|
|||||||
audioOutput,
|
audioOutput,
|
||||||
audioOutputs,
|
audioOutputs,
|
||||||
setAudioOutput,
|
setAudioOutput,
|
||||||
|
useDeviceNames,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
16
yarn.lock
16
yarn.lock
@@ -1828,10 +1828,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.3.1.tgz#b50a781709c81e10701004214340f25475a171a0"
|
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.3.1.tgz#b50a781709c81e10701004214340f25475a171a0"
|
||||||
integrity sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==
|
integrity sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==
|
||||||
|
|
||||||
"@matrix-org/matrix-sdk-crypto-js@^0.1.0-alpha.8":
|
"@matrix-org/matrix-sdk-crypto-js@^0.1.0-alpha.9":
|
||||||
version "0.1.0-alpha.8"
|
version "0.1.0-alpha.9"
|
||||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.8.tgz#18dd8e7fb56602d2999d8a502b49e902a2bb3782"
|
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.9.tgz#00bc266781502641a661858a5a521dd4d95275fc"
|
||||||
integrity sha512-hdmbbGXKrN6JNo3wdBaR5Zs3lXlzllT3U43ViNTlabB3nKkOZQnEAN/Isv+4EQSgz1+8897veI9Q8sqlQX22oA==
|
integrity sha512-g5cjpFwA9h0CbEGoAqNVI2QcyDsbI8FHoLo9+OXWHIezEKITsSv78mc5ilIwN+2YpmVlH0KNeQWTHw4vi0BMnw==
|
||||||
|
|
||||||
"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz":
|
"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz":
|
||||||
version "3.2.14"
|
version "3.2.14"
|
||||||
@@ -10557,12 +10557,12 @@ matrix-events-sdk@0.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd"
|
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd"
|
||||||
integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==
|
integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==
|
||||||
|
|
||||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#fcbc195fbe4170251b87f03a69c8dc5bfccfd5ac":
|
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#a7b1dcaf9514b2e424a387e266c6f383a5909927":
|
||||||
version "25.1.0"
|
version "25.1.1"
|
||||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/fcbc195fbe4170251b87f03a69c8dc5bfccfd5ac"
|
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/a7b1dcaf9514b2e424a387e266c6f383a5909927"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.12.5"
|
"@babel/runtime" "^7.12.5"
|
||||||
"@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.8"
|
"@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.9"
|
||||||
another-json "^0.2.0"
|
another-json "^0.2.0"
|
||||||
bs58 "^5.0.0"
|
bs58 "^5.0.0"
|
||||||
content-type "^1.0.4"
|
content-type "^1.0.4"
|
||||||
|
|||||||
Reference in New Issue
Block a user