import { html } from "lit"; import { customElement, property } from "lit/decorators.js"; import { translateText } from "./Utils"; import { BaseModal } from "./components/BaseModal"; import "./components/baseComponents/Modal"; import { modalHeader } from "./components/ui/ModalHeader"; import { collectGraphicsDiagnostics, GraphicsDiagnostics, } from "./utilities/Diagnostic"; import infoIcon from "/images/InfoIcon.svg?url"; @customElement("troubleshooting-modal") export class TroubleshootingModal extends BaseModal { @property({ type: String }) markdown = "Loading..."; @property({ type: Object }) diagnostics?: GraphicsDiagnostics; @property({ type: Boolean }) loading = true; private initialized: boolean = false; private async loadDiagnostics() { const canvas = document.createElement("canvas"); this.diagnostics = await collectGraphicsDiagnostics(canvas); this.loading = false; this.initialized = true; } render() { const content = html`
${modalHeader({ titleContent: html`
${translateText("main.help")} / ${translateText("troubleshooting.title")}
`, onBack: () => this.close(), ariaLabel: translateText("common.back"), })} ${this.loading ? "" : html`
${this.section( "", html`${this.infoTip( translateText("troubleshooting.hardware_acceleration_tip"), true, )}`, )} ${this.section( translateText("troubleshooting.environment"), html` ${this.row( translateText("troubleshooting.browser"), this.diagnostics!.browser.engine, )} ${this.row( translateText("troubleshooting.platform"), this.diagnostics!.browser.platform, )} ${this.row( translateText("troubleshooting.os"), this.diagnostics!.browser.os, )} ${this.row( translateText("troubleshooting.device_pixel_ratio"), this.diagnostics!.browser.dpr, )} ${this.infoTip( translateText("troubleshooting.chromium_tip"), )} `, )} ${this.section( translateText("troubleshooting.rendering"), html` ${this.row( translateText("troubleshooting.renderer"), this.describeRenderer(this.diagnostics!.rendering), )} ${this.row( translateText("troubleshooting.max_texture_size"), this.diagnostics!.rendering.maxTextureSize ?? translateText("troubleshooting.unknown"), )} ${this.row( translateText("troubleshooting.high_precision_shaders"), this.diagnostics!.rendering.shaderHighp === true ? translateText("troubleshooting.yes") : translateText("troubleshooting.no"), )}${this.row( translateText("troubleshooting.gpu"), !this.diagnostics!.rendering.gpu || this.diagnostics!.rendering.gpu.unavailable ? translateText("troubleshooting.unavailable") : `${this.diagnostics!.rendering.gpu.vendor} — ${this.diagnostics!.rendering.gpu.renderer}`, )} ${this.infoTip(translateText("troubleshooting.gpu_tip"))} `, )} ${this.section( translateText("troubleshooting.power"), html` ${this.diagnostics!.power.unavailable ? this.row( translateText("troubleshooting.battery"), translateText("troubleshooting.unavailable"), ) : html` ${this.row( translateText("troubleshooting.charging"), this.diagnostics!.power.charging ? translateText("troubleshooting.yes") : translateText("troubleshooting.no"), )} ${this.row( translateText("troubleshooting.battery_level"), this.diagnostics!.power.level, )} `} ${this.infoTip( translateText("troubleshooting.power_saving_tip"), )} `, )}
`}
`; if (this.inline) { return content; } return html` ${content} `; } private infoTip(text: string, warning?: boolean): unknown { return html`
${text}
`; } protected onOpen(): void { if (!this.initialized) { this.initialized = true; this.loadDiagnostics(); } } private section(title: string, content: unknown) { return html`

${title}

${content}
`; } private row(label: string, value: unknown) { return html`
${label} ${value}
`; } private async copyDiagnostics() { if (!this.diagnostics) return; const formatted = "```json\n" + JSON.stringify(this.diagnostics, null, 2) + "\n```"; await navigator.clipboard.writeText(formatted); window.dispatchEvent( new CustomEvent("show-message", { detail: { message: html`${translateText("troubleshooting.copied_to_clipboard")}`, type: "info", duration: 3000, }, }), ); } private describeRenderer(rendering: any): string { if (rendering.gpu?.software) { return translateText("troubleshooting.software_rendering"); } if (rendering.type === "Canvas2D") { return translateText("troubleshooting.canvas_2d_no_gpu"); } return `${rendering.type}`; } public close(): void { this.unregisterEscapeHandler(); if (this.inline) { this.style.pointerEvents = "none"; if (window.showPage) { window.showPage?.("page-help"); } } else { this.modalEl?.close(); } } }