diff options
author | metamuffin <metamuffin@disroot.org> | 2022-12-25 13:53:26 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-12-25 13:53:26 +0100 |
commit | ac68f06d230fd589edb9b1d13af50836d554f23e (patch) | |
tree | 00cf3d10cec1e024cf53cf434f17d6b1fadcdaae /client-web/source | |
parent | 7dc0c3ec6f982377f6c2e2e87c983c5d4b5870c6 (diff) | |
download | keks-meet-ac68f06d230fd589edb9b1d13af50836d554f23e.tar keks-meet-ac68f06d230fd589edb9b1d13af50836d554f23e.tar.bz2 keks-meet-ac68f06d230fd589edb9b1d13af50836d554f23e.tar.zst |
optimize accessability (screen readers 'n stuff)
Diffstat (limited to 'client-web/source')
-rw-r--r-- | client-web/source/chat.ts | 9 | ||||
-rw-r--r-- | client-web/source/helper.ts | 24 | ||||
-rw-r--r-- | client-web/source/index.ts | 4 | ||||
-rw-r--r-- | client-web/source/keybinds.ts | 13 | ||||
-rw-r--r-- | client-web/source/menu.ts | 10 | ||||
-rw-r--r-- | client-web/source/preferences/ui.ts | 11 |
6 files changed, 44 insertions, 27 deletions
diff --git a/client-web/source/chat.ts b/client-web/source/chat.ts index b7c572d..47b0678 100644 --- a/client-web/source/chat.ts +++ b/client-web/source/chat.ts @@ -6,7 +6,7 @@ /// <reference lib="dom" /> import { ChatMessage } from "../../common/packets.d.ts"; -import { ediv, espan, image_view, notify, OverlayUi } from "./helper.ts"; +import { ediv, esection, espan, image_view, notify, OverlayUi } from "./helper.ts"; import { log } from "./logger.ts"; import { PREFS } from "./preferences/mod.ts"; import { Room } from "./room.ts"; @@ -20,13 +20,15 @@ export class Chat extends OverlayUi { constructor(public room: Room) { const send = document.createElement("input") + send.ariaLabel = "send message" send.type = "text" + send.placeholder = "send a message..." - const messages = ediv({ class: "messages" }) + const messages = ediv({ class: "messages", aria_live: "polite" }) const controls = ediv({ class: "controls" }) controls.append(send) messages.append(document.createElement("hr")) - super(ediv({ class: "chat" }, messages, controls)) + super(esection({ class: "chat", aria_label: "chat", role: "dialog" }, messages, controls)) this.messages = messages this.controls = controls this.send_el = send @@ -61,6 +63,7 @@ export class Chat extends OverlayUi { } } + on_show(): void { this.focus() } focus() { this.send_el.focus() } send(msg: ChatMessage) { this.room.local_user.chat(msg) diff --git a/client-web/source/helper.ts b/client-web/source/helper.ts index c23beb6..1133afe 100644 --- a/client-web/source/helper.ts +++ b/client-web/source/helper.ts @@ -9,12 +9,25 @@ import { PREFS } from "./preferences/mod.ts"; const elem = <K extends keyof HTMLElementTagNameMap>(s: K): HTMLElementTagNameMap[K] => document.createElement(s) -interface Opts<El> { class?: string[] | string, id?: string, src?: string, onclick?: (e: El) => void } +interface Opts<El> { + class?: string[] | string, + id?: string, src?: string, + for?: string, + onclick?: (e: El) => void, + role?: "dialog" + aria_label?: string + aria_live?: "polite" | "assertive" + aria_modal?: boolean +} function apply_opts<El extends HTMLElement>(e: El, o: Opts<El> | undefined) { if (!o) return if (o.id) e.id = o.id if (o.onclick) e.onclick = () => o.onclick!(e) + if (o.aria_label) e.ariaLabel = o.aria_label + if (o.aria_live) e.ariaLive = o.aria_live + if (o.for) (e as unknown as HTMLLabelElement).htmlFor = o.for + if (o.aria_modal) e.ariaModal = "true" if (typeof o?.class == "string") e.classList.add(o.class) if (typeof o?.class == "object") e.classList.add(...o.class) } @@ -42,6 +55,9 @@ export const eh5 = elem_with_content("h5") export const eh6 = elem_with_content("h6") export const epre = elem_with_content("pre") export const ediv = elem_with_children("div") +export const efooter = elem_with_children("footer") +export const esection = elem_with_children("section") +export const enav = elem_with_children("nav") export const etr = elem_with_children("tr") export const etd = elem_with_children("td") export const eth = elem_with_children("th") @@ -59,10 +75,12 @@ export class OverlayUi { } get shown() { return this._shown } set shown(v: boolean) { - if (v && !this._shown) OVERLAYS.append(this.el) - if (!v && this._shown) OVERLAYS.removeChild(this.el) + if (v && !this._shown) OVERLAYS.append(this.el), this.on_show() + if (!v && this._shown) OVERLAYS.removeChild(this.el), this.on_hide() this._shown = v } + on_show() { } + on_hide() { } } export function image_view(url: string, opts?: Opts<HTMLElement>): HTMLElement { diff --git a/client-web/source/index.ts b/client-web/source/index.ts index d2bd276..a853c58 100644 --- a/client-web/source/index.ts +++ b/client-web/source/index.ts @@ -6,7 +6,7 @@ /// <reference lib="dom" /> import { init_serviceworker } from "./sw/init.ts"; -import { ediv, OVERLAYS } from "./helper.ts"; +import { esection, OVERLAYS } from "./helper.ts"; import { setup_keybinds } from "./keybinds.ts"; import { log, LOGGER_CONTAINER } from "./logger.ts" import { BottomMenu, MenuBr } from "./menu.ts"; @@ -15,7 +15,7 @@ import { SignalingConnection } from "./protocol/mod.ts"; import { Room } from "./room.ts" export const VERSION = "0.1.12" -export const ROOM_CONTAINER = ediv({ class: "room" }) +export const ROOM_CONTAINER = esection({ class: "room", aria_label: "user list" }) export const RTC_CONFIG: RTCConfiguration = { iceServers: [ diff --git a/client-web/source/keybinds.ts b/client-web/source/keybinds.ts index 5463e47..d096501 100644 --- a/client-web/source/keybinds.ts +++ b/client-web/source/keybinds.ts @@ -10,28 +10,23 @@ import { Room } from "./room.ts" import { update_serviceworker } from "./sw/init.ts"; export function setup_keybinds(room: Room) { - let command_mode = false + // let command_mode = false document.body.addEventListener("keydown", ev => { // TODO is there a proper solution? if (ev.target instanceof HTMLInputElement && !(ev.target.type == "button")) return if (ev.repeat) return - if (ev.code == "Enter") { + if (ev.code == "Enter" && ev.ctrlKey) { room.chat.shown = !room.chat.shown if (room.chat.shown) room.chat.focus() ev.preventDefault() // so focused buttons dont trigger } - if (ev.code == "Space") { - command_mode = true - ev.preventDefault() // so focused buttons dont trigger - return - } - if (command_mode) { + if (ev.shiftKey) { if (ev.code == "KeyM" || ev.code == "KeyR") room.local_user.await_add_resource(create_mic_res()) if (ev.code == "KeyS") room.local_user.await_add_resource(create_screencast_res()) if (ev.code == "KeyC" && !ev.ctrlKey) room.local_user.await_add_resource(create_camera_res()) if (ev.code == "KeyC" && ev.ctrlKey) room.local_user.resources.forEach(t => t.destroy()) if (ev.code == "KeyU") if (window.confirm("really update?")) update_serviceworker() } - command_mode = false + // command_mode = false }) } diff --git a/client-web/source/menu.ts b/client-web/source/menu.ts index 9126dc5..035f3aa 100644 --- a/client-web/source/menu.ts +++ b/client-web/source/menu.ts @@ -5,7 +5,7 @@ */ /// <reference lib="dom" /> -import { ebutton, ediv, ep, OverlayUi } from "./helper.ts" +import { ebutton, ediv, efooter, enav, ep, OverlayUi } from "./helper.ts" import { VERSION } from "./index.ts" import { PrefUi } from "./preferences/ui.ts" import { create_file_res } from "./resource/file.ts"; @@ -26,7 +26,7 @@ export class MenuBr extends OverlayUi { return p } - super(ediv({ class: "menu-br" }, + super(efooter({ class: "menu-br" }, ep(`keks-meet ${VERSION}`, { class: "version" }), item("License", "https://codeberg.org/metamuffin/keks-meet/raw/branch/master/COPYING"), item("Source code", "https://codeberg.org/metamuffin/keks-meet"), @@ -41,6 +41,7 @@ export class BottomMenu extends OverlayUi { const chat_toggle = document.createElement("input") chat_toggle.type = "button" chat_toggle.value = "Chat" + chat_toggle.ariaHasPopup = "menu" chat_toggle.onclick = () => { room.chat.shown = !room.chat.shown if (room.chat.shown) chat_toggle.classList.add("active") @@ -50,6 +51,7 @@ export class BottomMenu extends OverlayUi { const prefs_button = document.createElement("input") prefs_button.type = "button" prefs_button.value = "Settings" + prefs_button.ariaHasPopup = "menu" const prefs = new PrefUi() prefs_button.onclick = () => { @@ -58,13 +60,13 @@ export class BottomMenu extends OverlayUi { else prefs_button.classList.remove("active") } - const local_controls = ediv({ class: "local-controls" }, + const local_controls = ediv({ class: "local-controls", aria_label: "local resources" }, ebutton("Microphone", { onclick: () => room.local_user.await_add_resource(create_mic_res()) }), ebutton("Camera", { onclick: () => room.local_user.await_add_resource(create_camera_res()) }), ebutton("Screen", { onclick: () => room.local_user.await_add_resource(create_screencast_res()) }), ebutton("File", { onclick: () => room.local_user.await_add_resource(create_file_res()) }), ) - super(ediv({ class: "bottom-menu" }, chat_toggle, prefs_button, local_controls)) + super(enav({ class: "bottom-menu" }, chat_toggle, prefs_button, local_controls)) } } diff --git a/client-web/source/preferences/ui.ts b/client-web/source/preferences/ui.ts index bc0d123..2b1d0c7 100644 --- a/client-web/source/preferences/ui.ts +++ b/client-web/source/preferences/ui.ts @@ -5,7 +5,7 @@ */ /// <reference lib="dom" /> -import { ebr, ebutton, ediv, elabel, espan, etd, etr, OverlayUi } from "../helper.ts"; +import { ebr, ebutton, ediv, eh2, elabel, espan, etd, etr, OverlayUi } from "../helper.ts"; import { PREF_DECLS } from "./decl.ts"; import { change_pref, on_pref_changed, PrefDecl, PREFS } from "./mod.ts"; @@ -65,7 +65,7 @@ export class PrefUi extends OverlayUi { if (decl.default === undefined || decl.optional) { const use_opt = document.createElement("input") use_opt.type = "checkbox" - use_opt.id = id + use_opt.id = "enable-" + id use_opt.checked = PREFS[key] !== undefined if (prim_control) prim_control.disabled = !use_opt.checked use_opt.onchange = () => { @@ -79,10 +79,10 @@ export class PrefUi extends OverlayUi { use_opt_ = use_opt; } - const label = elabel(decl.description ?? `[${key}]`, { id }) + const label = elabel(decl.description ?? `[${key}]`, { for: id }) return etr({ class: "pref" }, etd({}, label), etd({}, use_opt_ ?? ""), etd({}, prim_control ?? "")) }) - + const notification_perm = Notification.permission == "granted" ? ediv() : ediv({}, espan("For keks-meet to send notifications, it needs you to grant permission: "), ebutton("Grant", { onclick: () => Notification.requestPermission() }), @@ -95,7 +95,6 @@ export class PrefUi extends OverlayUi { const table = document.createElement("table") table.append(...rows) - super(ediv({ class: "prefs-overlay" }, notification_perm, reset, ebr(), table)) + super(ediv({ class: "prefs-overlay" }, eh2("Settings"), notification_perm, ebr(), table, ebr(), reset)) } - } |