mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-10 21:55:19 +00:00
Speak every language in the component, not just English
The component bundled English alone: the standalone app fetches its locale files at runtime from URLs its own build emits, which a host serving the library from elsewhere could not resolve, so bundling one language was the self-contained option. Now every locale is a chunk of its own that the host's bundler loads the first time it is needed, with English still bundled in so that the fallback never waits. Element Call starts in the browser's language and follows the host's own setting through a `language` prop; `supportedLanguages` says what it accepts. Translations are shared by every Element Call on the page, so the most recently set language wins for all of them. The harness gets a language picker, and the app and the component share the parsing of locale paths. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
b7285064fd
commit
f994586eeb
@@ -17,7 +17,11 @@ import {
|
||||
import { type MatrixClient } from "matrix-js-sdk";
|
||||
import { logger } from "matrix-js-sdk/lib/logger";
|
||||
|
||||
import { ElementCall, type ElementCallHandle } from "../index";
|
||||
import {
|
||||
ElementCall,
|
||||
type ElementCallHandle,
|
||||
supportedLanguages,
|
||||
} from "../index";
|
||||
import { createDevHostBridge } from "./DevHostBridge";
|
||||
import { createSession, joinRoom } from "./session";
|
||||
import styles from "./Harness.module.css";
|
||||
@@ -90,8 +94,9 @@ interface LogEntry {
|
||||
const Pane: FC<{
|
||||
session: Session;
|
||||
roomId: string;
|
||||
language: string | undefined;
|
||||
log: (pane: string, message: string) => void;
|
||||
}> = ({ session, roomId, log }): ReactNode => {
|
||||
}> = ({ session, roomId, language, log }): ReactNode => {
|
||||
const [mounted, setMounted] = useState(true);
|
||||
|
||||
const bridge = useMemo(
|
||||
@@ -173,6 +178,7 @@ const Pane: FC<{
|
||||
client={session.client}
|
||||
roomId={roomId}
|
||||
hostBridge={bridge}
|
||||
language={language}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -226,6 +232,9 @@ export const Harness: FC = (): ReactNode => {
|
||||
const [state, setState] = useState<State>({ phase: "credentials" });
|
||||
const [entries, setEntries] = useState<LogEntry[]>([]);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
// The host's language setting, which Element Call follows. Undefined means
|
||||
// the host has none and Element Call uses the browser's.
|
||||
const [language, setLanguage] = useState<string | undefined>(undefined);
|
||||
|
||||
const log = useCallback((pane: string, message: string): void => {
|
||||
setEntries((entries) =>
|
||||
@@ -324,6 +333,20 @@ export const Harness: FC = (): ReactNode => {
|
||||
<button onClick={(): void => setDialogOpen(true)}>
|
||||
Open a host dialog
|
||||
</button>
|
||||
<label>
|
||||
Language{" "}
|
||||
<select
|
||||
value={language ?? ""}
|
||||
onChange={(e): void => setLanguage(e.target.value || undefined)}
|
||||
>
|
||||
<option value="">Browser default</option>
|
||||
{supportedLanguages.map((tag) => (
|
||||
<option key={tag} value={tag}>
|
||||
{tag}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</header>
|
||||
<div className={styles.middle}>
|
||||
<HostChrome />
|
||||
@@ -333,6 +356,7 @@ export const Harness: FC = (): ReactNode => {
|
||||
key={session.label}
|
||||
session={session}
|
||||
roomId={state.roomId}
|
||||
language={language}
|
||||
log={log}
|
||||
/>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user