From f5472b287fb436d82115138c7f43c727d5ccaffa Mon Sep 17 00:00:00 2001
From: "J. Doe" <253751817+strawberry-raccoon@users.noreply.github.com>
Date: Thu, 12 Feb 2026 18:59:16 +0000
Subject: [PATCH 1/3] feat: add share button to converted files
---
bun.lock | 3 +++
package.json | 1 +
public/results.js | 37 +++++++++++++++++++++++++++++++++++++
src/icons/share.tsx | 18 ++++++++++++++++++
src/pages/results.tsx | 14 ++++++++++++++
5 files changed, 73 insertions(+)
create mode 100644 src/icons/share.tsx
diff --git a/bun.lock b/bun.lock
index 56e3e6d0..543d8e49 100644
--- a/bun.lock
+++ b/bun.lock
@@ -10,6 +10,7 @@
"@elysiajs/static": "^1.4.6",
"@kitajs/html": "^4.2.11",
"elysia": "^1.4.16",
+ "mime": "^4.1.0",
"sanitize-filename": "^1.6.3",
"tar": "^7.5.2",
},
@@ -449,6 +450,8 @@
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
+ "mime": ["mime@4.1.0", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw=="],
+
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
diff --git a/package.json b/package.json
index 6aea0c44..0cd55797 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"@elysiajs/static": "^1.4.6",
"@kitajs/html": "^4.2.11",
"elysia": "^1.4.16",
+ "mime": "^4.1.0",
"sanitize-filename": "^1.6.3",
"tar": "^7.5.2"
},
diff --git a/public/results.js b/public/results.js
index 60c07eb5..43914eeb 100644
--- a/public/results.js
+++ b/public/results.js
@@ -3,6 +3,42 @@ const jobId = window.location.pathname.split("/").pop();
const main = document.querySelector("main");
let progressElem = document.querySelector("progress");
+const supportsWebShare = navigator.share && navigator.canShare;
+
+const setupShareButtons = () => {
+ if (!supportsWebShare) {
+ return;
+ }
+
+ document.querySelectorAll(".share-btn").forEach((btn) => {
+ if (btn.dataset.setupComplete) return;
+
+ const filename = btn.dataset.filename;
+ const mimeType = btn.dataset.mimeType;
+ const fileUrl = btn.dataset.downloadUrl;
+ const dummyFile = new File([], filename, { type: mimeType });
+
+ if (!navigator.canShare({ files: [dummyFile] })) {
+ return;
+ }
+ btn.addEventListener("click", async (e) => {
+ e.preventDefault();
+ try {
+ const response = await fetch(fileUrl);
+ const blob = await response.blob();
+ const file = new File([blob], filename, { type: mimeType });
+ await navigator.share({ files: [file] });
+ } catch (err) {
+ if (err.name !== "AbortError") {
+ console.error("Error sharing:", err);
+ }
+ }
+ });
+ btn.style.display = "";
+ btn.dataset.setupComplete = true;
+ });
+};
+
const refreshData = () => {
// console.log("Refreshing data...", progressElem.value, progressElem.max);
if (progressElem.value !== progressElem.max) {
@@ -12,6 +48,7 @@ const refreshData = () => {
.then((res) => res.text())
.then((html) => {
main.innerHTML = html;
+ setupShareButtons();
})
.catch((err) => console.log(err));
diff --git a/src/icons/share.tsx b/src/icons/share.tsx
new file mode 100644
index 00000000..83ec207f
--- /dev/null
+++ b/src/icons/share.tsx
@@ -0,0 +1,18 @@
+export function ShareIcon() {
+ return (
+
+ );
+}
diff --git a/src/pages/results.tsx b/src/pages/results.tsx
index a45c9051..444f7859 100644
--- a/src/pages/results.tsx
+++ b/src/pages/results.tsx
@@ -7,6 +7,8 @@ import { ALLOW_UNAUTHENTICATED, WEBROOT } from "../helpers/env";
import { DownloadIcon } from "../icons/download";
import { DeleteIcon } from "../icons/delete";
import { EyeIcon } from "../icons/eye";
+import { ShareIcon } from "../icons/share";
+import mime from "mime";
import { userService } from "./user";
function ResultsArticle({
@@ -119,6 +121,18 @@ function ResultsArticle({
>
+
))}
From de42c752e50ab050a997b7218020372f52a743a5 Mon Sep 17 00:00:00 2001
From: "J. Doe" <253751817+strawberry-raccoon@users.noreply.github.com>
Date: Fri, 6 Mar 2026 12:02:39 +0000
Subject: [PATCH 2/3] fix: share buttons not showing on complete conversions
---
public/results.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/public/results.js b/public/results.js
index 43914eeb..468195ef 100644
--- a/public/results.js
+++ b/public/results.js
@@ -58,6 +58,7 @@ const refreshData = () => {
progressElem = document.querySelector("progress");
};
+setupShareButtons();
refreshData();
window.downloadAll = function () {
From 20c1b9cf4bfa873d1c6b9627b33e805739b7147d Mon Sep 17 00:00:00 2001
From: "J. Doe" <253751817+strawberry-raccoon@users.noreply.github.com>
Date: Fri, 6 Mar 2026 12:05:18 +0000
Subject: [PATCH 3/3] chore: fix lint
---
eslint.config.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/eslint.config.ts b/eslint.config.ts
index 4eed44f5..78b333ae 100644
--- a/eslint.config.ts
+++ b/eslint.config.ts
@@ -61,6 +61,7 @@ export default tseslint.config(
"target",
"convert_to_target",
"job-details-toggle",
+ "share-btn",
],
},
],