diff --git a/.env.example b/.env.example
index 69d992c..e9d99fd 100644
--- a/.env.example
+++ b/.env.example
@@ -1,4 +1,8 @@
PUB_HOSTNAME=localhost:5173 # only gets used for plausible (for now)
PUB_PLAUSIBLE_URL=https://plausible.example.com # can be empty
PUB_ENV=development # "production", "development", or "nightly"
-PUB_VERTD_URL=https://vertd.vert.sh # default vertd instance
\ No newline at end of file
+PUB_VERTD_URL=https://vertd.vert.sh # default vertd instance
+
+# please do not change these. donations help a lot
+PUB_DONATION_URL=https://donations.vert.sh
+PUB_STRIPE_KEY=pk_live_51RDVmAGSxPVad6bQwzVNnbc28nlmzA30krLWk1fefCMpUPiSRPkavMMbGqa8A3lUaOCMlsUEVy2CWDYg0ip3aPpL00ZJlsMkf2
\ No newline at end of file
diff --git a/_headers b/_headers
deleted file mode 100644
index 2568767..0000000
--- a/_headers
+++ /dev/null
@@ -1,4 +0,0 @@
-# For libvips/wasm-vips converter (images)
-/*
- Cross-Origin-Embedder-Policy: require-corp
- Cross-Origin-Opener-Policy: same-origin
\ No newline at end of file
diff --git a/bun.lock b/bun.lock
index 98bb611..56ea25f 100644
--- a/bun.lock
+++ b/bun.lock
@@ -11,6 +11,7 @@
"@fontsource/lexend": "^5.1.2",
"@fontsource/radio-canada-big": "^5.1.1",
"@imagemagick/magick-wasm": "^0.0.34",
+ "@stripe/stripe-js": "^7.4.0",
"byte-data": "^19.0.1",
"client-zip": "^2.4.6",
"clsx": "^2.1.1",
@@ -18,10 +19,10 @@
"music-metadata": "^11.0.0",
"p-queue": "^8.1.0",
"riff-file": "^1.0.3",
+ "svelte-stripe": "^1.4.0",
"vert-wasm": "^0.0.2",
"vite-plugin-static-copy": "^2.2.0",
"vite-plugin-wasm": "^3.4.1",
- "wasm-vips": "^0.0.11",
},
"devDependencies": {
"@poppanator/sveltekit-svg": "^5.0.0",
@@ -235,6 +236,8 @@
"@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="],
+ "@stripe/stripe-js": ["@stripe/stripe-js@7.4.0", "", {}, "sha512-lQHQPfXPTBeh0XFjq6PqSBAyR7umwcJbvJhXV77uGCUDD6ymXJU/f2164ydLMLCCceNuPlbV9b+1smx98efwWQ=="],
+
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.8", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg=="],
@@ -727,6 +730,8 @@
"svelte-eslint-parser": ["svelte-eslint-parser@0.43.0", "", { "dependencies": { "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "postcss": "^8.4.39", "postcss-scss": "^4.0.9" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA=="],
+ "svelte-stripe": ["svelte-stripe@1.4.0", "", { "peerDependencies": { "@stripe/stripe-js": "^3 || ^4", "svelte": "^3 || ^4 || ^5" } }, "sha512-RUSui4IszIBXhGt3mT3pLJX17OJ34A0O+LAcZLooWVYQCAv95umVXoRB6WmjMabj3jOoJ8c3KHGufaJLRlIzRg=="],
+
"svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="],
"tailwindcss": ["tailwindcss@3.4.17", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.6", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og=="],
@@ -777,8 +782,6 @@
"vitefu": ["vitefu@1.0.6", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["vite"] }, "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA=="],
- "wasm-vips": ["wasm-vips@0.0.11", "", {}, "sha512-bzFU7WcimMY4WeqnZk7whKVpSXxpagISXPJwsk2VHF4lgIN9rl4uUo5sF9x6jOlACuCH6ITZUJ7QPTYmy60NCQ=="],
-
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
diff --git a/docker-compose.yml b/docker-compose.yml
index 13afdea..57bec0e 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -8,6 +8,8 @@ services:
- PUB_ENV=${PUB_ENV:-production}
- PORT=${PORT:-3000}
- PUB_VERTD_URL=${PUB_VERTD_URL:-https://vertd.vert.sh}
+ - PUB_DONATION_URL=${PUB_DONATION_URL:-https://donations.vert.sh}
+ - PUB_STRIPE_KEY=${PUB_STRIPE_KEY:-pk_live_51RDVmAGSxPVad6bQwzVNnbc28nlmzA30krLWk1fefCMpUPiSRPkavMMbGqa8A3lUaOCMlsUEVy2CWDYg0ip3aPpL00ZJlsMkf2}
build:
context: .
args:
@@ -15,6 +17,9 @@ services:
PUB_PLAUSIBLE_URL: ${PUB_PLAUSIBLE_URL:-https://plausible.example.com}
PUB_ENV: ${PUB_ENV:-production}
PUB_VERTD_URL: ${PUB_VERTD_URL:-https://vertd.vert.sh}
+ PUB_DONATION_URL: ${PUB_DONATION_URL:-https://donations.vert.sh}
+ PUB_STRIPE_KEY: ${PUB_STRIPE_KEY:-pk_live_51RDVmAGSxPVad6bQwzVNnbc28nlmzA30krLWk1fefCMpUPiSRPkavMMbGqa8A3lUaOCMlsUEVy2CWDYg0ip3aPpL00ZJlsMkf2}
+
restart: unless-stopped
ports:
- ${PORT:-3000}:80
diff --git a/nginx.conf b/nginx.conf
index 0a5be24..b8f487b 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -12,8 +12,4 @@ server {
}
error_page 404 /index.html;
-
- add_header Cross-Origin-Embedder-Policy "require-corp";
- add_header Cross-Origin-Opener-Policy "same-origin";
- add_header Cross-Origin-Resource-Policy "cross-origin";
}
\ No newline at end of file
diff --git a/package.json b/package.json
index 9f410a7..420f119 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
"@fontsource/lexend": "^5.1.2",
"@fontsource/radio-canada-big": "^5.1.1",
"@imagemagick/magick-wasm": "^0.0.34",
+ "@stripe/stripe-js": "^7.4.0",
"byte-data": "^19.0.1",
"client-zip": "^2.4.6",
"clsx": "^2.1.1",
@@ -49,9 +50,9 @@
"music-metadata": "^11.0.0",
"p-queue": "^8.1.0",
"riff-file": "^1.0.3",
+ "svelte-stripe": "^1.4.0",
"vert-wasm": "^0.0.2",
"vite-plugin-static-copy": "^2.2.0",
- "vite-plugin-wasm": "^3.4.1",
- "wasm-vips": "^0.0.11"
+ "vite-plugin-wasm": "^3.4.1"
}
}
diff --git a/src/lib/components/layout/Gradients.svelte b/src/lib/components/layout/Gradients.svelte
index 73ef662..7a7d85b 100644
--- a/src/lib/components/layout/Gradients.svelte
+++ b/src/lib/components/layout/Gradients.svelte
@@ -64,8 +64,6 @@
const maskImage = $derived(
`linear-gradient(to top, transparent ${100 - at.current}%, black 100%)`,
);
-
- $inspect(colors);
{#if page.url.pathname === "/"}
diff --git a/src/lib/components/layout/Navbar/Base.svelte b/src/lib/components/layout/Navbar/Base.svelte
index 29a9416..42aa298 100644
--- a/src/lib/components/layout/Navbar/Base.svelte
+++ b/src/lib/components/layout/Navbar/Base.svelte
@@ -63,9 +63,6 @@
let links = $state([]);
let container = $state();
let containerRect = $derived(container?.getBoundingClientRect());
- $effect(() => {
- $inspect(containerRect);
- });
const linkRects = $derived(links.map((l) => l.getBoundingClientRect()));
diff --git a/src/lib/converters/index.ts b/src/lib/converters/index.ts
index 2165207..83c5fe8 100644
--- a/src/lib/converters/index.ts
+++ b/src/lib/converters/index.ts
@@ -2,10 +2,10 @@ import type { Categories } from "$lib/types";
import { FFmpegConverter } from "./ffmpeg.svelte";
import { PandocConverter } from "./pandoc.svelte";
import { VertdConverter } from "./vertd.svelte";
-import { VipsConverter } from "./vips.svelte";
+import { MagickConverter } from "./magick.svelte";
export const converters = [
- new VipsConverter(),
+ new MagickConverter(),
new FFmpegConverter(),
new VertdConverter(),
new PandocConverter(),
@@ -37,9 +37,9 @@ categories.video.formats =
?.formatStrings((f) => f.toSupported) || [];
categories.image.formats =
converters
- .find((c) => c.name === "libvips")
+ .find((c) => c.name === "imagemagick")
?.formatStrings((f) => f.toSupported) || [];
categories.docs.formats =
converters
.find((c) => c.name === "pandoc")
- ?.formatStrings((f) => f.toSupported) || [];
\ No newline at end of file
+ ?.formatStrings((f) => f.toSupported) || [];
diff --git a/src/lib/converters/vips.svelte.ts b/src/lib/converters/magick.svelte.ts
similarity index 91%
rename from src/lib/converters/vips.svelte.ts
rename to src/lib/converters/magick.svelte.ts
index 9de7bb1..bf49918 100644
--- a/src/lib/converters/vips.svelte.ts
+++ b/src/lib/converters/magick.svelte.ts
@@ -3,17 +3,17 @@ import { error, log } from "$lib/logger";
import { addToast } from "$lib/store/ToastProvider";
import type { OmitBetterStrict, WorkerMessage } from "$lib/types";
import { VertFile } from "$lib/types";
-import VipsWorker from "$lib/workers/vips?worker&url";
+import MagickWorker from "$lib/workers/magick?worker&url";
import { Converter, FormatInfo } from "./converter.svelte";
-export class VipsConverter extends Converter {
+export class MagickConverter extends Converter {
private worker: Worker = browser
- ? new Worker(VipsWorker, {
+ ? new Worker(MagickWorker, {
type: "module",
})
: null!;
private id = 0;
- public name = "libvips";
+ public name = "imagemagick";
public ready = $state(false);
public supportedFormats = [
@@ -39,7 +39,6 @@ export class VipsConverter extends Converter {
new FormatInfo("pgm", true, true),
new FormatInfo("pnm", true, true),
new FormatInfo("ppm", false, true),
- new FormatInfo("raw", false, true),
new FormatInfo("tif", true, true),
new FormatInfo("tiff", true, true),
new FormatInfo("jfif", true, true),
@@ -51,7 +50,7 @@ export class VipsConverter extends Converter {
super();
log(["converters", this.name], `created converter`);
if (!browser) return;
- log(["converters", this.name], `loading worker @ ${VipsWorker}`);
+ log(["converters", this.name], `loading worker @ ${MagickWorker}`);
this.worker.onmessage = (e) => {
const message: WorkerMessage = e.data;
log(["converters", this.name], `received message ${message.type}`);
@@ -64,7 +63,7 @@ export class VipsConverter extends Converter {
);
addToast(
"error",
- `Error in VIPS worker, image conversion may not work as expected.`,
+ `Error in Magick worker, image conversion may not work as expected.`,
);
throw new Error(message.error);
}
diff --git a/src/lib/sections/about/Credits.svelte b/src/lib/sections/about/Credits.svelte
index a8dc5cd..d21e0fc 100644
--- a/src/lib/sections/about/Credits.svelte
+++ b/src/lib/sections/about/Credits.svelte
@@ -133,7 +133,7 @@
Libraries
- A big thanks to FFmpeg (audio, video), libvips (images) and
+ A big thanks to FFmpeg (audio, video), Imagemagick (images) and
Pandoc (documents) for maintaining such excellent libraries for
so many years. VERT relies on them to provide you with your
conversions.
diff --git a/src/lib/sections/about/Donate.svelte b/src/lib/sections/about/Donate.svelte
index f27ffdc..9248e99 100644
--- a/src/lib/sections/about/Donate.svelte
+++ b/src/lib/sections/about/Donate.svelte
@@ -7,12 +7,27 @@
-{#snippet donor(name: string, amount: number | string, avatar: string)}
-
-
-
${amount}
-
-{/snippet}
+ onMount(async () => {
+ stripe = await loadStripe(PUB_STRIPE_KEY);
+ });
+
+ const donate = async () => {
+ if (!stripe || !clientSecret || !elements) return;
+
+ enablePay = false;
+
+ const submitResult = await elements.submit();
+ if (submitResult.error) {
+ addToast(
+ "error",
+ `Payment failed: ${submitResult.error.message}. You have not been charged.`,
+ );
+ enablePay = true;
+ return;
+ }
+
+ const res = await stripe.confirmPayment({
+ elements,
+ clientSecret,
+ redirect: "if_required",
+ confirmParams: {
+ return_url: page.url.toString(),
+ },
+ });
+
+ if (res.error) {
+ addToast(
+ "error",
+ `Payment failed: ${res.error.message}. You have not been charged.`,
+ );
+ } else {
+ addToast("success", "Thank you for your donation!");
+ }
+
+ paymentState = "prepay";
+ clientSecret = null;
+ elements = null;
+ amount = 1;
+ customAmount = "";
+ type = "one-time";
+ enablePay = false;
+
+ stripe = await loadStripe(PUB_STRIPE_KEY);
+ };
+
+ onMount(() => {
+ const status = page.url.searchParams.get("redirect_status");
+ if (status) {
+ switch (status) {
+ case "succeeded":
+ addToast("success", "Thank you for your donation!");
+ break;
+ default:
+ addToast(
+ "error",
+ "An error occurred while processing your donation. Please try again later.",
+ );
+ }
+
+ goto("/about");
+ }
+ });
+