From 607934e74ffabc1dcce72b29fc28e92a669e54ce Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 16 Oct 2026 16:41:51 +0200 Subject: feat(assistant): the Do row of file operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conversions, extraction, merge and compression on the staged files from the file state, one at a time, with Stop; Compress… opens its formats. To .md goes through the daemon's write, the rest through fileops. The card keeps the result line, Saved name with Open and Folder, or the error, so another operation can follow on the same files. Results land in Documents/Assistant. Co-Authored-By: Claude Opus 5.5 --- desktop/assistant/Ops.js | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 desktop/assistant/Ops.js (limited to 'desktop/assistant/Ops.js') diff --git a/desktop/assistant/Ops.js b/desktop/assistant/Ops.js new file mode 100644 index 0000000..e59560d --- /dev/null +++ b/desktop/assistant/Ops.js @@ -0,0 +1,53 @@ +// Copyright (C) 2026 Danilo M. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +.pragma library + +// The file state's Do row. op is a fileops operation, or "md" for the +// daemon's write, or "compress", which opens the COMPRESS formats. kinds +// lists the staged kinds it fits ("any" fits every mix); min is the number +// of files it needs; format is the suffix a file already has when the +// operation would not change it. +const OPS = [ + { label: "To .md", op: "md", kinds: ["pdf"] }, + { label: "To images", op: "pdf-images", kinds: ["pdf"] }, + { label: "Merge", op: "pdf-merge", kinds: ["pdf"], min: 2 }, + { label: "Extract audio", op: "audio", kinds: ["video"] }, + { label: "To MP4", op: "mp4", kinds: ["video"], format: [".mp4"] }, + { label: "To WebM", op: "webm", kinds: ["video"], format: [".webm"] }, + { label: "To GIF", op: "gif", kinds: ["video"] }, + { label: "Trackcrop", op: "trackcrop", kinds: ["video"] }, + { label: "To PNG", op: "png", kinds: ["image"], format: [".png"] }, + { label: "To JPEG", op: "jpeg", kinds: ["image"], format: [".jpg", ".jpeg"] }, + { label: "To WebP", op: "webp", kinds: ["image"], format: [".webp"] }, + { label: "Resize 50%", op: "half", kinds: ["image"] }, + { label: "Extract", op: "extract", kinds: ["archive"] }, + { label: "Compress…", op: "compress", kinds: ["any"] }, +]; + +const COMPRESS = [ + { label: ".zip", op: "zip" }, + { label: ".tar.gz", op: "tgz" }, + { label: ".tar.xz", op: "txz" }, + { label: ".tar.bz2", op: "tbz2" }, +]; + +function ext(name) { + const n = name.toLowerCase(), dot = n.lastIndexOf("."); + return dot > 0 ? n.slice(dot) : ""; +} + +function offered(files) { + if (!files.length) return []; + return OPS.filter(o => (o.kinds.includes("any") || files.every(f => o.kinds.includes(f.kind))) + && files.length >= (o.min ?? 1) + && !(o.format && files.every(f => o.format.includes(ext(f.name))))); +} -- cgit v1.2.3