(feat): add sounds
This commit is contained in:
parent
6a5236bafe
commit
184b85190b
19 changed files with 207 additions and 16 deletions
|
|
@ -45,6 +45,15 @@ const settings = {
|
|||
},
|
||||
},
|
||||
},
|
||||
call: {
|
||||
call: {
|
||||
call_jingle: {
|
||||
display: "Jingle",
|
||||
type: "select",
|
||||
default: "jingle_1" as "jingle_1" | "jingle_2",
|
||||
},
|
||||
},
|
||||
},
|
||||
application: {
|
||||
cache: {},
|
||||
theme: {},
|
||||
|
|
@ -55,26 +64,35 @@ const settings = {
|
|||
// Assemble storage defaults
|
||||
export default settings;
|
||||
|
||||
type BooleanSettingNames<T extends SettingsSchema> = {
|
||||
type SettingStorageEntry<T extends SettingsSchema> = {
|
||||
[C in StringKeyOf<T>]: {
|
||||
[P in StringKeyOf<T[C]>]: {
|
||||
[S in StringKeyOf<T[C][P]>]: T[C][P][S] extends {
|
||||
type: "boolean";
|
||||
default: boolean;
|
||||
}
|
||||
? S
|
||||
[S in StringKeyOf<T[C][P]>]: T[C][P][S] extends { default: infer V }
|
||||
? { key: `settings.${S}`; value: V }
|
||||
: never;
|
||||
}[StringKeyOf<T[C][P]>];
|
||||
}[StringKeyOf<T[C]>];
|
||||
}[StringKeyOf<T>];
|
||||
|
||||
type Widen<T> = T extends boolean
|
||||
? boolean
|
||||
: T extends string
|
||||
? string extends T
|
||||
? string
|
||||
: T
|
||||
: T extends number
|
||||
? number
|
||||
: T;
|
||||
|
||||
export type SettingsStorageKey<T extends SettingsSchema = typeof settings> =
|
||||
`settings.${BooleanSettingNames<T>}`;
|
||||
SettingStorageEntry<T>["key"];
|
||||
|
||||
export type SettingsStorageDefaults<
|
||||
T extends SettingsSchema = typeof settings,
|
||||
> = {
|
||||
[K in SettingsStorageKey<T>]: boolean;
|
||||
[K in SettingsStorageKey<T>]: Widen<
|
||||
Extract<SettingStorageEntry<T>, { key: K }>["value"]
|
||||
>;
|
||||
};
|
||||
|
||||
function buildSettingsStorageDefaults<T extends SettingsSchema>(
|
||||
|
|
@ -85,12 +103,10 @@ function buildSettingsStorageDefaults<T extends SettingsSchema>(
|
|||
for (const category of Object.values(schema)) {
|
||||
for (const page of Object.values(category)) {
|
||||
for (const [settingName, setting] of Object.entries(page)) {
|
||||
if (
|
||||
setting.type === "boolean" &&
|
||||
typeof setting.default === "boolean"
|
||||
) {
|
||||
if ("default" in setting) {
|
||||
const key = `settings.${settingName}` as SettingsStorageKey<T>;
|
||||
defaults[key] = setting.default;
|
||||
defaults[key] =
|
||||
setting.default as SettingsStorageDefaults<T>[typeof key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
34
packages/shared/src/sounds.ts
Normal file
34
packages/shared/src/sounds.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
export type SoundName =
|
||||
| "call_jingle_1"
|
||||
| "call_jingle_2"
|
||||
| "call_join"
|
||||
| "call_leave"
|
||||
| "message"
|
||||
| "stream_end_other"
|
||||
| "stream_end_self"
|
||||
| "stream_start_other"
|
||||
| "stream_start_self"
|
||||
| "stream_watch_end"
|
||||
| "stream_watch_start";
|
||||
|
||||
function soundUrl(sound: SoundName) {
|
||||
if (window.location.protocol === "file:") {
|
||||
return new URL(`./sounds/${sound}.wav`, document.baseURI).href;
|
||||
}
|
||||
|
||||
return `/sounds/${sound}.wav`;
|
||||
}
|
||||
|
||||
export function playSound(sound: SoundName, loop = false) {
|
||||
const audio = new Audio(soundUrl(sound));
|
||||
audio.loop = loop;
|
||||
void audio.play().catch(() => undefined);
|
||||
return audio;
|
||||
}
|
||||
|
||||
export function stopSound(audio: HTMLAudioElement | null) {
|
||||
if (!audio) return;
|
||||
|
||||
audio.pause();
|
||||
audio.currentTime = 0;
|
||||
}
|
||||
Loading…
Reference in a new issue