Project refactoring

This commit is contained in:
Aleksi Lassila
2024-03-02 00:52:01 +02:00
parent 1c1fbbf043
commit 27b9fc57b3
94 changed files with 128 additions and 102 deletions

8
package-lock.json generated
View File

@@ -25,7 +25,7 @@
"hls.js": "^1.4.14", "hls.js": "^1.4.14",
"openapi-fetch": "^0.8.2", "openapi-fetch": "^0.8.2",
"openapi-typescript": "^6.7.3", "openapi-typescript": "^6.7.3",
"postcss": "^8.4.32", "postcss": "^8.4.35",
"prettier": "^2.8.0", "prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1", "prettier-plugin-svelte": "^2.10.1",
"radix-icons-svelte": "^1.2.1", "radix-icons-svelte": "^1.2.1",
@@ -5084,9 +5084,9 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.32", "version": "8.4.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
"integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {

View File

@@ -11,6 +11,7 @@
"build": "vite build", "build": "vite build",
"build:tizen": "vite build --outDir tizen/dist", "build:tizen": "vite build --outDir tizen/dist",
"preview": "vite preview", "preview": "vite preview",
"preview:tizen": "vite build --outDir tizen/dist && vite preview --outDir tizen/dist",
"deploy": "PORT=9494 NODE_ENV=production node build/", "deploy": "PORT=9494 NODE_ENV=production node build/",
"deploy:electron": "vite build && electron-builder -mw --x64 --config build.config.json; electron-builder -m --arm64 --config build.config.json", "deploy:electron": "vite build && electron-builder -mw --x64 --config build.config.json; electron-builder -m --arm64 --config build.config.json",
"test": "playwright test", "test": "playwright test",
@@ -21,10 +22,8 @@
"format": "prettier --plugin-search-dir . --write ." "format": "prettier --plugin-search-dir . --write ."
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.28.1",
"vitest": "^0.25.3",
"reflect-metadata": "^0.1.13",
"@jellyfin/sdk": "^0.8.2", "@jellyfin/sdk": "^0.8.2",
"@playwright/test": "^1.28.1",
"@sveltejs/vite-plugin-svelte": "^2.4.2", "@sveltejs/vite-plugin-svelte": "^2.4.2",
"@tsconfig/svelte": "^5.0.2", "@tsconfig/svelte": "^5.0.2",
"@types/axios": "^0.14.0", "@types/axios": "^0.14.0",
@@ -40,10 +39,11 @@
"hls.js": "^1.4.14", "hls.js": "^1.4.14",
"openapi-fetch": "^0.8.2", "openapi-fetch": "^0.8.2",
"openapi-typescript": "^6.7.3", "openapi-typescript": "^6.7.3",
"postcss": "^8.4.32", "postcss": "^8.4.35",
"prettier": "^2.8.0", "prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1", "prettier-plugin-svelte": "^2.10.1",
"radix-icons-svelte": "^1.2.1", "radix-icons-svelte": "^1.2.1",
"reflect-metadata": "^0.1.13",
"svelte": "^3.59.1", "svelte": "^3.59.1",
"svelte-check": "^3.6.2", "svelte-check": "^3.6.2",
"svelte-i18n": "^4.0.0", "svelte-i18n": "^4.0.0",
@@ -54,7 +54,8 @@
"tslib": "^2.6.2", "tslib": "^2.6.2",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^4.5.1", "vite": "^4.5.1",
"vite-plugin-singlefile": "^0.13.5" "vite-plugin-singlefile": "^0.13.5",
"vitest": "^0.25.3"
}, },
"browserslist": { "browserslist": {
"production": [ "production": [

11
postcss.config.js Normal file → Executable file
View File

@@ -1,6 +1,7 @@
export default { export default {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {}
}, // 'flex-gap-polyfill': {}
} }
};

View File

@@ -4,7 +4,7 @@
import { handleKeyboardNavigation, Selectable } from './lib/selectable'; import { handleKeyboardNavigation, Selectable } from './lib/selectable';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import Container from './Container.svelte'; import Container from './Container.svelte';
import NavbarItem from './lib/components-new/NavbarItem.svelte'; import NavbarItem from './lib/components/NavbarItem.svelte';
import { Bookmark, CardStack, Gear, Laptop, MagnifyingGlass } from 'radix-icons-svelte'; import { Bookmark, CardStack, Gear, Laptop, MagnifyingGlass } from 'radix-icons-svelte';
import classNames from 'classnames'; import classNames from 'classnames';
import type { Readable } from 'svelte/store'; import type { Readable } from 'svelte/store';

View File

@@ -3,7 +3,7 @@
import IconButton from '../IconButton.svelte'; import IconButton from '../IconButton.svelte';
import { ChevronLeft, ChevronRight } from 'radix-icons-svelte'; import { ChevronLeft, ChevronRight } from 'radix-icons-svelte';
import classNames from 'classnames'; import classNames from 'classnames';
import Container from '../../../Container.svelte'; import type { Registerer } from '../../selectable';
export let gradientFromColor = 'from-stone-950'; export let gradientFromColor = 'from-stone-950';
export let heading = ''; export let heading = '';
@@ -44,19 +44,17 @@
</div> </div>
<div class="relative"> <div class="relative">
<Container horizontal> <div
<div class={classNames(
class={classNames( 'flex overflow-x-scroll items-center overflow-y-visible gap-4 relative scrollbar-hide p-1',
'flex overflow-x-scroll items-center overflow-y-visible gap-4 relative scrollbar-hide p-1', scrollClass
scrollClass )}
)} bind:this={carousel}
bind:this={carousel} tabindex="-1"
tabindex="-1" on:scroll={() => (scrollX = carousel?.scrollLeft || scrollX)}
on:scroll={() => (scrollX = carousel?.scrollLeft || scrollX)} >
> <slot />
<slot /> </div>
</div>
</Container>
{#if scrollX > 50} {#if scrollX > 50}
<div <div
transition:fade={{ duration: 200 }} transition:fade={{ duration: 200 }}

View File

@@ -0,0 +1,29 @@
<script lang="ts">
import { addMessages, init, locale } from 'svelte-i18n';
import de from '../../lang/de.json';
import en from '../../lang/en.json';
import es from '../../lang/es.json';
import fr from '../../lang/fr.json';
import it from '../../lang/it.json';
import { settings } from '../../stores/settings.store';
addMessages('de', de);
addMessages('en', en);
addMessages('es', es);
addMessages('fr', fr);
addMessages('it', it);
settings.subscribe((value) => {
if (value.language) {
locale.set(value.language);
} else {
locale.set('en');
}
});
init({
initialLocale: $settings.language,
fallbackLocale: 'en'
});
</script>

View File

@@ -1,5 +1,6 @@
<script> <script>
import { TriangleRight } from 'radix-icons-svelte'; import { TriangleRight } from 'radix-icons-svelte';
import IconButton from './IconButton.svelte';
import classNames from 'classnames'; import classNames from 'classnames';
</script> </script>

View File

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 309 B

View File

Before

Width:  |  Height:  |  Size: 867 B

After

Width:  |  Height:  |  Size: 867 B

View File

Before

Width:  |  Height:  |  Size: 684 B

After

Width:  |  Height:  |  Size: 684 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 697 B

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 382 B

View File

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 448 B

View File

@@ -1,23 +1,23 @@
<script lang="ts"> <script lang="ts">
import classNames from 'classnames'; import classNames from 'classnames';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
export let index = 0; export let index = 0;
export let size: 'dynamic' | 'md' | 'lg' = 'md'; export let size: 'dynamic' | 'md' | 'lg' = 'md';
export let orientation: 'portrait' | 'landscape' = 'landscape'; export let orientation: 'portrait' | 'landscape' = 'landscape';
</script> </script>
<div <div
class={classNames('rounded-xl overflow-hidden shadow-lg placeholder shrink-0', { class={classNames('rounded-xl overflow-hidden shadow-lg placeholder shrink-0', {
'aspect-video': orientation === 'landscape', 'aspect-video': orientation === 'landscape',
'aspect-[2/3]': orientation === 'portrait', 'aspect-[2/3]': orientation === 'portrait',
'w-44': size === 'md' && orientation === 'portrait', 'w-44': size === 'md' && orientation === 'portrait',
'h-44': size === 'md' && orientation === 'landscape', 'h-44': size === 'md' && orientation === 'landscape',
'w-60': size === 'lg' && orientation === 'portrait', 'w-60': size === 'lg' && orientation === 'portrait',
'h-60': size === 'lg' && orientation === 'landscape', 'h-60': size === 'lg' && orientation === 'landscape',
'w-full': size === 'dynamic' 'w-full': size === 'dynamic'
})} })}
style={'animation-delay: ' + ((index * 100) % 2000) + 'ms;'} style={'animation-delay: ' + ((index * 100) % 2000) + 'ms;'}
transition:fade|global transition:fade|global
tabindex="0" tabindex="0"
/> />

View File

@@ -3,7 +3,7 @@
import IconButton from '../IconButton.svelte'; import IconButton from '../IconButton.svelte';
import { ChevronLeft, ChevronRight } from 'radix-icons-svelte'; import { ChevronLeft, ChevronRight } from 'radix-icons-svelte';
import classNames from 'classnames'; import classNames from 'classnames';
import type { Registerer } from '../../selectable'; import Container from '../../../Container.svelte';
export let gradientFromColor = 'from-stone-950'; export let gradientFromColor = 'from-stone-950';
export let heading = ''; export let heading = '';
@@ -44,17 +44,19 @@
</div> </div>
<div class="relative"> <div class="relative">
<div <Container horizontal>
class={classNames( <div
'flex overflow-x-scroll items-center overflow-y-visible gap-4 relative scrollbar-hide p-1', class={classNames(
scrollClass 'flex overflow-x-scroll items-center overflow-y-visible gap-4 relative scrollbar-hide p-1',
)} scrollClass
bind:this={carousel} )}
tabindex="-1" bind:this={carousel}
on:scroll={() => (scrollX = carousel?.scrollLeft || scrollX)} tabindex="-1"
> on:scroll={() => (scrollX = carousel?.scrollLeft || scrollX)}
<slot /> >
</div> <slot />
</div>
</Container>
{#if scrollX > 50} {#if scrollX > 50}
<div <div
transition:fade={{ duration: 200 }} transition:fade={{ duration: 200 }}

View File

@@ -1,26 +1,26 @@
<script lang="ts"> <script lang="ts">
import classNames from 'classnames'; import classNames from 'classnames';
import { useNavigate } from 'svelte-navigator'; import { useNavigate } from 'svelte-navigator';
import { type Readable } from 'svelte/store'; import { type Readable } from 'svelte/store';
import Container from '../../Container.svelte'; import Container from '../../Container.svelte';
export let to: string; export let to: string;
let hasFocus: Readable<boolean>; let hasFocus: Readable<boolean>;
const navigate = useNavigate(); const navigate = useNavigate();
function handleClick() { function handleClick() {
navigate(to); navigate(to);
} }
</script> </script>
<Container tag="button" on:click={handleClick} bind:hasFocus> <Container tag="button" on:click={handleClick} bind:hasFocus>
<div <div
class={classNames('flex items-center my-2', { class={classNames('flex items-center my-2', {
'text-amber-200': $hasFocus 'text-amber-200': $hasFocus
})} })}
> >
<slot name="icon" /> <slot name="icon" />
<slot name="text" /> <slot name="text" />
</div> </div>
</Container> </Container>

View File

@@ -1,6 +1,5 @@
<script> <script>
import { TriangleRight } from 'radix-icons-svelte'; import { TriangleRight } from 'radix-icons-svelte';
import IconButton from './IconButton.svelte';
import classNames from 'classnames'; import classNames from 'classnames';
</script> </script>

View File

@@ -4,7 +4,6 @@
import Carousel from '../components/Carousel/Carousel.svelte'; import Carousel from '../components/Carousel/Carousel.svelte';
import CarouselPlaceholderItems from '../components/Carousel/CarouselPlaceholderItems.svelte'; import CarouselPlaceholderItems from '../components/Carousel/CarouselPlaceholderItems.svelte';
import Container from '../../Container.svelte'; import Container from '../../Container.svelte';
import type { Readable } from 'svelte/store';
settings.update((prev) => ({ settings.update((prev) => ({
...prev, ...prev,
@@ -20,15 +19,11 @@
jellyfinItemsStore.subscribe((items) => { jellyfinItemsStore.subscribe((items) => {
console.warn('GOT ITEMS', items.data); console.warn('GOT ITEMS', items.data);
}); });
let focusIndex: Readable<number>;
</script> </script>
<Container focusOnMount> <Container focusOnMount>
<div>LibraryPage</div> <div>LibraryPage</div>
<Container horizontal bind:focusIndex> <Carousel>
<Carousel> <CarouselPlaceholderItems />
<CarouselPlaceholderItems {focusIndex} /> </Carousel>
</Carousel>
</Container>
</Container> </Container>

View File

@@ -5,12 +5,12 @@
import { settings } from '../stores/settings.store'; import { settings } from '../stores/settings.store';
import type { TitleType } from '../types'; import type { TitleType } from '../types';
import type { ComponentProps } from 'svelte'; import type { ComponentProps } from 'svelte';
import Poster from '../components-new/Poster.svelte'; import Poster from '../components/Poster.svelte';
import type { JellyfinItem } from '../apis/jellyfin/jellyfinApi'; import type { JellyfinItem } from '../apis/jellyfin/jellyfinApi';
import { jellyfinItemsStore } from '../stores/data.store'; import { jellyfinItemsStore } from '../stores/data.store';
import Carousel from '../components-new/Carousel/Carousel.svelte'; import Carousel from '../components/Carousel/Carousel.svelte';
import { _ } from 'svelte-i18n'; import { _ } from 'svelte-i18n';
import CarouselPlaceholderItems from '../components-new/Carousel/CarouselPlaceholderItems.svelte'; import CarouselPlaceholderItems from '../components/Carousel/CarouselPlaceholderItems.svelte';
const jellyfinItemsPromise = new Promise<JellyfinItem[]>((resolve) => { const jellyfinItemsPromise = new Promise<JellyfinItem[]>((resolve) => {
jellyfinItemsStore.subscribe((data) => { jellyfinItemsStore.subscribe((data) => {

0
svelte.config.js Normal file → Executable file
View File