Refactor catalog

This commit is contained in:
ZXY101
2023-09-27 11:06:03 +02:00
parent 53f5a48d3e
commit d6bb0b1ddc
11 changed files with 109 additions and 99 deletions

View File

@@ -10,7 +10,7 @@
/>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<body data-sveltekit-preload-data="hover" class="bg-white dark:bg-gray-800 dark:text-white">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -1,7 +1,4 @@
import type { Volume } from '$lib/types';
import { writable } from 'svelte/store';
import { db } from '$lib/catalog/db';
import { liveQuery } from 'dexie';
export const currentManga = writable<Volume[] | undefined>(undefined);
export const currentVolume = writable<Volume | undefined>(undefined);
export const catalog = liveQuery(() => db.catalog.toArray());

View File

@@ -1,24 +1,14 @@
<script lang="ts">
import { catalog } from '$lib/catalog';
import { Button } from 'flowbite-svelte';
import CatalogItem from './CatalogItem.svelte';
import { promptConfirmation } from '$lib/util';
import { db } from '$lib/catalog/db';
function onClear() {
promptConfirmation('Are you sure you want to clear your catalog?', () => db.catalog.clear());
}
</script>
{#if $catalog}
{#if $catalog.length > 0}
<div class="flex flex-col gap-5">
<div class="sm:block flex-col flex">
<Button outline color="red" class="float-right" on:click={onClear}>Clear catalog</Button>
</div>
<div class="flex sm:flex-row flex-col gap-5 flex-wrap justify-center sm:justify-start">
{#each $catalog as { id, manga } (id)}
<CatalogItem {manga} />
{#each $catalog as { id } (id)}
<CatalogItem {id} />
{/each}
</div>
</div>

View File

@@ -1,23 +1,22 @@
<script lang="ts">
import { currentManga } from '$lib/catalog';
import type { Volume } from '$lib/types';
export let manga: Volume[];
const { volumeName, files, mokuroData } = manga[0];
import { catalog } from '$lib/catalog';
function onClick() {
currentManga.set(manga);
}
export let id: string;
$: manga = $catalog?.find((item) => item.id === id)?.manga[0];
</script>
<a href={volumeName} on:click={onClick}>
{#if manga}
<a href={id}>
<div class="flex flex-col gap-[5px] text-center items-center">
{mokuroData.title}
{#if files}
{manga.mokuroData.title}
{#if manga.files}
<img
src={URL.createObjectURL(Object.values(files)[0])}
src={URL.createObjectURL(Object.values(manga.files)[0])}
alt="img"
class="object-contain w-[250px] h-[350px] bg-black border-gray-900 border"
/>
{/if}
</div>
</a>
{/if}

View File

@@ -1,16 +1,19 @@
<script lang="ts">
import type { Page } from '$lib/types';
import { onMount } from 'svelte';
import TextBoxes from './TextBoxes.svelte';
export let page: Page;
export let src: File;
$: url = `url(${URL.createObjectURL(src)})`;
</script>
<div
draggable="false"
style:width={`${page.img_width}px`}
style:height={`${page.img_height}px`}
style:background-image={`url(${URL.createObjectURL(src)})`}
style:background-image={url}
class="relative"
>
<TextBoxes {page} {src} />

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import { currentVolume } from '$lib/catalog';
import { catalog } from '$lib/catalog';
import { Panzoom, toggleFullScreen, zoomDefault } from '$lib/panzoom';
import { progress, settings, updateProgress } from '$lib/settings';
import { clamp } from '$lib/util';
import { Input, Popover, Range } from 'flowbite-svelte';
import { Input, Popover, Range, Spinner } from 'flowbite-svelte';
import MangaPage from './MangaPage.svelte';
import {
ChervonDoubleLeftSolid,
@@ -13,9 +13,13 @@
} from 'flowbite-svelte-icons';
import { afterUpdate, onMount } from 'svelte';
import Cropper from './Cropper.svelte';
import { page as pageStore } from '$app/stores';
const volume = $currentVolume;
const pages = volume?.mokuroData.pages;
$: volume = $catalog
?.find((item) => item.id === $pageStore.params.manga)
?.manga.find((item) => item.mokuroData.volume_uuid === $pageStore.params.volume);
$: pages = volume?.mokuroData.pages;
$: page = $progress?.[volume?.mokuroData.volume_uuid || 0] || 1;
$: index = page - 1;
@@ -102,7 +106,6 @@
});
onMount(() => {
getMaxCharCount();
updateCharacterCount(page);
});
@@ -143,7 +146,7 @@
function updateCharacterCount(currentPage: number) {
charCount = 0;
if (pages && $settings.charCount) {
if (pages && pages.length > 0 && $settings.charCount) {
for (let i = 0; i < currentPage; i++) {
const blocks = pages[i].blocks;
blocks.forEach((block) => {
@@ -157,8 +160,10 @@
let maxCharCount = 0;
$: pages?.length, getMaxCharCount();
function getMaxCharCount() {
if (pages) {
if (pages && pages.length > 0) {
for (let i = 0; i < pages.length; i++) {
const blocks = pages[i].blocks;
blocks.forEach((block) => {
@@ -174,6 +179,9 @@
</script>
<svelte:window on:resize={zoomDefault} on:keyup|preventDefault={handleShortcuts} />
<svelte:head>
<title>{volume?.mokuroData.volume || 'Volume'}</title>
</svelte:head>
{#if volume && pages}
<Cropper />
<Popover placement="bottom-end" trigger="click" triggeredBy="#page-num" class="z-20">
@@ -235,4 +243,8 @@
on:mouseup={right}
class="right-0 top-0 absolute h-full w-10 hover:bg-slate-400 opacity-[0.01]"
/>
{:else}
<div class="fixed z-50 left-1/2 top-1/2">
<Spinner />
</div>
{/if}

View File

@@ -1,5 +1,7 @@
<script lang="ts">
import { AccordionItem, Button, Label, Select } from 'flowbite-svelte';
import { db } from '$lib/catalog/db';
import { promptConfirmation } from '$lib/util';
import { AccordionItem, Button, Select } from 'flowbite-svelte';
let profiles = [
{ value: 'default', name: 'Default' },
@@ -8,12 +10,19 @@
];
let profile = 'default';
function onClear() {
promptConfirmation('Are you sure you want to clear your catalog?', () => db.catalog.clear());
}
</script>
<AccordionItem>
<span slot="header">Profile</span>
<div class="flex flex-col gap-5">
<div class="flex flex-col gap-2">
<Select items={profiles} value={profile} />
<Button size="sm" outline color="dark">Manage profiles</Button>
</div>
<Button on:click={onClear} outline color="red">Clear catalog</Button>
</div>
</AccordionItem>

View File

@@ -1,25 +1,30 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { currentVolume } from '$lib/catalog';
import { progress } from '$lib/settings';
import type { Volume } from '$lib/types';
import { ListgroupItem } from 'flowbite-svelte';
import type { ListGroupItemType } from 'flowbite-svelte/dist/types';
export let volume: Volume;
const { volumeName, files } = volume;
export let item: string | ListGroupItemType;
const volume = item as Volume;
const { volumeName, mokuroData } = volume as Volume;
function onClick() {
currentVolume.set(volume);
goto(`${$page.params.manga}/${mokuroData.volume_uuid}`);
}
$: currentPage = $progress?.[volume?.mokuroData.volume_uuid || 0] || 1;
$: progressDisplay = `${currentPage} / ${volume.mokuroData.pages.length}`;
</script>
<a href={`${$page.params.manga}/${volumeName}`} on:click={onClick}>
<div class="flex flex-col gap-[5px] text-center items-center">
{volumeName}
{#if files}
<img
src={URL.createObjectURL(Object.values(files)[0])}
alt="img"
class="object-contain sm:w-[250px] h-[350px] bg-black border-gray-900 border"
/>
{/if}
<a href={`${$page.params.manga}/${mokuroData.volume_uuid}`} class="h-full w-full">
<ListgroupItem>
<div>
<h3 class="font-semibold">{volumeName}</h3>
<p>{progressDisplay}</p>
</div>
</ListgroupItem>
</a>

View File

@@ -2,6 +2,10 @@
import Catalog from '$lib/components/Catalog.svelte';
</script>
<div class="p-2">
<svelte:head>
<title>Mokuro</title>
</svelte:head>
<div class="p-5">
<Catalog />
</div>

View File

@@ -1,13 +1,15 @@
<script lang="ts">
import { currentManga } from '$lib/catalog';
import { catalog } from '$lib/catalog';
import { goto } from '$app/navigation';
import { onMount } from 'svelte';
import VolumeItem from '$lib/components/VolumeItem.svelte';
import { Button } from 'flowbite-svelte';
import { Button, Listgroup } from 'flowbite-svelte';
import { db } from '$lib/catalog/db';
import { promptConfirmation } from '$lib/util';
import { page } from '$app/stores';
import type { Volume } from '$lib/types';
import { onMount } from 'svelte';
const manga = $currentManga?.sort((a, b) => {
function sortManga(a: Volume, b: Volume) {
if (a.volumeName < b.volumeName) {
return -1;
}
@@ -15,13 +17,9 @@
return 1;
}
return 0;
});
onMount(() => {
if (!manga) {
goto('/');
}
});
$: manga = $catalog?.find((item) => item.id === $page.params.manga)?.manga.sort(sortManga);
async function confirmDelete() {
const title = manga?.[0].mokuroData.title_uuid;
@@ -34,15 +32,22 @@
}
</script>
<div class="p-2 flex flex-col gap-5">
<div class="sm:block flex-col flex">
<Button outline color="red" class="float-right" on:click={onDelete}>Delete manga</Button>
</div>
<div class="flex sm:flex-row flex-col justify-center sm:justify-start gap-5 flex-wrap">
<svelte:head>
<title>{manga?.[0].mokuroData.title || 'Manga'}</title>
</svelte:head>
{#if manga}
{#each manga as volume}
<VolumeItem {volume} />
{/each}
<div class="p-5 flex flex-col gap-5">
<div class="flex flex-row justify-between">
<div class="flex flex-col">
<h3 class="font-bold">{manga[0].mokuroData.title}</h3>
<p>Volumes: {manga.length}</p>
</div>
<div><Button color="alternative" on:click={onDelete}>Remove manga</Button></div>
</div>
<Listgroup items={manga} let:item active class="flex-1 h-full w-full">
<VolumeItem {item} />
</Listgroup>
</div>
{:else}
<div class="flex justify-center p-16">Manga not found</div>
{/if}
</div>
</div>

View File

@@ -1,17 +1,3 @@
<script lang="ts">
import { currentVolume } from '$lib/catalog';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
const volume = $currentVolume;
onMount(() => {
if (!volume) {
goto('/');
}
});
</script>
<slot />
<style>