TeaWeb/shared/js/KeyControl.ts

207 lines
6.2 KiB
TypeScript

import {LogCategory, logError, logWarn} from "./log";
import {getKeyBoard, KeyDescriptor, KeyHook} from "./PPTListener";
import {Settings, settings} from "./settings";
import {server_connections} from "tc-shared/ConnectionManager";
import {tr} from "./i18n/localize";
export interface KeyControl {
category: string;
description: string;
handler: () => void;
icon: string;
}
export const TypeCategories: {[key: string]: { name: string }} = {
"connection": {
name: "Server connection"
},
"microphone": {
name: "Microphone"
},
"speaker": {
name: "Speaker"
},
"away": {
name: "Away"
}
};
export const KeyTypes: {[key: string]:KeyControl} = {
"disconnect-current": {
category: "connection",
description: "Disconnect from the current server",
handler: () => server_connections.getActiveConnectionHandler()?.disconnectFromServer(),
icon: "client-disconnect"
},
"disconnect-all": {
category: "connection",
description: "Disconnect from all connected servers",
handler: () => server_connections.getAllConnectionHandlers().forEach(e => e.disconnectFromServer()),
icon: "client-disconnect"
},
"toggle-microphone": {
category: "microphone",
description: "Toggle your microphone status",
handler: () => server_connections.getActiveConnectionHandler()?.toggleMicrophone(),
icon: "client-input_muted"
},
"enable-microphone": {
category: "microphone",
description: "Enable your microphone",
handler: () => server_connections.getActiveConnectionHandler()?.setMicrophoneMuted(false),
icon: "client-input_muted"
},
"disable-microphone": {
category: "microphone",
description: "Disable your microphone",
handler: () => server_connections.getActiveConnectionHandler()?.setMicrophoneMuted(true),
icon: "client-input_muted"
},
"toggle-speaker": {
category: "speaker",
description: "Toggle your speaker status",
handler: () => server_connections.getActiveConnectionHandler()?.toggleSpeakerMuted(),
icon: "client-output_muted"
},
"enable-speaker": {
category: "speaker",
description: "Enable your speakers",
handler: () => server_connections.getActiveConnectionHandler()?.setSpeakerMuted(false),
icon: "client-output_muted"
},
"disable-speaker": {
category: "speaker",
description: "Disable your speakers",
handler: () => server_connections.getActiveConnectionHandler()?.setSpeakerMuted(true),
icon: "client-output_muted"
},
/* toggle away */
"toggle-away-state": {
category: "away",
description: "Toggle your away state",
handler: () => server_connections.getActiveConnectionHandler()?.toggleAway(),
icon: "client-away"
},
"enable-away-state": {
category: "away",
description: "Enable away for the current server",
handler: () => server_connections.getActiveConnectionHandler()?.setAway(true),
icon: "client-away"
},
"disable-away-state": {
category: "away",
description: "Disable away for the current server",
handler: () => server_connections.getActiveConnectionHandler()?.setAway(false),
icon: "client-present"
},
"toggle-away-state-globally": {
category: "away",
description: "Toggle your away state for every server",
handler: () => server_connections.getAllConnectionHandlers().forEach(e => e.toggleAway()),
icon: "client-away"
},
"enable-away-state-globally": {
category: "away",
description: "Enable away for every server",
handler: () => server_connections.getAllConnectionHandlers().forEach(e => e.setAway(true)),
icon: "client-away"
},
"disable-away-state-globally": {
category: "away",
description: "Disable away for every server",
handler: () => server_connections.getAllConnectionHandlers().forEach(e => e.setAway(false)),
icon: "client-present"
},
};
let keyBindings: {[key: string]: {
binding: KeyDescriptor,
hook: KeyHook
}} = {};
interface Config {
version?: number;
keys?: {[key: string]: KeyDescriptor};
}
let config: Config;
export function initializeKeyControl() {
let cfg: Config;
try {
cfg = JSON.parse(settings.getValue(Settings.KEY_KEYCONTROL_DATA));
} catch (e) {
logError(LogCategory.GENERAL, tr("Failed to parse old key control data."));
cfg = {};
}
if(typeof cfg.version !== "number") {
/* new config */
cfg.version = 0;
}
switch (cfg.version) {
case 0:
cfg.version = 1;
cfg.keys = {};
/* fall though wanted */
case 1:
/* config up to date */
break;
default:
logWarn(LogCategory.GENERAL, tr("Key control config has an invalid version:%o"), cfg.version);
break;
}
config = cfg;
for(const key of Object.keys(config.keys)) {
if(typeof KeyTypes[key] !== "object")
continue;
bindKey(key, config.keys[key]);
}
}
function saveConfig() {
settings.setValue(Settings.KEY_KEYCONTROL_DATA, JSON.stringify(config));
}
function bindKey(action: string, key: KeyDescriptor) {
const control = KeyTypes[action];
if(typeof control === "undefined") {
throw "missing control event";
}
keyBindings[action] = {
hook: Object.assign({
callbackPress: () => control.handler(),
callbackRelease: () => {},
cancel: false
}, key),
binding: key
};
getKeyBoard().registerHook(keyBindings[action].hook);
}
export function setKey(action: string, key?: KeyDescriptor) {
if(typeof keyBindings[action] !== "undefined") {
getKeyBoard().unregisterHook(keyBindings[action].hook);
delete keyBindings[action];
}
if(key) {
bindKey(action, key);
config.keys[action] = key;
} else {
delete config.keys[action];
}
saveConfig();
}
export function key(action: string) : KeyDescriptor | undefined { return keyBindings[action]?.binding; }