Better implementation of PPT and key listener.
parent
69b4730bd8
commit
f37b918a5b
|
@ -5,22 +5,59 @@ namespace ppt {
|
|||
KEY_TYPED
|
||||
}
|
||||
|
||||
export interface KeyEvent {
|
||||
export enum SpecialKey {
|
||||
CTRL,
|
||||
WINDOWS,
|
||||
SHIFT,
|
||||
ALT
|
||||
}
|
||||
|
||||
export interface KeyDescriptor {
|
||||
key_code: string;
|
||||
|
||||
key_ctrl: boolean;
|
||||
key_windows: boolean;
|
||||
key_shift: boolean;
|
||||
key_alt: boolean;
|
||||
}
|
||||
|
||||
export interface KeyEvent extends KeyDescriptor {
|
||||
readonly type: EventType;
|
||||
|
||||
readonly key: string;
|
||||
readonly key_code: string;
|
||||
}
|
||||
|
||||
readonly key_ctrl: boolean;
|
||||
readonly key_windows: boolean;
|
||||
readonly key_shift: boolean;
|
||||
readonly key_alt: boolean;
|
||||
export interface KeyHook extends KeyDescriptor {
|
||||
cancel: boolean;
|
||||
|
||||
|
||||
callback_press: () => any;
|
||||
callback_release: () => any;
|
||||
}
|
||||
|
||||
export function key_description(key: KeyDescriptor) {
|
||||
let result = "";
|
||||
if(key.key_shift)
|
||||
result += " + Shift";
|
||||
if(key.key_alt)
|
||||
result += " + Alt";
|
||||
if(key.key_ctrl)
|
||||
result += " + CTRL";
|
||||
if(key.key_windows)
|
||||
result += " + Win";
|
||||
|
||||
result += " + " + (key.key_code ? key.key_code : "unset");
|
||||
return result.substr(3);
|
||||
}
|
||||
|
||||
export declare function initialize() : Promise<void>;
|
||||
export declare function finalize(); /* most the times not really required */
|
||||
|
||||
export declare function register_key_hook(callback: (event: KeyEvent) => any, cancel: boolean);
|
||||
export declare function unregister_key_hook(callback: (event: KeyEvent) => any);
|
||||
export declare function register_key_listener(listener: (_: KeyEvent) => any);
|
||||
export declare function unregister_key_listener(listener: (_: KeyEvent) => any);
|
||||
|
||||
export declare function register_key_hook(hook: KeyHook);
|
||||
export declare function unregister_key_hook(hook: KeyHook);
|
||||
|
||||
export declare function key_pressed(code: string | SpecialKey) : boolean;
|
||||
}
|
|
@ -122,6 +122,7 @@ function loadDebug() {
|
|||
console.log("Adding browser audio player");
|
||||
custom_scripts.push(["js/audio/AudioPlayer.js"]);
|
||||
custom_scripts.push(["js/audio/WebCodec.js"]);
|
||||
custom_scripts.push(["js/WebPPTListener.js"]);
|
||||
}
|
||||
|
||||
load_wait_scripts([
|
||||
|
@ -186,6 +187,7 @@ function loadDebug() {
|
|||
"js/chat.js",
|
||||
"js/Identity.js",
|
||||
|
||||
"js/PPTListener.js",
|
||||
...custom_scripts
|
||||
]).then(() => load_wait_scripts([
|
||||
"js/codec/CodecWrapperWorker.js"
|
||||
|
|
|
@ -135,6 +135,11 @@ function main() {
|
|||
}
|
||||
}
|
||||
|
||||
ppt.initialize().catch(error => {
|
||||
console.error("Failed to initialize ppt!");
|
||||
//TODO error notification?
|
||||
});
|
||||
|
||||
/*
|
||||
let tag = $("#tmpl_music_frame").renderTag({
|
||||
//thumbnail: "img/loading_image.svg"
|
||||
|
|
|
@ -29,7 +29,7 @@ class StaticSettings {
|
|||
if (typeof input === "string") return input as string;
|
||||
else if (typeof input === "number") return input.toString();
|
||||
else if (typeof input === "boolean") return input ? "1" : "0";
|
||||
else if (typeof input == "undefined") return undefined;
|
||||
else if (typeof input === "undefined") return undefined;
|
||||
return JSON.stringify(input);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
/// <reference path="../../voice/AudioController.ts" />
|
||||
|
||||
namespace Modals {
|
||||
import set = Reflect.set;
|
||||
|
||||
export function spawnSettingsModal() {
|
||||
let modal;
|
||||
modal = createModal({
|
||||
|
@ -59,8 +57,10 @@ namespace Modals {
|
|||
|
||||
switch (select.value) {
|
||||
case "ppt":
|
||||
let keyCode: number = parseInt(settings.global("vad_ppt_key", String.fromCharCode(JQuery.Key.T)));
|
||||
vad_tag.find(".vat_ppt_key").text(String.fromCharCode(keyCode));
|
||||
let ppt_settings: PPTKeySettings = settings.global('vad_ppt_settings', undefined);
|
||||
ppt_settings = ppt_settings ? JSON.parse(ppt_settings as any as string) : {};
|
||||
|
||||
vad_tag.find(".vat_ppt_key").text(ppt.key_description(ppt_settings));
|
||||
break;
|
||||
case "vad":
|
||||
let slider = vad_tag.find(".vad_vad_slider");
|
||||
|
@ -88,13 +88,25 @@ namespace Modals {
|
|||
},
|
||||
footer: ""
|
||||
});
|
||||
$(document).one("keypress", function (e) {
|
||||
console.log("Got key " + e.keyCode);
|
||||
modal.close();
|
||||
settings.changeGlobal("vad_ppt_key", e.keyCode.toString());
|
||||
globalClient.voiceConnection.voiceRecorder.reinitialiseVAD();
|
||||
vad_tag.find(".vat_ppt_key").text(String.fromCharCode(e.keyCode));
|
||||
});
|
||||
|
||||
let listener = (event: ppt.KeyEvent) => {
|
||||
if(event.type == ppt.EventType.KEY_TYPED) {
|
||||
settings.changeGlobal('vad_ppt_key', undefined); //TODO remove that because its legacy shit
|
||||
console.log("Got key %o", event);
|
||||
|
||||
let ppt_settings: PPTKeySettings = settings.global('vad_ppt_settings', undefined);
|
||||
ppt_settings = ppt_settings ? JSON.parse(ppt_settings as any as string) : {};
|
||||
Object.assign(ppt_settings, event);
|
||||
settings.changeGlobal('vad_ppt_settings', ppt_settings);
|
||||
|
||||
globalClient.voiceConnection.voiceRecorder.reinitialiseVAD();
|
||||
|
||||
ppt.unregister_key_listener(listener);
|
||||
modal.close();
|
||||
vad_tag.find(".vat_ppt_key").text(ppt.key_description(event));
|
||||
}
|
||||
};
|
||||
ppt.register_key_listener(listener);
|
||||
modal.open();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
/// <reference path="client.ts" />
|
||||
/// <reference path="modal/ModalCreateChannel.ts" />
|
||||
|
||||
let shift_pressed = false;
|
||||
$(document).on('keyup keydown', function(e){
|
||||
shift_pressed = e.shiftKey;
|
||||
console.log(shift_pressed);
|
||||
});
|
||||
class ChannelTree {
|
||||
client: TSClient;
|
||||
htmlTree: JQuery;
|
||||
|
@ -271,8 +266,7 @@ class ChannelTree {
|
|||
}
|
||||
|
||||
onSelect(entry?: ChannelEntry | ClientEntry | ServerEntry, enforce_single?: boolean) {
|
||||
console.log(shift_pressed);
|
||||
if(this.currently_selected && shift_pressed && entry instanceof ClientEntry) { //Currently we're only supporting client multiselects :D
|
||||
if(this.currently_selected && ppt.key_pressed(ppt.SpecialKey.SHIFT) && entry instanceof ClientEntry) { //Currently we're only supporting client multiselects :D
|
||||
if(!entry) return; //Nowhere
|
||||
|
||||
if($.isArray(this.currently_selected)) {
|
||||
|
|
|
@ -120,10 +120,34 @@ class VoiceRecorder {
|
|||
reinitialiseVAD() {
|
||||
let type = settings.global("vad_type", "vad");
|
||||
if(type == "ppt") {
|
||||
let keyCode: number = parseInt(settings.global("vad_ppt_key", String.fromCharCode(JQuery.Key.T)));
|
||||
if(settings.global('vad_ppt_key', undefined)) {
|
||||
//TODO remove that because its legacy shit
|
||||
createErrorModal("VAD changed!", "VAD key detection changed.<br>Please reset your PPT key!").open();
|
||||
}
|
||||
let ppt_settings: PPTKeySettings = settings.global('vad_ppt_settings', undefined);
|
||||
ppt_settings = ppt_settings ? JSON.parse(ppt_settings as any as string) : {};
|
||||
|
||||
if(ppt_settings.version === undefined)
|
||||
ppt_settings.version = 1;
|
||||
|
||||
if(ppt_settings.key_code === undefined)
|
||||
ppt_settings.key_code = "KeyT";
|
||||
|
||||
if(ppt_settings.key_ctrl === undefined)
|
||||
ppt_settings.key_ctrl = false;
|
||||
|
||||
if(ppt_settings.key_shift === undefined)
|
||||
ppt_settings.key_shift = false;
|
||||
|
||||
if(ppt_settings.key_alt === undefined)
|
||||
ppt_settings.key_alt = false;
|
||||
|
||||
if(ppt_settings.key_windows === undefined)
|
||||
ppt_settings.key_windows = false;
|
||||
|
||||
if(!(this.getVADHandler() instanceof PushToTalkVAD))
|
||||
this.setVADHandler(new PushToTalkVAD(keyCode));
|
||||
else (this.getVADHandler() as PushToTalkVAD).key = keyCode;
|
||||
this.setVADHandler(new PushToTalkVAD(ppt_settings));
|
||||
else (this.getVADHandler() as PushToTalkVAD).key = ppt_settings;
|
||||
} else if(type == "pt") {
|
||||
if(!(this.getVADHandler() instanceof PassThroughVAD))
|
||||
this.setVADHandler(new PassThroughVAD());
|
||||
|
@ -298,35 +322,36 @@ class VoiceActivityDetectorVAD extends VoiceActivityDetector {
|
|||
}
|
||||
}
|
||||
|
||||
interface PPTKeySettings extends ppt.KeyDescriptor{
|
||||
version?: number;
|
||||
}
|
||||
|
||||
class PushToTalkVAD extends VoiceActivityDetector {
|
||||
private _key: number;
|
||||
private _key: ppt.KeyDescriptor;
|
||||
private _key_hook: ppt.KeyHook;
|
||||
|
||||
private _pushed: boolean = false;
|
||||
private _evListenerDown = (e: KeyboardEvent) => {
|
||||
//console.log("Down -> " + e.key + " -> " + e.keyCode);
|
||||
if(e.key == String.fromCharCode(this._key))
|
||||
this.pushed = true;
|
||||
};
|
||||
|
||||
private _evListenerUp = e => {
|
||||
if(e.key == String.fromCharCode(this._key))
|
||||
this.pushed = false;
|
||||
};
|
||||
|
||||
constructor(key: any) {
|
||||
constructor(key: ppt.KeyDescriptor) {
|
||||
super();
|
||||
this._key = key;
|
||||
this._key_hook = {
|
||||
callback_release: () => this._pushed = false,
|
||||
callback_press: () => this._pushed = true,
|
||||
|
||||
cancel: false
|
||||
} as ppt.KeyHook;
|
||||
Object.assign(this._key_hook, this._key);
|
||||
}
|
||||
|
||||
|
||||
initialise() {
|
||||
document.addEventListener("keydown", this._evListenerDown);
|
||||
document.addEventListener("keyup", this._evListenerUp);
|
||||
ppt.register_key_hook(this._key_hook);
|
||||
return super.initialise();
|
||||
}
|
||||
|
||||
finalize() {
|
||||
document.removeEventListener("keydown", this._evListenerDown);
|
||||
document.removeEventListener("keyup", this._evListenerUp);
|
||||
ppt.unregister_key_hook(this._key_hook);
|
||||
return super.finalize();
|
||||
}
|
||||
|
||||
|
@ -334,8 +359,8 @@ class PushToTalkVAD extends VoiceActivityDetector {
|
|||
this._pushed = flag;
|
||||
}
|
||||
|
||||
set key(key: number) {
|
||||
this._key = key;
|
||||
set key(key: ppt.KeyDescriptor) {
|
||||
Object.assign(this._key_hook, this._key);
|
||||
this._pushed = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,12 @@
|
|||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"js/workers",
|
||||
"shared/js/workers",
|
||||
"shared/declarations/**/*.d.ts",
|
||||
"shared/generated",
|
||||
"web/declarations/**/*.d.ts",
|
||||
"web/generated/",
|
||||
"web/environment/",
|
||||
"vendor/**/*.ts"
|
||||
]
|
||||
}
|
|
@ -1,13 +1,133 @@
|
|||
/// <reference path="../declarations/imports_shared.d.ts"/>
|
||||
|
||||
namespace ppt {
|
||||
interface WebKeyEvent extends KeyEvent {
|
||||
canceled: boolean;
|
||||
}
|
||||
|
||||
let key_listener: ((_: KeyEvent) => any)[] = [];
|
||||
|
||||
function listener_key(type: EventType, event: KeyboardEvent) {
|
||||
const key_event = {
|
||||
type: type,
|
||||
|
||||
key: event.key,
|
||||
key_code: event.code,
|
||||
|
||||
key_ctrl: event.ctrlKey,
|
||||
key_shift: event.shiftKey,
|
||||
key_alt: event.altKey,
|
||||
key_windows: event.metaKey,
|
||||
|
||||
canceled: event.defaultPrevented
|
||||
} as WebKeyEvent;
|
||||
//console.debug("Trigger key event %o", key_event);
|
||||
|
||||
for(const listener of key_listener)
|
||||
listener(key_event);
|
||||
|
||||
if(key_event.canceled)
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
const proxy_key_press = event => listener_key(EventType.KEY_PRESS, event);
|
||||
const proxy_key_release = event => listener_key(EventType.KEY_RELEASE, event);
|
||||
const proxy_key_typed = event => listener_key(EventType.KEY_TYPED, event);
|
||||
|
||||
export function initialize() : Promise<void> {
|
||||
document.addEventListener('keypress', proxy_key_typed);
|
||||
document.addEventListener('keydown', proxy_key_press);
|
||||
document.addEventListener('keyup', proxy_key_release);
|
||||
|
||||
register_key_listener(listener_hook);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
export function finalize() {}
|
||||
export function finalize() {
|
||||
document.removeEventListener("keypress", proxy_key_typed);
|
||||
document.removeEventListener("keydown", proxy_key_press);
|
||||
document.removeEventListener("keyup", proxy_key_release);
|
||||
|
||||
export function register_key_hook(callback: (event: KeyEvent) => any, cancel: boolean) {}
|
||||
export function unregister_key_hook(callback: (event: KeyEvent) => any) {}
|
||||
unregister_key_listener(listener_hook);
|
||||
}
|
||||
|
||||
export function register_key_listener(listener: (_: KeyEvent) => any) {
|
||||
key_listener.push(listener);
|
||||
}
|
||||
|
||||
export function unregister_key_listener(listener: (_: KeyEvent) => any) {
|
||||
key_listener.remove(listener);
|
||||
}
|
||||
|
||||
|
||||
let key_hooks: KeyHook[] = [];
|
||||
|
||||
interface CurrentState {
|
||||
event: KeyEvent;
|
||||
code: string;
|
||||
|
||||
special: { [key:number]:boolean };
|
||||
}
|
||||
let current_state: CurrentState = {
|
||||
special: []
|
||||
} as any;
|
||||
|
||||
let key_hooks_active: KeyHook[] = [];
|
||||
|
||||
function listener_hook(event: KeyEvent) {
|
||||
if(event.type == EventType.KEY_TYPED)
|
||||
return;
|
||||
|
||||
let old_hooks = [...key_hooks_active];
|
||||
let new_hooks = [];
|
||||
|
||||
current_state.special[SpecialKey.ALT] = event.key_alt;
|
||||
current_state.special[SpecialKey.CTRL] = event.key_ctrl;
|
||||
current_state.special[SpecialKey.SHIFT] = event.key_shift;
|
||||
current_state.special[SpecialKey.WINDOWS] = event.key_windows;
|
||||
|
||||
current_state.code = undefined;
|
||||
current_state.event = undefined;
|
||||
|
||||
if(event.type == EventType.KEY_PRESS) {
|
||||
current_state.event = event;
|
||||
current_state.code = event.key_code;
|
||||
|
||||
for(const hook of key_hooks) {
|
||||
if(hook.key_code != event.key_code) continue;
|
||||
if(hook.key_alt != event.key_alt) continue;
|
||||
if(hook.key_ctrl != event.key_ctrl) continue;
|
||||
if(hook.key_shift != event.key_shift) continue;
|
||||
if(hook.key_windows != event.key_windows) continue;
|
||||
|
||||
new_hooks.push(hook);
|
||||
if(!old_hooks.remove(hook) && hook.callback_press) {
|
||||
hook.callback_press();
|
||||
console.debug("Trigger key press for %o!", hook);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//We have a new situation
|
||||
for(const hook of old_hooks)
|
||||
if(hook.callback_release) {
|
||||
hook.callback_release();
|
||||
console.debug("Trigger key release for %o!", hook);
|
||||
}
|
||||
key_hooks_active = new_hooks;
|
||||
}
|
||||
|
||||
export function register_key_hook(hook: KeyHook) {
|
||||
key_hooks.push(hook);
|
||||
}
|
||||
|
||||
export function unregister_key_hook(hook: KeyHook) {
|
||||
key_hooks.remove(hook);
|
||||
}
|
||||
|
||||
export function key_pressed(code: string | SpecialKey) : boolean {
|
||||
if(typeof(code) === 'string')
|
||||
return current_state.code == code;
|
||||
return current_state.special[code];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue