Files
devplacepy/devplacepy/static/js/components/AppContent.js
T
retoor 9a8046ab2a feat: add ISSLOP AI usage analysis CLI commands, game router, and politics topic
- Add `cmd_isslop_prune`, `cmd_isslop_clear`, `cmd_isslop_analyze` CLI commands for AI usage analysis job management
- Register `/game` router with `index` and `farm` endpoints for Code Farm idle game
- Add `politics` to allowed TOPICS constant replacing `signals`
- Introduce `ISSLOP_DIR`, `ISSLOP_WORKSPACES_DIR`, `ISSLOP_RUNS_DIR`, `ISSLOP_MEDIA_DIR` config paths
- Add `clear_user_stars` and `clear_user_projects_cache` calls on vote and project create/delete
- Update `make prod` to use `nproc` workers via `DEVPLACE_WEB_WORKERS` env var
- Convert `database.py` and `utils.py` to packages for modular structure
- Add `devplace apikey` and `devplace token` CLI subcommands for API key and access token management
2026-07-06 03:57:47 +00:00

56 lines
1.8 KiB
JavaScript

// retoor <retoor@molodetz.nl>
import { Component } from "./Component.js";
import { contentRenderer } from "../ContentRenderer.js";
export class AppContent extends Component {
connectedCallback() {
if (this._rendered) {
return;
}
if (typeof DOMPurify === "undefined" || typeof marked === "undefined") {
window.addEventListener("load", () => this.connectedCallback(), { once: true });
return;
}
if (!contentRenderer.emojiLoaded) {
contentRenderer.ready.then(() => this.connectedCallback());
return;
}
this._rendered = true;
this._source = this.textContent;
this.classList.add("rendered-content");
contentRenderer.applyTo(this);
if (typeof hljs !== "undefined") {
this.querySelectorAll("pre code").forEach((block) => hljs.highlightElement(block));
}
if (!this.hasAttribute("no-copy")) {
this.addCopyButton();
}
}
addCopyButton() {
if (!this._source || !this._source.trim()) {
return;
}
if (this.querySelector(":scope > .content-copy-btn")) {
return;
}
const btn = document.createElement("button");
btn.type = "button";
btn.className = "content-copy-btn";
btn.textContent = "Copy";
btn.addEventListener("click", async () => {
try {
await navigator.clipboard.writeText(this._source);
btn.textContent = "Copied";
} catch {
btn.textContent = "Failed";
}
setTimeout(() => { btn.textContent = "Copy"; }, 1500);
});
this.appendChild(btn);
}
}
customElements.define("dp-content", AppContent);