| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import Combine from "./Combine" | 
					
						
							|  |  |  | import BaseUIElement from "../BaseUIElement" | 
					
						
							|  |  |  | import Title from "./Title" | 
					
						
							|  |  |  | import Table from "./Table" | 
					
						
							|  |  |  | import { UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							|  |  |  | import { VariableUiElement } from "./VariableUIElement" | 
					
						
							| 
									
										
										
										
											2022-12-28 00:37:48 +01:00
										 |  |  | import { Translation } from "../i18n/Translation" | 
					
						
							|  |  |  | import { FixedUiElement } from "./FixedUiElement" | 
					
						
							| 
									
										
										
										
											2023-01-11 01:37:44 +01:00
										 |  |  | import Translations from "../i18n/Translations" | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | export default class Hotkeys { | 
					
						
							|  |  |  |     private static readonly _docs: UIEventSource< | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean } | 
					
						
							| 
									
										
										
										
											2022-12-28 00:37:48 +01:00
										 |  |  |             documentation: string | Translation | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |         }[] | 
					
						
							|  |  |  |     > = new UIEventSource< | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean } | 
					
						
							| 
									
										
										
										
											2022-12-28 00:37:48 +01:00
										 |  |  |             documentation: string | Translation | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |         }[] | 
					
						
							|  |  |  |     >([]) | 
					
						
							| 
									
										
										
										
											2022-12-24 16:08:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private static textElementSelected(): boolean { | 
					
						
							| 
									
										
										
										
											2022-12-30 15:51:18 +01:00
										 |  |  |         return ["input", "textarea"].includes(document?.activeElement?.tagName?.toLowerCase()) | 
					
						
							| 
									
										
										
										
											2022-12-24 16:08:08 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |     public static RegisterHotkey( | 
					
						
							|  |  |  |         key: ( | 
					
						
							|  |  |  |             | { | 
					
						
							|  |  |  |                   ctrl: string | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             | { | 
					
						
							|  |  |  |                   shift: string | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             | { | 
					
						
							|  |  |  |                   alt: string | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             | { | 
					
						
							|  |  |  |                   nomod: string | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |         ) & { | 
					
						
							|  |  |  |             onUp?: boolean | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2022-12-28 00:37:48 +01:00
										 |  |  |         documentation: string | Translation, | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |         action: () => void | 
					
						
							|  |  |  |     ) { | 
					
						
							|  |  |  |         const type = key["onUp"] ? "keyup" : "keypress" | 
					
						
							|  |  |  |         let keycode: string = key["ctrl"] ?? key["shift"] ?? key["alt"] ?? key["nomod"] | 
					
						
							|  |  |  |         if (keycode.length == 1) { | 
					
						
							|  |  |  |             keycode = keycode.toLowerCase() | 
					
						
							|  |  |  |             if (key["shift"] !== undefined) { | 
					
						
							|  |  |  |                 keycode = keycode.toUpperCase() | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this._docs.data.push({ key, documentation }) | 
					
						
							|  |  |  |         this._docs.ping() | 
					
						
							|  |  |  |         if (Utils.runningFromConsole) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (key["ctrl"] !== undefined) { | 
					
						
							|  |  |  |             document.addEventListener("keydown", function (event) { | 
					
						
							|  |  |  |                 if (event.ctrlKey && event.key === keycode) { | 
					
						
							|  |  |  |                     action() | 
					
						
							|  |  |  |                     event.preventDefault() | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } else if (key["shift"] !== undefined) { | 
					
						
							|  |  |  |             document.addEventListener(type, function (event) { | 
					
						
							| 
									
										
										
										
											2022-12-24 16:08:08 +01:00
										 |  |  |                 if (Hotkeys.textElementSelected()) { | 
					
						
							|  |  |  |                     // A text element is selected, we don't do anything special
 | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |                 if (event.shiftKey && event.key === keycode) { | 
					
						
							|  |  |  |                     action() | 
					
						
							|  |  |  |                     event.preventDefault() | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } else if (key["alt"] !== undefined) { | 
					
						
							|  |  |  |             document.addEventListener(type, function (event) { | 
					
						
							|  |  |  |                 if (event.altKey && event.key === keycode) { | 
					
						
							|  |  |  |                     action() | 
					
						
							|  |  |  |                     event.preventDefault() | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } else if (key["nomod"] !== undefined) { | 
					
						
							|  |  |  |             document.addEventListener(type, function (event) { | 
					
						
							| 
									
										
										
										
											2022-12-24 16:08:08 +01:00
										 |  |  |                 if (Hotkeys.textElementSelected()) { | 
					
						
							|  |  |  |                     // A text element is selected, we don't do anything special
 | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |                 if (event.key === keycode) { | 
					
						
							|  |  |  |                     action() | 
					
						
							|  |  |  |                     event.preventDefault() | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static generateDocumentation(): BaseUIElement { | 
					
						
							| 
									
										
										
										
											2022-12-28 00:37:48 +01:00
										 |  |  |         const byKey: [string, string | Translation][] = Hotkeys._docs.data | 
					
						
							|  |  |  |             .map(({ key, documentation }) => { | 
					
						
							|  |  |  |                 const modifiers = Object.keys(key).filter((k) => k !== "nomod" && k !== "onUp") | 
					
						
							|  |  |  |                 const keycode: string = key["ctrl"] ?? key["shift"] ?? key["alt"] ?? key["nomod"] | 
					
						
							|  |  |  |                 modifiers.push(keycode) | 
					
						
							|  |  |  |                 return <[string, string | Translation]>[modifiers.join("+"), documentation] | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             .sort() | 
					
						
							| 
									
										
										
										
											2023-01-11 01:37:44 +01:00
										 |  |  |         const t = Translations.t.hotkeyDocumentation | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |         return new Combine([ | 
					
						
							| 
									
										
										
										
											2023-01-11 01:37:44 +01:00
										 |  |  |             new Title(t.title, 1), | 
					
						
							|  |  |  |             t.intro, | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |             new Table( | 
					
						
							| 
									
										
										
										
											2023-01-11 01:37:44 +01:00
										 |  |  |                 [t.key, t.action], | 
					
						
							| 
									
										
										
										
											2022-12-28 00:37:48 +01:00
										 |  |  |                 byKey.map(([key, doc]) => { | 
					
						
							|  |  |  |                     return [new FixedUiElement(key).SetClass("code"), doc] | 
					
						
							|  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2022-12-24 03:44:21 +01:00
										 |  |  |             ), | 
					
						
							|  |  |  |         ]) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static generateDocumentationDynamic(): BaseUIElement { | 
					
						
							|  |  |  |         return new VariableUiElement(Hotkeys._docs.map((_) => Hotkeys.generateDocumentation())) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |