+
{_('Select Metadata Source')}
{sources.map((source, index) => (
-
onSelect(source)}
- className='hover:bg-base-200 cursor-pointer rounded-md border p-3 transition-colors'
+ className='hover:bg-base-300/75 bg-base-200 border-base-200 cursor-pointer rounded-md border p-3 transition-colors'
>
@@ -86,18 +100,19 @@ const SourceSelector: React.FC = ({ sources, isOpen, onSele
-
+
))}
-
{_('Keep manual input')}
-
+
diff --git a/apps/readest-app/src/context/EnvContext.tsx b/apps/readest-app/src/context/EnvContext.tsx
index aeaa4ae1..5b80e8a0 100644
--- a/apps/readest-app/src/context/EnvContext.tsx
+++ b/apps/readest-app/src/context/EnvContext.tsx
@@ -2,8 +2,8 @@
import React, { createContext, useContext, useState, ReactNode } from 'react';
import { EnvConfigType } from '../services/environment';
-import env from '../services/environment';
import { AppService } from '@/types/system';
+import env from '../services/environment';
interface EnvContextType {
envConfig: EnvConfigType;
diff --git a/apps/readest-app/src/hooks/useDrag.ts b/apps/readest-app/src/hooks/useDrag.ts
index da68ab32..5a2f0bc9 100644
--- a/apps/readest-app/src/hooks/useDrag.ts
+++ b/apps/readest-app/src/hooks/useDrag.ts
@@ -1,7 +1,10 @@
import { useCallback, useRef } from 'react';
+export type DragKey = 'ArrowLeft' | 'ArrowRight' | 'ArrowUp' | 'ArrowDown';
+
export const useDrag = (
onDragMove: (data: { clientX: number; clientY: number; deltaX: number; deltaY: number }) => void,
+ onDragKeyDown: (data: { key: DragKey; step: number }) => void,
onDragEnd?: (data: {
velocity: number;
deltaT: number;
@@ -31,6 +34,10 @@ export const useDrag = (
}
startTime.current = performance.now();
+ document.body.style.pointerEvents = 'none';
+ document.body.style.userSelect = 'none';
+ document.documentElement.style.cursor = 'col-resize';
+
const handleMove = (event: MouseEvent | TouchEvent) => {
if (isDragging.current) {
let deltaX = 0;
@@ -58,6 +65,11 @@ export const useDrag = (
const handleEnd = (event: MouseEvent | TouchEvent) => {
isDragging.current = false;
+
+ document.body.style.pointerEvents = '';
+ document.body.style.userSelect = '';
+ document.documentElement.style.cursor = '';
+
let deltaX = 0;
let deltaY = 0;
let clientX = 0;
@@ -96,5 +108,24 @@ export const useDrag = (
[onDragMove, onDragEnd],
);
- return { handleDragStart };
+ const handleDragKeyDown = useCallback(
+ (e: React.KeyboardEvent) => {
+ const step = 0.02;
+ switch (e.key) {
+ case 'ArrowUp':
+ case 'ArrowDown':
+ case 'ArrowLeft':
+ case 'ArrowRight':
+ onDragKeyDown({ key: e.key, step });
+ break;
+ default:
+ return;
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ },
+ [onDragKeyDown],
+ );
+
+ return { handleDragStart, handleDragKeyDown };
};
diff --git a/apps/readest-app/src/pages/_app.tsx b/apps/readest-app/src/pages/_app.tsx
index 72f1f7b7..50205794 100644
--- a/apps/readest-app/src/pages/_app.tsx
+++ b/apps/readest-app/src/pages/_app.tsx
@@ -1,5 +1,5 @@
-import { AppProps } from 'next/app';
import Head from 'next/head';
+import { AppProps } from 'next/app';
import { EnvProvider } from '@/context/EnvContext';
import Providers from '@/components/Providers';
diff --git a/apps/readest-app/src/store/notebookStore.ts b/apps/readest-app/src/store/notebookStore.ts
index 071e521d..ec0ce4e7 100644
--- a/apps/readest-app/src/store/notebookStore.ts
+++ b/apps/readest-app/src/store/notebookStore.ts
@@ -12,6 +12,7 @@ interface NotebookState {
getIsNotebookVisible: () => boolean;
toggleNotebook: () => void;
toggleNotebookPin: () => void;
+ getNotebookWidth: () => string;
setNotebookWidth: (width: string) => void;
setNotebookVisible: (visible: boolean) => void;
setNotebookPin: (pinned: boolean) => void;
@@ -29,6 +30,7 @@ export const useNotebookStore = create((set, get) => ({
notebookEditAnnotation: null,
notebookAnnotationDrafts: {},
getIsNotebookVisible: () => get().isNotebookVisible,
+ getNotebookWidth: () => get().notebookWidth,
setNotebookWidth: (width: string) => set({ notebookWidth: width }),
toggleNotebook: () => set((state) => ({ isNotebookVisible: !state.isNotebookVisible })),
toggleNotebookPin: () => set((state) => ({ isNotebookPinned: !state.isNotebookPinned })),
diff --git a/apps/readest-app/src/store/sidebarStore.ts b/apps/readest-app/src/store/sidebarStore.ts
index 9d463aad..16e57ee4 100644
--- a/apps/readest-app/src/store/sidebarStore.ts
+++ b/apps/readest-app/src/store/sidebarStore.ts
@@ -6,6 +6,7 @@ interface SidebarState {
isSideBarVisible: boolean;
isSideBarPinned: boolean;
getIsSideBarVisible: () => boolean;
+ getSideBarWidth: () => string;
setSideBarBookKey: (key: string) => void;
setSideBarWidth: (width: string) => void;
toggleSideBar: () => void;
@@ -20,6 +21,7 @@ export const useSidebarStore = create((set, get) => ({
isSideBarVisible: false,
isSideBarPinned: false,
getIsSideBarVisible: () => get().isSideBarVisible,
+ getSideBarWidth: () => get().sideBarWidth,
setSideBarBookKey: (key: string) => set({ sideBarBookKey: key }),
setSideBarWidth: (width: string) => set({ sideBarWidth: width }),
toggleSideBar: () => set((state) => ({ isSideBarVisible: !state.isSideBarVisible })),
diff --git a/apps/readest-app/src/store/themeStore.ts b/apps/readest-app/src/store/themeStore.ts
index 7556868a..320769c8 100644
--- a/apps/readest-app/src/store/themeStore.ts
+++ b/apps/readest-app/src/store/themeStore.ts
@@ -135,6 +135,16 @@ export const useThemeStore = create((set, get) => {
};
});
+export const loadDataTheme = () => {
+ if (typeof localStorage === 'undefined' || typeof document === 'undefined') return;
+
+ const themeMode = localStorage.getItem('themeMode');
+ const themeColor = localStorage.getItem('themeColor');
+ if (themeMode && themeColor) {
+ document.documentElement.setAttribute('data-theme', `${themeColor}-${themeMode}`);
+ }
+};
+
export const initSystemThemeListener = (appService: AppService) => {
if (typeof window === 'undefined' || !appService) return;
diff --git a/apps/readest-app/src/utils/a11y.ts b/apps/readest-app/src/utils/a11y.ts
new file mode 100644
index 00000000..d0001359
--- /dev/null
+++ b/apps/readest-app/src/utils/a11y.ts
@@ -0,0 +1,5 @@
+export const removeTabIndex = (document: Document) => {
+ document.querySelectorAll('a').forEach((a) => {
+ a.setAttribute('tabindex', '-1');
+ });
+};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ce7d5ed8..a2624f1a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -282,6 +282,9 @@ importers:
eslint-config-next:
specifier: 15.0.3
version: 15.0.3(eslint@9.28.0(jiti@1.21.6))(typescript@5.7.2)
+ eslint-plugin-jsx-a11y:
+ specifier: ^6.10.2
+ version: 6.10.2(eslint@9.28.0(jiti@1.21.6))
i18next-scanner:
specifier: ^4.6.0
version: 4.6.0(typescript@5.7.2)
@@ -11197,8 +11200,8 @@ snapshots:
call-bind: 1.0.7
define-properties: 1.2.1
es-abstract: 1.23.5
- es-object-atoms: 1.0.0
- get-intrinsic: 1.2.4
+ es-object-atoms: 1.1.1
+ get-intrinsic: 1.3.0
is-string: 1.0.7
array.prototype.findlast@1.2.5:
@@ -11248,7 +11251,7 @@ snapshots:
define-properties: 1.2.1
es-abstract: 1.23.5
es-errors: 1.3.0
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
is-array-buffer: 3.0.4
is-shared-array-buffer: 1.0.3
@@ -11388,10 +11391,10 @@ snapshots:
call-bind@1.0.7:
dependencies:
- es-define-property: 1.0.0
+ es-define-property: 1.0.1
es-errors: 1.3.0
function-bind: 1.1.2
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
set-function-length: 1.2.2
call-bound@1.0.4:
@@ -11676,9 +11679,9 @@ snapshots:
define-data-property@1.1.4:
dependencies:
- es-define-property: 1.0.0
+ es-define-property: 1.0.1
es-errors: 1.3.0
- gopd: 1.1.0
+ gopd: 1.2.0
define-properties@1.2.1:
dependencies:
@@ -11795,19 +11798,19 @@ snapshots:
data-view-buffer: 1.0.1
data-view-byte-length: 1.0.1
data-view-byte-offset: 1.0.0
- es-define-property: 1.0.0
+ es-define-property: 1.0.1
es-errors: 1.3.0
- es-object-atoms: 1.0.0
- es-set-tostringtag: 2.0.3
+ es-object-atoms: 1.1.1
+ es-set-tostringtag: 2.1.0
es-to-primitive: 1.3.0
function.prototype.name: 1.1.6
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
get-symbol-description: 1.0.2
globalthis: 1.0.4
- gopd: 1.1.0
+ gopd: 1.2.0
has-property-descriptors: 1.0.2
has-proto: 1.0.3
- has-symbols: 1.0.3
+ has-symbols: 1.1.0
hasown: 2.0.2
internal-slot: 1.0.7
is-array-buffer: 3.0.4
@@ -11837,7 +11840,7 @@ snapshots:
es-define-property@1.0.0:
dependencies:
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
es-define-property@1.0.1: {}
@@ -11873,7 +11876,7 @@ snapshots:
es-set-tostringtag@2.0.3:
dependencies:
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
has-tostringtag: 1.0.2
hasown: 2.0.2
@@ -12417,7 +12420,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
es-errors: 1.3.0
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
get-tsconfig@4.8.1:
dependencies:
@@ -12506,7 +12509,7 @@ snapshots:
gopd@1.1.0:
dependencies:
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
gopd@1.2.0: {}
@@ -12538,7 +12541,7 @@ snapshots:
has-tostringtag@1.0.2:
dependencies:
- has-symbols: 1.0.3
+ has-symbols: 1.1.0
hasown@2.0.2:
dependencies:
@@ -12669,7 +12672,7 @@ snapshots:
is-array-buffer@3.0.4:
dependencies:
call-bind: 1.0.7
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
is-arrayish@0.3.2: {}
@@ -12753,7 +12756,7 @@ snapshots:
is-regex@1.2.0:
dependencies:
call-bind: 1.0.7
- gopd: 1.1.0
+ gopd: 1.2.0
has-tostringtag: 1.0.2
hasown: 2.0.2
@@ -12773,7 +12776,7 @@ snapshots:
is-symbol@1.0.4:
dependencies:
- has-symbols: 1.0.3
+ has-symbols: 1.1.0
is-typed-array@1.1.13:
dependencies:
@@ -12809,7 +12812,7 @@ snapshots:
iterator.prototype@1.1.3:
dependencies:
define-properties: 1.2.1
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
has-symbols: 1.0.3
reflect.getprototypeof: 1.0.7
set-function-name: 2.0.2
@@ -13199,7 +13202,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
define-properties: 1.2.1
- has-symbols: 1.0.3
+ has-symbols: 1.1.0
object-keys: 1.1.1
object.entries@1.1.8:
@@ -13213,7 +13216,7 @@ snapshots:
call-bind: 1.0.7
define-properties: 1.2.1
es-abstract: 1.23.5
- es-object-atoms: 1.0.0
+ es-object-atoms: 1.1.1
object.groupby@1.0.3:
dependencies:
@@ -13611,8 +13614,8 @@ snapshots:
define-properties: 1.2.1
es-abstract: 1.23.5
es-errors: 1.3.0
- get-intrinsic: 1.2.4
- gopd: 1.1.0
+ get-intrinsic: 1.3.0
+ gopd: 1.2.0
which-builtin-type: 1.2.0
regenerate-unicode-properties@10.2.0:
@@ -13750,7 +13753,7 @@ snapshots:
safe-array-concat@1.1.2:
dependencies:
call-bind: 1.0.7
- get-intrinsic: 1.2.4
+ get-intrinsic: 1.3.0
has-symbols: 1.0.3
isarray: 2.0.5
@@ -13832,8 +13835,8 @@ snapshots:
define-data-property: 1.1.4
es-errors: 1.3.0
function-bind: 1.1.2
- get-intrinsic: 1.2.4
- gopd: 1.1.0
+ get-intrinsic: 1.3.0
+ gopd: 1.2.0
has-property-descriptors: 1.0.2
set-function-name@2.0.2:
@@ -14051,7 +14054,7 @@ snapshots:
call-bind: 1.0.7
define-properties: 1.2.1
es-abstract: 1.23.5
- es-object-atoms: 1.0.0
+ es-object-atoms: 1.1.1
string.prototype.trimend@1.0.8:
dependencies:
@@ -14063,7 +14066,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
define-properties: 1.2.1
- es-object-atoms: 1.0.0
+ es-object-atoms: 1.1.1
string_decoder@1.1.1:
dependencies:
@@ -14357,7 +14360,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
for-each: 0.3.3
- gopd: 1.1.0
+ gopd: 1.2.0
has-proto: 1.0.3
is-typed-array: 1.1.13
@@ -14366,7 +14369,7 @@ snapshots:
available-typed-arrays: 1.0.7
call-bind: 1.0.7
for-each: 0.3.3
- gopd: 1.1.0
+ gopd: 1.2.0
has-proto: 1.0.3
is-typed-array: 1.1.13
reflect.getprototypeof: 1.0.7
@@ -14375,7 +14378,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
for-each: 0.3.3
- gopd: 1.1.0
+ gopd: 1.2.0
is-typed-array: 1.1.13
possible-typed-array-names: 1.0.0
reflect.getprototypeof: 1.0.7
@@ -14388,7 +14391,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
has-bigints: 1.0.2
- has-symbols: 1.0.3
+ has-symbols: 1.1.0
which-boxed-primitive: 1.0.2
undici-types@5.26.5: {}
@@ -14727,7 +14730,7 @@ snapshots:
available-typed-arrays: 1.0.7
call-bind: 1.0.7
for-each: 0.3.3
- gopd: 1.1.0
+ gopd: 1.2.0
has-tostringtag: 1.0.2
which@2.0.2: