Converge reader navigation buttons

This commit is contained in:
Richard R 2026-06-01 11:05:43 -06:00
parent d2d06e15b6
commit fdceed6067
4 changed files with 23 additions and 21 deletions

View file

@ -20,6 +20,7 @@ import { RateLimitBanner } from '@/components/auth/RateLimitBanner';
import { useAuthRateLimit } from '@/contexts/AuthRateLimitContext';
import { useFeatureFlag } from '@/contexts/RuntimeConfigContext';
import { useUnmountCleanupRef } from '@/hooks/useUnmountCleanupRef';
import { buttonClass } from '@/components/ui';
import { useEpubDocument } from './useEpubDocument';
export default function EPUBPage() {
@ -173,9 +174,9 @@ export default function EPUBPage() {
<p className="text-danger mb-4">{error}</p>
<Link
href="/app"
className="inline-flex items-center px-3 py-1 bg-surface text-foreground rounded-lg hover:bg-accent-wash transition duration-base ease-standard hover:text-accent"
className={buttonClass({ variant: 'secondary', size: 'md', className: 'gap-2' })}
>
<svg className="w-4 h-4 mr-2 text-soft" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-4 h-4 text-soft" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Back to Documents
@ -190,10 +191,10 @@ export default function EPUBPage() {
left={
<Link
href="/app"
className="inline-flex items-center py-1 px-2 rounded-md border border-line bg-surface text-foreground text-xs hover:bg-accent-wash transition duration-base ease-standard hover:text-accent"
className={buttonClass({ variant: 'secondary', size: 'sm', className: 'gap-2' })}
aria-label="Back to documents"
>
<svg className="w-3 h-3 mr-2" fill="currentColor" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-3 h-3" fill="currentColor" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Documents

View file

@ -18,6 +18,7 @@ import { AudiobookExportModal } from '@/components/AudiobookExportModal';
import { useAuthRateLimit } from '@/contexts/AuthRateLimitContext';
import { useFeatureFlag } from '@/contexts/RuntimeConfigContext';
import { useUnmountCleanupRef } from '@/hooks/useUnmountCleanupRef';
import { buttonClass } from '@/components/ui';
import type { TTSAudiobookChapter } from '@/types/tts';
import type { AudiobookGenerationSettings } from '@/types/client';
import { useHtmlDocument } from './useHtmlDocument';
@ -160,9 +161,9 @@ export default function HTMLPage() {
<p className="text-danger mb-4">{error}</p>
<Link
href="/app"
className="inline-flex items-center px-3 py-1 bg-surface text-foreground rounded-lg hover:bg-accent-wash transition duration-base ease-standard hover:text-accent"
className={buttonClass({ variant: 'secondary', size: 'md', className: 'gap-2' })}
>
<svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Back to Documents
@ -177,10 +178,10 @@ export default function HTMLPage() {
left={
<Link
href="/app"
className="inline-flex items-center py-1 px-2 rounded-md border border-line bg-surface text-foreground text-xs hover:bg-accent-wash transition duration-base ease-standard hover:text-accent"
className={buttonClass({ variant: 'secondary', size: 'sm', className: 'gap-2' })}
aria-label="Back to documents"
>
<svg className="w-3 h-3 mr-2" fill="currentColor" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-3 h-3" fill="currentColor" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Documents

View file

@ -20,6 +20,7 @@ import { RateLimitBanner } from '@/components/auth/RateLimitBanner';
import { useAuthRateLimit } from '@/contexts/AuthRateLimitContext';
import { useFeatureFlag } from '@/contexts/RuntimeConfigContext';
import { LoadingSpinner } from '@/components/Spinner';
import { buttonClass } from '@/components/ui';
import {
FORCE_REPARSE_CONFIRM_MESSAGE,
FORCE_REPARSE_CONFIRM_TEXT,
@ -255,9 +256,9 @@ export default function PDFViewerPage() {
<Link
href="/app"
onClick={handleBackToDocuments}
className="inline-flex items-center px-3 py-1 bg-surface text-foreground rounded-lg hover:bg-accent-wash transition duration-base ease-standard hover:text-accent"
className={buttonClass({ variant: 'secondary', size: 'md', className: 'gap-2' })}
>
<svg className="w-4 h-4 mr-2 text-soft" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-4 h-4 text-soft" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Back to Documents
@ -384,10 +385,10 @@ export default function PDFViewerPage() {
<Link
href="/app"
onClick={handleBackToDocuments}
className="inline-flex items-center py-1 px-2 rounded-md border border-line bg-surface text-foreground text-xs hover:bg-accent-wash transition duration-base ease-standard hover:text-accent"
className={buttonClass({ variant: 'secondary', size: 'sm', className: 'gap-2' })}
aria-label="Back to documents"
>
<svg className="w-3 h-3 mr-2" fill="currentColor" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-3 h-3" fill="currentColor" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Documents

View file

@ -9,6 +9,7 @@ import { useEPUBTheme, getThemeStyles } from '@/hooks/epub/useEPUBTheme';
import { useEPUBResize } from '@/hooks/epub/useEPUBResize';
import { DotsVerticalIcon, ChevronLeftIcon, ChevronRightIcon } from '@/components/icons/Icons';
import type { EpubDocumentState } from '@/app/(app)/epub/[id]/useEpubDocument';
import { ToolbarButton } from '@/components/ui';
const ReactReader = dynamic(() => import('react-reader').then(mod => mod.ReactReader), {
ssr: false,
@ -160,36 +161,34 @@ export function EPUBViewer({ className = '', epubState }: EPUBViewerProps) {
<div className={`h-full flex flex-col relative z-0 ${className}`} ref={containerRef}>
<div className="flex items-center justify-between px-2 py-1 border-b border-line-soft bg-surface text-xs text-soft">
<div className="flex items-center gap-2">
<button
<ToolbarButton
type="button"
onClick={() => setIsTocOpen(open => !open)}
className="inline-flex items-center py-1 px-1 rounded-md border border-line bg-surface text-foreground text-xs hover:bg-accent-wash transition duration-base ease-standard transform hover:text-accent"
aria-label={isTocOpen ? 'Hide chapters' : 'Show chapters'}
className="px-1"
>
<DotsVerticalIcon className="w-4 h-4" />
</button>
<button
</ToolbarButton>
<ToolbarButton
type="button"
onClick={() => handleLocationChanged('prev')}
className="inline-flex items-center py-1 px-2 rounded-md border border-line bg-surface text-foreground text-xs hover:bg-accent-wash transition duration-base ease-standard transform hover:text-accent"
aria-label="Previous section"
>
<ChevronLeftIcon className="w-4 h-4" />
</button>
</ToolbarButton>
</div>
{currDocPages !== undefined && typeof currDocPage === 'number' && (
<span className="px-2 tabular-nums">
{currDocPage} / {currDocPages}
</span>
)}
<button
<ToolbarButton
type="button"
onClick={() => handleLocationChanged('next')}
className="inline-flex items-center py-1 px-2 rounded-md border border-line bg-surface text-foreground text-xs hover:bg-accent-wash transition duration-base ease-standard transform hover:text-accent"
aria-label="Next section"
>
<ChevronRightIcon className="w-4 h-4" />
</button>
</ToolbarButton>
</div>
{isTocOpen && tocRef.current && tocRef.current.length > 0 && (
<div className="border-b border-line-soft bg-background text-xs overflow-y-auto max-h-64 p-2">