mirror of https://github.com/VERT-sh/VERT.git
Merge branch 'nightly'
This commit is contained in:
commit
21faba31f1
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { files } from "$lib/store/index.svelte";
|
import { effects, files } from "$lib/store/index.svelte";
|
||||||
import { FolderArchiveIcon, RefreshCw } from "lucide-svelte";
|
import { FolderArchiveIcon, RefreshCw } from "lucide-svelte";
|
||||||
import Panel from "../visual/Panel.svelte";
|
import Panel from "../visual/Panel.svelte";
|
||||||
import Dropdown from "./Dropdown.svelte";
|
import Dropdown from "./Dropdown.svelte";
|
||||||
|
|
@ -11,14 +11,14 @@
|
||||||
<div class="flex items-center flex-col md:flex-row gap-2.5 max-md:w-full">
|
<div class="flex items-center flex-col md:flex-row gap-2.5 max-md:w-full">
|
||||||
<button
|
<button
|
||||||
onclick={() => files.convertAll()}
|
onclick={() => files.convertAll()}
|
||||||
class="btn highlight flex gap-3 max-md:w-full"
|
class="btn {$effects ? "" : "!scale-100"} highlight flex gap-3 max-md:w-full"
|
||||||
disabled={!files.ready}
|
disabled={!files.ready}
|
||||||
>
|
>
|
||||||
<RefreshCw size="24" />
|
<RefreshCw size="24" />
|
||||||
<p>Convert all</p>
|
<p>Convert all</p>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn flex gap-3 max-md:w-full"
|
class="btn {$effects ? "" : "!scale-100"} flex gap-3 max-md:w-full"
|
||||||
disabled={!files.ready || !files.results}
|
disabled={!files.ready || !files.results}
|
||||||
onclick={() => files.downloadAll()}
|
onclick={() => files.downloadAll()}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
import Panel from "../visual/Panel.svelte";
|
import Panel from "../visual/Panel.svelte";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { files } from "$lib/store/index.svelte";
|
import { effects, files } from "$lib/store/index.svelte";
|
||||||
import { converters } from "$lib/converters";
|
import { converters } from "$lib/converters";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
<button
|
<button
|
||||||
onclick={uploadFiles}
|
onclick={uploadFiles}
|
||||||
bind:this={uploaderButton}
|
bind:this={uploaderButton}
|
||||||
class={clsx(`hover:scale-105 active:scale-100 duration-200 ${classList}`)}
|
class={clsx(`hover:scale-105 active:scale-100 ${$effects ? "" : "!scale-100"} duration-200 ${classList}`)}
|
||||||
>
|
>
|
||||||
<Panel
|
<Panel
|
||||||
class="flex justify-center items-center w-full h-full flex-col pointer-events-none"
|
class="flex justify-center items-center w-full h-full flex-col pointer-events-none"
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,23 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
type Props = {
|
import { GITHUB_URL_VERT, DISCORD_URL } from "$lib/consts";
|
||||||
class: string;
|
|
||||||
items: { [name: string]: string };
|
|
||||||
};
|
|
||||||
|
|
||||||
const { class: classList, items }: Props = $props();
|
const items = Object.entries({
|
||||||
|
//"Privacy policy": "#",
|
||||||
|
"Source code": GITHUB_URL_VERT,
|
||||||
|
"Discord server": DISCORD_URL,
|
||||||
|
});
|
||||||
|
|
||||||
const year = new Date().getFullYear();
|
const year = new Date().getFullYear();
|
||||||
|
|
||||||
const links = $derived(Object.entries(items));
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<footer class={classList}>
|
<footer
|
||||||
|
class="hidden md:block w-full h-14 border-t border-separator fixed bottom-0 mt-12"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="w-full h-full flex items-center justify-center text-muted gap-3 relative"
|
class="w-full h-full flex items-center justify-center text-muted gap-3 relative"
|
||||||
>
|
>
|
||||||
<p>© {year} VERT.</p>
|
<p>© {year} VERT.</p>
|
||||||
{#each links as [name, url] (name)}
|
{#each items as [name, url] (name)}
|
||||||
<!-- bullet point -->
|
<!-- bullet point -->
|
||||||
<p>•</p>
|
<p>•</p>
|
||||||
<a
|
<a
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { page } from "$app/state";
|
||||||
|
import { duration } from "$lib/animation";
|
||||||
|
import VertVBig from "$lib/assets/vert-bg.svg?component";
|
||||||
|
import { files, gradientColor, showGradient } from "$lib/store/index.svelte";
|
||||||
|
import { quintOut } from "svelte/easing";
|
||||||
|
import { fade } from "$lib/animation";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if page.url.pathname === "/"}
|
||||||
|
<div
|
||||||
|
class="fixed -z-30 top-0 left-0 w-screen h-screen flex items-center justify-center overflow-hidden"
|
||||||
|
transition:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<VertVBig
|
||||||
|
class="fill-[--fg] opacity-10 dynadark:opacity-5 scale-[200%] md:scale-[80%]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="gradient-bg"
|
||||||
|
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
||||||
|
style="background: var(--bg-gradient);"
|
||||||
|
transition:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
{:else if page.url.pathname === "/convert" && $showGradient}
|
||||||
|
{#key $gradientColor}
|
||||||
|
<div
|
||||||
|
id="gradient-bg"
|
||||||
|
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
||||||
|
style="background: var(--bg-gradient-{$gradientColor || 'pink'});"
|
||||||
|
transition:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
{/key}
|
||||||
|
{:else if page.url.pathname === "/convert" && files.files.length === 1 && files.files[0].blobUrl}
|
||||||
|
<div
|
||||||
|
class="fixed w-screen h-screen opacity-75 overflow-hidden top-0 left-0 -z-50 pointer-events-none grid grid-cols-1 grid-rows-1 scale-105"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="w-full relative"
|
||||||
|
transition:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="object-cover w-full h-full blur-md"
|
||||||
|
src={files.files[0].blobUrl}
|
||||||
|
alt={files.files[0].name}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="absolute top-0 left-0 w-full h-full"
|
||||||
|
style="background: var(--bg-gradient-image);"
|
||||||
|
></div>
|
||||||
|
<!-- <div class="absolute bottom-0 left-0 w-full h-full">
|
||||||
|
<ProgressiveBlur
|
||||||
|
direction="bottom"
|
||||||
|
endIntensity={256}
|
||||||
|
iterations={8}
|
||||||
|
fadeTo="var(--bg)"
|
||||||
|
/>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else if page.url.pathname === "/settings"}
|
||||||
|
<div
|
||||||
|
id="gradient-bg"
|
||||||
|
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
||||||
|
style="background: var(--bg-gradient-blue);"
|
||||||
|
transition:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
{:else if page.url.pathname === "/about"}
|
||||||
|
<div
|
||||||
|
id="gradient-bg"
|
||||||
|
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
||||||
|
style="background: var(--bg-gradient-pink);"
|
||||||
|
transition:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
{/if}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script>
|
||||||
|
import Logo from "$lib/components/visual/svg/Logo.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex md:hidden justify-center items-center pb-8 pt-4">
|
||||||
|
<a
|
||||||
|
class="flex items-center justify-center bg-panel p-2 rounded-[20px] shadow-panel"
|
||||||
|
href="/"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="h-14 bg-accent rounded-[14px] flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<div class="w-28 h-5">
|
||||||
|
<Logo />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
@ -2,24 +2,56 @@
|
||||||
import { browser } from "$app/environment";
|
import { browser } from "$app/environment";
|
||||||
import { page } from "$app/state";
|
import { page } from "$app/state";
|
||||||
import { duration, fade } from "$lib/animation";
|
import { duration, fade } from "$lib/animation";
|
||||||
import { effects, setTheme } from "$lib/store/index.svelte";
|
import { effects, files, goingLeft, setTheme } from "$lib/store/index.svelte";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { MoonIcon, SunIcon } from "lucide-svelte";
|
import {
|
||||||
|
InfoIcon,
|
||||||
|
MoonIcon,
|
||||||
|
RefreshCw,
|
||||||
|
SettingsIcon,
|
||||||
|
SunIcon,
|
||||||
|
UploadIcon,
|
||||||
|
} from "lucide-svelte";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
import Panel from "../visual/Panel.svelte";
|
import Panel from "../../visual/Panel.svelte";
|
||||||
import Logo from "../visual/svg/Logo.svelte";
|
import Logo from "../../visual/svg/Logo.svelte";
|
||||||
|
import { beforeNavigate } from "$app/navigation";
|
||||||
|
|
||||||
type Props = {
|
const items = $derived<
|
||||||
items: {
|
{
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
activeMatch: (pathname: string) => boolean;
|
activeMatch: (pathname: string) => boolean;
|
||||||
icon: any;
|
icon: any;
|
||||||
badge?: number;
|
badge?: number;
|
||||||
}[];
|
}[]
|
||||||
};
|
>([
|
||||||
|
{
|
||||||
let { items }: Props = $props();
|
name: "Upload",
|
||||||
|
url: "/",
|
||||||
|
activeMatch: (pathname) => pathname === "/",
|
||||||
|
icon: UploadIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Convert",
|
||||||
|
url: "/convert",
|
||||||
|
activeMatch: (pathname) => pathname === "/convert",
|
||||||
|
icon: RefreshCw,
|
||||||
|
badge: files.files.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Settings",
|
||||||
|
url: "/settings",
|
||||||
|
activeMatch: (pathname) => pathname.startsWith("/settings"),
|
||||||
|
icon: SettingsIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "About",
|
||||||
|
url: "/about",
|
||||||
|
activeMatch: (pathname) => pathname.startsWith("/about"),
|
||||||
|
icon: InfoIcon,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
let links = $state<HTMLAnchorElement[]>([]);
|
let links = $state<HTMLAnchorElement[]>([]);
|
||||||
let container = $state<HTMLDivElement>();
|
let container = $state<HTMLDivElement>();
|
||||||
|
|
@ -33,6 +65,20 @@
|
||||||
const selectedIndex = $derived(
|
const selectedIndex = $derived(
|
||||||
items.findIndex((i) => i.activeMatch(page.url.pathname)),
|
items.findIndex((i) => i.activeMatch(page.url.pathname)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
beforeNavigate((e) => {
|
||||||
|
const oldIndex = items.findIndex((i) =>
|
||||||
|
i.activeMatch(e.from?.url.pathname || ""),
|
||||||
|
);
|
||||||
|
const newIndex = items.findIndex((i) =>
|
||||||
|
i.activeMatch(e.to?.url.pathname || ""),
|
||||||
|
);
|
||||||
|
if (newIndex < oldIndex) {
|
||||||
|
goingLeft.set(true)
|
||||||
|
} else {
|
||||||
|
goingLeft.set(false)
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet link(item: (typeof items)[0], index: number)}
|
{#snippet link(item: (typeof items)[0], index: number)}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import Navbar from "./Base.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="hidden md:flex p-8 w-screen justify-center">
|
||||||
|
<Navbar />
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import Navbar from "./Base.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="fixed md:hidden bottom-0 left-0 w-screen p-8 justify-center z-50">
|
||||||
|
<div class="flex flex-col justify-center items-center">
|
||||||
|
<Navbar />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
export { default as Desktop } from "./Desktop.svelte";
|
||||||
|
export { default as Mobile } from "./Mobile.svelte";
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { page } from "$app/state";
|
||||||
|
import { duration } from "$lib/animation";
|
||||||
|
import { goingLeft, isMobile } from "$lib/store/index.svelte";
|
||||||
|
import { quintOut } from "svelte/easing";
|
||||||
|
import { fly, fade } from "$lib/animation";
|
||||||
|
|
||||||
|
let { children } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="grid grid-rows-1 grid-cols-1 h-full flex-grow">
|
||||||
|
{#key page.url.pathname}
|
||||||
|
<div
|
||||||
|
class="row-start-1 col-start-1"
|
||||||
|
in:fly={{
|
||||||
|
x: $goingLeft ? -window.innerWidth : window.innerWidth,
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
delay: 25,
|
||||||
|
}}
|
||||||
|
out:fly={{
|
||||||
|
x: $goingLeft ? window.innerWidth : -window.innerWidth,
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex flex-col h-full pb-32"
|
||||||
|
in:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
delay: $isMobile ? 0 : 100,
|
||||||
|
}}
|
||||||
|
out:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
delay: $isMobile ? 0 : 200,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{@render children()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/key}
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { duration, fade } from "$lib/animation";
|
||||||
|
import { dropping, effects } from "$lib/store/index.svelte";
|
||||||
|
import { quintOut } from "svelte/easing";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if $dropping}
|
||||||
|
<div
|
||||||
|
class="fixed w-screen h-screen opacity-40 dynadark:opacity-20 z-[100] pointer-events-none blur-2xl {$effects
|
||||||
|
? 'dragoverlay'
|
||||||
|
: 'bg-accent-blue'}"
|
||||||
|
class:_dragover={dropping && $effects}
|
||||||
|
transition:fade={{
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.dragoverlay {
|
||||||
|
animation: dragoverlay-animation 3s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dragoverlay-animation {
|
||||||
|
0% {
|
||||||
|
@apply bg-accent-pink;
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
@apply bg-accent-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
@apply bg-accent-purple;
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
@apply bg-accent-red;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
@apply bg-accent-pink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
export { default as UploadRegion } from './UploadRegion.svelte';
|
||||||
|
export { default as Gradients } from './Gradients.svelte';
|
||||||
|
export { default as PageContent } from './PageContent.svelte';
|
||||||
|
export { default as MobileLogo } from './MobileLogo.svelte';
|
||||||
|
export { default as Footer } from './Footer.svelte';
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
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 {
|
import {
|
||||||
CalendarHeartIcon,
|
CalendarHeartIcon,
|
||||||
HandCoinsIcon,
|
HandCoinsIcon,
|
||||||
|
|
@ -41,29 +42,29 @@
|
||||||
<div class="flex flex-col gap-3 w-full">
|
<div class="flex flex-col gap-3 w-full">
|
||||||
<div class="flex gap-3 w-full">
|
<div class="flex gap-3 w-full">
|
||||||
<button
|
<button
|
||||||
class="btn flex-1 p-4 rounded-lg bg-accent-red text-black flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg bg-accent-red text-black flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<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 flex-1 p-4 rounded-lg bg-button text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg bg-button text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<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 bg-accent-red text-black p-4 rounded-lg flex-1"
|
<button class="btn {$effects ? "" : "!scale-100"} bg-accent-red text-black p-4 rounded-lg flex-1"
|
||||||
>$1 USD</button
|
>$1 USD</button
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn bg-button text-black dynadark:text-white p-4 rounded-lg flex-1"
|
class="btn {$effects ? "" : "!scale-100"} bg-button text-black dynadark:text-white p-4 rounded-lg flex-1"
|
||||||
>$5 USD</button
|
>$5 USD</button
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn bg-button text-black dynadark:text-white p-4 rounded-lg flex-1"
|
class="btn {$effects ? "" : "!scale-100"} bg-button text-black dynadark:text-white p-4 rounded-lg flex-1"
|
||||||
>$10 USD</button
|
>$10 USD</button
|
||||||
>
|
>
|
||||||
<!-- <div class="relative flex items-center flex-[2]">
|
<!-- <div class="relative flex items-center flex-[2]">
|
||||||
|
|
@ -86,7 +87,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn flex-1 p-3 rounded-3xl bg-accent-red text-black flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 p-3 rounded-3xl bg-accent-red text-black flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<WalletIcon size="24" class="inline-block mr-2" />
|
<WalletIcon size="24" class="inline-block mr-2" />
|
||||||
Pay now
|
Pay now
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import { DISCORD_URL, GITHUB_URL_VERT } from "$lib/consts";
|
import { DISCORD_URL, GITHUB_URL_VERT } from "$lib/consts";
|
||||||
|
import { effects } from "$lib/store/index.svelte";
|
||||||
import { GithubIcon, LinkIcon, MessageCircleMoreIcon } from "lucide-svelte";
|
import { GithubIcon, LinkIcon, MessageCircleMoreIcon } from "lucide-svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -18,7 +19,7 @@
|
||||||
href={DISCORD_URL}
|
href={DISCORD_URL}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="btn flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<MessageCircleMoreIcon size="24" class="inline-block mr-2" />
|
<MessageCircleMoreIcon size="24" class="inline-block mr-2" />
|
||||||
Discord
|
Discord
|
||||||
|
|
@ -27,7 +28,7 @@
|
||||||
href={GITHUB_URL_VERT}
|
href={GITHUB_URL_VERT}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="btn flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<GithubIcon size="24" class="inline-block mr-2" />
|
<GithubIcon size="24" class="inline-block mr-2" />
|
||||||
Source
|
Source
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,11 @@
|
||||||
if (effectsUnsubscribe) effectsUnsubscribe();
|
if (effectsUnsubscribe) effectsUnsubscribe();
|
||||||
if (themeUnsubscribe) themeUnsubscribe();
|
if (themeUnsubscribe) themeUnsubscribe();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
updateEffectsClasses($effects);
|
||||||
|
updateThemeClasses($theme);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Panel class="flex flex-col gap-8 p-6">
|
<Panel class="flex flex-col gap-8 p-6">
|
||||||
|
|
@ -80,7 +85,7 @@
|
||||||
<button
|
<button
|
||||||
bind:this={lightElement}
|
bind:this={lightElement}
|
||||||
onclick={() => setTheme("light")}
|
onclick={() => setTheme("light")}
|
||||||
class="btn flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<SunIcon size="24" class="inline-block mr-2" />
|
<SunIcon size="24" class="inline-block mr-2" />
|
||||||
Light
|
Light
|
||||||
|
|
@ -89,7 +94,7 @@
|
||||||
<button
|
<button
|
||||||
bind:this={darkElement}
|
bind:this={darkElement}
|
||||||
onclick={() => setTheme("dark")}
|
onclick={() => setTheme("dark")}
|
||||||
class="btn flex-1 p-4 rounded-lg text-black flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<MoonIcon size="24" class="inline-block mr-2" />
|
<MoonIcon size="24" class="inline-block mr-2" />
|
||||||
Dark
|
Dark
|
||||||
|
|
@ -110,7 +115,7 @@
|
||||||
<button
|
<button
|
||||||
bind:this={enableEffectsElement}
|
bind:this={enableEffectsElement}
|
||||||
onclick={() => setEffects(true)}
|
onclick={() => setEffects(true)}
|
||||||
class="btn flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<PlayIcon size="24" class="inline-block mr-2" />
|
<PlayIcon size="24" class="inline-block mr-2" />
|
||||||
Enable
|
Enable
|
||||||
|
|
@ -119,7 +124,7 @@
|
||||||
<button
|
<button
|
||||||
bind:this={disableEffectsElement}
|
bind:this={disableEffectsElement}
|
||||||
onclick={() => setEffects(false)}
|
onclick={() => setEffects(false)}
|
||||||
class="btn flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<PauseIcon size="24" class="inline-block mr-2" />
|
<PauseIcon size="24" class="inline-block mr-2" />
|
||||||
Disable
|
Disable
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
import type { ISettings } from "./index.svelte";
|
import type { ISettings } from "./index.svelte";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
||||||
|
import { vertdLoaded } from "$lib/store/index.svelte";
|
||||||
|
|
||||||
let vertdCommit = $state<string | null>(null);
|
let vertdCommit = $state<string | null>(null);
|
||||||
let abortController: AbortController | null = null;
|
let abortController: AbortController | null = null;
|
||||||
|
|
@ -12,7 +13,7 @@
|
||||||
const { settings }: { settings: ISettings } = $props();
|
const { settings }: { settings: ISettings } = $props();
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (settings.vertdURL) {
|
if (settings.vertdURL) {
|
||||||
if (abortController) abortController.abort();
|
if (abortController) abortController.abort();
|
||||||
abortController = new AbortController();
|
abortController = new AbortController();
|
||||||
const { signal } = abortController;
|
const { signal } = abortController;
|
||||||
|
|
@ -21,17 +22,23 @@
|
||||||
fetch(`${settings.vertdURL}/api/version`, { signal })
|
fetch(`${settings.vertdURL}/api/version`, { signal })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res.ok) throw new Error("bad response");
|
if (!res.ok) throw new Error("bad response");
|
||||||
|
vertdLoaded.set(false);
|
||||||
return res.json();
|
return res.json();
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
vertdCommit = data.data;
|
vertdCommit = data.data;
|
||||||
|
vertdLoaded.set(true);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (err.name !== "AbortError") vertdCommit = null;
|
if (err.name !== "AbortError") {
|
||||||
|
vertdCommit = null;
|
||||||
|
vertdLoaded.set(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (abortController) abortController.abort();
|
if (abortController) abortController.abort();
|
||||||
vertdCommit = null;
|
vertdCommit = null;
|
||||||
|
vertdLoaded.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
|
@ -48,7 +55,7 @@
|
||||||
class="inline-block -mt-1 mr-2 bg-accent-red p-2 rounded-full overflow-visible"
|
class="inline-block -mt-1 mr-2 bg-accent-red p-2 rounded-full overflow-visible"
|
||||||
color="black"
|
color="black"
|
||||||
/>
|
/>
|
||||||
Converting Video
|
Video conversion
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
class={clsx("text-sm font-normal", {
|
class={clsx("text-sm font-normal", {
|
||||||
|
|
|
||||||
|
|
@ -32,16 +32,6 @@ function addToast(
|
||||||
exit: 500,
|
exit: 500,
|
||||||
};
|
};
|
||||||
|
|
||||||
// if "disappearing" not set, default error/warning to infinite duration
|
|
||||||
if (disappearing === undefined) {
|
|
||||||
switch (type) {
|
|
||||||
case "error":
|
|
||||||
case "warning":
|
|
||||||
durations.stay = 86400000; // 24h cause why not
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const newToast: Toast = {
|
const newToast: Toast = {
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,9 @@ export function setEffects(effectsEnabled: boolean) {
|
||||||
export const files = new Files();
|
export const files = new Files();
|
||||||
export const showGradient = writable(true);
|
export const showGradient = writable(true);
|
||||||
export const gradientColor = writable("");
|
export const gradientColor = writable("");
|
||||||
|
export const goingLeft = writable(false);
|
||||||
|
export const dropping = writable(false);
|
||||||
|
export const vertdLoaded = writable(false);
|
||||||
|
|
||||||
export const isMobile = writable(false);
|
export const isMobile = writable(false);
|
||||||
export const effects = writable(true);
|
export const effects = writable(true);
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,35 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from "$app/state";
|
import { onMount } from "svelte";
|
||||||
import { beforeNavigate, goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { PUB_HOSTNAME, PUB_PLAUSIBLE_URL } from "$env/static/public";
|
|
||||||
import { duration, fly } from "$lib/animation";
|
|
||||||
import VertVBig from "$lib/assets/vert-bg.svg?component";
|
|
||||||
import featuredImage from "$lib/assets/VERT_Feature.webp";
|
|
||||||
import Navbar from "$lib/components/functional/Navbar.svelte";
|
|
||||||
import Footer from "$lib/components/visual/Footer.svelte";
|
|
||||||
import Logo from "$lib/components/visual/svg/Logo.svelte";
|
|
||||||
|
|
||||||
import { fade } from "$lib/animation";
|
import { PUB_HOSTNAME, PUB_PLAUSIBLE_URL } from "$env/static/public";
|
||||||
|
import { VERT_NAME } from "$lib/consts";
|
||||||
|
import Toast from "$lib/components/visual/Toast.svelte";
|
||||||
|
import * as Layout from "$lib/components/layout";
|
||||||
|
import * as Navbar from "$lib/components/layout/Navbar";
|
||||||
|
import featuredImage from "$lib/assets/VERT_Feature.webp";
|
||||||
|
import { type Toast as ToastType, toasts } from "$lib/store/ToastProvider";
|
||||||
|
import { Settings } from "$lib/sections/settings/index.svelte";
|
||||||
import {
|
import {
|
||||||
files,
|
files,
|
||||||
gradientColor,
|
|
||||||
isMobile,
|
isMobile,
|
||||||
effects,
|
effects,
|
||||||
showGradient,
|
|
||||||
theme,
|
theme,
|
||||||
|
dropping,
|
||||||
} from "$lib/store/index.svelte";
|
} from "$lib/store/index.svelte";
|
||||||
import {
|
|
||||||
InfoIcon,
|
|
||||||
RefreshCw,
|
|
||||||
SettingsIcon,
|
|
||||||
UploadIcon,
|
|
||||||
} from "lucide-svelte";
|
|
||||||
import { onMount } from "svelte";
|
|
||||||
import { quintOut } from "svelte/easing";
|
|
||||||
import "../app.scss";
|
import "../app.scss";
|
||||||
import { DISCORD_URL, GITHUB_URL_VERT, VERT_NAME } from "$lib/consts";
|
|
||||||
import { type Toast as ToastType, toasts } from "$lib/store/ToastProvider";
|
|
||||||
import Toast from "$lib/components/visual/Toast.svelte";
|
|
||||||
import { Settings } from "$lib/sections/settings/index.svelte";
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
||||||
let dropping = $state(false);
|
|
||||||
let goingLeft = $state(false);
|
|
||||||
let toastList = $state<ToastType[]>([]);
|
let toastList = $state<ToastType[]>([]);
|
||||||
|
|
||||||
toasts.subscribe((value) => {
|
toasts.subscribe((value) => {
|
||||||
toastList = value as ToastType[];
|
toastList = value as ToastType[];
|
||||||
});
|
});
|
||||||
|
|
||||||
const items = $derived<
|
|
||||||
{
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
activeMatch: (pathname: string) => boolean;
|
|
||||||
icon: any;
|
|
||||||
badge?: number;
|
|
||||||
}[]
|
|
||||||
>([
|
|
||||||
{
|
|
||||||
name: "Upload",
|
|
||||||
url: "/",
|
|
||||||
activeMatch: (pathname) => pathname === "/",
|
|
||||||
icon: UploadIcon,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Convert",
|
|
||||||
url: "/convert",
|
|
||||||
activeMatch: (pathname) => pathname === "/convert",
|
|
||||||
icon: RefreshCw,
|
|
||||||
badge: files.files.length,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Settings",
|
|
||||||
url: "/settings",
|
|
||||||
activeMatch: (pathname) => pathname.startsWith("/settings"),
|
|
||||||
icon: SettingsIcon,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "About",
|
|
||||||
url: "/about",
|
|
||||||
activeMatch: (pathname) => pathname.startsWith("/about"),
|
|
||||||
icon: InfoIcon,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const dropFiles = (e: DragEvent) => {
|
const dropFiles = (e: DragEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dropping = false;
|
dropping.set(false);
|
||||||
const oldLength = files.files.length;
|
const oldLength = files.files.length;
|
||||||
files.add(e.dataTransfer?.files);
|
files.add(e.dataTransfer?.files);
|
||||||
if (oldLength !== files.files.length) goto("/convert");
|
if (oldLength !== files.files.length) goto("/convert");
|
||||||
|
|
@ -87,7 +37,7 @@
|
||||||
|
|
||||||
const handleDrag = (e: DragEvent, drag: boolean) => {
|
const handleDrag = (e: DragEvent, drag: boolean) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dropping = drag;
|
dropping.set(drag);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
|
@ -103,20 +53,6 @@
|
||||||
|
|
||||||
Settings.instance.load();
|
Settings.instance.load();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeNavigate((e) => {
|
|
||||||
const oldIndex = items.findIndex((i) =>
|
|
||||||
i.activeMatch(e.from?.url.pathname || ""),
|
|
||||||
);
|
|
||||||
const newIndex = items.findIndex((i) =>
|
|
||||||
i.activeMatch(e.to?.url.pathname || ""),
|
|
||||||
);
|
|
||||||
if (newIndex < oldIndex) {
|
|
||||||
goingLeft = true;
|
|
||||||
} else {
|
|
||||||
goingLeft = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|
@ -158,6 +94,7 @@
|
||||||
<script src="/coi-serviceworker.min.js"></script>
|
<script src="/coi-serviceworker.min.js"></script>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
|
<!-- FIXME: if user resizes between desktop/mobile, highlight of page disappears (only shows on original size) -->
|
||||||
<div
|
<div
|
||||||
class="flex flex-col min-h-screen h-full"
|
class="flex flex-col min-h-screen h-full"
|
||||||
ondrop={dropFiles}
|
ondrop={dropFiles}
|
||||||
|
|
@ -166,77 +103,18 @@
|
||||||
ondragleave={(e) => handleDrag(e, false)}
|
ondragleave={(e) => handleDrag(e, false)}
|
||||||
role="region"
|
role="region"
|
||||||
>
|
>
|
||||||
{#if dropping}
|
<Layout.UploadRegion />
|
||||||
<div
|
|
||||||
class="fixed w-screen h-screen opacity-40 dynadark:opacity-20 z-[100] pointer-events-none blur-2xl {$effects
|
|
||||||
? 'dragoverlay'
|
|
||||||
: 'bg-accent-blue'}"
|
|
||||||
class:_dragover={dropping && $effects}
|
|
||||||
transition:fade={{
|
|
||||||
duration,
|
|
||||||
easing: quintOut,
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- FIXME: if user resizes between desktop/mobile, highlight of page disappears (only shows on original size) -->
|
|
||||||
<div>
|
<div>
|
||||||
<!-- Mobile logo -->
|
<Layout.MobileLogo />
|
||||||
<div class="flex md:hidden justify-center items-center pb-8 pt-4">
|
<Navbar.Desktop />
|
||||||
<a
|
|
||||||
class="flex items-center justify-center bg-panel p-2 rounded-[20px] shadow-panel"
|
|
||||||
href="/"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="h-14 bg-accent rounded-[14px] flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<div class="w-28 h-5">
|
|
||||||
<Logo />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Desktop navbar -->
|
|
||||||
<div class="hidden md:flex p-8 w-screen justify-center">
|
|
||||||
<Navbar {items} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-rows-1 grid-cols-1 h-full flex-grow">
|
<!--
|
||||||
{#key page.url.pathname}
|
SvelteKit throws the following warning when developing - safe to ignore as we render the children in this component:
|
||||||
<div
|
`<slot />` or `{@render ...}` tag missing — inner content will not be rendered
|
||||||
class="row-start-1 col-start-1"
|
-->
|
||||||
in:fly={{
|
<Layout.PageContent {children} />
|
||||||
x: goingLeft ? -window.innerWidth : window.innerWidth,
|
|
||||||
duration,
|
|
||||||
easing: quintOut,
|
|
||||||
delay: 25,
|
|
||||||
}}
|
|
||||||
out:fly={{
|
|
||||||
x: goingLeft ? window.innerWidth : -window.innerWidth,
|
|
||||||
duration,
|
|
||||||
easing: quintOut,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="flex flex-col h-full pb-32"
|
|
||||||
in:fade={{
|
|
||||||
duration,
|
|
||||||
easing: quintOut,
|
|
||||||
delay: $isMobile ? 0 : 100,
|
|
||||||
}}
|
|
||||||
out:fade={{
|
|
||||||
duration,
|
|
||||||
easing: quintOut,
|
|
||||||
delay: $isMobile ? 0 : 200,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{@render children()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/key}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fixed bottom-28 md:bottom-0 right-0 p-4 space-y-4 z-50">
|
<div class="fixed bottom-28 md:bottom-0 right-0 p-4 space-y-4 z-50">
|
||||||
{#each toastList as { id, type, message, durations }}
|
{#each toastList as { id, type, message, durations }}
|
||||||
|
|
@ -245,118 +123,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div
|
<Layout.Footer />
|
||||||
class="hidden md:block w-full h-14 border-t border-separator fixed bottom-0 mt-12"
|
<Navbar.Mobile />
|
||||||
>
|
|
||||||
<Footer
|
|
||||||
class="w-full h-full"
|
|
||||||
items={{
|
|
||||||
//"Privacy policy": "#",
|
|
||||||
"Source code": GITHUB_URL_VERT,
|
|
||||||
"Discord server": DISCORD_URL,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Mobile navbar -->
|
|
||||||
<div
|
|
||||||
class="fixed md:hidden bottom-0 left-0 w-screen p-8 justify-center z-50"
|
|
||||||
>
|
|
||||||
<div class="flex flex-col justify-center items-center">
|
|
||||||
<Navbar {items} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Gradients placed here to prevent it overlapping in transitions -->
|
<!-- Gradients placed here to prevent it overlapping in transitions -->
|
||||||
{#if page.url.pathname === "/"}
|
<Layout.Gradients />
|
||||||
<div
|
|
||||||
class="fixed -z-30 top-0 left-0 w-screen h-screen flex items-center justify-center overflow-hidden"
|
|
||||||
>
|
|
||||||
<VertVBig
|
|
||||||
class="fill-[--fg] opacity-10 dynadark:opacity-5 scale-[200%] md:scale-[80%]"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
id="gradient-bg"
|
|
||||||
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
|
||||||
style="background: var(--bg-gradient);"
|
|
||||||
></div>
|
|
||||||
{:else if page.url.pathname === "/convert" && $showGradient}
|
|
||||||
<div
|
|
||||||
id="gradient-bg"
|
|
||||||
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
|
||||||
style="background: var(--bg-gradient-{$gradientColor || 'pink'});"
|
|
||||||
></div>
|
|
||||||
{:else if page.url.pathname === "/convert" && files.files.length === 1 && files.files[0].blobUrl}
|
|
||||||
<div
|
|
||||||
class="fixed w-screen h-screen opacity-75 overflow-hidden top-0 left-0 -z-50 pointer-events-none grid grid-cols-1 grid-rows-1 scale-105"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="w-full relative"
|
|
||||||
transition:fade={{
|
|
||||||
duration,
|
|
||||||
easing: quintOut,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="object-cover w-full h-full blur-md"
|
|
||||||
src={files.files[0].blobUrl}
|
|
||||||
alt={files.files[0].name}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="absolute top-0 left-0 w-full h-full"
|
|
||||||
style="background: var(--bg-gradient-image);"
|
|
||||||
></div>
|
|
||||||
<!-- <div class="absolute bottom-0 left-0 w-full h-full">
|
|
||||||
<ProgressiveBlur
|
|
||||||
direction="bottom"
|
|
||||||
endIntensity={256}
|
|
||||||
iterations={8}
|
|
||||||
fadeTo="var(--bg)"
|
|
||||||
/>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else if page.url.pathname === "/settings"}
|
|
||||||
<div
|
|
||||||
id="gradient-bg"
|
|
||||||
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
|
||||||
style="background: var(--bg-gradient-blue);"
|
|
||||||
></div>
|
|
||||||
{:else if page.url.pathname === "/about"}
|
|
||||||
<div
|
|
||||||
id="gradient-bg"
|
|
||||||
class="fixed top-0 left-0 w-screen h-screen -z-40 pointer-events-none"
|
|
||||||
style="background: var(--bg-gradient-pink);"
|
|
||||||
></div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.dragoverlay {
|
|
||||||
animation: dragoverlay-animation 3s infinite linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes dragoverlay-animation {
|
|
||||||
0% {
|
|
||||||
@apply bg-accent-pink;
|
|
||||||
}
|
|
||||||
|
|
||||||
25% {
|
|
||||||
@apply bg-accent-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
@apply bg-accent-purple;
|
|
||||||
}
|
|
||||||
|
|
||||||
75% {
|
|
||||||
@apply bg-accent-red;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
@apply bg-accent-pink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,18 @@
|
||||||
// -- JovannMC
|
// -- JovannMC
|
||||||
|
|
||||||
import Uploader from "$lib/components/functional/Uploader.svelte";
|
import Uploader from "$lib/components/functional/Uploader.svelte";
|
||||||
|
import { converters } from "$lib/converters";
|
||||||
import { AudioLines, Check, Film, Image } from "lucide-svelte";
|
import { AudioLines, Check, Film, Image } from "lucide-svelte";
|
||||||
|
|
||||||
|
const getSupportedFormats = (name: string) =>
|
||||||
|
converters.find((c) => c.name === name)?.supportedFormats.join(", ") ||
|
||||||
|
"none";
|
||||||
|
|
||||||
|
const supportedFormats = {
|
||||||
|
images: getSupportedFormats("libvips"),
|
||||||
|
audio: getSupportedFormats("ffmpeg"),
|
||||||
|
video: getSupportedFormats("vertd"),
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="max-w-6xl w-full mx-auto px-6 md:px-8">
|
<div class="max-w-6xl w-full mx-auto px-6 md:px-8">
|
||||||
|
|
@ -40,7 +51,7 @@
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="mt-10 md:mt-16">
|
<div class="mt-10 md:mt-16">
|
||||||
<h2 class="text-center text-4xl">VERT Supports...</h2>
|
<h2 class="text-center text-4xl">VERT supports...</h2>
|
||||||
|
|
||||||
<div class="grid gap-4 md:grid-cols-3 mt-8">
|
<div class="grid gap-4 md:grid-cols-3 mt-8">
|
||||||
<div class="file-category-card">
|
<div class="file-category-card">
|
||||||
|
|
@ -51,7 +62,13 @@
|
||||||
<span>Images</span>
|
<span>Images</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Animated images are not supported (yet).</p>
|
<div class="flex flex-col text-center justify-center">
|
||||||
|
<p>Animated images are not supported (yet).</p>
|
||||||
|
<p>
|
||||||
|
<b>Supported formats:</b>
|
||||||
|
{supportedFormats.images}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="file-category-card">
|
<div class="file-category-card">
|
||||||
|
|
@ -62,9 +79,15 @@
|
||||||
<span>Audio</span>
|
<span>Audio</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="flex items-center justify-center gap-2">
|
<div class="flex flex-col text-center justify-between">
|
||||||
<Check size="20" /> Fully supported
|
<p class="flex items-center justify-center gap-2">
|
||||||
</p>
|
<Check size="20" /> Fully supported
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Supported formats:</b>
|
||||||
|
{supportedFormats.audio}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="file-category-card">
|
<div class="file-category-card">
|
||||||
|
|
@ -74,13 +97,16 @@
|
||||||
</div>
|
</div>
|
||||||
<span>Video *</span>
|
<span>Video *</span>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<div class="flex flex-col text-center justify-between">
|
||||||
Video requires special setup. <a
|
<p>
|
||||||
target="_blank"
|
Video requires special setup. <a
|
||||||
href="https://github.com/VERT-sh/VERT/wiki/How-to-convert-video-with-VERT"
|
target="_blank"
|
||||||
>Learn more</a
|
href="https://github.com/VERT-sh/VERT/wiki/How-to-convert-video-with-VERT"
|
||||||
>
|
>Learn more</a
|
||||||
</p>
|
>.
|
||||||
|
</p>
|
||||||
|
<p><b>Supported formats:</b> {supportedFormats.video}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,13 @@
|
||||||
import Uploader from "$lib/components/functional/Uploader.svelte";
|
import Uploader from "$lib/components/functional/Uploader.svelte";
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import ProgressBar from "$lib/components/visual/ProgressBar.svelte";
|
import ProgressBar from "$lib/components/visual/ProgressBar.svelte";
|
||||||
|
import { converters } from "$lib/converters";
|
||||||
import {
|
import {
|
||||||
|
effects,
|
||||||
files,
|
files,
|
||||||
gradientColor,
|
gradientColor,
|
||||||
showGradient,
|
showGradient,
|
||||||
|
vertdLoaded,
|
||||||
} from "$lib/store/index.svelte";
|
} from "$lib/store/index.svelte";
|
||||||
import { VertFile } from "$lib/types";
|
import { VertFile } from "$lib/types";
|
||||||
import {
|
import {
|
||||||
|
|
@ -24,12 +27,6 @@
|
||||||
} from "lucide-svelte";
|
} from "lucide-svelte";
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (files.files.length === 1 && files.files[0].blobUrl) {
|
|
||||||
showGradient.set(false);
|
|
||||||
} else {
|
|
||||||
showGradient.set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set gradient color depending on the file types
|
// Set gradient color depending on the file types
|
||||||
// TODO: if more file types added, add a "fileType" property to the file object
|
// TODO: if more file types added, add a "fileType" property to the file object
|
||||||
const allAudio = files.files.every(
|
const allAudio = files.files.every(
|
||||||
|
|
@ -44,6 +41,12 @@
|
||||||
(file) => file.converter?.name === "vertd",
|
(file) => file.converter?.name === "vertd",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (files.files.length === 1 && files.files[0].blobUrl && !allVideos) {
|
||||||
|
showGradient.set(false);
|
||||||
|
} else {
|
||||||
|
showGradient.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
files.files.length === 0 ||
|
files.files.length === 0 ||
|
||||||
(!allAudio && !allImages && !allVideos)
|
(!allAudio && !allImages && !allVideos)
|
||||||
|
|
@ -95,12 +98,38 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{#if !file.converter}
|
{#if !file.converter}
|
||||||
|
{#if file.name.startsWith("vertd")}
|
||||||
|
<div
|
||||||
|
class="h-full flex flex-col text-center justify-center text-failure"
|
||||||
|
>
|
||||||
|
<p class="font-body font-bold">
|
||||||
|
We can't convert this file.
|
||||||
|
</p>
|
||||||
|
<p class="font-normal">
|
||||||
|
what are you doing..? you're supposed to run the vertd
|
||||||
|
server!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div
|
||||||
|
class="h-full flex flex-col text-center justify-center text-failure"
|
||||||
|
>
|
||||||
|
<p class="font-body font-bold">
|
||||||
|
We can't convert this file.
|
||||||
|
</p>
|
||||||
|
<p class="font-normal">
|
||||||
|
Only image, video, and audio files are supported
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{:else if isVideo && !$vertdLoaded}
|
||||||
<div
|
<div
|
||||||
class="h-full flex flex-col text-center justify-center text-failure"
|
class="h-full flex flex-col text-center justify-center text-failure"
|
||||||
>
|
>
|
||||||
<p class="font-body font-bold">We can't convert this file.</p>
|
<p class="font-body font-bold">We can't convert this file.</p>
|
||||||
<p class="font-normal">
|
<p class="font-normal">
|
||||||
Only image, video, and audio files are supported
|
Could not find the vertd instance to start video conversion.
|
||||||
|
Are you sure the instance URL is set correctly?
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
@ -148,7 +177,9 @@
|
||||||
/>
|
/>
|
||||||
<div class="w-full flex items-center justify-between">
|
<div class="w-full flex items-center justify-between">
|
||||||
<button
|
<button
|
||||||
class="btn p-0 w-14 h-14 text-black {isAudio
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} p-0 w-14 h-14 text-black {isAudio
|
||||||
? 'bg-accent-purple'
|
? 'bg-accent-purple'
|
||||||
: isVideo
|
: isVideo
|
||||||
? 'bg-accent-red'
|
? 'bg-accent-red'
|
||||||
|
|
@ -159,7 +190,9 @@
|
||||||
<RotateCwIcon size="24" />
|
<RotateCwIcon size="24" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn p-0 w-14 h-14"
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} p-0 w-14 h-14"
|
||||||
onclick={file.download}
|
onclick={file.download}
|
||||||
disabled={!file.result}
|
disabled={!file.result}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue