feat: ready for bytecrush!

This commit is contained in:
not-nullptr 2025-04-16 21:56:15 +01:00
parent 4e18269204
commit fdec0c77e9
8 changed files with 145 additions and 36 deletions

3
.npmignore Normal file
View File

@ -0,0 +1,3 @@
src/routes
src/app.d.ts
src/app.html

View File

@ -1,5 +1,5 @@
{ {
"name": "VERT", "name": "vert",
"version": "0.0.1", "version": "0.0.1",
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@ -65,6 +65,7 @@ export class PandocConverter extends Converter {
public supportedFormats = [ public supportedFormats = [
new FormatInfo("docx", true, true), new FormatInfo("docx", true, true),
new FormatInfo("xml", true, true),
new FormatInfo("doc", true, true), new FormatInfo("doc", true, true),
new FormatInfo("md", true, true), new FormatInfo("md", true, true),
new FormatInfo("html", true, true), new FormatInfo("html", true, true),

View File

@ -1,15 +1,58 @@
<script lang="ts" module>
export interface Donor {
name: string;
amount: number;
avatar: string;
}
</script>
<script lang="ts"> <script lang="ts">
import { PUB_STRIPE_KEY, PUB_DONATION_API } from "$env/static/public";
import { fade } from "$lib/animation";
import FancyInput from "$lib/components/functional/FancyInput.svelte"; import FancyInput from "$lib/components/functional/FancyInput.svelte";
import Panel from "$lib/components/visual/Panel.svelte"; import Panel from "$lib/components/visual/Panel.svelte";
import { effects } from "$lib/store/index.svelte"; import { effects } from "$lib/store/index.svelte";
import { addToast } from "$lib/store/ToastProvider";
import clsx from "clsx";
import { import {
CalendarHeartIcon, CalendarHeartIcon,
HandCoinsIcon, HandCoinsIcon,
HeartIcon, HeartIcon,
WalletIcon, WalletIcon,
} from "lucide-svelte"; } from "lucide-svelte";
import { onMount, tick } from "svelte";
import { quintOut } from "svelte/easing";
let { donors } = $props(); type Props = {
donors: Donor[];
};
let { donors }: Props = $props();
let amount = $state(1);
let customAmount = $state("");
let type = $state("one-time");
const presetAmounts = [1, 10, 25];
let paying = $state(false);
let clientSecret = $state<string | null>(null);
const amountClick = (preset: number) => {
amount = preset;
customAmount = "";
};
const paymentClick = async () => {};
$effect(() => {
if (customAmount) {
amount = parseFloat(customAmount);
}
});
const payDuration = 400;
const transition = "cubic-bezier(0.23, 1, 0.320, 1)";
</script> </script>
{#snippet donor(name: string, amount: number | string, avatar: string)} {#snippet donor(name: string, amount: number | string, avatar: string)}
@ -39,59 +82,96 @@
</p> </p>
</div> </div>
<div class="flex flex-col gap-3 w-full"> <div
class="flex flex-col gap-3 w-full overflow-visible"
style="height: {paying ? 0 : 124}px;
transform: scaleY({paying ? 0 : 1});
opacity: {paying ? 0 : 1};
filter: blur({paying ? 4 : 0}px);
transition: height {payDuration}ms {transition},
opacity {payDuration - 200}ms {transition},
transform {payDuration}ms {transition},
filter {payDuration}ms {transition};"
>
<div class="flex gap-3 w-full"> <div class="flex gap-3 w-full">
<button <button
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg bg-accent-red text-black flex items-center justify-center" onclick={() => (type = "one-time")}
class={clsx(
"btn flex-1 p-4 rounded-lg flex items-center justify-center",
{
"!scale-100": !$effects,
"bg-accent-red text-black": type === "one-time",
},
)}
> >
<HandCoinsIcon size="24" class="inline-block mr-2" /> <HandCoinsIcon size="24" class="inline-block mr-2" />
One-time One-time
</button> </button>
<button <button
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg bg-button text-black dynadark:text-white flex items-center justify-center" disabled
onclick={() => (type = "monthly")}
class={clsx(
"btn flex-1 p-4 rounded-lg flex items-center justify-center",
{
"!scale-100": !$effects,
"bg-accent-red text-black": type === "monthly",
},
)}
> >
<CalendarHeartIcon size="24" class="inline-block mr-2" /> <CalendarHeartIcon size="24" class="inline-block mr-2" />
Monthly Monthly
</button> </button>
</div> </div>
<div class="flex gap-3 w-full"> <div class="flex gap-3 w-full">
<button class="btn {$effects ? "" : "!scale-100"} bg-accent-red text-black p-4 rounded-lg flex-1" {#each presetAmounts as preset}
>$1 USD</button <button
> onclick={() => amountClick(preset)}
<button class={clsx(
class="btn {$effects ? "" : "!scale-100"} bg-button text-black dynadark:text-white p-4 rounded-lg flex-1" "btn flex-1 p-4 rounded-lg flex items-center justify-center",
>$5 USD</button {
> "!scale-100": !$effects,
<button "bg-accent-red text-black": amount === preset,
class="btn {$effects ? "" : "!scale-100"} bg-button text-black dynadark:text-white p-4 rounded-lg flex-1" },
>$10 USD</button )}
> >
<!-- <div class="relative flex items-center flex-[2]"> ${preset} USD
<span class="absolute left-3 text-gray-500">$</span> </button>
<input {/each}
type="number"
class="pl-8 pr-2 rounded-lg border border-gray-300 dynadark:border-gray-500 w-full h-full bg-button text-black dynadark:text-white"
placeholder="Custom"
/>
</div> -->
<div class="flex-[2] flex items-center justify-center"> <div class="flex-[2] flex items-center justify-center">
<FancyInput placeholder="Custom" prefix="$" type="number" /> <FancyInput
bind:value={customAmount}
placeholder="Custom"
prefix="$"
type="number"
/>
</div> </div>
</div> </div>
</div> </div>
<div class="flex flex-row justify-center w-full"> <div class="flex flex-row justify-center w-full">
<p class="text-muted text-sm flex-[4] flex items-center"> <div
Payments and subscription management <br /> are handled through Liberapay role="button"
</p> tabindex="0"
onkeydown={(e) => {
<button if (e.key === "Enter") {
class="btn {$effects ? "" : "!scale-100"} flex-1 p-3 rounded-3xl bg-accent-red text-black flex items-center justify-center" paymentClick();
}
}}
onclick={paymentClick}
class={clsx(
"btn flex-1 p-3 relative rounded-3xl bg-accent-red border-2 border-accent-red h-14 text-black",
{
"h-64 rounded-2xl bg-transparent cursor-auto !scale-100 -mt-10 -mb-2":
paying,
"!scale-100": !$effects,
},
)}
style="transition: height {payDuration}ms {transition}, border-radius {payDuration}ms {transition}, background-color {payDuration}ms {transition}, transform {payDuration}ms {transition}, margin {payDuration}ms {transition};"
> >
<WalletIcon size="24" class="inline-block mr-2" /> <WalletIcon size="24" class="inline-block mr-2" />
Pay now Pay now
</button> </div>
</div> </div>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
@ -114,9 +194,20 @@
<div class="flex flex-row flex-wrap gap-2"> <div class="flex flex-row flex-wrap gap-2">
{#each donors as dono} {#each donors as dono}
{@const { name, amount, avatar } = dono} {@const { name, amount, avatar } = dono}
{@render donor(name, amount, avatar)} {@render donor(name, amount || "0.00", avatar)}
{/each} {/each}
</div> </div>
{/if} {/if}
</div> </div>
</Panel> </Panel>
<style>
:global(
.StripeElement,
.StripeElement *,
iframe[name="__privateStripeFrame39314"]
) {
width: 50px !important;
height: 50px !important;
}
</style>

View File

@ -113,6 +113,8 @@ const formatToReader = (format: Format): string => {
return "rtf"; return "rtf";
case ".rst": case ".rst":
return "rst"; return "rst";
case ".xml":
return "xml";
} }
throw new Error(`Unsupported format: ${format}`); throw new Error(`Unsupported format: ${format}`);

View File

@ -16,7 +16,7 @@
dropping, dropping,
vertdLoaded, vertdLoaded,
} from "$lib/store/index.svelte"; } from "$lib/store/index.svelte";
import "../app.scss"; import "$lib/css/app.scss";
import { browser } from "$app/environment"; import { browser } from "$app/environment";
import { page } from "$app/state"; import { page } from "$app/state";

View File

@ -8,6 +8,8 @@
import avatarJovannMC from "$lib/assets/avatars/jovannmc.jpg"; import avatarJovannMC from "$lib/assets/avatars/jovannmc.jpg";
import { GITHUB_API_URL } from "$lib/consts"; import { GITHUB_API_URL } from "$lib/consts";
import { addToast } from "$lib/store/ToastProvider"; import { addToast } from "$lib/store/ToastProvider";
import { dev } from "$app/environment";
import { page } from "$app/state";
/* interface Donator { /* interface Donator {
name: string; name: string;
@ -105,6 +107,9 @@
error(["general"], `Error fetching GitHub contributors: ${e}`); error(["general"], `Error fetching GitHub contributors: ${e}`);
} }
}); });
// const donationsEnabled = dev || page.url.origin.endsWith("//vert.sh");
const donationsEnabled = false;
</script> </script>
<div class="flex flex-col h-full items-center"> <div class="flex flex-col h-full items-center">
@ -118,15 +123,22 @@
> >
<!-- Why VERT? & Credits --> <!-- Why VERT? & Credits -->
<div class="flex flex-col gap-4 flex-1"> <div class="flex flex-col gap-4 flex-1">
{#if donationsEnabled}
<About.Donate donors={[]} />
{/if}
<About.Why /> <About.Why />
<About.Vertd /> {#if !donationsEnabled}
<About.Vertd />
{/if}
</div> </div>
<!-- Resources & Donate to VERT --> <!-- Resources & Donate to VERT -->
<div class="flex flex-col gap-4 flex-1"> <div class="flex flex-col gap-4 flex-1">
<About.Resources /> <About.Resources />
<About.Credits {mainContribs} {ghContribs} /> <About.Credits {mainContribs} {ghContribs} />
<!-- <About.Donate /> --> {#if donationsEnabled}
<About.Vertd />
{/if}
</div> </div>
</div> </div>
</div> </div>