diff options
Diffstat (limited to 'client-web')
| -rw-r--r-- | client-web/source/helper.ts | 37 | ||||
| -rw-r--r-- | client-web/source/index.ts | 5 | ||||
| -rw-r--r-- | client-web/source/local_user.ts | 30 | ||||
| -rw-r--r-- | client-web/source/menu.ts | 10 | ||||
| -rw-r--r-- | client-web/source/preferences.ts | 63 | 
5 files changed, 85 insertions, 60 deletions
| diff --git a/client-web/source/helper.ts b/client-web/source/helper.ts index 31e500a..ef95e3a 100644 --- a/client-web/source/helper.ts +++ b/client-web/source/helper.ts @@ -1,43 +1,6 @@  /// <reference lib="dom" /> -import { parameters } from "./index.ts" - -export function get_query_params(): { [key: string]: string } { -    const q: { [key: string]: string } = {} -    for (const kv of window.location.hash.substring(1).split("&")) { -        const [key, value] = kv.split("=") -        q[decodeURIComponent(key)] = decodeURIComponent(value) -    } -    return q -} -  export function hex_id(len = 8): string {      if (len > 8) return hex_id() + hex_id(len - 8)      return Math.floor(Math.random() * 16 ** len).toString(16).padStart(len, "0")  } - -export function parameter_bool(name: string, def: boolean): boolean { -    const v = parameters[name] -    if (!v) return def -    if (v == "0" || v == "false" || v == "no") return false -    if (v == "1" || v == "true" || v == "yes") return true -    alert(`parameter ${name} is invalid`) -    return def -} - -export function parameter_number(name: string, def: number): number { -    const v = parameters[name] -    if (!v) return def -    const n = parseFloat(v) -    if (Number.isNaN(n)) { -        alert(`parameter ${name} is invalid`) -        return def -    } -    return n -} - -export function parameter_string(name: string, def: string): string { -    const v = parameters[name] -    if (!v) return def -    return v -} diff --git a/client-web/source/index.ts b/client-web/source/index.ts index 6266aff..670cb46 100644 --- a/client-web/source/index.ts +++ b/client-web/source/index.ts @@ -1,6 +1,5 @@  /// <reference lib="dom" /> -import { get_query_params } from "./helper.ts"  import { log } from "./logger.ts"  import { create_menu } from "./menu.ts";  import { Room } from "./room.ts" @@ -16,8 +15,6 @@ export interface User {      stream: MediaStream,  } -export const parameters = get_query_params() -  window.onload = () => main()  export function main() { @@ -25,6 +22,6 @@ export function main() {      log("*", "starting up")      const room_name = window.location.pathname.substring("/".length)      const room = new Room(room_name) -    create_menu(room) +    create_menu()      document.body.append(room.el)  } diff --git a/client-web/source/local_user.ts b/client-web/source/local_user.ts index b3d5692..85a2a23 100644 --- a/client-web/source/local_user.ts +++ b/client-web/source/local_user.ts @@ -1,7 +1,7 @@  /// <reference lib="dom" /> -import { parameter_bool, parameter_number } from "./helper.ts";  import { log } from "./logger.ts"; +import { PREFS } from "./preferences.ts";  import { RemoteUser } from "./remote_user.ts";  import { get_rnnoise_node } from "./rnnoise.ts";  import { Room } from "./room.ts"; @@ -10,7 +10,7 @@ import { User } from "./user.ts";  export class LocalUser extends User {      mic_gain?: GainNode -    default_gain: number = parameter_number("mic_gain", 1) +    default_gain: number = PREFS.microphone_gain      constructor(room: Room, id: number, name: string) {          super(room, id, name) @@ -22,9 +22,9 @@ export class LocalUser extends User {      }      async add_initial_tracks() { -        if (parameter_bool("mic_enabled", false)) this.publish_track(await this.create_mic_track()) -        if (parameter_bool("camera_enabled", false)) this.publish_track(await this.create_camera_track()) -        if (parameter_bool("screen_enabled", false)) this.publish_track(await this.create_screen_track()) +        if (PREFS.microphone_enabled) this.publish_track(await this.create_mic_track()) +        if (PREFS.camera_enabled) this.publish_track(await this.create_camera_track()) +        if (PREFS.screencast_enabled) this.publish_track(await this.create_screencast_track())      }      publish_track(t: TrackHandle) { @@ -50,7 +50,7 @@ export class LocalUser extends User {          mic_toggle.type = camera_toggle.type = screen_toggle.type = "button"          mic_toggle.value = "Microphone"          camera_toggle.value = "Camera" -        screen_toggle.value = "Screen" +        screen_toggle.value = "Screencast"          const create = async (_e: HTMLElement, tp: Promise<TrackHandle>) => {              log("media", "awaiting track") @@ -61,7 +61,7 @@ export class LocalUser extends User {          mic_toggle.addEventListener("click", () => create(mic_toggle, this.create_mic_track()))          camera_toggle.addEventListener("click", () => create(camera_toggle, this.create_camera_track())) -        screen_toggle.addEventListener("click", () => create(screen_toggle, this.create_screen_track())) +        screen_toggle.addEventListener("click", () => create(screen_toggle, this.create_screencast_track()))          const el = document.createElement("div")          el.classList.add("local-controls") @@ -75,20 +75,24 @@ export class LocalUser extends User {          const user_media = await window.navigator.mediaDevices.getUserMedia({ video: true })          return new TrackHandle(user_media.getVideoTracks()[0], true)      } -    async create_screen_track() { +    async create_screencast_track() {          log("media", "requesting user media (screen)")          const user_media = await window.navigator.mediaDevices.getDisplayMedia({ video: true })          return new TrackHandle(user_media.getVideoTracks()[0], true)      }      async create_mic_track() {          log("media", "requesting user media (audio)") -        const use_rnnoise = parameter_bool("rnnoise", true) -        const audio_contraints = use_rnnoise ? { +        const audio_contraints = PREFS.rnnoise ? {              channelCount: { ideal: 1 },              noiseSuppression: { ideal: false },              echoCancellation: { ideal: true }, -            autoGainControl: { ideal: false }, -        } : true; +            autoGainControl: { ideal: true }, +        } : { +            channelCount: { ideal: 1 }, +            noiseSuppression: { ideal: false }, +            echoCancellation: { ideal: true }, +            autoGainControl: { ideal: true }, +        };          const user_media = await window.navigator.mediaDevices.getUserMedia({ audio: audio_contraints })          const context = new AudioContext() @@ -99,7 +103,7 @@ export class LocalUser extends User {          this.mic_gain = gain          let rnnoise: RNNoiseNode; -        if (use_rnnoise) { +        if (PREFS.rnnoise) {              rnnoise = await get_rnnoise_node(context)              source.connect(rnnoise)              rnnoise.connect(gain) diff --git a/client-web/source/menu.ts b/client-web/source/menu.ts index 1401b42..dfeed18 100644 --- a/client-web/source/menu.ts +++ b/client-web/source/menu.ts @@ -1,6 +1,6 @@ -import { Room } from "./room.ts"; +/// <reference lib="dom" /> -export function create_menu(room?: Room) { +export function create_menu() {      const menu = document.createElement("div")      menu.classList.add("menu-overlay")      document.body.append(menu) @@ -16,11 +16,9 @@ export function create_menu(room?: Room) {          return p      } -    if (room) menu.append( -        item("Settings", () => alert("todo, refer to the url parameters in the docs for now")) -    )      menu.append( +        item("Settings", () => alert("todo, refer to the url parameters in the docs for now")),          item("Licence", "/licence"),          item("Sources / Documentation", "https://codeberg.org/metamuffin/keks-meet"),      ) -}
\ No newline at end of file +} diff --git a/client-web/source/preferences.ts b/client-web/source/preferences.ts new file mode 100644 index 0000000..e7fc7bb --- /dev/null +++ b/client-web/source/preferences.ts @@ -0,0 +1,63 @@ + +export interface PrefDecl<T> { +    name: string, +    default: T +    description: string, +    possible_values?: T[] +} + +type Type = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"; + +type PrefMap<T extends { [key: string]: { default: unknown } }> = { [Key in keyof T]: T[Key]["default"] } +export function register_prefs<T extends Record<string, PrefDecl<unknown>>>(ds: T): PrefMap<T> { +    const p: PrefMap<T> = {} as PrefMap<T> +    for (const key in ds) { +        const d = ds[key]; +        let value = get_param(d.default, d.name) ?? d.default; +        if (d.possible_values) if (!d.possible_values.includes(value)) value = d.default +        p[key] = value +    } +    return p +} + +const raw_params = load_query_params(); +export function load_query_params(): { [key: string]: string } { +    const q: { [key: string]: string } = {} +    for (const kv of window.location.hash.substring(1).split("&")) { +        const [key, value] = kv.split("=") +        if (key == "prototype") continue +        q[decodeURIComponent(key)] = decodeURIComponent(value) +    } +    return q +} + +export function get_param<T>(example: T, key: string): T | undefined { +    const v = raw_params[key] +    if (v == undefined) return undefined +    const ty = typeof example +    if (ty == "string") return v as unknown as T +    else if (ty == "number") { +        const n = parseInt(v) +        if (!Number.isNaN(n)) return n as unknown as T +        console.warn("invalid number parameter"); +    } else if (ty == "boolean") { +        if (v == "0" || v == "false" || v == "no") return false as unknown as T +        if (v == "1" || v == "true" || v == "yes") return true as unknown as T +        console.warn("invalid boolean parameter"); +    } else { +        throw new Error("invalid param type"); +    } +    return undefined +} + + +const PREF_DECLS = { +    rnnoise: { name: "rnnoise", default: true, description: "Use RNNoise for noise suppression" }, +    native_noise_suppression: { name: "native_noise_suppression", default: false, description: "Suggest the browser to do noise suppression" }, +    username: { name: "username", default: "guest", description: "Username" }, +    microphone_gain: { name: "microphone_gain", default: 1, description: "Amplify microphone volume" }, +    microphone_enabled: { name: "microphone_enabled", default: false, description: "Add one microphone track on startup" }, +    camera_enabled: { name: "camera_enabled", default: false, description: "Add one camera track on startup" }, +    screencast_enabled: { name: "screencast_enabled", default: false, description: "Add one screencast track on startup" }, +} +export const PREFS = register_prefs(PREF_DECLS) | 
