blob: 30ad89b52c5e9f8daa927560fa7b44c8004b995e (
plain) (
tree)
|
|
<script lang="ts">
import { upsertComics } from '$gql/Mutations';
import { comicScrapersQuery, scrapeComic } from '$gql/Queries';
import { isError } from '$gql/Utils';
import { OnMissing, type FullComicFragment } from '$gql/graphql';
import { ScrapedComicSelector, getScraperContext } from '$lib/Scraper';
import { toastError, toastFinally } from '$lib/Toasts';
import Select from '$lib/components/Select.svelte';
import Spinner from '$lib/components/Spinner.svelte';
import { getContextClient } from '@urql/svelte';
import SelectorGroup from './components/SelectorGroup.svelte';
import SelectorItem from './components/SelectorItem.svelte';
let client = getContextClient();
const context = getScraperContext();
export let comic: FullComicFragment;
let createMissing = false;
let loading = false;
$: scrapersResult = comicScrapersQuery(client, { id: comic.id });
$: scrapers = $scrapersResult.data?.comicScrapers;
function scrape() {
loading = true;
scrapeComic(client, { id: comic.id, scraper: $context.scraper })
.then((result) => {
if (result.error) {
toastError(result.error.message);
return;
}
if (result.data) {
if (isError(result.data.scrapeComic)) {
toastError(result.data.scrapeComic.message);
return;
}
if (result.data.scrapeComic.__typename === 'ScrapeComicResult') {
$context.selector = new ScrapedComicSelector(result.data.scrapeComic.data, comic);
$context.warnings = result.data.scrapeComic.warnings;
}
}
})
.catch(toastFinally)
.finally(() => (loading = false));
}
function updateFromScrape(createMissing: boolean) {
if (!$context.selector) return;
upsertComics(client, {
ids: comic.id,
input: $context.selector.toInput(createMissing ? OnMissing.Create : OnMissing.Ignore)
})
.then(() => {
$context.selector = undefined;
$context.warnings = [];
})
.catch(toastFinally);
}
</script>
<div class="flex flex-col gap-4 text-sm">
{#if scrapers && scrapers.length === 0}
<h2 class="text-base">No scrapers available.</h2>
{:else}
<form on:submit|preventDefault={scrape}>
<div class="grid grid-cols-6 gap-2">
<div class="col-span-5">
<Select
id="scrapers"
options={scrapers}
placeholder={'Select scraper...'}
bind:value={$context.scraper}
/>
</div>
<button type="submit" disabled={!$context.scraper} class="btn-blue">Scrape</button>
</div>
</form>
{/if}
{#if loading}
<Spinner />
{:else if $context.selector}
{#if $context.warnings.length > 0}
<div class="flex flex-col gap-2">
<h2 class="flex gap-1 border-b border-slate-700 text-base font-medium">Warnings</h2>
<ul class="ml-2 list-inside list-disc">
{#each $context.warnings as warning}
<li>{warning}</li>
{/each}
</ul>
</div>
{/if}
{#if !$context.selector.hasData()}
<h2 class="text-base">No data to merge.</h2>
{:else}
<div class="flex flex-col gap-2">
<h2 class="border-b border-slate-700 text-base font-medium">Results</h2>
<form on:submit|preventDefault={() => updateFromScrape(createMissing)}>
<div class="grid grid-cols-6 gap-4 pb-2">
<SelectorItem title="Title" selector={$context.selector.title} />
<SelectorItem title="Original Title" selector={$context.selector.originalTitle} />
<SelectorItem title="URL" selector={$context.selector.url} />
<SelectorItem title="Date" selector={$context.selector.date} --span="2" />
<SelectorItem title="Category" selector={$context.selector.category} --span="2" />
<SelectorItem title="Language" selector={$context.selector.language} --span="2" />
<SelectorItem title="Rating" selector={$context.selector.rating} --span="2" />
<SelectorItem title="Censorship" selector={$context.selector.censorship} --span="2" />
<SelectorItem title="Direction" selector={$context.selector.direction} --span="2" />
<SelectorItem title="Layout" selector={$context.selector.layout} --span="2" />
<SelectorGroup title="Artists" selectors={$context.selector.artists} />
<SelectorGroup title="Circles" selectors={$context.selector.circles} />
<SelectorGroup title="Characters" selectors={$context.selector.characters} />
<SelectorGroup title="Worlds" selectors={$context.selector.worlds} />
<SelectorGroup title="Tags" selectors={$context.selector.tags} />
</div>
<div class="flex flex-col gap-2">
<h2 class="border-b border-slate-700 text-base font-medium">Options</h2>
<div class="flex items-center gap-1">
<input
class="h-4 w-4"
type="checkbox"
id="create-missing"
bind:checked={createMissing}
/>
<label class="shrink-0" for="create-missing">Create missing items</label>
</div>
</div>
<div class="flex gap-4">
<button type="submit" class="btn-blue">Merge</button>
</div>
</form>
</div>
{/if}
{/if}
</div>
|