|
// retoor <retoor@molodetz.nl>
|
|
|
|
import { Http } from "./Http.js";
|
|
import "./devii/devii-avatar.js";
|
|
import "./devii/devii-terminal.js";
|
|
|
|
export class DeviiTerminal {
|
|
constructor() {
|
|
this.element = null;
|
|
this.avatar = null;
|
|
this.bindEscapeTrigger();
|
|
this.ready = this.init();
|
|
}
|
|
|
|
async init() {
|
|
try {
|
|
await Http.getJson("/devii/session");
|
|
} catch (error) {
|
|
return;
|
|
}
|
|
|
|
this.avatar = document.createElement("devii-avatar");
|
|
this.avatar.id = "devii";
|
|
this.avatar.setAttribute("character", "Clippy");
|
|
document.body.appendChild(this.avatar);
|
|
|
|
this.element = document.createElement("devii-terminal");
|
|
this.element.setAttribute("avatar", "devii");
|
|
document.body.appendChild(this.element);
|
|
|
|
this.bindTriggers();
|
|
}
|
|
|
|
bindTriggers() {
|
|
document.querySelectorAll("[data-devii-open]").forEach((trigger) => {
|
|
trigger.addEventListener("click", (event) => {
|
|
event.preventDefault();
|
|
this.open();
|
|
});
|
|
});
|
|
const stored = this.element && this.element.hasStoredState && this.element.hasStoredState();
|
|
if (document.querySelector("[data-devii-autoopen]") && !stored) {
|
|
this.open();
|
|
}
|
|
}
|
|
|
|
bindEscapeTrigger() {
|
|
document.addEventListener(
|
|
"keydown",
|
|
(event) => {
|
|
if (event.key !== "Escape" || event.repeat) return;
|
|
if (this._canTriggerOnEscape()) this.open();
|
|
},
|
|
true,
|
|
);
|
|
}
|
|
|
|
_canTriggerOnEscape() {
|
|
if (this.element && this.element.state !== "closed") return false;
|
|
if (document.querySelector(".modal-overlay.visible")) return false;
|
|
if (document.querySelector(".dialog-overlay.visible")) return false;
|
|
if (document.querySelector(".context-menu.visible")) return false;
|
|
const mobilePanel = document.getElementById("mobile-panel");
|
|
if (mobilePanel && mobilePanel.classList.contains("open")) return false;
|
|
const active = document.activeElement;
|
|
if (active) {
|
|
const editable = ["INPUT", "TEXTAREA", "SELECT"].includes(active.tagName);
|
|
if (editable || active.isContentEditable) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
async open() {
|
|
await this.ready;
|
|
if (this.element) this.element.open();
|
|
}
|
|
|
|
async close() {
|
|
await this.ready;
|
|
if (this.element) this.element.close();
|
|
}
|
|
|
|
async toggle() {
|
|
await this.ready;
|
|
if (this.element) this.element.toggle();
|
|
}
|
|
}
|