[FA-27] Bookmark implementation
This commit is contained in:
@@ -1,29 +1,131 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Popover, PopoverTrigger, PopoverContent } from '$lib/components/ui/popover';
|
||||
import { Textarea } from '$lib/components/ui/textarea';
|
||||
import { client } from '$lib/graphql/client';
|
||||
import { UpsertBookmarkDocument, RemoveBookmarkDocument } from '$lib/graphql/__generated__/graphql';
|
||||
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
|
||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||
import List from '@lucide/svelte/icons/list';
|
||||
import Bookmark from '@lucide/svelte/icons/bookmark';
|
||||
import BookmarkCheck from '@lucide/svelte/icons/bookmark-check';
|
||||
|
||||
interface Props {
|
||||
novelId: string;
|
||||
chapterId?: number;
|
||||
prevChapterVolumeOrder: number | null | undefined;
|
||||
prevChapterOrder: number | null | undefined;
|
||||
nextChapterVolumeOrder: number | null | undefined;
|
||||
nextChapterOrder: number | null | undefined;
|
||||
showKeyboardHints?: boolean;
|
||||
isBookmarked?: boolean;
|
||||
bookmarkDescription?: string | null;
|
||||
onBookmarkChange?: (isBookmarked: boolean, description?: string | null) => void;
|
||||
}
|
||||
|
||||
let {
|
||||
novelId,
|
||||
chapterId,
|
||||
prevChapterVolumeOrder,
|
||||
prevChapterOrder,
|
||||
nextChapterVolumeOrder,
|
||||
nextChapterOrder,
|
||||
showKeyboardHints = true
|
||||
showKeyboardHints = true,
|
||||
isBookmarked = false,
|
||||
bookmarkDescription = null,
|
||||
onBookmarkChange
|
||||
}: Props = $props();
|
||||
|
||||
const hasPrev = $derived(prevChapterOrder != null && prevChapterVolumeOrder != null);
|
||||
const hasNext = $derived(nextChapterOrder != null && nextChapterVolumeOrder != null);
|
||||
|
||||
// Bookmark state
|
||||
let popoverOpen = $state(false);
|
||||
let description = $state(bookmarkDescription ?? '');
|
||||
let saving = $state(false);
|
||||
let removing = $state(false);
|
||||
let error: string | null = $state(null);
|
||||
|
||||
// Reset description when popover opens
|
||||
$effect(() => {
|
||||
if (popoverOpen) {
|
||||
description = bookmarkDescription ?? '';
|
||||
error = null;
|
||||
}
|
||||
});
|
||||
|
||||
async function saveBookmark() {
|
||||
if (!chapterId) return;
|
||||
|
||||
saving = true;
|
||||
error = null;
|
||||
|
||||
try {
|
||||
const result = await client
|
||||
.mutation(UpsertBookmarkDocument, {
|
||||
input: {
|
||||
chapterId,
|
||||
novelId: parseInt(novelId, 10),
|
||||
description: description.trim() || null
|
||||
}
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
if (result.error) {
|
||||
error = result.error.message;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.data?.upsertBookmark?.errors?.length) {
|
||||
error = result.data.upsertBookmark.errors[0]?.message ?? 'Failed to save bookmark';
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.data?.upsertBookmark?.bookmarkPayload?.success) {
|
||||
popoverOpen = false;
|
||||
onBookmarkChange?.(true, description.trim() || null);
|
||||
}
|
||||
} catch (e) {
|
||||
error = e instanceof Error ? e.message : 'Failed to save bookmark';
|
||||
} finally {
|
||||
saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function removeBookmark() {
|
||||
if (!chapterId) return;
|
||||
|
||||
removing = true;
|
||||
error = null;
|
||||
|
||||
try {
|
||||
const result = await client
|
||||
.mutation(RemoveBookmarkDocument, {
|
||||
input: { chapterId }
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
if (result.error) {
|
||||
error = result.error.message;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.data?.removeBookmark?.errors?.length) {
|
||||
error = result.data.removeBookmark.errors[0]?.message ?? 'Failed to remove bookmark';
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.data?.removeBookmark?.bookmarkPayload?.success) {
|
||||
popoverOpen = false;
|
||||
description = '';
|
||||
onBookmarkChange?.(false, null);
|
||||
}
|
||||
} catch (e) {
|
||||
error = e instanceof Error ? e.message : 'Failed to remove bookmark';
|
||||
} finally {
|
||||
removing = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -38,10 +140,72 @@
|
||||
<span class="hidden sm:inline">Previous</span>
|
||||
</Button>
|
||||
|
||||
<Button variant="outline" href="/novels/{novelId}" class="gap-2">
|
||||
<List class="h-4 w-4" />
|
||||
<span class="hidden sm:inline">Contents</span>
|
||||
</Button>
|
||||
<div class="flex items-center gap-2">
|
||||
<Button variant="outline" href="/novels/{novelId}" class="gap-2">
|
||||
<List class="h-4 w-4" />
|
||||
<span class="hidden sm:inline">Contents</span>
|
||||
</Button>
|
||||
|
||||
{#if chapterId}
|
||||
<Popover bind:open={popoverOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
{#snippet child({ props })}
|
||||
<Button
|
||||
variant={isBookmarked ? 'default' : 'outline'}
|
||||
class="gap-2"
|
||||
{...props}
|
||||
>
|
||||
{#if isBookmarked}
|
||||
<BookmarkCheck class="h-4 w-4" />
|
||||
{:else}
|
||||
<Bookmark class="h-4 w-4" />
|
||||
{/if}
|
||||
<span class="hidden sm:inline">{isBookmarked ? 'Bookmarked' : 'Bookmark'}</span>
|
||||
</Button>
|
||||
{/snippet}
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-80">
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-2">
|
||||
<h4 class="font-medium leading-none">
|
||||
{isBookmarked ? 'Edit bookmark' : 'Bookmark this chapter'}
|
||||
</h4>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{isBookmarked ? 'Update your note or remove the bookmark.' : 'Add an optional note to remember why you bookmarked this.'}
|
||||
</p>
|
||||
</div>
|
||||
<Textarea
|
||||
bind:value={description}
|
||||
placeholder="Add a note..."
|
||||
class="min-h-[80px] resize-none"
|
||||
/>
|
||||
{#if error}
|
||||
<p class="text-sm text-destructive">{error}</p>
|
||||
{/if}
|
||||
<div class="flex justify-end gap-2">
|
||||
{#if isBookmarked}
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
onclick={removeBookmark}
|
||||
disabled={removing || saving}
|
||||
>
|
||||
{removing ? 'Removing...' : 'Remove'}
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
size="sm"
|
||||
onclick={saveBookmark}
|
||||
disabled={saving || removing}
|
||||
>
|
||||
{saving ? 'Saving...' : 'Save'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script lang="ts" module>
|
||||
import type { GetChapterQuery } from '$lib/graphql/__generated__/graphql';
|
||||
import type { GetChapterQuery, GetBookmarksQuery } from '$lib/graphql/__generated__/graphql';
|
||||
|
||||
export type ChapterData = NonNullable<GetChapterQuery['chapter']>;
|
||||
export type BookmarkData = GetBookmarksQuery['bookmarks'][number];
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { client } from '$lib/graphql/client';
|
||||
import { GetChapterDocument } from '$lib/graphql/__generated__/graphql';
|
||||
import { GetChapterDocument, GetBookmarksDocument } from '$lib/graphql/__generated__/graphql';
|
||||
import { Card, CardContent } from '$lib/components/ui/card';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import ChapterNavigation from './ChapterNavigation.svelte';
|
||||
@@ -28,6 +29,10 @@
|
||||
let error: string | null = $state(null);
|
||||
let scrollProgress = $state(0);
|
||||
|
||||
// Bookmark state
|
||||
let isBookmarked = $state(false);
|
||||
let bookmarkDescription: string | null = $state(null);
|
||||
|
||||
// Derived values
|
||||
const sanitizedBody = $derived(chapter?.body ? sanitizeChapterHtml(chapter.body) : '');
|
||||
|
||||
@@ -78,6 +83,8 @@
|
||||
chapter = result.data.chapter;
|
||||
// Update the page title with chapter info
|
||||
document.title = `${chapter.novelName} - ${chapter.order}`;
|
||||
// Fetch bookmark status
|
||||
await fetchBookmarks();
|
||||
} else {
|
||||
error = 'Chapter not found';
|
||||
}
|
||||
@@ -88,6 +95,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchBookmarks() {
|
||||
if (!novelId || !chapter) return;
|
||||
|
||||
try {
|
||||
const result = await client
|
||||
.query(GetBookmarksDocument, { novelId: parseInt(novelId, 10) })
|
||||
.toPromise();
|
||||
|
||||
if (result.data?.bookmarks) {
|
||||
const bookmark = result.data.bookmarks.find((b) => b.chapterId === chapter!.id);
|
||||
if (bookmark) {
|
||||
isBookmarked = true;
|
||||
bookmarkDescription = bookmark.description ?? null;
|
||||
} else {
|
||||
isBookmarked = false;
|
||||
bookmarkDescription = null;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Silently fail - bookmark status is non-critical
|
||||
}
|
||||
}
|
||||
|
||||
function handleBookmarkChange(newIsBookmarked: boolean, newDescription?: string | null) {
|
||||
isBookmarked = newIsBookmarked;
|
||||
bookmarkDescription = newDescription ?? null;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
fetchChapter();
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
@@ -139,10 +174,14 @@
|
||||
<!-- Navigation (top) -->
|
||||
<ChapterNavigation
|
||||
novelId={novelId ?? ''}
|
||||
chapterId={chapter.id}
|
||||
prevChapterVolumeOrder={chapter.prevChapterVolumeOrder}
|
||||
prevChapterOrder={chapter.prevChapterOrder}
|
||||
nextChapterVolumeOrder={chapter.nextChapterVolumeOrder}
|
||||
nextChapterOrder={chapter.nextChapterOrder}
|
||||
{isBookmarked}
|
||||
{bookmarkDescription}
|
||||
onBookmarkChange={handleBookmarkChange}
|
||||
/>
|
||||
|
||||
<!-- Chapter Header -->
|
||||
@@ -173,11 +212,15 @@
|
||||
<!-- Navigation (bottom) -->
|
||||
<ChapterNavigation
|
||||
novelId={novelId ?? ''}
|
||||
chapterId={chapter.id}
|
||||
prevChapterVolumeOrder={chapter.prevChapterVolumeOrder}
|
||||
prevChapterOrder={chapter.prevChapterOrder}
|
||||
nextChapterVolumeOrder={chapter.nextChapterVolumeOrder}
|
||||
nextChapterOrder={chapter.nextChapterOrder}
|
||||
showKeyboardHints={false}
|
||||
{isBookmarked}
|
||||
{bookmarkDescription}
|
||||
onBookmarkChange={handleBookmarkChange}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<script lang="ts" module>
|
||||
import type { NovelQuery, NovelStatus, Language } from '$lib/graphql/__generated__/graphql';
|
||||
import type { NovelQuery, NovelStatus, Language, GetBookmarksQuery } from '$lib/graphql/__generated__/graphql';
|
||||
import { TagType } from '$lib/graphql/__generated__/graphql';
|
||||
import { SystemTags } from '$lib/constants/systemTags';
|
||||
|
||||
export type BookmarkData = GetBookmarksQuery['bookmarks'][number];
|
||||
|
||||
export type NovelNode = NonNullable<NonNullable<NovelQuery['novels']>['nodes']>[number];
|
||||
|
||||
const statusColors: Record<NovelStatus, string> = {
|
||||
@@ -32,7 +34,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { client } from '$lib/graphql/client';
|
||||
import { NovelDocument, ImportNovelDocument, DeleteNovelDocument } from '$lib/graphql/__generated__/graphql';
|
||||
import { NovelDocument, ImportNovelDocument, DeleteNovelDocument, GetBookmarksDocument } from '$lib/graphql/__generated__/graphql';
|
||||
import { isAuthenticated } from '$lib/auth/authStore';
|
||||
import { Card, CardContent, CardHeader } from '$lib/components/ui/card';
|
||||
import { Badge } from '$lib/components/ui/badge';
|
||||
@@ -98,6 +100,11 @@
|
||||
let activeTab = $state('chapters');
|
||||
let galleryLoaded = $state(false);
|
||||
|
||||
// Bookmarks state
|
||||
let bookmarks: BookmarkData[] = $state([]);
|
||||
let bookmarksLoaded = $state(false);
|
||||
let bookmarksFetching = $state(false);
|
||||
|
||||
const DESCRIPTION_PREVIEW_LENGTH = 300;
|
||||
|
||||
// Derived values
|
||||
@@ -128,6 +135,15 @@
|
||||
|
||||
const isSingleVolume = $derived(sortedVolumes.length === 1);
|
||||
|
||||
// Chapter lookup for bookmarks (maps chapterId to chapter details)
|
||||
const chapterLookup = $derived(
|
||||
new Map(
|
||||
sortedVolumes.flatMap((v) =>
|
||||
v.chapters.map((c) => [c.id, { ...c, volumeOrder: v.order }])
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const chapterCount = $derived(
|
||||
sortedVolumes.reduce((sum, v) => sum + v.chapters.length, 0)
|
||||
);
|
||||
@@ -184,6 +200,34 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Load bookmarks when tab is first activated
|
||||
$effect(() => {
|
||||
if (activeTab === 'bookmarks' && !bookmarksLoaded && novelId) {
|
||||
fetchBookmarks();
|
||||
}
|
||||
});
|
||||
|
||||
async function fetchBookmarks() {
|
||||
if (!novelId || bookmarksFetching) return;
|
||||
|
||||
bookmarksFetching = true;
|
||||
|
||||
try {
|
||||
const result = await client
|
||||
.query(GetBookmarksDocument, { novelId: parseInt(novelId, 10) })
|
||||
.toPromise();
|
||||
|
||||
if (result.data?.bookmarks) {
|
||||
bookmarks = result.data.bookmarks;
|
||||
}
|
||||
} catch {
|
||||
// Silently fail - bookmarks are non-critical
|
||||
} finally {
|
||||
bookmarksFetching = false;
|
||||
bookmarksLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Image viewer functions
|
||||
function openImageViewer(index: number) {
|
||||
viewerIndex = index;
|
||||
@@ -528,10 +572,9 @@
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="bookmarks"
|
||||
disabled
|
||||
class="rounded-md data-[state=active]:bg-background data-[state=active]:shadow-sm px-3 py-1.5 text-sm font-medium transition-all disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
class="rounded-md data-[state=active]:bg-background data-[state=active]:shadow-sm px-3 py-1.5 text-sm font-medium transition-all"
|
||||
>
|
||||
Bookmarks
|
||||
Bookmarks{bookmarksLoaded ? ` (${bookmarks.length})` : ''}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</CardHeader>
|
||||
@@ -646,9 +689,50 @@
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="bookmarks" class="mt-0">
|
||||
<p class="text-muted-foreground text-sm py-8 text-center">
|
||||
Bookmarks coming soon.
|
||||
</p>
|
||||
{#if bookmarksFetching}
|
||||
<div class="flex items-center justify-center py-8">
|
||||
<div
|
||||
class="border-primary h-8 w-8 animate-spin rounded-full border-2 border-t-transparent"
|
||||
aria-label="Loading bookmarks"
|
||||
></div>
|
||||
</div>
|
||||
{:else if bookmarks.length === 0}
|
||||
<p class="text-muted-foreground text-sm py-8 text-center">
|
||||
No bookmarks yet. Add bookmarks while reading chapters.
|
||||
</p>
|
||||
{:else}
|
||||
<div class="max-h-96 overflow-y-auto -mx-2">
|
||||
{#each bookmarks as bookmark (bookmark.id)}
|
||||
{@const chapter = chapterLookup.get(bookmark.chapterId)}
|
||||
{#if chapter}
|
||||
{@const bookmarkDate = new Date(bookmark.createdTime)}
|
||||
<a
|
||||
href="/novels/{novelId}/volumes/{chapter.volumeOrder}/chapters/{chapter.order}"
|
||||
class="flex items-center justify-between px-3 py-2.5 hover:bg-muted/50 rounded-md transition-colors group"
|
||||
>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-muted-foreground text-sm font-medium shrink-0 w-14">
|
||||
Ch. {chapter.order}
|
||||
</span>
|
||||
<span class="text-sm truncate group-hover:text-primary transition-colors">
|
||||
{chapter.name}
|
||||
</span>
|
||||
</div>
|
||||
{#if bookmark.description}
|
||||
<p class="text-xs text-muted-foreground/70 mt-1 ml-[4.25rem] truncate">
|
||||
{bookmark.description}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
<span class="text-xs text-muted-foreground/70 shrink-0 ml-2">
|
||||
{formatRelativeTime(bookmarkDate)}
|
||||
</span>
|
||||
</a>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</TabsContent>
|
||||
</CardContent>
|
||||
</Tabs>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Popover as PopoverPrimitive } from 'bits-ui';
|
||||
import Content from './popover-content.svelte';
|
||||
|
||||
const Root = PopoverPrimitive.Root;
|
||||
const Trigger = PopoverPrimitive.Trigger;
|
||||
const Close = PopoverPrimitive.Close;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Trigger,
|
||||
Content,
|
||||
Close,
|
||||
//
|
||||
Root as Popover,
|
||||
Trigger as PopoverTrigger,
|
||||
Content as PopoverContent,
|
||||
Close as PopoverClose
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { Popover as PopoverPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
sideOffset = 4,
|
||||
align = 'center',
|
||||
class: className,
|
||||
...restProps
|
||||
}: PopoverPrimitive.ContentProps = $props();
|
||||
</script>
|
||||
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
bind:ref
|
||||
data-slot="popover-content"
|
||||
{sideOffset}
|
||||
{align}
|
||||
class={cn(
|
||||
'bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 overflow-hidden rounded-md border p-4 shadow-md outline-none',
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
@@ -0,0 +1,7 @@
|
||||
import Root from './textarea.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Textarea
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||
|
||||
type Props = WithElementRef<HTMLTextareaAttributes, HTMLTextAreaElement>;
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
value = $bindable(),
|
||||
class: className,
|
||||
'data-slot': dataSlot = 'textarea',
|
||||
...restProps
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<textarea
|
||||
bind:this={ref}
|
||||
data-slot={dataSlot}
|
||||
class={cn(
|
||||
'border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex min-h-[80px] w-full min-w-0 rounded-md border px-3 py-2 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
||||
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
||||
className
|
||||
)}
|
||||
bind:value
|
||||
{...restProps}
|
||||
></textarea>
|
||||
@@ -29,6 +29,19 @@ export const ApplyPolicy = {
|
||||
} as const;
|
||||
|
||||
export type ApplyPolicy = typeof ApplyPolicy[keyof typeof ApplyPolicy];
|
||||
export type BookmarkDto = {
|
||||
chapterId: Scalars['UnsignedInt']['output'];
|
||||
createdTime: Scalars['Instant']['output'];
|
||||
description: Maybe<Scalars['String']['output']>;
|
||||
id: Scalars['Int']['output'];
|
||||
novelId: Scalars['UnsignedInt']['output'];
|
||||
};
|
||||
|
||||
export type BookmarkPayload = {
|
||||
bookmark: Maybe<BookmarkDto>;
|
||||
success: Scalars['Boolean']['output'];
|
||||
};
|
||||
|
||||
export type ChapterDto = {
|
||||
body: Scalars['String']['output'];
|
||||
createdTime: Scalars['Instant']['output'];
|
||||
@@ -266,9 +279,11 @@ export type Mutation = {
|
||||
fetchChapterContents: FetchChapterContentsPayload;
|
||||
importNovel: ImportNovelPayload;
|
||||
inviteUser: InviteUserPayload;
|
||||
removeBookmark: RemoveBookmarkPayload;
|
||||
runJob: RunJobPayload;
|
||||
scheduleEventJob: ScheduleEventJobPayload;
|
||||
translateText: TranslateTextPayload;
|
||||
upsertBookmark: UpsertBookmarkPayload;
|
||||
};
|
||||
|
||||
|
||||
@@ -297,6 +312,11 @@ export type MutationInviteUserArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationRemoveBookmarkArgs = {
|
||||
input: RemoveBookmarkInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationRunJobArgs = {
|
||||
input: RunJobInput;
|
||||
};
|
||||
@@ -311,6 +331,11 @@ export type MutationTranslateTextArgs = {
|
||||
input: TranslateTextInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpsertBookmarkArgs = {
|
||||
input: UpsertBookmarkInput;
|
||||
};
|
||||
|
||||
export type NovelDto = {
|
||||
author: PersonDto;
|
||||
coverImage: Maybe<ImageDto>;
|
||||
@@ -471,6 +496,7 @@ export type PersonDtoSortInput = {
|
||||
};
|
||||
|
||||
export type Query = {
|
||||
bookmarks: Array<BookmarkDto>;
|
||||
chapter: Maybe<ChapterReaderDto>;
|
||||
currentUser: Maybe<UserDto>;
|
||||
jobs: Array<SchedulerJob>;
|
||||
@@ -480,6 +506,11 @@ export type Query = {
|
||||
};
|
||||
|
||||
|
||||
export type QueryBookmarksArgs = {
|
||||
novelId: Scalars['UnsignedInt']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryChapterArgs = {
|
||||
chapterOrder: Scalars['UnsignedInt']['input'];
|
||||
novelId: Scalars['UnsignedInt']['input'];
|
||||
@@ -514,6 +545,17 @@ export type QueryTranslationRequestsArgs = {
|
||||
where?: InputMaybe<TranslationRequestDtoFilterInput>;
|
||||
};
|
||||
|
||||
export type RemoveBookmarkError = InvalidOperationError;
|
||||
|
||||
export type RemoveBookmarkInput = {
|
||||
chapterId: Scalars['UnsignedInt']['input'];
|
||||
};
|
||||
|
||||
export type RemoveBookmarkPayload = {
|
||||
bookmarkPayload: Maybe<BookmarkPayload>;
|
||||
errors: Maybe<Array<RemoveBookmarkError>>;
|
||||
};
|
||||
|
||||
export type RunJobError = JobPersistenceError;
|
||||
|
||||
export type RunJobInput = {
|
||||
@@ -739,6 +781,19 @@ export type UnsignedIntOperationFilterInputType = {
|
||||
nlte?: InputMaybe<Scalars['UnsignedInt']['input']>;
|
||||
};
|
||||
|
||||
export type UpsertBookmarkError = InvalidOperationError;
|
||||
|
||||
export type UpsertBookmarkInput = {
|
||||
chapterId: Scalars['UnsignedInt']['input'];
|
||||
description?: InputMaybe<Scalars['String']['input']>;
|
||||
novelId: Scalars['UnsignedInt']['input'];
|
||||
};
|
||||
|
||||
export type UpsertBookmarkPayload = {
|
||||
bookmarkPayload: Maybe<BookmarkPayload>;
|
||||
errors: Maybe<Array<UpsertBookmarkError>>;
|
||||
};
|
||||
|
||||
export type UserDto = {
|
||||
availableInvites: Scalars['Int']['output'];
|
||||
createdTime: Scalars['Instant']['output'];
|
||||
@@ -807,6 +862,27 @@ export type InviteUserMutationVariables = Exact<{
|
||||
|
||||
export type InviteUserMutation = { inviteUser: { userDto: { id: any, username: string, email: string } | null, errors: Array<{ message: string }> | null } };
|
||||
|
||||
export type RemoveBookmarkMutationVariables = Exact<{
|
||||
input: RemoveBookmarkInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type RemoveBookmarkMutation = { removeBookmark: { bookmarkPayload: { success: boolean } | null, errors: Array<{ message: string }> | null } };
|
||||
|
||||
export type UpsertBookmarkMutationVariables = Exact<{
|
||||
input: UpsertBookmarkInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpsertBookmarkMutation = { upsertBookmark: { bookmarkPayload: { success: boolean, bookmark: { id: number, chapterId: any, novelId: any, description: string | null, createdTime: any } | null } | null, errors: Array<{ message: string }> | null } };
|
||||
|
||||
export type GetBookmarksQueryVariables = Exact<{
|
||||
novelId: Scalars['UnsignedInt']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetBookmarksQuery = { bookmarks: Array<{ id: number, chapterId: any, novelId: any, description: string | null, createdTime: any }> };
|
||||
|
||||
export type GetChapterQueryVariables = Exact<{
|
||||
novelId: Scalars['UnsignedInt']['input'];
|
||||
volumeOrder: Scalars['UnsignedInt']['input'];
|
||||
@@ -842,6 +918,9 @@ export type GetSettingsPageDataQuery = { currentUser: { id: any, username: strin
|
||||
export const DeleteNovelDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteNovel"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DeleteNovelInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteNovel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"boolean"}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode<DeleteNovelMutation, DeleteNovelMutationVariables>;
|
||||
export const ImportNovelDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ImportNovel"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ImportNovelInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importNovel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"novelUpdateRequestedEvent"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"novelUrl"}}]}}]}}]}}]} as unknown as DocumentNode<ImportNovelMutation, ImportNovelMutationVariables>;
|
||||
export const InviteUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InviteUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"InviteUserInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inviteUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userDto"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"InvalidOperationError"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode<InviteUserMutation, InviteUserMutationVariables>;
|
||||
export const RemoveBookmarkDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RemoveBookmark"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RemoveBookmarkInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"removeBookmark"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"bookmarkPayload"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode<RemoveBookmarkMutation, RemoveBookmarkMutationVariables>;
|
||||
export const UpsertBookmarkDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertBookmark"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpsertBookmarkInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsertBookmark"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"bookmarkPayload"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"bookmark"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"chapterId"}},{"kind":"Field","name":{"kind":"Name","value":"novelId"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"createdTime"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UpsertBookmarkMutation, UpsertBookmarkMutationVariables>;
|
||||
export const GetBookmarksDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetBookmarks"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"novelId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UnsignedInt"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"bookmarks"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"novelId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"novelId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"chapterId"}},{"kind":"Field","name":{"kind":"Name","value":"novelId"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"createdTime"}}]}}]}}]} as unknown as DocumentNode<GetBookmarksQuery, GetBookmarksQueryVariables>;
|
||||
export const GetChapterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetChapter"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"novelId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UnsignedInt"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"volumeOrder"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UnsignedInt"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"chapterOrder"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UnsignedInt"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"chapter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"novelId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"novelId"}}},{"kind":"Argument","name":{"kind":"Name","value":"volumeOrder"},"value":{"kind":"Variable","name":{"kind":"Name","value":"volumeOrder"}}},{"kind":"Argument","name":{"kind":"Name","value":"chapterOrder"},"value":{"kind":"Variable","name":{"kind":"Name","value":"chapterOrder"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"order"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"body"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"revision"}},{"kind":"Field","name":{"kind":"Name","value":"createdTime"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedTime"}},{"kind":"Field","name":{"kind":"Name","value":"images"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"newPath"}}]}},{"kind":"Field","name":{"kind":"Name","value":"novelId"}},{"kind":"Field","name":{"kind":"Name","value":"novelName"}},{"kind":"Field","name":{"kind":"Name","value":"volumeId"}},{"kind":"Field","name":{"kind":"Name","value":"volumeName"}},{"kind":"Field","name":{"kind":"Name","value":"volumeOrder"}},{"kind":"Field","name":{"kind":"Name","value":"totalChaptersInVolume"}},{"kind":"Field","name":{"kind":"Name","value":"prevChapterVolumeOrder"}},{"kind":"Field","name":{"kind":"Name","value":"prevChapterOrder"}},{"kind":"Field","name":{"kind":"Name","value":"nextChapterVolumeOrder"}},{"kind":"Field","name":{"kind":"Name","value":"nextChapterOrder"}}]}}]}}]} as unknown as DocumentNode<GetChapterQuery, GetChapterQueryVariables>;
|
||||
export const NovelDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Novel"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UnsignedInt"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"novels"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"nodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"rawLanguage"}},{"kind":"Field","name":{"kind":"Name","value":"rawStatus"}},{"kind":"Field","name":{"kind":"Name","value":"statusOverride"}},{"kind":"Field","name":{"kind":"Name","value":"externalId"}},{"kind":"Field","name":{"kind":"Name","value":"createdTime"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedTime"}},{"kind":"Field","name":{"kind":"Name","value":"author"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"externalUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"source"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"coverImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"newPath"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"tagType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"volumes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"order"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdTime"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedTime"}},{"kind":"Field","name":{"kind":"Name","value":"chapters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"order"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedTime"}},{"kind":"Field","name":{"kind":"Name","value":"images"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"newPath"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode<NovelQuery, NovelQueryVariables>;
|
||||
export const NovelsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Novels"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"after"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"where"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"NovelDtoFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"order"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"NovelDtoSortInput"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"novels"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"after"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"Variable","name":{"kind":"Name","value":"where"}}},{"kind":"Argument","name":{"kind":"Name","value":"order"},"value":{"kind":"Variable","name":{"kind":"Name","value":"order"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"coverImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"newPath"}}]}},{"kind":"Field","name":{"kind":"Name","value":"rawStatus"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedTime"}},{"kind":"Field","name":{"kind":"Name","value":"volumes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"order"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"chapters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"tagType"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}}]}}]}}]}}]} as unknown as DocumentNode<NovelsQuery, NovelsQueryVariables>;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
mutation RemoveBookmark($input: RemoveBookmarkInput!) {
|
||||
removeBookmark(input: $input) {
|
||||
bookmarkPayload {
|
||||
success
|
||||
}
|
||||
errors {
|
||||
... on Error {
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
mutation UpsertBookmark($input: UpsertBookmarkInput!) {
|
||||
upsertBookmark(input: $input) {
|
||||
bookmarkPayload {
|
||||
success
|
||||
bookmark {
|
||||
id
|
||||
chapterId
|
||||
novelId
|
||||
description
|
||||
createdTime
|
||||
}
|
||||
}
|
||||
errors {
|
||||
... on Error {
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
query GetBookmarks($novelId: UnsignedInt!) {
|
||||
bookmarks(novelId: $novelId) {
|
||||
id
|
||||
chapterId
|
||||
novelId
|
||||
description
|
||||
createdTime
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user