aboutsummaryrefslogtreecommitdiff
path: root/client-web/source
diff options
context:
space:
mode:
Diffstat (limited to 'client-web/source')
-rw-r--r--client-web/source/helper.ts37
-rw-r--r--client-web/source/index.ts5
-rw-r--r--client-web/source/local_user.ts30
-rw-r--r--client-web/source/menu.ts10
-rw-r--r--client-web/source/preferences.ts63
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)