From 70158a7f15738200bf77f486b4d9b7785473ee6e Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Wed, 3 Dec 2025 15:50:55 +0800 Subject: [PATCH] refactor(opds): use catalog id instead of credentials in url params, closes #2599 (#2606) --- .../src/app/library/components/OPDSDialog.tsx | 2 +- .../opds/{ => components}/CatelogManager.tsx | 5 ++- .../app/opds/{ => components}/FeedView.tsx | 2 +- .../app/opds/{ => components}/Navigation.tsx | 0 .../opds/{ => components}/NavigationCard.tsx | 0 .../opds/{ => components}/PublicationCard.tsx | 4 +-- .../opds/{ => components}/PublicationView.tsx | 4 +-- .../app/opds/{ => components}/SearchView.tsx | 0 apps/readest-app/src/app/opds/page.tsx | 35 +++++++++++-------- 9 files changed, 28 insertions(+), 24 deletions(-) rename apps/readest-app/src/app/opds/{ => components}/CatelogManager.tsx (98%) rename apps/readest-app/src/app/opds/{ => components}/FeedView.tsx (99%) rename apps/readest-app/src/app/opds/{ => components}/Navigation.tsx (100%) rename apps/readest-app/src/app/opds/{ => components}/NavigationCard.tsx (100%) rename apps/readest-app/src/app/opds/{ => components}/PublicationCard.tsx (98%) rename apps/readest-app/src/app/opds/{ => components}/PublicationView.tsx (99%) rename apps/readest-app/src/app/opds/{ => components}/SearchView.tsx (100%) diff --git a/apps/readest-app/src/app/library/components/OPDSDialog.tsx b/apps/readest-app/src/app/library/components/OPDSDialog.tsx index 014b55ff..9f0c81af 100644 --- a/apps/readest-app/src/app/library/components/OPDSDialog.tsx +++ b/apps/readest-app/src/app/library/components/OPDSDialog.tsx @@ -1,5 +1,5 @@ import { clsx } from 'clsx'; -import { CatalogManager } from '@/app/opds/CatelogManager'; +import { CatalogManager } from '@/app/opds/components/CatelogManager'; import { useTranslation } from '@/hooks/useTranslation'; import Dialog from '@/components/Dialog'; diff --git a/apps/readest-app/src/app/opds/CatelogManager.tsx b/apps/readest-app/src/app/opds/components/CatelogManager.tsx similarity index 98% rename from apps/readest-app/src/app/opds/CatelogManager.tsx rename to apps/readest-app/src/app/opds/components/CatelogManager.tsx index 82e378e0..2262b8ee 100644 --- a/apps/readest-app/src/app/opds/CatelogManager.tsx +++ b/apps/readest-app/src/app/opds/components/CatelogManager.tsx @@ -10,7 +10,7 @@ import { isWebAppPlatform } from '@/services/environment'; import { saveSysSettings } from '@/helpers/settings'; import { OPDSCatalog } from '@/types/opds'; import { isLanAddress } from '@/utils/network'; -import { validateOPDSURL } from './utils/opdsUtils'; +import { validateOPDSURL } from '../utils/opdsUtils'; import ModalPortal from '@/components/ModalPortal'; const POPULAR_CATALOGS: OPDSCatalog[] = [ @@ -119,8 +119,7 @@ export function CatalogManager() { const handleOpenCatalog = (catalog: OPDSCatalog) => { const params = new URLSearchParams({ url: catalog.url }); - if (catalog.username) params.set('username', catalog.username); - if (catalog.password) params.set('password', catalog.password); + if (catalog.username) params.set('id', catalog.id); router.push(`/opds?${params.toString()}`); }; diff --git a/apps/readest-app/src/app/opds/FeedView.tsx b/apps/readest-app/src/app/opds/components/FeedView.tsx similarity index 99% rename from apps/readest-app/src/app/opds/FeedView.tsx rename to apps/readest-app/src/app/opds/components/FeedView.tsx index 15fd13eb..6495e0e6 100644 --- a/apps/readest-app/src/app/opds/FeedView.tsx +++ b/apps/readest-app/src/app/opds/components/FeedView.tsx @@ -6,7 +6,7 @@ import { useTranslation } from '@/hooks/useTranslation'; import { OPDSFeed, OPDSLink } from '@/types/opds'; import { PublicationCard } from './PublicationCard'; import { NavigationCard } from './NavigationCard'; -import { groupByArray } from './utils/opdsUtils'; +import { groupByArray } from '../utils/opdsUtils'; interface FeedViewProps { feed: OPDSFeed; diff --git a/apps/readest-app/src/app/opds/Navigation.tsx b/apps/readest-app/src/app/opds/components/Navigation.tsx similarity index 100% rename from apps/readest-app/src/app/opds/Navigation.tsx rename to apps/readest-app/src/app/opds/components/Navigation.tsx diff --git a/apps/readest-app/src/app/opds/NavigationCard.tsx b/apps/readest-app/src/app/opds/components/NavigationCard.tsx similarity index 100% rename from apps/readest-app/src/app/opds/NavigationCard.tsx rename to apps/readest-app/src/app/opds/components/NavigationCard.tsx diff --git a/apps/readest-app/src/app/opds/PublicationCard.tsx b/apps/readest-app/src/app/opds/components/PublicationCard.tsx similarity index 98% rename from apps/readest-app/src/app/opds/PublicationCard.tsx rename to apps/readest-app/src/app/opds/components/PublicationCard.tsx index 74d002d8..a536c9f5 100644 --- a/apps/readest-app/src/app/opds/PublicationCard.tsx +++ b/apps/readest-app/src/app/opds/components/PublicationCard.tsx @@ -1,10 +1,10 @@ 'use client'; import { useMemo } from 'react'; -import { groupByArray } from './utils/opdsUtils'; +import { useTranslation } from '@/hooks/useTranslation'; import { CachedImage } from '@/components/CachedImage'; import { OPDSPublication, REL } from '@/types/opds'; -import { useTranslation } from '@/hooks/useTranslation'; +import { groupByArray } from '../utils/opdsUtils'; interface PublicationCardProps { publication: OPDSPublication; diff --git a/apps/readest-app/src/app/opds/PublicationView.tsx b/apps/readest-app/src/app/opds/components/PublicationView.tsx similarity index 99% rename from apps/readest-app/src/app/opds/PublicationView.tsx rename to apps/readest-app/src/app/opds/components/PublicationView.tsx index e93bf5a8..9d87611a 100644 --- a/apps/readest-app/src/app/opds/PublicationView.tsx +++ b/apps/readest-app/src/app/opds/components/PublicationView.tsx @@ -5,13 +5,13 @@ import { useMemo, useState } from 'react'; import { useRouter } from 'next/navigation'; import { IoPricetag } from 'react-icons/io5'; import { Book } from '@/types/book'; -import { groupByArray } from './utils/opdsUtils'; +import { OPDSLink, OPDSPublication, REL, SYMBOL } from '@/types/opds'; import { useTranslation } from '@/hooks/useTranslation'; import { formatDate, formatLanguage } from '@/utils/book'; import { eventDispatcher } from '@/utils/event'; import { navigateToReader } from '@/utils/nav'; import { CachedImage } from '@/components/CachedImage'; -import { OPDSLink, OPDSPublication, REL, SYMBOL } from '@/types/opds'; +import { groupByArray } from '../utils/opdsUtils'; import Dropdown from '@/components/Dropdown'; import MenuItem from '@/components/MenuItem'; diff --git a/apps/readest-app/src/app/opds/SearchView.tsx b/apps/readest-app/src/app/opds/components/SearchView.tsx similarity index 100% rename from apps/readest-app/src/app/opds/SearchView.tsx rename to apps/readest-app/src/app/opds/components/SearchView.tsx diff --git a/apps/readest-app/src/app/opds/page.tsx b/apps/readest-app/src/app/opds/page.tsx index b9b019cc..00bcc9da 100644 --- a/apps/readest-app/src/app/opds/page.tsx +++ b/apps/readest-app/src/app/opds/page.tsx @@ -1,29 +1,30 @@ 'use client'; +import clsx from 'clsx'; +import { md5 } from 'js-md5'; import { useEffect, useState, useCallback, useRef } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { isOPDSCatalog, getPublication, getFeed, getOpenSearch } from 'foliate-js/opds.js'; -import { md5 } from 'js-md5'; import { openUrl } from '@tauri-apps/plugin-opener'; import { useEnv } from '@/context/EnvContext'; import { isWebAppPlatform } from '@/services/environment'; -import { FeedView } from './FeedView'; -import { PublicationView } from './PublicationView'; -import { SearchView } from './SearchView'; -import { Navigation } from './Navigation'; import { downloadFile } from '@/libs/storage'; import { Toast } from '@/components/Toast'; +import { useThemeStore } from '@/store/themeStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useLibraryStore } from '@/store/libraryStore'; +import { useSettingsStore } from '@/store/settingsStore'; +import { useTheme } from '@/hooks/useTheme'; import { useLibrary } from '@/hooks/useLibrary'; import { eventDispatcher } from '@/utils/event'; import { getFileExtFromMimeType } from '@/libs/document'; import { OPDSFeed, OPDSPublication, OPDSSearch } from '@/types/opds'; import { MIME, parseMediaType, resolveURL } from './utils/opdsUtils'; import { getProxiedURL, fetchWithAuth, probeAuth, needsProxy } from './utils/opdsReq'; -import clsx from 'clsx'; -import { useThemeStore } from '@/store/themeStore'; -import { useTheme } from '@/hooks/useTheme'; +import { FeedView } from './components/FeedView'; +import { PublicationView } from './components/PublicationView'; +import { SearchView } from './components/SearchView'; +import { Navigation } from './components/Navigation'; type ViewMode = 'feed' | 'publication' | 'search' | 'loading' | 'error'; @@ -49,6 +50,7 @@ export default function BrowserPage() { const { appService } = useEnv(); const { libraryLoaded } = useLibrary(); const { safeAreaInsets, isRoundedWindow } = useThemeStore(); + const { settings } = useSettingsStore(); const [viewMode, setViewMode] = useState('loading'); const [state, setState] = useState({ baseURL: '', @@ -64,10 +66,10 @@ export default function BrowserPage() { const [historyIndex, setHistoryIndex] = useState(-1); const searchParams = useSearchParams(); - const usernameRef = useRef(searchParams?.get('username')); - const passwordRef = useRef(searchParams?.get('password')); + const usernameRef = useRef(undefined); + const passwordRef = useRef(undefined); + const startURLRef = useRef(undefined); const loadingOPDSRef = useRef(false); - const startURLRef = useRef(undefined); const historyIndexRef = useRef(-1); const isNavigatingHistoryRef = useRef(false); @@ -235,9 +237,10 @@ export default function BrowserPage() { useEffect(() => { const url = searchParams?.get('url'); - const username = searchParams?.get('username'); - const password = searchParams?.get('password'); if (url && !isNavigatingHistoryRef.current) { + const catalogId = searchParams?.get('id') || ''; + const catalog = settings.opdsCatalogs?.find((cat) => cat.id === catalogId); + const { username, password } = catalog || {}; if (username || password) { usernameRef.current = username; passwordRef.current = password; @@ -245,14 +248,16 @@ export default function BrowserPage() { usernameRef.current = null; passwordRef.current = null; } - loadOPDS(url); + if (libraryLoaded) { + loadOPDS(url); + } } else if (isNavigatingHistoryRef.current) { isNavigatingHistoryRef.current = false; } else { setViewMode('error'); setError(new Error('No OPDS URL provided')); } - }, [searchParams, loadOPDS]); + }, [searchParams, settings, libraryLoaded, loadOPDS]); const handleNavigate = useCallback( (url: string) => {