cyreader 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/server/dist/config/paths.js +3 -0
- package/bundle/server/dist/library/cache.js +70 -0
- package/bundle/server/dist/library/scan.js +54 -8
- package/bundle/server/dist/library/scan.test.js +99 -18
- package/bundle/server/dist/library/service.js +5 -1
- package/bundle/server/dist/library/service.test.js +16 -1
- package/bundle/server/dist/reading/progress/merge.js +5 -4
- package/bundle/server/dist/reading/progress/schema.js +39 -3
- package/bundle/server/dist/reading/progress/schema.test.js +36 -3
- package/bundle/server/dist/reading/progress/service.js +2 -3
- package/bundle/server/dist/reading/progress/service.test.js +10 -9
- package/bundle/server/dist/routes/library.test.js +8 -1
- package/bundle/web/dist/assets/_shell-Bm2pxAQP.js +5 -0
- package/bundle/web/dist/assets/_shell-Cij8gMSv.js +1 -0
- package/bundle/web/dist/assets/comic._id-Djtr8diE.js +1 -0
- package/bundle/web/dist/assets/dist-DzLEGVNH.js +1 -0
- package/bundle/web/dist/assets/dist-QfKKfHSL.js +1 -0
- package/bundle/web/dist/assets/index-BHhqsr5H.js +10 -0
- package/bundle/web/dist/assets/index-D9hL3zrL.css +2 -0
- package/bundle/web/dist/assets/library-D_1sil_O.js +1 -0
- package/bundle/web/dist/assets/library-utils-BRrejTkM.js +1 -0
- package/bundle/web/dist/assets/mutation-ChAIwNv3.js +1 -0
- package/bundle/web/dist/assets/novel._id-C62VYvcl.js +4 -0
- package/bundle/web/dist/assets/query-keys-CbbgiZx4.js +1 -0
- package/bundle/web/dist/assets/reading-BozmJNi1.js +1 -0
- package/bundle/web/dist/assets/reading-progress-C5bkK-vF.js +1 -0
- package/bundle/web/dist/assets/save-reading-progress-D231ROaQ.js +1 -0
- package/bundle/web/dist/assets/scroll-area-CyEO8R_G.js +1 -0
- package/bundle/web/dist/assets/{settings-2-CCv0KiQI.js → settings-2-8mnAuSax.js} +1 -1
- package/bundle/web/dist/assets/settings-BRi0XyRg.js +1 -0
- package/bundle/web/dist/assets/shell-context-Buw4m44t.js +41 -0
- package/bundle/web/dist/assets/use-library-Bh7Bunn1.js +1 -0
- package/bundle/web/dist/assets/{useNavigate-BMyovDLu.js → useNavigate-B29ssGbr.js} +1 -1
- package/bundle/web/dist/assets/useRouterState-4dM5FKiy.js +1 -0
- package/bundle/web/dist/assets/utils-ChkMmPzE.js +1 -0
- package/bundle/web/dist/index.html +5 -5
- package/package.json +2 -2
- package/bundle/server/dist/app.test.js +0 -9
- package/bundle/web/dist/assets/_shell-Co1KI-wo.js +0 -5
- package/bundle/web/dist/assets/_shell-bNqNRnHj.js +0 -1
- package/bundle/web/dist/assets/comic._id-CC6qdNbU.js +0 -1
- package/bundle/web/dist/assets/dist-CqonX7c8.js +0 -1
- package/bundle/web/dist/assets/image-BZKAkGUy.js +0 -1
- package/bundle/web/dist/assets/index-BQZoypuf.css +0 -2
- package/bundle/web/dist/assets/index-Pdit8x1d.js +0 -10
- package/bundle/web/dist/assets/input-tgPw9P7N.js +0 -41
- package/bundle/web/dist/assets/library-g-QZ29Jj.js +0 -1
- package/bundle/web/dist/assets/mutation-CwzbY9ri.js +0 -1
- package/bundle/web/dist/assets/novel._id-ByrQLxAT.js +0 -4
- package/bundle/web/dist/assets/query-keys-CDsPIOEO.js +0 -1
- package/bundle/web/dist/assets/reading-BseNE7P3.js +0 -1
- package/bundle/web/dist/assets/reading-progress-BcmbUd_d.js +0 -1
- package/bundle/web/dist/assets/save-reading-progress-yvAw7ZNh.js +0 -1
- package/bundle/web/dist/assets/scroll-area-awhNOWo3.js +0 -1
- package/bundle/web/dist/assets/settings-DmjzIwkt.js +0 -1
- package/bundle/web/dist/assets/shell-context-BT0BT8PF.js +0 -1
- package/bundle/web/dist/assets/toggle-group-CLpSuWfq.js +0 -1
- package/bundle/web/dist/assets/utils-BmM72imW.js +0 -1
|
@@ -4,6 +4,7 @@ import path from 'node:path';
|
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
5
|
import { NotFoundError } from '../../library/errors.js';
|
|
6
6
|
import { LibraryService } from '../../library/service.js';
|
|
7
|
+
import { writeTestImage } from '../../library/test-images.js';
|
|
7
8
|
import { ProgressService } from './service.js';
|
|
8
9
|
import { readProgressStoreFromDisk } from './storage.js';
|
|
9
10
|
describe('ProgressService', () => {
|
|
@@ -26,9 +27,9 @@ describe('ProgressService', () => {
|
|
|
26
27
|
await mkdir(novelRoot);
|
|
27
28
|
await mkdir(mangaDir, { recursive: true });
|
|
28
29
|
await writeFile(path.join(novelRoot, 'book.txt'), 'line one\n\nline two');
|
|
29
|
-
await
|
|
30
|
-
await
|
|
31
|
-
await
|
|
30
|
+
await writeTestImage(path.join(mangaDir, '1.jpg'), 300, 400);
|
|
31
|
+
await writeTestImage(path.join(mangaDir, '2.jpg'), 300, 400);
|
|
32
|
+
await writeTestImage(path.join(mangaDir, '3.jpg'), 300, 400);
|
|
32
33
|
libraryService = new LibraryService(() => ({
|
|
33
34
|
novelDirectories: [{ id: 'novel-root', path: novelRoot }],
|
|
34
35
|
comicDirectories: [{ id: 'comic-root', path: comicRoot }],
|
|
@@ -49,21 +50,21 @@ describe('ProgressService', () => {
|
|
|
49
50
|
}
|
|
50
51
|
await rm(tempDir, { recursive: true, force: true });
|
|
51
52
|
});
|
|
52
|
-
it('saves and reads comic progress with clamped
|
|
53
|
+
it('saves and reads comic progress with clamped scroll ratio', async () => {
|
|
53
54
|
const entry = await progressService.saveProgress(comicId, {
|
|
54
55
|
type: 'comic',
|
|
55
|
-
|
|
56
|
+
scrollRatio: 1.5,
|
|
56
57
|
});
|
|
57
58
|
expect(entry).toEqual({
|
|
58
59
|
type: 'comic',
|
|
59
|
-
|
|
60
|
+
scrollRatio: 1,
|
|
60
61
|
updatedAt: expect.any(String),
|
|
61
62
|
});
|
|
62
63
|
const map = await progressService.getProgressMap();
|
|
63
64
|
const comicProgress = map[comicId];
|
|
64
65
|
expect(comicProgress?.type).toBe('comic');
|
|
65
|
-
if (comicProgress?.type === 'comic') {
|
|
66
|
-
expect(comicProgress.
|
|
66
|
+
if (comicProgress?.type === 'comic' && 'scrollRatio' in comicProgress) {
|
|
67
|
+
expect(comicProgress.scrollRatio).toBe(1);
|
|
67
68
|
}
|
|
68
69
|
});
|
|
69
70
|
it('saves novel progress', async () => {
|
|
@@ -83,7 +84,7 @@ describe('ProgressService', () => {
|
|
|
83
84
|
await expect(progressService.saveProgress('missing', { type: 'novel', paragraphIndex: 0 })).rejects.toBeInstanceOf(NotFoundError);
|
|
84
85
|
});
|
|
85
86
|
it('throws when progress type mismatches item type', async () => {
|
|
86
|
-
await expect(progressService.saveProgress(novelId, { type: 'comic',
|
|
87
|
+
await expect(progressService.saveProgress(novelId, { type: 'comic', scrollRatio: 0 })).rejects.toBeInstanceOf(TypeError);
|
|
87
88
|
});
|
|
88
89
|
it('prunes stale progress entries', async () => {
|
|
89
90
|
await progressService.saveProgress(novelId, { type: 'novel', paragraphIndex: 1 });
|
|
@@ -59,12 +59,14 @@ describe('library routes', () => {
|
|
|
59
59
|
id: expect.any(String),
|
|
60
60
|
type: 'novel',
|
|
61
61
|
title: 'book',
|
|
62
|
+
addedAt: expect.any(String),
|
|
62
63
|
progress: null,
|
|
63
64
|
},
|
|
64
65
|
{
|
|
65
66
|
id: expect.any(String),
|
|
66
67
|
type: 'comic',
|
|
67
68
|
title: 'manga',
|
|
69
|
+
addedAt: expect.any(String),
|
|
68
70
|
cover: expect.stringMatching(/^\/static\/comic-root\/manga\/cover\.jpg$/),
|
|
69
71
|
pageCount: 2,
|
|
70
72
|
progress: null,
|
|
@@ -80,6 +82,7 @@ describe('library routes', () => {
|
|
|
80
82
|
id: novel.id,
|
|
81
83
|
type: 'novel',
|
|
82
84
|
title: 'book',
|
|
85
|
+
addedAt: expect.any(String),
|
|
83
86
|
directoryId: 'novel-root',
|
|
84
87
|
filename: 'book.txt',
|
|
85
88
|
progress: null,
|
|
@@ -102,8 +105,12 @@ describe('library routes', () => {
|
|
|
102
105
|
id: comic.id,
|
|
103
106
|
type: 'comic',
|
|
104
107
|
title: 'manga',
|
|
108
|
+
addedAt: expect.any(String),
|
|
105
109
|
directoryId: 'comic-root',
|
|
106
|
-
pages: [
|
|
110
|
+
pages: [
|
|
111
|
+
{ filename: '1.jpg', width: 300, height: 400 },
|
|
112
|
+
{ filename: '2.jpg', width: 300, height: 400 },
|
|
113
|
+
],
|
|
107
114
|
progress: null,
|
|
108
115
|
});
|
|
109
116
|
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{Y as e,a as t,b as n,c as r,f as i,g as a,h as o,i as s,l as c,p as l,s as u,t as d,u as f,x as p}from"./utils-ChkMmPzE.js";import{a as m,i as h,r as g}from"./query-keys-CbbgiZx4.js";import{i as _,r as ee,t as te}from"./use-library-Bh7Bunn1.js";import{t as ne}from"./useNavigate-B29ssGbr.js";import{t as v}from"./useRouterState-4dM5FKiy.js";import{a as re,t as ie}from"./library-utils-BRrejTkM.js";import{a as ae,i as oe,o as se,s as ce,t as le}from"./shell-context-Buw4m44t.js";import{a as ue,f as de,i as fe,m as y,p as pe,r as me,v as he,y as ge}from"./index-BHhqsr5H.js";var _e=a(`bookmark`,[[`path`,{d:`M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z`,key:`oz39mx`}]]),ve=a(`circle-check-big`,[[`path`,{d:`M21.801 10A10 10 0 1 1 17 3.335`,key:`yps3ct`}],[`path`,{d:`m9 11 3 3L22 4`,key:`1pflzl`}]]),ye=a(`circle-plus`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M8 12h8`,key:`1wcyev`}],[`path`,{d:`M12 8v8`,key:`napkw2`}]]),be=a(`layers`,[[`path`,{d:`M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z`,key:`zw3jo`}],[`path`,{d:`M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12`,key:`1wduqc`}],[`path`,{d:`M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17`,key:`kqbvx6`}]]),xe=a(`library`,[[`path`,{d:`m16 6 4 14`,key:`ji33uf`}],[`path`,{d:`M12 6v14`,key:`1n7gus`}],[`path`,{d:`M8 8v12`,key:`1gg7y9`}],[`path`,{d:`M4 4v16`,key:`6qkkli`}]]),Se=a(`settings`,[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),b=e(p(),1),x=n(),S=`Dialog`,[C,Ce]=c(S),[we,w]=C(S),T=e=>{let{__scopeDialog:n,children:r,open:i,defaultOpen:a,onOpenChange:o,modal:c=!0}=e,l=b.useRef(null),u=b.useRef(null),[d,f]=t({prop:i,defaultProp:a??!1,onChange:o,caller:S});return(0,x.jsx)(we,{scope:n,triggerRef:l,contentRef:u,contentId:s(),titleId:s(),descriptionId:s(),open:d,onOpenChange:f,onOpenToggle:b.useCallback(()=>f(e=>!e),[f]),modal:c,children:r})};T.displayName=S;var E=`DialogTrigger`,Te=b.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=w(E,n),a=o(t,i.triggerRef);return(0,x.jsx)(f.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.open?i.contentId:void 0,"data-state":V(i.open),...r,ref:a,onClick:u(e.onClick,i.onOpenToggle)})});Te.displayName=E;var D=`DialogPortal`,[Ee,O]=C(D,{forceMount:void 0}),k=e=>{let{__scopeDialog:t,forceMount:n,children:r,container:i}=e,a=w(D,t);return(0,x.jsx)(Ee,{scope:t,forceMount:n,children:b.Children.map(r,e=>(0,x.jsx)(y,{present:n||a.open,children:(0,x.jsx)(de,{asChild:!0,container:i,children:e})}))})};k.displayName=D;var A=`DialogOverlay`,j=b.forwardRef((e,t)=>{let n=O(A,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=w(A,e.__scopeDialog);return a.modal?(0,x.jsx)(y,{present:r||a.open,children:(0,x.jsx)(Oe,{...i,ref:t})}):null});j.displayName=A;var De=l(`DialogOverlay.RemoveScroll`),Oe=b.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=w(A,n);return(0,x.jsx)(ae,{as:De,allowPinchZoom:!0,shards:[i.contentRef],children:(0,x.jsx)(f.div,{"data-state":V(i.open),...r,ref:t,style:{pointerEvents:`auto`,...r.style}})})}),M=`DialogContent`,N=b.forwardRef((e,t)=>{let n=O(M,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=w(M,e.__scopeDialog);return(0,x.jsx)(y,{present:r||a.open,children:a.modal?(0,x.jsx)(ke,{...i,ref:t}):(0,x.jsx)(Ae,{...i,ref:t})})});N.displayName=M;var ke=b.forwardRef((e,t)=>{let n=w(M,e.__scopeDialog),r=b.useRef(null),i=o(t,n.contentRef,r);return b.useEffect(()=>{let e=r.current;if(e)return oe(e)},[]),(0,x.jsx)(P,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:n.open,onCloseAutoFocus:u(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:u(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;(t.button===2||n)&&e.preventDefault()}),onFocusOutside:u(e.onFocusOutside,e=>e.preventDefault())})}),Ae=b.forwardRef((e,t)=>{let n=w(M,e.__scopeDialog),r=b.useRef(!1),i=b.useRef(!1);return(0,x.jsx)(P,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})}),P=b.forwardRef((e,t)=>{let{__scopeDialog:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,...s}=e,c=w(M,n),l=b.useRef(null),u=o(t,l);return se(),(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(ce,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,x.jsx)(pe,{role:`dialog`,id:c.contentId,"aria-describedby":c.descriptionId,"aria-labelledby":c.titleId,"data-state":V(c.open),...s,ref:u,onDismiss:()=>c.onOpenChange(!1)})}),(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Me,{titleId:c.titleId}),(0,x.jsx)(Pe,{contentRef:l,descriptionId:c.descriptionId})]})]})}),F=`DialogTitle`,I=b.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=w(F,n);return(0,x.jsx)(f.h2,{id:i.titleId,...r,ref:t})});I.displayName=F;var L=`DialogDescription`,R=b.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=w(L,n);return(0,x.jsx)(f.p,{id:i.descriptionId,...r,ref:t})});R.displayName=L;var z=`DialogClose`,B=b.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=w(z,n);return(0,x.jsx)(f.button,{type:`button`,...r,ref:t,onClick:u(e.onClick,()=>i.onOpenChange(!1))})});B.displayName=z;function V(e){return e?`open`:`closed`}var H=`DialogTitleWarning`,[je,U]=r(H,{contentName:M,titleName:F,docsSlug:`dialog`}),Me=({titleId:e})=>{let t=U(H),n=`\`${t.contentName}\` requires a \`${t.titleName}\` for the component to be accessible for screen reader users.
|
|
2
|
+
|
|
3
|
+
If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component.
|
|
4
|
+
|
|
5
|
+
For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return b.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},Ne=`DialogDescriptionWarning`,Pe=({contentRef:e,descriptionId:t})=>{let n=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${U(Ne).contentName}}.`;return b.useEffect(()=>{let r=e.current?.getAttribute(`aria-describedby`);t&&r&&(document.getElementById(t)||console.warn(n))},[n,e,t]),null},Fe=T,Ie=k,Le=j,Re=N,ze=I,Be=R,Ve=B,W=768;function He(){let[e,t]=b.useState(void 0);return b.useEffect(()=>{let e=window.matchMedia(`(max-width: ${W-1}px)`),n=()=>{t(window.innerWidth<W)};return e.addEventListener(`change`,n),t(window.innerWidth<W),()=>e.removeEventListener(`change`,n)},[]),!!e}function Ue({...e}){return(0,x.jsx)(Fe,{"data-slot":`sheet`,...e})}function We({...e}){return(0,x.jsx)(Ie,{"data-slot":`sheet-portal`,...e})}function Ge({className:e,...t}){return(0,x.jsx)(Le,{"data-slot":`sheet-overlay`,className:d(`fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0`,e),...t})}function Ke({className:e,children:t,side:n=`right`,showCloseButton:r=!0,...i}){return(0,x.jsxs)(We,{children:[(0,x.jsx)(Ge,{}),(0,x.jsxs)(Re,{"data-slot":`sheet-content`,"data-side":n,className:d(`fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10`,e),...i,children:[t,r&&(0,x.jsx)(Ve,{"data-slot":`sheet-close`,asChild:!0,children:(0,x.jsxs)(h,{variant:`ghost`,className:`absolute top-3 right-3`,size:`icon-sm`,children:[(0,x.jsx)(re,{}),(0,x.jsx)(`span`,{className:`sr-only`,children:`Close`})]})})]})]})}function qe({className:e,...t}){return(0,x.jsx)(`div`,{"data-slot":`sheet-header`,className:d(`flex flex-col gap-0.5 p-4`,e),...t})}function Je({className:e,...t}){return(0,x.jsx)(ze,{"data-slot":`sheet-title`,className:d(`font-heading text-base font-medium text-foreground`,e),...t})}function Ye({className:e,...t}){return(0,x.jsx)(Be,{"data-slot":`sheet-description`,className:d(`text-sm text-muted-foreground`,e),...t})}var Xe=`sidebar_state`,Ze=3600*24*7,Qe=`16rem`,$e=`18rem`,et=`3rem`,tt=`b`,G=b.createContext(null);function K(){let e=b.useContext(G);if(!e)throw Error(`useSidebar must be used within a SidebarProvider.`);return e}function nt({defaultOpen:e=!0,open:t,onOpenChange:n,className:r,style:i,children:a,...o}){let s=He(),[c,l]=b.useState(!1),[u,f]=b.useState(e),p=t??u,m=b.useCallback(e=>{let t=typeof e==`function`?e(p):e;n?n(t):f(t),document.cookie=`${Xe}=${t}; path=/; max-age=${Ze}`},[n,p]),h=b.useCallback(()=>s?l(e=>!e):m(e=>!e),[s,m,l]);b.useEffect(()=>{let e=e=>{e.key===tt&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),h())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[h]);let g=p?`expanded`:`collapsed`,_=b.useMemo(()=>({state:g,open:p,setOpen:m,isMobile:s,openMobile:c,setOpenMobile:l,toggleSidebar:h}),[g,p,m,s,c,l,h]);return(0,x.jsx)(G.Provider,{value:_,children:(0,x.jsx)(`div`,{"data-slot":`sidebar-wrapper`,style:{"--sidebar-width":Qe,"--sidebar-width-icon":et,...i},className:d(`group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar`,r),...o,children:a})})}function rt({side:e=`left`,variant:t=`sidebar`,collapsible:n=`offcanvas`,className:r,children:i,dir:a,...o}){let{isMobile:s,state:c,openMobile:l,setOpenMobile:u}=K();return n===`none`?(0,x.jsx)(`div`,{"data-slot":`sidebar`,className:d(`flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground`,r),...o,children:i}):s?(0,x.jsx)(Ue,{open:l,onOpenChange:u,...o,children:(0,x.jsxs)(Ke,{dir:a,"data-sidebar":`sidebar`,"data-slot":`sidebar`,"data-mobile":`true`,className:`w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden`,style:{"--sidebar-width":$e},side:e,children:[(0,x.jsxs)(qe,{className:`sr-only`,children:[(0,x.jsx)(Je,{children:`Sidebar`}),(0,x.jsx)(Ye,{children:`Displays the mobile sidebar.`})]}),(0,x.jsx)(`div`,{className:`flex h-full w-full flex-col`,children:i})]})}):(0,x.jsxs)(`div`,{className:`group peer hidden text-sidebar-foreground md:block`,"data-state":c,"data-collapsible":c===`collapsed`?n:``,"data-variant":t,"data-side":e,"data-slot":`sidebar`,children:[(0,x.jsx)(`div`,{"data-slot":`sidebar-gap`,className:d(`relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear`,`group-data-[collapsible=offcanvas]:w-0`,`group-data-[side=right]:rotate-180`,t===`floating`||t===`inset`?`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon)`)}),(0,x.jsx)(`div`,{"data-slot":`sidebar-container`,"data-side":e,className:d(`fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex`,t===`floating`||t===`inset`?`p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l`,r),...o,children:(0,x.jsx)(`div`,{"data-sidebar":`sidebar`,"data-slot":`sidebar-inner`,className:`flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border`,children:i})})]})}function it({className:e,...t}){return(0,x.jsx)(`main`,{"data-slot":`sidebar-inset`,className:d(`relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2`,e),...t})}function at({className:e,...t}){return(0,x.jsx)(`div`,{"data-slot":`sidebar-header`,"data-sidebar":`header`,className:d(`flex flex-col gap-2 p-2`,e),...t})}function ot({className:e,...t}){return(0,x.jsx)(`div`,{"data-slot":`sidebar-footer`,"data-sidebar":`footer`,className:d(`flex flex-col gap-2 p-2`,e),...t})}function st({className:e,...t}){return(0,x.jsx)(`div`,{"data-slot":`sidebar-content`,"data-sidebar":`content`,className:d(`no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,e),...t})}function q({className:e,...t}){return(0,x.jsx)(`div`,{"data-slot":`sidebar-group`,"data-sidebar":`group`,className:d(`relative flex w-full min-w-0 flex-col p-2`,e),...t})}function J({className:e,asChild:t=!1,...n}){return(0,x.jsx)(t?i:`div`,{"data-slot":`sidebar-group-label`,"data-sidebar":`group-label`,className:d(`flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0`,e),...n})}function Y({className:e,...t}){return(0,x.jsx)(`div`,{"data-slot":`sidebar-group-content`,"data-sidebar":`group-content`,className:d(`w-full text-sm`,e),...t})}function X({className:e,...t}){return(0,x.jsx)(`ul`,{"data-slot":`sidebar-menu`,"data-sidebar":`menu`,className:d(`flex w-full min-w-0 flex-col gap-0`,e),...t})}function Z({className:e,...t}){return(0,x.jsx)(`li`,{"data-slot":`sidebar-menu-item`,"data-sidebar":`menu-item`,className:d(`group/menu-item relative`,e),...t})}var ct=m(`peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate`,{variants:{variant:{default:`hover:bg-sidebar-accent hover:text-sidebar-accent-foreground`,outline:`bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]`},size:{default:`h-8 text-sm`,sm:`h-7 text-xs`,lg:`h-12 text-sm group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}});function Q({asChild:e=!1,isActive:t=!1,variant:n=`default`,size:r=`default`,tooltip:a,className:o,...s}){let c=e?i:`button`,{isMobile:l,state:u}=K(),f=(0,x.jsx)(c,{"data-slot":`sidebar-menu-button`,"data-sidebar":`menu-button`,"data-size":r,"data-active":t,className:d(ct({variant:n,size:r}),o),...s});return a?(typeof a==`string`&&(a={children:a}),(0,x.jsxs)(me,{children:[(0,x.jsx)(ue,{asChild:!0,children:f}),(0,x.jsx)(fe,{side:`right`,align:`center`,hidden:u!==`collapsed`||l,...a})]})):f}function $(e,t){return e.filter(e=>e.type===t).length}function lt({items:e,activeFilter:t,onFilterChange:n}){let r=v({select:e=>e.location.pathname})===`/settings`,i=ie(e),a=[{id:`all`,label:`全部`,icon:be,count:e.length},{id:`novel`,label:`小说`,icon:_,count:$(e,`novel`)},{id:`comic`,label:`漫画`,icon:ee,count:$(e,`comic`)}],o=[{id:`reading`,label:`阅读中`,icon:_e,count:i.reading},{id:`unread`,label:`未开始`,icon:ye,count:i.unread},{id:`completed`,label:`已完成`,icon:ve,count:i.completed}],s=`h-9 text-[13px] text-[#9f9fad] hover:bg-[#1e1e24] hover:text-[#d5d5dd] data-[active=true]:bg-[#1e1e24] data-[active=true]:font-normal data-[active=true]:text-[#e2e2e8]`;return(0,x.jsxs)(rt,{collapsible:`none`,className:`w-[220px] shrink-0 border-r border-sidebar-border bg-sidebar`,children:[(0,x.jsx)(at,{className:`border-b border-sidebar-border px-[18px] py-3.5`,children:(0,x.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[(0,x.jsx)(`div`,{className:`flex size-7 items-center justify-center rounded-md bg-indigo-500`,children:(0,x.jsx)(xe,{className:`size-4 text-white`})}),(0,x.jsx)(`span`,{className:`text-[15px] font-bold tracking-wide text-[#f3f3f7]`,children:`CYReader`})]})}),(0,x.jsxs)(st,{className:`px-3 py-2`,children:[(0,x.jsxs)(q,{children:[(0,x.jsx)(J,{className:`px-2 text-[11px] font-semibold tracking-[0.8px] text-[#6b6b78] uppercase`,children:`书库`}),(0,x.jsx)(Y,{children:(0,x.jsx)(X,{className:`gap-1`,children:a.map(e=>(0,x.jsx)(Z,{children:(0,x.jsxs)(Q,{isActive:!r&&t===e.id,onClick:()=>n(e.id),className:s,children:[(0,x.jsx)(e.icon,{}),(0,x.jsx)(`span`,{children:e.label}),(0,x.jsx)(`span`,{className:`ml-auto text-[11px] font-medium text-[#6b6b78]`,children:e.count})]})},e.id))})})]}),(0,x.jsxs)(q,{children:[(0,x.jsx)(J,{className:`px-2 text-[11px] font-semibold tracking-[0.8px] text-[#6b6b78] uppercase`,children:`阅读状态`}),(0,x.jsx)(Y,{children:(0,x.jsx)(X,{className:`gap-1`,children:o.map(e=>(0,x.jsx)(Z,{children:(0,x.jsxs)(Q,{isActive:!r&&t===e.id,onClick:()=>n(e.id),className:s,children:[(0,x.jsx)(e.icon,{}),(0,x.jsx)(`span`,{children:e.label}),(0,x.jsx)(`span`,{className:`ml-auto text-[11px] font-medium text-[#6b6b78]`,children:e.count})]})},e.id))})})]})]}),(0,x.jsx)(ot,{className:`border-t border-sidebar-border px-3 py-2`,children:(0,x.jsx)(X,{children:(0,x.jsx)(Z,{children:(0,x.jsx)(Q,{asChild:!0,isActive:r,className:d(s,!r&&`text-[#6b6b78]`,r&&`bg-[#1e1e24] text-[#e2e2e8]`),children:(0,x.jsxs)(ge,{to:`/settings`,children:[(0,x.jsx)(Se,{}),(0,x.jsx)(`span`,{children:`设置`})]})})})})})]})}function ut(){let e=ne(),t=v({select:e=>e.location.pathname}),{state:n,loading:r,refresh:i}=te(),[a,o]=(0,b.useState)(`all`),s=n?.items??[];return(0,x.jsxs)(nt,{defaultOpen:!0,className:`h-screen overflow-hidden`,children:[(0,x.jsx)(lt,{items:s,activeFilter:a,onFilterChange:n=>{o(n),t!==`/`&&e({to:`/`})}}),(0,x.jsx)(it,{className:`min-w-0 overflow-hidden`,children:r&&t===`/`?(0,x.jsxs)(`div`,{className:`flex flex-col gap-3 p-5`,children:[(0,x.jsx)(g,{className:`h-10 w-full max-w-lg`}),(0,x.jsx)(g,{className:`h-40 w-full`})]}):(0,x.jsx)(le,{value:{filter:a,items:s,scanning:n?.scanning??!1,refreshLibrary:i},children:(0,x.jsx)(he,{})})})]})}export{ut as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Y as e,b as t,f as n,g as r,t as i,x as a}from"./utils-ChkMmPzE.js";import{a as o,i as s,o as c,r as l,t as u}from"./query-keys-CbbgiZx4.js";import{t as ee}from"./useNavigate-B29ssGbr.js";import{a as d,i as f,n as p,o as m,r as h,s as g,t as _}from"./scroll-area-CyEO8R_G.js";import{a as v,i as y,n as te,r as ne}from"./library-utils-BRrejTkM.js";import{n as b,r as x}from"./shell-context-Buw4m44t.js";import{a as S,i as C,t as w}from"./reading-BozmJNi1.js";import{a as T,i as E}from"./reading-progress-C5bkK-vF.js";var D=r(`clock`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 6v6l4 2`,key:`mmk7yg`}]]),O=r(`layout-grid`,[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]),k=r(`list`,[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]),A=r(`search-x`,[[`path`,{d:`m13.5 8.5-5 5`,key:`1cs55j`}],[`path`,{d:`m8.5 8.5 5 5`,key:`a8mexj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}],[`path`,{d:`m21 21-4.3-4.3`,key:`1qie3q`}]]),j=r(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),M=e(a(),1),N=t();function P({className:e,...t}){return(0,N.jsx)(`div`,{"data-slot":`empty`,className:i(`flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-xl border-dashed p-6 text-center text-balance`,e),...t})}function F({className:e,...t}){return(0,N.jsx)(`div`,{"data-slot":`empty-header`,className:i(`flex max-w-sm flex-col items-center gap-2`,e),...t})}var I=o(`mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{default:`bg-transparent`,icon:`flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-4`}},defaultVariants:{variant:`default`}});function L({className:e,variant:t=`default`,...n}){return(0,N.jsx)(`div`,{"data-slot":`empty-icon`,"data-variant":t,className:i(I({variant:t,className:e})),...n})}function R({className:e,...t}){return(0,N.jsx)(`div`,{"data-slot":`empty-title`,className:i(`font-heading text-sm font-medium tracking-tight`,e),...t})}function z({className:e,...t}){return(0,N.jsx)(`div`,{"data-slot":`empty-description`,className:i(`text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary`,e),...t})}var B=o(`group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!`,{variants:{variant:{default:`bg-primary text-primary-foreground [a]:hover:bg-primary/80`,secondary:`bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80`,destructive:`bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20`,outline:`border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground`,ghost:`hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50`,link:`text-primary underline-offset-4 hover:underline`}},defaultVariants:{variant:`default`}});function re({className:e,variant:t=`default`,asChild:r=!1,...a}){return(0,N.jsx)(r?n:`span`,{"data-slot":`badge`,"data-variant":t,className:i(B({variant:t}),e),...a})}var V=`/novel-default-cover.png`;function H(e){return e.type===`comic`?e.cover:V}function U(e,t){if(t.type===`novel`){e({to:`/read/novel/$id`,params:{id:t.id},state:{readerTitle:t.title}});return}e({to:`/read/comic/$id`,params:{id:t.id},state:{readerTitle:t.title}})}var W=`h-[180px]`,G=`h-16`,K=`h-[244px]`,q={reading:`bg-indigo-500 shadow-[0_0_6px_rgba(99,102,241,0.4)]`,unread:`bg-green-500 shadow-[0_0_6px_rgba(34,197,94,0.4)]`,completed:`bg-muted-foreground`};function J({item:e,view:t}){let n=ee(),r=()=>{U(n,e)},a=E(e.progress),o=T(e);return t===`list`?(0,N.jsxs)(`button`,{type:`button`,onClick:r,className:`flex h-14 w-full items-stretch overflow-hidden rounded-md border border-[#25252a] bg-[#1a1a20] text-left transition-colors hover:border-[#3a3a44]`,children:[(0,N.jsx)(`div`,{className:`relative h-full w-10 shrink-0 overflow-hidden bg-muted`,children:(0,N.jsx)(`img`,{src:H(e),alt:``,className:`absolute inset-0 block size-full object-cover`,loading:`lazy`})}),(0,N.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-center gap-4 px-3.5`,children:[(0,N.jsx)(`div`,{className:`min-w-0 flex-1 truncate text-xs font-semibold text-[#e2e2e8]`,children:e.title}),(0,N.jsx)(`div`,{className:`min-w-[100px]`,children:(0,N.jsx)(`div`,{className:`h-[3px] w-full overflow-hidden rounded-full bg-[#2a2a32]`,children:(0,N.jsx)(`div`,{className:i(`h-full rounded-full`,a===`unread`?`bg-muted-foreground`:`bg-indigo-500`),style:{width:`${o}%`}})})})]})]}):(0,N.jsxs)(`button`,{type:`button`,onClick:r,className:i(`group flex w-full flex-col overflow-hidden rounded-lg border border-[#25252a] bg-[#1a1a20] text-left transition-all hover:-translate-y-px hover:border-[#3a3a44]`,K),children:[(0,N.jsxs)(`div`,{className:i(`relative w-full shrink-0 overflow-hidden bg-muted`,W),children:[(0,N.jsx)(`img`,{src:H(e),alt:``,className:`absolute inset-0 block size-full object-cover`,loading:`lazy`}),(0,N.jsx)(re,{variant:`secondary`,className:`absolute top-1.5 left-1.5 border-0 bg-black/60 px-1.5 py-0 text-[10px] text-[#c2c2ca] backdrop-blur-sm`,children:e.type===`novel`?`小说`:`漫画`}),(0,N.jsx)(`span`,{className:i(`absolute top-1.5 right-1.5 size-2 rounded-full`,q[a])})]}),(0,N.jsxs)(`div`,{className:i(`flex shrink-0 flex-col justify-between p-2.5`,G),children:[(0,N.jsx)(`div`,{className:`truncate text-xs leading-4 font-semibold text-[#e2e2e8]`,children:e.title}),(0,N.jsx)(`div`,{className:`h-[3px] w-full overflow-hidden rounded-full bg-[#2a2a32]`,children:(0,N.jsx)(`div`,{className:i(`h-full rounded-full`,a===`unread`?`bg-muted-foreground`:`bg-indigo-500`),style:{width:`${o}%`}})})]})]})}function Y({items:e,view:t,filterLabel:n}){return e.length===0?(0,N.jsx)(P,{className:`border py-16`,children:(0,N.jsxs)(F,{children:[(0,N.jsx)(L,{variant:`icon`,children:(0,N.jsx)(A,{})}),(0,N.jsx)(R,{children:`未找到匹配的作品`}),(0,N.jsx)(z,{children:`尝试调整搜索词或筛选条件`})]})}):(0,N.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,N.jsx)(`div`,{className:`flex items-center justify-between py-2`,children:(0,N.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[n,` · `,e.length,` 部作品`]})}),t===`list`?(0,N.jsxs)(`div`,{className:`mb-1.5 hidden grid-cols-[40px_1fr_1fr_80px_100px] gap-4 border-b px-3.5 py-1.5 text-[11px] font-semibold tracking-wide text-muted-foreground uppercase md:grid`,children:[(0,N.jsx)(`div`,{}),(0,N.jsx)(`div`,{children:`作品`}),(0,N.jsx)(`div`,{children:`作者`}),(0,N.jsx)(`div`,{className:`text-right`,children:`进度`}),(0,N.jsx)(`div`,{className:`text-right`,children:`状态`})]}):null,(0,N.jsx)(`div`,{className:i(t===`grid`?`grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3.5`:`flex flex-col gap-1.5`),children:e.map(e=>(0,N.jsx)(J,{item:e,view:t},e.id))})]})}var X=`h-8 border-[#2a2a32] bg-[#1a1a20] text-xs text-[#9f9fad] hover:bg-[#23232a] hover:text-[#d5d5dd]`;function ie({query:e,onQueryChange:t,sort:n,onSortChange:r,view:a,onViewChange:o}){return(0,N.jsxs)(`header`,{className:`flex h-14 shrink-0 items-center gap-3 border-b px-5`,children:[(0,N.jsxs)(`div`,{className:`relative max-w-[520px] flex-1`,children:[(0,N.jsx)(j,{className:`pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-muted-foreground`}),(0,N.jsx)(x,{value:e,onChange:e=>t(e.target.value),placeholder:`搜索作品、作者...`,className:`h-[34px] border-[#2a2a32] bg-[#1a1a20] pl-8 text-[13px] text-[#e2e2e8] placeholder:text-[#6b6b78] focus-visible:border-indigo-500`}),e?(0,N.jsx)(s,{type:`button`,variant:`ghost`,size:`icon-xs`,className:`absolute top-1/2 right-1.5 -translate-y-1/2`,onClick:()=>t(``),children:(0,N.jsx)(v,{})}):null]}),(0,N.jsxs)(`div`,{className:`ml-auto flex items-center gap-3`,children:[(0,N.jsxs)(p,{value:n,onValueChange:e=>r(e),children:[(0,N.jsx)(m,{size:`sm`,className:i(X,`h-8 min-w-[108px] px-2.5`),children:(0,N.jsx)(g,{})}),(0,N.jsx)(h,{children:(0,N.jsxs)(f,{children:[(0,N.jsx)(d,{value:`addedAt`,children:`最近添加`}),(0,N.jsx)(d,{value:`name`,children:`名称`})]})})]}),(0,N.jsxs)(C,{type:`single`,value:a,onValueChange:e=>{e&&o(e)},variant:`outline`,size:`sm`,className:`gap-0.5`,children:[(0,N.jsx)(S,{value:`grid`,"aria-label":`网格视图`,className:i(X,`px-2 data-[state=on]:border-[#3e3e52] data-[state=on]:bg-[#2a2a3a] data-[state=on]:text-[#e2e2e8]`),children:(0,N.jsx)(O,{})}),(0,N.jsx)(S,{value:`list`,"aria-label":`列表视图`,className:i(X,`px-2 data-[state=on]:border-[#3e3e52] data-[state=on]:bg-[#2a2a3a] data-[state=on]:text-[#e2e2e8]`),children:(0,N.jsx)(k,{})})]})]})]})}function ae(){let e=c({queryKey:u.recent,queryFn:w});return{items:e.data?.items??[],loading:e.isPending,error:e.error?e.error instanceof Error?e.error.message:`Failed to load recent reading`:null}}function oe(){let{filter:e}=b(),{items:t,loading:n}=ae(),r=(0,M.useMemo)(()=>e===`novel`||e===`comic`?t.filter(t=>t.type===e):t,[e,t]);return(0,N.jsxs)(`section`,{className:`mb-2`,children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-2 py-4 text-[13px] font-semibold text-foreground/80`,children:[(0,N.jsx)(D,{className:`size-3.5 text-indigo-500`}),`最近阅读`]}),n?(0,N.jsx)(`div`,{className:`grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3.5 pb-2`,children:Array.from({length:4},(e,t)=>(0,N.jsxs)(`div`,{className:i(`flex flex-col overflow-hidden rounded-lg border border-[#25252a] bg-[#1a1a20]`,K),children:[(0,N.jsx)(l,{className:i(`w-full shrink-0 rounded-none`,W)}),(0,N.jsxs)(`div`,{className:i(`flex flex-col justify-between p-2.5`,G),children:[(0,N.jsx)(l,{className:`h-3 w-4/5`}),(0,N.jsx)(l,{className:`h-[3px] w-full`})]})]},t))}):null,!n&&r.length===0?(0,N.jsx)(`div`,{className:`pb-2 text-xs text-muted-foreground`,children:`暂无阅读记录`}):null,!n&&r.length>0?(0,N.jsx)(`div`,{className:`grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3.5 pb-2`,children:r.map(e=>(0,N.jsx)(J,{item:e,view:`grid`},e.id))}):null]})}var Z=`cyreader:library-sort`,Q=`addedAt`,$=new Set([`name`,`addedAt`]);function se(e){return typeof e==`string`&&$.has(e)?e:Q}function ce(){if(typeof window>`u`)return Q;try{let e=window.localStorage.getItem(Z);return e?se(JSON.parse(e)):Q}catch{return Q}}function le(e){if(!(typeof window>`u`))try{window.localStorage.setItem(Z,JSON.stringify(e))}catch{}}function ue(){let{filter:e,items:t,scanning:n}=b(),[r,i]=(0,M.useState)(``),[a,o]=(0,M.useState)(`grid`),[s,c]=(0,M.useState)(()=>ce()),l=(0,M.useMemo)(()=>y(te(t,e,r),s),[t,e,r,s]);return(0,N.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,N.jsx)(ie,{query:r,onQueryChange:i,sort:s,onSortChange:e=>{c(e),le(e)},view:a,onViewChange:o}),(0,N.jsx)(_,{className:`min-h-0 flex-1`,children:(0,N.jsxs)(`div`,{className:`px-5 pb-5`,children:[n?(0,N.jsx)(`div`,{className:`py-2 text-xs text-muted-foreground`,children:`正在扫描书库...`}):null,(0,N.jsx)(oe,{}),(0,N.jsx)(Y,{items:l,view:a,filterLabel:ne(e)})]})})]})}export{ue as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Y as e,b as t,t as n,x as r}from"./utils-ChkMmPzE.js";import{i,r as a}from"./query-keys-CbbgiZx4.js";import{t as o}from"./useRouterState-4dM5FKiy.js";import{a as s,d as c,i as l,l as u,n as d,r as f,t as p,u as m}from"./save-reading-progress-D231ROaQ.js";import{t as h}from"./settings-2-8mnAuSax.js";import{a as g,i as _}from"./reading-BozmJNi1.js";import{t as v,y}from"./index-BHhqsr5H.js";import{n as b}from"./reading-progress-C5bkK-vF.js";var x=e(r(),1),S=t();function C({open:e,direction:t,onDirectionChange:n}){return e?(0,S.jsx)(`div`,{className:`absolute top-14 right-0 z-20 flex w-80 flex-col gap-4 border-b border-l border-[#25252a] bg-[#0a0a0f] p-4`,children:(0,S.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,S.jsx)(`span`,{className:`text-sm text-[#d4c5a9]`,children:`阅读方向`}),(0,S.jsxs)(_,{type:`single`,value:t,onValueChange:e=>{(e===`ltr`||e===`rtl`)&&n(e)},children:[(0,S.jsx)(g,{value:`ltr`,"aria-label":`从左往右`,children:`左→右`}),(0,S.jsx)(g,{value:`rtl`,"aria-label":`从右往左`,children:`右→左`})]})]})}):null}function w(e){(0,x.useEffect)(()=>{let t=e.current;if(!t)return;let n=!1,r=0,i=0,a=null,o=null,s=0,c=()=>{s=0,o!==null&&(t.scrollLeft=o,o=null)},l=e=>{n&&(n=!1,a=null,s&&=(cancelAnimationFrame(s),0),o=null,t.hasPointerCapture(e)&&t.releasePointerCapture(e),t.style.cursor=`grab`)},u=e=>{e.button===0&&(n=!0,a=e.pointerId,r=e.clientX,i=t.scrollLeft,t.setPointerCapture(e.pointerId),t.style.cursor=`grabbing`)},d=e=>{!n||a!==e.pointerId||(o=i-(e.clientX-r),s||=requestAnimationFrame(c))},f=e=>{l(e.pointerId)};return t.style.cursor=`grab`,t.style.userSelect=`none`,t.addEventListener(`pointerdown`,u),t.addEventListener(`pointermove`,d),t.addEventListener(`pointerup`,f),t.addEventListener(`pointercancel`,f),()=>{s&&cancelAnimationFrame(s),t.removeEventListener(`pointerdown`,u),t.removeEventListener(`pointermove`,d),t.removeEventListener(`pointerup`,f),t.removeEventListener(`pointercancel`,f),t.style.cursor=``,t.style.userSelect=``}},[e])}function T(e,t,n){return`/static/${e}/${encodeURIComponent(t)}/${encodeURIComponent(n)}`}var E=2/3,D=.995;function O(e){return Number.isFinite(e)?Math.min(Math.max(e,0),1):0}function k(e,t){return Math.max(0,e-t)}function A(e,t,n,r=`ltr`){let i=k(t,n);if(i===0)return 0;let a=O(e/i);return r===`rtl`?1-a:a}function j(e,t,n,r=`ltr`){let i=k(t,n),a=O(e);return(r===`rtl`?1-a:a)*i}function M(e,t,n=`ltr`){e.scrollLeft=j(t,e.scrollWidth,e.clientWidth,n)}function N(e,t){return t<=1?0:Math.min(Math.max(e,0),t-1)/(t-1)}function P(e){return O(e)>=D}function F(e,t,n){if(t<=0)return 0;let r=Math.min(Math.max(e,0),t-1);return n===`rtl`?t-1-r:r}function I(e){return e<=0?200:Math.round(e*E)+8}function L(e,t,n){return e<=0||t<=0||n<=0?I(n):Math.round(e/t*n)+8}function R(e,t){return e.reduce((e,n)=>e+L(n.width,n.height,t),0)}function z({directoryId:e,title:t,pages:r,direction:i,initialScrollRatio:a,onScrollProgress:o}){let s=(0,x.useRef)(null),c=(0,x.useRef)(o),l=(0,x.useRef)(a),u=(0,x.useRef)(!0),d=(0,x.useRef)(!1),[f,p]=(0,x.useState)(0);c.current=o;let h=f>0,g=r.length,_=(0,x.useMemo)(()=>I(f),[f]);w(s);let v=(0,x.useCallback)(e=>F(e,g,i),[i,g]),y=m({horizontal:!0,count:g,enabled:h,getScrollElement:()=>s.current,estimateSize:(0,x.useCallback)(e=>{let t=r[v(e)];return t?L(t.width,t.height,f):_},[f,_,v,r]),overscan:4,initialOffset:(0,x.useCallback)(()=>{let e=s.current;if(!e||!h)return 0;let t=R(r,f);return j(l.current,t,e.clientWidth,i)},[f,i,h,r]),getItemKey:e=>r[v(e)]?.filename??e}),b=(0,x.useRef)(y.measure);b.current=y.measure;let C=(0,x.useCallback)(()=>{let e=s.current;e&&(d.current=!0,M(e,l.current,i),window.setTimeout(()=>{d.current=!1},0))},[i]);return(0,x.useLayoutEffect)(()=>{let e=s.current;if(!e)return;let t=()=>{p(e.clientHeight)};t();let n=new ResizeObserver(t);return n.observe(e),()=>{n.disconnect()}},[]),(0,x.useLayoutEffect)(()=>{l.current=a,u.current=!0},[i,a,r,t]),(0,x.useLayoutEffect)(()=>{g===0||!h||(b.current(),u.current&&C())},[C,f,i,h,g]),(0,x.useEffect)(()=>{if(g===0||!h||!u.current)return;let e=window.setTimeout(()=>{C(),u.current=!1},120);return()=>{window.clearTimeout(e)}},[C,a,h,g]),(0,x.useEffect)(()=>{let e=s.current;if(!e||!h)return;let t,n=()=>{t&&clearTimeout(t),t=setTimeout(()=>{if(d.current||u.current)return;let t=A(e.scrollLeft,e.scrollWidth,e.clientWidth,i);c.current(t)},100)};return e.addEventListener(`scroll`,n,{passive:!0}),()=>{e.removeEventListener(`scroll`,n),t&&clearTimeout(t)}},[i,h]),(0,S.jsx)(`div`,{ref:s,className:n(`reader-scrollbar-none h-full overflow-x-auto overflow-y-hidden`),children:(0,S.jsx)(`div`,{style:{width:y.getTotalSize(),height:`100%`,position:`relative`},children:y.getVirtualItems().map(n=>{let i=v(n.index),a=r[i];return a?(0,S.jsx)(`div`,{"data-index":n.index,className:`flex h-full items-center`,style:{position:`absolute`,top:0,left:0,height:`100%`,width:n.size,paddingRight:8,transform:`translateX(${n.start}px)`},children:(0,S.jsx)(`img`,{src:T(e,t,a.filename),alt:`第 ${i+1} 页`,draggable:!1,decoding:`async`,className:`h-full w-auto max-w-none select-none`})},n.key):null})})})}function B(e,t){return e?typeof e.scrollRatio==`number`?O(e.scrollRatio):typeof e.pageIndex==`number`?N(e.pageIndex,t):0:0}function V({id:e}){let t=o({select:e=>e.location.state?.readerTitle}),{data:r,isPending:m,error:g}=u(e),{settings:_,patchSettings:v}=s(`comic`),[w,T]=(0,x.useState)(0),[E,D]=(0,x.useState)(null),[k,A]=(0,x.useState)(!1),j=r&&r.type===`comic`?r:null,M=j?.pages.length??0,N=t??r?.title??`加载中...`,F=g?g instanceof Error?g.message:`加载失败`:null,I=(0,x.useMemo)(()=>b(w),[w]),L=(0,x.useCallback)((t,n)=>{j&&d(e,{type:`comic`,scrollRatio:t,completedAt:n})},[j,e]),R=(0,x.useCallback)(e=>{let t=O(e);T(t),L(t,P(t)?new Date().toISOString():null)},[L]),V=(0,x.useCallback)(e=>{D(w),v({direction:e})},[v,w]);return(0,x.useEffect)(()=>{D(null),T(0)},[e]),(0,x.useEffect)(()=>{if(!j||E!==null)return;let e=B(j.progress,M);D(e),T(e)},[j,M,E]),(0,x.useEffect)(()=>(l(e),()=>{f(e),p(e)}),[e]),(0,S.jsxs)(`div`,{className:`relative flex h-screen flex-col overflow-hidden bg-[#0a0a0f] text-[#d4c5a9]`,children:[(0,S.jsxs)(`header`,{className:`relative z-10 flex h-14 shrink-0 items-center gap-3 border-b border-[#25252a] px-4`,children:[(0,S.jsx)(i,{type:`button`,variant:`ghost`,size:`sm`,asChild:!0,children:(0,S.jsxs)(y,{to:`/`,children:[(0,S.jsx)(c,{"data-icon":`inline-start`}),`返回`]})}),(0,S.jsx)(`div`,{className:`flex-1 truncate text-center text-sm font-medium`,children:N}),(0,S.jsx)(i,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:()=>A(e=>!e),className:n(k&&`bg-[#25252a]`),children:(0,S.jsx)(h,{})})]}),(0,S.jsx)(C,{open:k,direction:_.direction,onDirectionChange:V}),(0,S.jsxs)(`div`,{className:`relative min-h-0 flex-1`,children:[m&&!j?(0,S.jsx)(`div`,{className:`flex size-full items-center justify-center`,children:(0,S.jsx)(a,{className:`h-[70vh] w-full max-w-3xl`})}):null,F?(0,S.jsx)(`div`,{className:`p-8 text-sm text-red-400`,children:F}):null,!m&&!F&&r&&r.type!==`comic`?(0,S.jsx)(`div`,{className:`p-8 text-sm text-red-400`,children:`作品类型不匹配`}):null,j&&M>0&&E!==null?(0,S.jsx)(z,{directoryId:j.directoryId,title:j.title,pages:j.pages,direction:_.direction,initialScrollRatio:E,onScrollProgress:R},`${e}-${_.direction}`):null,j&&M===0?(0,S.jsx)(`div`,{className:`flex size-full items-center justify-center text-sm text-muted-foreground`,children:`暂无页面`}):null]}),(0,S.jsxs)(`footer`,{className:`flex h-11 shrink-0 items-center justify-center border-t border-[#25252a] text-xs opacity-80`,children:[`已读 `,I,`%`]})]})}function H(){let{id:e}=v.useParams();return(0,S.jsx)(V,{id:e})}export{H as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Y as e,x as t}from"./utils-ChkMmPzE.js";var n=e(t(),1);function r(e){let t=n.useRef({value:e,previous:e});return n.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}function i(e,[t,n]){return Math.min(n,Math.max(t,e))}export{r as n,i as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Y as e,b as t,h as n,l as r,p as i,x as a}from"./utils-ChkMmPzE.js";var o=e(a(),1),s=t();function c(e){let t=e+`CollectionProvider`,[a,c]=r(t),[l,u]=a(t,{collectionRef:{current:null},itemMap:new Map}),d=e=>{let{scope:t,children:n}=e,r=o.useRef(null),i=o.useRef(new Map).current;return(0,s.jsx)(l,{scope:t,itemMap:i,collectionRef:r,children:n})};d.displayName=t;let f=e+`CollectionSlot`,p=i(f),m=o.forwardRef((e,t)=>{let{scope:r,children:i}=e;return(0,s.jsx)(p,{ref:n(t,u(f,r).collectionRef),children:i})});m.displayName=f;let h=e+`CollectionItemSlot`,g=`data-radix-collection-item`,_=i(h),v=o.forwardRef((e,t)=>{let{scope:r,children:i,...a}=e,c=o.useRef(null),l=n(t,c),d=u(h,r);return o.useEffect(()=>(d.itemMap.set(c,{ref:c,...a}),()=>void d.itemMap.delete(c))),(0,s.jsx)(_,{[g]:``,ref:l,children:i})});v.displayName=h;function y(t){let n=u(e+`CollectionConsumer`,t);return o.useCallback(()=>{let e=n.collectionRef.current;if(!e)return[];let t=Array.from(e.querySelectorAll(`[${g}]`));return Array.from(n.itemMap.values()).sort((e,n)=>t.indexOf(e.ref.current)-t.indexOf(n.ref.current))},[n.collectionRef,n.itemMap])}return[{Provider:d,Slot:m,ItemSlot:v},y,c]}var l=o.createContext(void 0);function u(e){let t=o.useContext(l);return e||t||`ltr`}export{c as n,u as t};
|