mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-10 21:55:19 +00:00
Supply Element Call's parameters through a context
Element Call's parameters come from its URL, which works while it owns the page but leaves an embedder with nowhere to put them. Add a context so they can be provided directly, falling back to parsing window.location when no provider is present. This also decouples the thirteen consumers from react-router: useUrlParams called useLocation, so each of them required a router ancestor, which the embedded build will not have. The standalone and widget builds keep their URL-derived behaviour via useUrlParamsFromLocation, provided in App. No functional change.
This commit is contained in:
+19
-1
@@ -31,7 +31,13 @@ import { useTheme } from "./useTheme";
|
|||||||
import { ProcessorProvider } from "./livekit/TrackProcessorContext";
|
import { ProcessorProvider } from "./livekit/TrackProcessorContext";
|
||||||
import { type AppViewModel } from "./state/AppViewModel";
|
import { type AppViewModel } from "./state/AppViewModel";
|
||||||
import { MediaDevicesContext } from "./MediaDevicesContext";
|
import { MediaDevicesContext } from "./MediaDevicesContext";
|
||||||
import { getUrlParams, HeaderStyle, useUrlParams } from "./UrlParams";
|
import {
|
||||||
|
getUrlParams,
|
||||||
|
HeaderStyle,
|
||||||
|
UrlParamsProvider,
|
||||||
|
useUrlParams,
|
||||||
|
useUrlParamsFromLocation,
|
||||||
|
} from "./UrlParams";
|
||||||
import { AppBar } from "./AppBar";
|
import { AppBar } from "./AppBar";
|
||||||
import { i18n } from "./utils/i18n";
|
import { i18n } from "./utils/i18n";
|
||||||
import { useRootElement } from "./RootElementContext";
|
import { useRootElement } from "./RootElementContext";
|
||||||
@@ -42,6 +48,16 @@ interface SimpleProviderProps {
|
|||||||
children: JSX.Element;
|
children: JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supplies the URL-derived params to the rest of the app. Only the standalone
|
||||||
|
* and widget builds own the URL, so this lives here in the app shell rather
|
||||||
|
* than alongside the context itself.
|
||||||
|
*/
|
||||||
|
const LocationUrlParamsProvider: FC<SimpleProviderProps> = ({ children }) => {
|
||||||
|
const urlParams = useUrlParamsFromLocation();
|
||||||
|
return <UrlParamsProvider value={urlParams}>{children}</UrlParamsProvider>;
|
||||||
|
};
|
||||||
|
|
||||||
const BackgroundProvider: FC<SimpleProviderProps> = ({ children }) => {
|
const BackgroundProvider: FC<SimpleProviderProps> = ({ children }) => {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const { background } = useUrlParams();
|
const { background } = useUrlParams();
|
||||||
@@ -102,6 +118,7 @@ export const App: FC<Props> = ({ vm }) => {
|
|||||||
return (
|
return (
|
||||||
<I18nextProvider i18n={i18n}>
|
<I18nextProvider i18n={i18n}>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
<LocationUrlParamsProvider>
|
||||||
<BackgroundProvider>
|
<BackgroundProvider>
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
@@ -115,6 +132,7 @@ export const App: FC<Props> = ({ vm }) => {
|
|||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</BackgroundProvider>
|
</BackgroundProvider>
|
||||||
|
</LocationUrlParamsProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</I18nextProvider>
|
</I18nextProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
+29
-4
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|||||||
Please see LICENSE in the repository root for full details.
|
Please see LICENSE in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useMemo } from "react";
|
import { createContext, use, useMemo } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { logger } from "matrix-js-sdk/lib/logger";
|
import { logger } from "matrix-js-sdk/lib/logger";
|
||||||
import {
|
import {
|
||||||
@@ -519,11 +519,36 @@ export const computeUrlParams = (search = "", hash = ""): UrlParams => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const UrlParamsContext = createContext<UrlParams | null>(null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to simplify use of getUrlParams.
|
* Supplies the parameters Element Call should run with.
|
||||||
* @returns The app parameters for the current URL
|
*
|
||||||
|
* The standalone and widget builds derive these from the URL, but an embedder
|
||||||
|
* has no URL of its own to put them in, so it provides them directly instead.
|
||||||
|
*
|
||||||
|
* TODO: `UrlParams` is no longer an accurate name now that these need not come
|
||||||
|
* from a URL. Renaming it touches every consumer, so it is left until the rest
|
||||||
|
* of the de-globalisation work has settled.
|
||||||
*/
|
*/
|
||||||
export const useUrlParams = (): UrlParams => {
|
export const UrlParamsProvider = UrlParamsContext.Provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameters Element Call is running with.
|
||||||
|
*
|
||||||
|
* Falls back to parsing `window.location` when no provider is present, so that
|
||||||
|
* tests and stories keep working without one.
|
||||||
|
*/
|
||||||
|
export const useUrlParams = (): UrlParams =>
|
||||||
|
use(UrlParamsContext) ?? getUrlParams();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derives {@link UrlParams} from the current router location.
|
||||||
|
*
|
||||||
|
* Only meaningful when Element Call owns the URL; embedders provide the params
|
||||||
|
* directly through {@link UrlParamsProvider}.
|
||||||
|
*/
|
||||||
|
export const useUrlParamsFromLocation = (): UrlParams => {
|
||||||
const { search, hash } = useLocation();
|
const { search, hash } = useLocation();
|
||||||
return useMemo(() => getUrlParams(search, hash), [search, hash]);
|
return useMemo(() => getUrlParams(search, hash), [search, hash]);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user