TeaWeb/shared/js/KeyControl.ts

207 lines
6.2 KiB
TypeScript
Raw Normal View History

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