From f7c52d0b1ce5deb11aa95014adf444df6523740e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20B=C3=B6ttcher?= Date: Wed, 13 May 2026 15:14:31 +0200 Subject: [PATCH] feat: add CasaOS support to TerminalTyper and update related components --- frontend/app/components/TerminalTyper.tsx | 133 ++++++++++++++++++++-- frontend/app/daterup/page.tsx | 2 +- frontend/app/page.tsx | 4 +- 3 files changed, 124 insertions(+), 15 deletions(-) diff --git a/frontend/app/components/TerminalTyper.tsx b/frontend/app/components/TerminalTyper.tsx index e4ac044..f1da62b 100644 --- a/frontend/app/components/TerminalTyper.tsx +++ b/frontend/app/components/TerminalTyper.tsx @@ -104,11 +104,89 @@ function buildDaterupComposeLines(links: TerminalLinks): Line[] { ]; } -function buildLines(mode: "docker-run" | "docker-compose" | "daterup" | "daterup-compose" = "docker-run", links: TerminalLinks = {}): Line[] { +function buildCasaOsLines(links: TerminalLinks): Line[] { + const dockerImage = links.dockerImage ?? LINKS.dockerImage; + const uiPort = links.uiPort ?? LINKS.uiPort; + return [ + { type: "comment", text: "# CasaOS custom app compose — import via App Store → Custom Install" }, + { type: "output", text: "name: backerup" }, + { type: "output", text: "services:" }, + { type: "output", text: " backerup:" }, + { type: "output", text: ` image: ${dockerImage}` }, + { type: "output", text: " ports:" }, + { type: "output", text: ` - target: 80` }, + { type: "output", text: ` published: "${uiPort}"` }, + { type: "output", text: " protocol: tcp" }, + { type: "output", text: " volumes:" }, + { type: "output", text: " - /var/run/docker.sock:/var/run/docker.sock" }, + { type: "output", text: " - /DATA/AppData/backerup/backups:/backups" }, + { type: "output", text: " - /DATA/AppData/backerup/config:/app/config" }, + { type: "output", text: " environment:" }, + { type: "output", text: " - BACKUP_DIR=/backups" }, + { type: "output", text: " - BACKUP_CONFIG_DIR=/app/config" }, + { type: "output", text: " - HOST_BACKUP_DIR=/DATA/AppData/backerup/backups" }, + { type: "output", text: " restart: unless-stopped" }, + { type: "output", text: " network_mode: bridge" }, + { type: "output", text: "x-casaos:" }, + { type: "output", text: " architectures:" }, + { type: "output", text: " - amd64" }, + { type: "output", text: " - arm64" }, + { type: "output", text: " main: backerup" }, + { type: "output", text: " description:" }, + { type: "output", text: " en_us: Docker container backup — save and share configs" }, + { type: "output", text: " tagline:" }, + { type: "output", text: " en_us: Container Backup Manager" }, + { type: "output", text: " developer: DoomLabs" }, + { type: "output", text: " title:" }, + { type: "output", text: " en_us: Backerup" }, + { type: "output", text: " index: /" }, + { type: "output", text: ` port_map: "${uiPort}"` }, + { type: "success", text: "✓ Paste this into CasaOS → App Store → Custom Install" }, + ]; +} + +function buildCasaOsDaterupLines(links: TerminalLinks): Line[] { + const daterupDockerImage = links.daterupDockerImage ?? LINKS.daterupDockerImage; + return [ + { type: "comment", text: "# CasaOS custom app compose — import via App Store → Custom Install" }, + { type: "output", text: "name: daterup" }, + { type: "output", text: "services:" }, + { type: "output", text: " daterup:" }, + { type: "output", text: ` image: ${daterupDockerImage}` }, + { type: "output", text: " ports:" }, + { type: "output", text: " - target: 80" }, + { type: "output", text: " published: \"8081\"" }, + { type: "output", text: " protocol: tcp" }, + { type: "output", text: " volumes:" }, + { type: "output", text: " - /var/run/docker.sock:/var/run/docker.sock" }, + { type: "output", text: " - /DATA/AppData/daterup/config:/app/config" }, + { type: "output", text: " restart: unless-stopped" }, + { type: "output", text: " network_mode: bridge" }, + { type: "output", text: "x-casaos:" }, + { type: "output", text: " architectures:" }, + { type: "output", text: " - amd64" }, + { type: "output", text: " - arm64" }, + { type: "output", text: " main: daterup" }, + { type: "output", text: " description:" }, + { type: "output", text: " en_us: Docker container update manager — one-click image updates" }, + { type: "output", text: " tagline:" }, + { type: "output", text: " en_us: Container Update Manager" }, + { type: "output", text: " developer: DoomLabs" }, + { type: "output", text: " title:" }, + { type: "output", text: " en_us: Daterup" }, + { type: "output", text: " index: /" }, + { type: "output", text: " port_map: \"8081\"" }, + { type: "success", text: "✓ Paste this into CasaOS → App Store → Custom Install" }, + ]; +} + +function buildLines(mode: "docker-run" | "docker-compose" | "daterup" | "daterup-compose" | "casaos" | "casaos-daterup" = "docker-run", links: TerminalLinks = {}): Line[] { switch (mode) { case "docker-compose": return buildDockerComposeLines(links); case "daterup": return buildDaterupRunLines(links); case "daterup-compose": return buildDaterupComposeLines(links); + case "casaos": return buildCasaOsLines(links); + case "casaos-daterup": return buildCasaOsDaterupLines(links); default: return buildDockerRunLines(links); } } @@ -142,16 +220,23 @@ function linePrompt(line: Line): string { return ""; } -export default function TerminalTyper({ mode = "docker-run", links = {} }: { mode?: "docker-run" | "docker-compose" | "daterup" | "daterup-compose"; links?: TerminalLinks } = {}) { +export default function TerminalTyper({ mode = "docker-run", links = {}, casaosMode }: { mode?: "docker-run" | "docker-compose" | "daterup" | "daterup-compose" | "casaos" | "casaos-daterup"; links?: TerminalLinks; casaosMode?: "casaos" | "casaos-daterup" } = {}) { const LINES = buildLines(mode, links); + const CASAOS_LINES = casaosMode ? buildLines(casaosMode, links) : null; const [doneLines, setDoneLines] = useState([]); const [current, setCurrent] = useState<{ idx: number; chars: number } | null>({ idx: 0, chars: 0 }); const [copied, setCopied] = useState(false); + const [copiedCasaOs, setCopiedCasaOs] = useState(false); const copyToClipboard = () => { let textToCopy = ""; - if (mode === "docker-compose" || mode === "daterup-compose") { + if (mode === "casaos" || mode === "casaos-daterup") { + // Copy all output lines as a clean YAML file + textToCopy = LINES.filter(line => line.type === "output") + .map(line => line.text) + .join("\n"); + } else if (mode === "docker-compose" || mode === "daterup-compose") { // For docker-compose, copy the YAML content only const startIdx = LINES.findIndex(line => line.type === "output" && line.text === "services:"); const endIdx = LINES.findIndex((line, i) => i > startIdx && line.type === "output" && line.text === "EOF"); @@ -175,6 +260,17 @@ export default function TerminalTyper({ mode = "docker-run", links = {} }: { mod }); }; + const copyCasaOs = () => { + if (!CASAOS_LINES) return; + const text = CASAOS_LINES.filter(line => line.type === "output") + .map(line => line.text) + .join("\n"); + navigator.clipboard.writeText(text).then(() => { + setCopiedCasaOs(true); + setTimeout(() => setCopiedCasaOs(false), 2000); + }); + }; + useEffect(() => { if (!current) return; @@ -204,15 +300,28 @@ export default function TerminalTyper({ mode = "docker-run", links = {} }: { mod return (
- +
+ + {CASAOS_LINES && ( + + )} +
{doneLines.map((i) => { const line = LINES[i]; diff --git a/frontend/app/daterup/page.tsx b/frontend/app/daterup/page.tsx index 6abcd4c..286c254 100644 --- a/frontend/app/daterup/page.tsx +++ b/frontend/app/daterup/page.tsx @@ -513,7 +513,7 @@ export default async function DaterupPage() { docker-compose setup
- +
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index 1f2f007..405830b 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -510,7 +510,7 @@ export default async function LandingPage() { docker-compose setup
- +
@@ -583,7 +583,7 @@ export default async function LandingPage() { - {/* Daterup card */}} + {/* Daterup card */}