Handle database
This commit is contained in:
14458
Bocchi-the-Rock!-02.json
Normal file
14458
Bocchi-the-Rock!-02.json
Normal file
File diff suppressed because it is too large
Load Diff
11
package-lock.json
generated
11
package-lock.json
generated
@@ -9,6 +9,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@zip.js/zip.js": "^2.7.20",
|
"@zip.js/zip.js": "^2.7.20",
|
||||||
|
"dexie": "^4.0.1-alpha.25",
|
||||||
"panzoom": "^9.4.3"
|
"panzoom": "^9.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1279,6 +1280,11 @@
|
|||||||
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/dexie": {
|
||||||
|
"version": "4.0.1-alpha.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/dexie/-/dexie-4.0.1-alpha.25.tgz",
|
||||||
|
"integrity": "sha512-udAExYYfJaC6IzVC+ygHdlWYoYxhwYHtiITkthGgSH7dh2FBk3qqDGkJ/Mn2lfxsmATcq9qJDUjyO7yWOo/ZPA=="
|
||||||
|
},
|
||||||
"node_modules/dir-glob": {
|
"node_modules/dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
@@ -4025,6 +4031,11 @@
|
|||||||
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"dexie": {
|
||||||
|
"version": "4.0.1-alpha.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/dexie/-/dexie-4.0.1-alpha.25.tgz",
|
||||||
|
"integrity": "sha512-udAExYYfJaC6IzVC+ygHdlWYoYxhwYHtiITkthGgSH7dh2FBk3qqDGkJ/Mn2lfxsmATcq9qJDUjyO7yWOo/ZPA=="
|
||||||
|
},
|
||||||
"dir-glob": {
|
"dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@zip.js/zip.js": "^2.7.20",
|
"@zip.js/zip.js": "^2.7.20",
|
||||||
|
"dexie": "^4.0.1-alpha.25",
|
||||||
"panzoom": "^9.4.3"
|
"panzoom": "^9.4.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/lib/catalog/db.ts
Normal file
20
src/lib/catalog/db.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { Volume } from '$lib/upload';
|
||||||
|
import Dexie, { type Table } from 'dexie';
|
||||||
|
|
||||||
|
export interface Catalog {
|
||||||
|
id?: number;
|
||||||
|
manga: Volume[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CatalogDexie extends Dexie {
|
||||||
|
catalog!: Table<Catalog>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super('mokuro');
|
||||||
|
this.version(1).stores({
|
||||||
|
catalog: '++id, manga'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const db = new CatalogDexie();
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Manga, Volume } from "$lib/types/catalog";
|
import type { Volume } from "$lib/upload";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
export const currentManga = writable<Manga | undefined>(undefined);
|
export const currentManga = writable<Volume[] | undefined>(undefined);
|
||||||
export const currentVolume = writable<Volume | undefined>(undefined);
|
export const currentVolume = writable<Volume | undefined>(undefined);
|
||||||
|
|||||||
9
src/lib/catalog/test.ts
Normal file
9
src/lib/catalog/test.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { writable } from "svelte/store";
|
||||||
|
import { db } from "$lib/catalog/db";
|
||||||
|
import type { Volume } from "$lib/upload";
|
||||||
|
import { liveQuery } from "dexie";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const catalog = liveQuery(() => db.catalog.toArray());
|
||||||
@@ -1,110 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import image1 from '$lib/assets/1.jpg';
|
import { catalog } from '$lib/catalog/test';
|
||||||
import image2 from '$lib/assets/2.jpg';
|
|
||||||
import image3 from '$lib/assets/3.jpg';
|
|
||||||
import image4 from '$lib/assets/4.jpg';
|
|
||||||
import image5 from '$lib/assets/5.jpg';
|
|
||||||
import type { Manga } from '$lib/types/catalog';
|
|
||||||
import CatalogItem from './CatalogItem.svelte';
|
import CatalogItem from './CatalogItem.svelte';
|
||||||
|
|
||||||
const manga: Manga[] = [
|
|
||||||
{
|
|
||||||
title: 'Manga name',
|
|
||||||
cover: image1,
|
|
||||||
volumes: [
|
|
||||||
{
|
|
||||||
cover: image1,
|
|
||||||
title: 'Volume 1',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cover: image1,
|
|
||||||
title: 'Volume 2',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Another',
|
|
||||||
cover: image2,
|
|
||||||
volumes: [
|
|
||||||
{
|
|
||||||
cover: image2,
|
|
||||||
title: 'Volume 1',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cover: image2,
|
|
||||||
title: 'Volume 2',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Awooo',
|
|
||||||
cover: image3,
|
|
||||||
volumes: [
|
|
||||||
{
|
|
||||||
cover: image3,
|
|
||||||
title: 'Volume 1',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cover: image3,
|
|
||||||
title: 'Volume 2',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Title',
|
|
||||||
cover: image4,
|
|
||||||
volumes: [
|
|
||||||
{
|
|
||||||
cover: image4,
|
|
||||||
title: 'Volume 1',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cover: image4,
|
|
||||||
title: 'Volume 2',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'sdhfjksdh',
|
|
||||||
cover: image5,
|
|
||||||
volumes: [
|
|
||||||
{
|
|
||||||
cover: image5,
|
|
||||||
title: 'Volume 1',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cover: image5,
|
|
||||||
title: 'Volume 2',
|
|
||||||
currentPage: 0,
|
|
||||||
totalPages: 100
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{#each manga as item}
|
{#if $catalog}
|
||||||
<CatalogItem manga={item} />
|
{#each $catalog as { manga }}
|
||||||
|
<CatalogItem {manga} />
|
||||||
{/each}
|
{/each}
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { currentManga } from '$lib/catalog';
|
import { currentManga } from '$lib/catalog';
|
||||||
import type { Manga } from '$lib/types/catalog';
|
import type { Volume } from '$lib/upload';
|
||||||
import { navbarTitle } from './NavBar.svelte';
|
export let manga: Volume[];
|
||||||
export let manga: Manga;
|
const { volumeName, files, mokuroData } = manga[0];
|
||||||
const { cover, title } = manga;
|
|
||||||
|
|
||||||
function onClick() {
|
function onClick() {
|
||||||
console.log('bruh');
|
|
||||||
|
|
||||||
navbarTitle.set(title);
|
|
||||||
currentManga.set(manga);
|
currentManga.set(manga);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a href={title} on:click={onClick}>
|
<a href={volumeName} on:click={onClick}>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{title}
|
{mokuroData.title}
|
||||||
<img src={cover} alt={title} />
|
{#if files}
|
||||||
|
<img src={URL.createObjectURL(Object.values(files)[0])} alt="img" />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
|
|
||||||
switch ($page?.route.id) {
|
switch ($page?.route.id) {
|
||||||
case '/[manga]':
|
case '/[manga]':
|
||||||
title = $currentManga?.title;
|
title = $currentManga?.[0].mokuroData.title;
|
||||||
back = '/';
|
back = '/';
|
||||||
break;
|
break;
|
||||||
case '/[manga]/[volume]':
|
case '/[manga]/[volume]':
|
||||||
window.document.body.classList.add('reader');
|
window.document.body.classList.add('reader');
|
||||||
title = $currentVolume?.title;
|
title = $currentVolume?.volumeName;
|
||||||
back = '/manga';
|
back = '/manga';
|
||||||
break;
|
break;
|
||||||
case '/upload':
|
case '/upload':
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import img from '$lib/assets/001.jpg';
|
|
||||||
|
|
||||||
type Block = {
|
type Block = {
|
||||||
box: number[];
|
box: number[];
|
||||||
vertical: boolean;
|
vertical: boolean;
|
||||||
@@ -10,102 +8,35 @@
|
|||||||
|
|
||||||
type Page = {
|
type Page = {
|
||||||
version?: string;
|
version?: string;
|
||||||
imgWidth: number;
|
img_width: number;
|
||||||
imgHeight: number;
|
img_height: number;
|
||||||
blocks: Block[];
|
blocks: Block[];
|
||||||
imgPath: string;
|
imgPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
let page: Page = {
|
export let page: Page;
|
||||||
version: '0.1.6',
|
|
||||||
imgWidth: 1078,
|
|
||||||
imgHeight: 1530,
|
|
||||||
blocks: [
|
|
||||||
{
|
|
||||||
box: [924, 167, 948, 380],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 21.0,
|
|
||||||
lines: ['私も頑張らなくちゃ!']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [584, 242, 610, 397],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 26.0,
|
|
||||||
lines: ['リョウ先輩!']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [895, 474, 943, 687],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 20.0,
|
|
||||||
lines: ['私のギターの練習', 'みてもらえませんか!']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [898, 787, 947, 979],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 21.0,
|
|
||||||
lines: ['ぼっちに教えて', 'もらってるじゃん?']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [708, 796, 783, 936],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 20.0,
|
|
||||||
lines: ['〜〜っ', 'もっと練習', 'したいんです!!']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [663, 832, 701, 971],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 20.0,
|
|
||||||
lines: ['後藤さんだって', '?の練習あるし...']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [568, 800, 616, 1011],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 20.0,
|
|
||||||
lines: ['ちょっと喜多ちゃん', '急にどうしちゃったの']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [874, 1122, 951, 1380],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 22.0,
|
|
||||||
lines: ['まさか結束パンドの', 'ギター同士で血で血を洗う', 'パート争いを...']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [636, 1135, 682, 1256],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 20.0,
|
|
||||||
lines: ['ちょっと', '結束してよ〜']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
box: [560, 1240, 590, 1381],
|
|
||||||
vertical: true,
|
|
||||||
fontSize: 27.0,
|
|
||||||
lines: ['違います!!']
|
|
||||||
}
|
|
||||||
],
|
|
||||||
imgPath: '049.jpg'
|
|
||||||
};
|
|
||||||
|
|
||||||
let bold = false;
|
let bold = false;
|
||||||
|
|
||||||
$: fontWeight = bold ? 'bold' : '400';
|
$: fontWeight = bold ? 'bold' : '400';
|
||||||
|
|
||||||
console.log(bold);
|
|
||||||
|
|
||||||
function clamp(x: number, min: number, max: number) {
|
function clamp(x: number, min: number, max: number) {
|
||||||
return Math.min(Math.max(x, min), max);
|
return Math.min(Math.max(x, min), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { blocks, imgHeight, imgPath, imgWidth } = page;
|
console.log(page);
|
||||||
const area = imgWidth * imgHeight;
|
|
||||||
|
|
||||||
const textBoxes = blocks.map((block) => {
|
$: textBoxes = page.blocks.map((block) => {
|
||||||
|
const { img_height, img_width } = page;
|
||||||
const { box, fontSize, lines, vertical } = block;
|
const { box, fontSize, lines, vertical } = block;
|
||||||
|
|
||||||
let [_xmin, _ymin, _xmax, _ymax] = box;
|
let [_xmin, _ymin, _xmax, _ymax] = box;
|
||||||
|
|
||||||
const xmin = clamp(_xmin, 0, imgWidth);
|
const xmin = clamp(_xmin, 0, img_width);
|
||||||
const ymin = clamp(_ymin, 0, imgHeight);
|
const ymin = clamp(_ymin, 0, img_height);
|
||||||
const xmax = clamp(_xmax, 0, imgWidth);
|
const xmax = clamp(_xmax, 0, img_width);
|
||||||
const ymax = clamp(_ymax, 0, imgHeight);
|
const ymax = clamp(_ymax, 0, img_height);
|
||||||
|
console.log('ymax', img_width);
|
||||||
|
|
||||||
const width = xmax - xmin;
|
const width = xmax - xmin;
|
||||||
const height = ymax - ymin;
|
const height = ymax - ymin;
|
||||||
@@ -120,11 +51,11 @@
|
|||||||
lines
|
lines
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(textBox);
|
|
||||||
|
|
||||||
return textBox;
|
return textBox;
|
||||||
});
|
});
|
||||||
let src = `/src/lib/assets/${imgPath}`;
|
console.log(textBoxes);
|
||||||
|
|
||||||
|
export let src;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div style:--bold={fontWeight}>
|
<div style:--bold={fontWeight}>
|
||||||
@@ -132,7 +63,7 @@
|
|||||||
<label>Bold</label>
|
<label>Bold</label>
|
||||||
<input bind:checked={bold} type="checkbox" placeholder="????" />
|
<input bind:checked={bold} type="checkbox" placeholder="????" />
|
||||||
</div>
|
</div>
|
||||||
<img draggable="false" {src} alt="Page 1" />
|
<img draggable="false" src={URL.createObjectURL(src)} alt="img" />
|
||||||
{#each textBoxes as { left, top, width, height, lines, fontSize, writingMode }}
|
{#each textBoxes as { left, top, width, height, lines, fontSize, writingMode }}
|
||||||
<div
|
<div
|
||||||
class="text-box"
|
class="text-box"
|
||||||
|
|||||||
@@ -5,14 +5,28 @@
|
|||||||
import MangaPage from './MangaPage.svelte';
|
import MangaPage from './MangaPage.svelte';
|
||||||
|
|
||||||
const volume = $currentVolume;
|
const volume = $currentVolume;
|
||||||
|
let page = 1;
|
||||||
|
|
||||||
|
let pages = volume?.mokuroData.pages;
|
||||||
|
function right() {
|
||||||
|
page++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function left() {
|
||||||
|
if (page > 1) {
|
||||||
|
page--;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if volume}
|
{#if volume}
|
||||||
<div>
|
<div>
|
||||||
<Button on:click={zoomOriginal}>Reset Zoom</Button>
|
<Button on:click={zoomOriginal}>Reset Zoom</Button>
|
||||||
|
<Button on:click={left}>{'<'}</Button>
|
||||||
|
<Button on:click={right}>{'>'}</Button>
|
||||||
</div>
|
</div>
|
||||||
<Panzoom>
|
<Panzoom>
|
||||||
<MangaPage />
|
<MangaPage page={pages[page - 1]} src={Object.values(volume?.files)[page - 1]} />
|
||||||
</Panzoom>
|
</Panzoom>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { currentManga, currentVolume } from '$lib/catalog';
|
import { currentVolume } from '$lib/catalog';
|
||||||
import type { Volume } from '$lib/types/catalog';
|
import type { Volume } from '$lib/upload';
|
||||||
|
|
||||||
export let volume: Volume;
|
export let volume: Volume;
|
||||||
const { cover, title, currentPage, totalPages } = volume;
|
const { volumeName, files } = volume;
|
||||||
|
|
||||||
function onClick() {
|
function onClick() {
|
||||||
currentVolume.set(volume);
|
currentVolume.set(volume);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a href={`${$page.params.manga}/${title}`} on:click={onClick}>
|
<a href={`${$page.params.manga}/${volumeName}`} on:click={onClick}>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{title}
|
{volumeName}
|
||||||
<img src={cover} alt={title} />
|
{#if files}
|
||||||
{currentPage} / {totalPages}
|
<img src={URL.createObjectURL(Object.values(files)[0])} alt="img" />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
export type Volume = {
|
|
||||||
title: string;
|
|
||||||
cover: string;
|
|
||||||
currentPage: number;
|
|
||||||
totalPages: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Manga = {
|
|
||||||
title: string;
|
|
||||||
cover: string;
|
|
||||||
volumes: Volume[];
|
|
||||||
};
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { db } from "$lib/catalog/db";
|
||||||
import { requestPersistentStorage } from "$lib/util/upload";
|
import { requestPersistentStorage } from "$lib/util/upload";
|
||||||
import { BlobReader, ZipReader } from "@zip.js/zip.js";
|
import { BlobReader, ZipReader } from "@zip.js/zip.js";
|
||||||
|
|
||||||
@@ -83,6 +84,6 @@ export async function processFiles(fileList: FileList) {
|
|||||||
if (vols.length > 0) {
|
if (vols.length > 0) {
|
||||||
await requestPersistentStorage();
|
await requestPersistentStorage();
|
||||||
await processVolumes(vols)
|
await processVolumes(vols)
|
||||||
return vols;
|
await db.catalog.put({ manga: vols })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
import { db } from '$lib/catalog/db';
|
||||||
|
import { catalog } from '$lib/catalog/test';
|
||||||
import Button from '$lib/components/Button.svelte';
|
import Button from '$lib/components/Button.svelte';
|
||||||
import Catalog from '$lib/components/Catalog.svelte';
|
import Catalog from '$lib/components/Catalog.svelte';
|
||||||
import Modal from '$lib/components/Modal.svelte';
|
import Modal from '$lib/components/Modal.svelte';
|
||||||
import { showSnackbar } from '$lib/util/snackbar';
|
|
||||||
|
|
||||||
function onClick() {
|
function onClick() {
|
||||||
goto('/upload');
|
goto('/upload');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
db.catalog.clear();
|
||||||
|
}
|
||||||
|
|
||||||
let modal: HTMLDialogElement;
|
let modal: HTMLDialogElement;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button variant="secondary" on:click={onClick}>Upload</Button>
|
<Button variant="secondary" on:click={onClick}>Upload</Button>
|
||||||
|
<Button variant="danger" on:click={clear}>Clear</Button>
|
||||||
|
|
||||||
<Modal bind:modal>
|
<Modal bind:modal>
|
||||||
<div slot="title">Title</div>
|
<div slot="title">Title</div>
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
import { currentManga } from '$lib/catalog';
|
import { currentManga } from '$lib/catalog';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import Button from '$lib/components/Button.svelte';
|
|
||||||
import { panAlign, Panzoom, zoomOriginal } from '$lib/panzoom';
|
|
||||||
import VolumeItem from '$lib/components/VolumeItem.svelte';
|
import VolumeItem from '$lib/components/VolumeItem.svelte';
|
||||||
|
|
||||||
const manga = $currentManga;
|
const manga = $currentManga;
|
||||||
@@ -17,7 +15,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
{#if manga}
|
{#if manga}
|
||||||
{#each manga.volumes as volume}
|
{#each manga as volume}
|
||||||
<VolumeItem {volume} />
|
<VolumeItem {volume} />
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,44 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { db } from '$lib/catalog/db';
|
||||||
import Button from '$lib/components/Button.svelte';
|
import Button from '$lib/components/Button.svelte';
|
||||||
|
import Catalog from '$lib/components/Catalog.svelte';
|
||||||
import FileUpload from '$lib/components/FileUpload.svelte';
|
import FileUpload from '$lib/components/FileUpload.svelte';
|
||||||
import { processFiles, unzipManga, type Volume } from '$lib/upload';
|
import { processFiles } from '$lib/upload';
|
||||||
|
|
||||||
let promise: Promise<Volume[] | undefined> | undefined;
|
let promise: Promise<void>;
|
||||||
|
|
||||||
async function onUpload(files: FileList) {
|
async function onUpload(files: FileList) {
|
||||||
promise = processFiles(files);
|
promise = processFiles(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
function up() {
|
|
||||||
page++;
|
|
||||||
}
|
|
||||||
|
|
||||||
function down() {
|
|
||||||
if (page > 0) {
|
|
||||||
page--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let page = 0;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Note: webkitdirectory is not fully supported and does not work on mobile -->
|
<!-- Note: webkitdirectory is not fully supported and does not work on mobile -->
|
||||||
<Button on:click={down}>{'<'}</Button>
|
|
||||||
<Button on:click={up}>{'>'}</Button>
|
|
||||||
{page}
|
|
||||||
<FileUpload {onUpload} webkitdirectory>Upload directory</FileUpload>
|
<FileUpload {onUpload} webkitdirectory>Upload directory</FileUpload>
|
||||||
<FileUpload {onUpload} accept=".mokuro,.zip,.cbz,.rar" multiple>Upload files</FileUpload>
|
<FileUpload {onUpload} accept=".mokuro,.zip,.cbz,.rar" multiple>Upload files</FileUpload>
|
||||||
{#if promise}
|
|
||||||
{#await promise}
|
{#await promise}
|
||||||
<p>Loading...</p>
|
<h2>Loading...</h2>
|
||||||
{:then volumes}
|
|
||||||
{#if volumes}
|
|
||||||
{#each volumes as { mokuroData, volumeName, archiveFile, files }}
|
|
||||||
<p>{volumeName}</p>
|
|
||||||
{#if files}
|
|
||||||
<img src={URL.createObjectURL(Object.values(files)[page])} alt="img" />
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
{/await}
|
{/await}
|
||||||
{/if}
|
<Catalog />
|
||||||
|
|||||||
Reference in New Issue
Block a user