1
0
Fork 0

WIP client frontend

This commit is contained in:
Leon Grünewald 2024-03-17 22:30:34 +01:00
parent abf74b04cc
commit c704958470
8 changed files with 157 additions and 67 deletions

100
r621-theme.js Normal file
View file

@ -0,0 +1,100 @@
export const r621Theme = {
name: 'r621',
properties: {
// =~= Theme Properties =~=
"--theme-font-family-base": `system-ui`,
"--theme-font-family-heading": `system-ui`,
"--theme-font-color-base": "0 0 0",
"--theme-font-color-dark": "255 255 255",
"--theme-rounded-base": "9999px",
"--theme-rounded-container": "8px",
"--theme-border-base": "1px",
// =~= Theme On-X Colors =~=
"--on-primary": "255 255 255",
"--on-secondary": "0 0 0",
"--on-tertiary": "0 0 0",
"--on-success": "0 0 0",
"--on-warning": "0 0 0",
"--on-error": "255 255 255",
"--on-surface": "255 255 255",
// =~= Theme Colors =~=
// primary | #1f3c67
"--color-primary-50": "221 226 232", // #dde2e8
"--color-primary-100": "210 216 225", // #d2d8e1
"--color-primary-200": "199 206 217", // #c7ced9
"--color-primary-300": "165 177 194", // #a5b1c2
"--color-primary-400": "98 119 149", // #627795
"--color-primary-500": "31 60 103", // #1f3c67
"--color-primary-600": "28 54 93", // #1c365d
"--color-primary-700": "23 45 77", // #172d4d
"--color-primary-800": "19 36 62", // #13243e
"--color-primary-900": "15 29 50", // #0f1d32
// secondary | #f2bb51
"--color-secondary-50": "253 245 229", // #fdf5e5
"--color-secondary-100": "252 241 220", // #fcf1dc
"--color-secondary-200": "252 238 212", // #fceed4
"--color-secondary-300": "250 228 185", // #fae4b9
"--color-secondary-400": "246 207 133", // #f6cf85
"--color-secondary-500": "242 187 81", // #f2bb51
"--color-secondary-600": "218 168 73", // #daa849
"--color-secondary-700": "182 140 61", // #b68c3d
"--color-secondary-800": "145 112 49", // #917031
"--color-secondary-900": "119 92 40", // #775c28
// tertiary | #FFFFFF
"--color-tertiary-50": "255 255 255", // #ffffff
"--color-tertiary-100": "255 255 255", // #ffffff
"--color-tertiary-200": "255 255 255", // #ffffff
"--color-tertiary-300": "255 255 255", // #ffffff
"--color-tertiary-400": "255 255 255", // #ffffff
"--color-tertiary-500": "255 255 255", // #FFFFFF
"--color-tertiary-600": "230 230 230", // #e6e6e6
"--color-tertiary-700": "191 191 191", // #bfbfbf
"--color-tertiary-800": "153 153 153", // #999999
"--color-tertiary-900": "125 125 125", // #7d7d7d
// success | #BFFF00
"--color-success-50": "245 255 217", // #f5ffd9
"--color-success-100": "242 255 204", // #f2ffcc
"--color-success-200": "239 255 191", // #efffbf
"--color-success-300": "229 255 153", // #e5ff99
"--color-success-400": "210 255 77", // #d2ff4d
"--color-success-500": "191 255 0", // #BFFF00
"--color-success-600": "172 230 0", // #ace600
"--color-success-700": "143 191 0", // #8fbf00
"--color-success-800": "115 153 0", // #739900
"--color-success-900": "94 125 0", // #5e7d00
// warning | #cccc00
"--color-warning-50": "247 247 217", // #f7f7d9
"--color-warning-100": "245 245 204", // #f5f5cc
"--color-warning-200": "242 242 191", // #f2f2bf
"--color-warning-300": "235 235 153", // #ebeb99
"--color-warning-400": "219 219 77", // #dbdb4d
"--color-warning-500": "204 204 0", // #cccc00
"--color-warning-600": "184 184 0", // #b8b800
"--color-warning-700": "153 153 0", // #999900
"--color-warning-800": "122 122 0", // #7a7a00
"--color-warning-900": "100 100 0", // #646400
// error | #EE0000
"--color-error-50": "252 217 217", // #fcd9d9
"--color-error-100": "252 204 204", // #fccccc
"--color-error-200": "251 191 191", // #fbbfbf
"--color-error-300": "248 153 153", // #f89999
"--color-error-400": "243 77 77", // #f34d4d
"--color-error-500": "238 0 0", // #EE0000
"--color-error-600": "214 0 0", // #d60000
"--color-error-700": "179 0 0", // #b30000
"--color-error-800": "143 0 0", // #8f0000
"--color-error-900": "117 0 0", // #750000
// surface | #020f23
"--color-surface-50": "217 219 222", // #d9dbde
"--color-surface-100": "204 207 211", // #cccfd3
"--color-surface-200": "192 195 200", // #c0c3c8
"--color-surface-300": "154 159 167", // #9a9fa7
"--color-surface-400": "78 87 101", // #4e5765
"--color-surface-500": "2 15 35", // #020f23
"--color-surface-600": "2 14 32", // #020e20
"--color-surface-700": "2 11 26", // #020b1a
"--color-surface-800": "1 9 21", // #010915
"--color-surface-900": "1 7 17", // #010711
}
}

View file

@ -3,11 +3,10 @@
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link rel="stylesheet" href="node_modules/svelte-material-ui/bare.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" data-themem="skeleton">
<body data-sveltekit-preload-data="hover" data-theme="r621">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View file

@ -2,3 +2,5 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
body { @apply bg-surface-50-900-token; }

View file

@ -1,21 +1,20 @@
<script>
import {imageGridPreviewQuality, imageGridColumns} from '$lib/stores';
export let posts = [];
export let columns = 8;
</script>
<div class="grid gap-3" style={`grid-template-columns: repeat(${columns}, minmax(0, 1fr))`}>
<div class="grid gap-3" style={`grid-template-columns: repeat(${$imageGridColumns}, minmax(0, 1fr))`}>
{#each posts as post}
<a href={`/posts/${post.id}`} class="flex flex-col place-items-center place-content-end border-2 underline hover:no-underline border-blue-200">
<div class="post-main">
<img src={post.preview.url}
<a href={`/posts/${post.id}`} class="card flex flex-col justify-end">
<section class="flex">
<img src={post[$imageGridPreviewQuality].url}
loading="lazy"
alt={`Post ${post.id}`} />
</div>
<div class="post-meta">
<p class="text-blue-200">{post.id} {post.file.ext} {post.rating}</p>
</div>
</section>
<footer>
<p class="text-center">{post.id} {post.file.ext} {post.rating}</p>
</footer>
</a>
{/each}
</div>
<style lang="postcss"></style>

View file

@ -1,13 +1,5 @@
import {writable} from 'svelte/store';
export const lastSearch = writable(window.localStorage.getItem('lastSearch') ?? '');
export const gridColumns = writable(Number(window.localStorage.getItem('gridColumns')) ?? 8);
lastSearch.subscribe((value) => {
window.localStorage.setItem('lastSearch', value);
});
gridColumns.subscribe((value) => {
window.localStorage.setItem('gridColumns', value.toString());
});
import { localStorageStore } from '@skeletonlabs/skeleton';
export const lastSearch = localStorageStore('lastSearch', '');
export const imageGridColumns = localStorageStore('gridColumns', 8);
export const imageGridPreviewQuality = localStorageStore('gridPreviewQuality', 'preview');

View file

@ -5,7 +5,7 @@
initializeStores();
</script>
<div class="min-h-dvh bg-blue-950">
<div class="min-h-dvh bg-surface-400-500-token">
<slot />
</div>

View file

@ -2,8 +2,8 @@
import { ImageGrid } from '$lib/components';
import { onMount } from 'svelte';
import { invoke } from '@tauri-apps/api/tauri'
import { lastSearch, gridColumns } from '$lib/stores';
import { AppBar, AppShell, Drawer, RangeSlider, getDrawerStore } from '@skeletonlabs/skeleton';
import { lastSearch, imageGridColumns, imageGridPreviewQuality } from '$lib/stores';
import { AppShell, Drawer, RangeSlider, getDrawerStore } from '@skeletonlabs/skeleton';
const drawerStore = getDrawerStore();
@ -19,53 +19,51 @@
$lastSearch = query;
data = invoke('get_posts', { query });
}
</script>
<Drawer class="w-full lg:w-6/12">
<div class="bg-gray-400 min-h-dvh">
<div class="m-2">
<div class="flex flex-row">
<label class="label flex-grow">
<span class="font-bold">Query</span>
<input type="text" bind:value={query} />
</label>
<button class="btn variant-filled flex-grow" type="button" on:click={() => {onSearch()}}>Search</button>
</div>
<RangeSlider name="grid-columns" min={1} max={12} bind:value={$gridColumns}>
<div class="flex justify-between items-center">
<div class="font-bold">Grid Columns</div>
<div class="text-xs">{$gridColumns} / {12}</div>
</div>
</RangeSlider>
<label class="label">
<span class="font-bold">Preview type</span>
<select class="select">
<option value="preview">Preview</option>
<option value="sample">Sample</option>
<option value="file">File</option>
</select>
<button class="absolute top-1 left-1 z-50 btn variant-filled-primary"
on:click|preventDefault={() => {
drawerStore.open();
}}
>Button</button>
<Drawer bgDrawer="bg-surface-500/90" width="w-6/12" height="h-dvh" position="left">
<div class="h-full p-4 flex flex-col justify-between bg-token">
<div class="flex flex-row">
<label class="label basis-1 flex-grow">
<span class="font-bold">Query</span>
<input class="input" type="text" bind:value={query} />
</label>
<button class="btn variant-filled flex-shrink" type="button" on:click={() => {onSearch()}}>Search</button>
</div>
<div class="flex flex-row gap-3">
<div class="basis-1/2">
<RangeSlider name="grid-columns" min={1} max={12} bind:value={$imageGridColumns} ticked={true}>
<div class="flex flex-grow justify-between items-center">
<div class="font-bold">Grid Columns</div>
<div class="text-xs">{$imageGridColumns} / {12}</div>
</div>
</RangeSlider>
</div>
<div class="basis-1/2">
<label class="label">
<span class="font-bold">Preview type</span>
<select class="select" bind:value={$imageGridPreviewQuality}>
<option value="preview">Preview</option>
<option value="sample">Sample</option>
</select>
</label>
</div>
</div>
</div>
</Drawer>
<AppShell>
<svelte:fragment slot="header">
<AppBar>
<button class="btn variant" on:click|preventDefault={() => {
drawerStore.open();
}}>|||</button>
eSix Client
</AppBar>
</svelte:fragment>
<svelte:fragment>
<div class="m-2">
{#if data}
{#await data}
<p>Loading...</p>
{:then result}
<ImageGrid columns={$gridColumns} posts={result} />
<ImageGrid posts={result} />
{:catch err}
<p>Error: {err}</p>
{/await}
@ -73,5 +71,3 @@
</div>
</svelte:fragment>
</AppShell>
<style lang="postcss"></style>

View file

@ -3,6 +3,7 @@ import { join } from 'path';
// 1. Import the Skeleton plugin
import { skeleton } from '@skeletonlabs/tw-plugin';
import { r621Theme } from './r621-theme';
/** @type {import('tailwindcss').Config} */
export default {
@ -11,8 +12,7 @@ export default {
content: [
'./src/**/*.{html,js,svelte,ts}',
// 3. Append the path to the Skeleton package
join(require.resolve(
'@skeletonlabs/skeleton'),
join(require.resolve('@skeletonlabs/skeleton'),
'../**/*.{html,js,svelte,ts}'
)
],
@ -22,7 +22,9 @@ export default {
plugins: [
// 4. Append the Skeleton plugin (after other plugins)
skeleton({
themes: ['skeleton']
themes: {
custom: [r621Theme]
}
})
]
}