Teleprompter-style continuous scrolling toggled from the View menu (Shift+A), available only in scrolled mode. A PacedScroller drives whole-pixel forward steps at a constant, user-adjustable velocity; the speed (25-500 percent, persisted as autoScrollSpeed) is tuned from a floating control pill that also offers pause/resume and exit, and fades away while scrolling to keep the mode immersive. Tapping the page pauses and resumes instead of turning pages or toggling the bars; manual wheel or drag input simply composes with the paced scrolling. Escape or leaving scrolled mode ends the session. When forward progress stalls the session hops to the next section (single-section scroll mode) or stops with a toast at the end of the book. Vertical-writing books scroll along the horizontal axis with the sign convention foliate uses for scrolled offsets. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,9 @@ interface ViewState {
|
||||
`getBookProgress(key)` for one-shot reads. */
|
||||
ribbonVisible: boolean;
|
||||
ttsEnabled: boolean;
|
||||
/* True while an Auto Scroll session (#4998) is engaged for this view;
|
||||
session-only, never persisted. Drives the View menu checkmark. */
|
||||
autoScrollEnabled: boolean;
|
||||
syncing: boolean;
|
||||
gridInsets: Insets | null;
|
||||
/* True while the reader is showing a position requested by an external
|
||||
@@ -65,6 +68,7 @@ interface ReaderStore {
|
||||
setHoveredBookKey: (key: string | null) => void;
|
||||
setBookmarkRibbonVisibility: (key: string, visible: boolean) => void;
|
||||
setTTSEnabled: (key: string, enabled: boolean) => void;
|
||||
setAutoScrollEnabled: (key: string, enabled: boolean) => void;
|
||||
setIsLoading: (key: string, loading: boolean) => void;
|
||||
setIsSyncing: (key: string, syncing: boolean) => void;
|
||||
setProgress: (
|
||||
@@ -157,6 +161,7 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
|
||||
error: null,
|
||||
ribbonVisible: false,
|
||||
ttsEnabled: false,
|
||||
autoScrollEnabled: false,
|
||||
syncing: false,
|
||||
gridInsets: null,
|
||||
previewMode: false,
|
||||
@@ -296,6 +301,7 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
|
||||
error: null,
|
||||
ribbonVisible: false,
|
||||
ttsEnabled: false,
|
||||
autoScrollEnabled: false,
|
||||
syncing: false,
|
||||
gridInsets: null,
|
||||
previewMode: false,
|
||||
@@ -319,6 +325,7 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
|
||||
error: 'Failed to load book.',
|
||||
ribbonVisible: false,
|
||||
ttsEnabled: false,
|
||||
autoScrollEnabled: false,
|
||||
syncing: false,
|
||||
gridInsets: null,
|
||||
previewMode: false,
|
||||
@@ -466,6 +473,17 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
|
||||
},
|
||||
})),
|
||||
|
||||
setAutoScrollEnabled: (key: string, enabled: boolean) =>
|
||||
set((state) => ({
|
||||
viewStates: {
|
||||
...state.viewStates,
|
||||
[key]: {
|
||||
...state.viewStates[key]!,
|
||||
autoScrollEnabled: enabled,
|
||||
},
|
||||
},
|
||||
})),
|
||||
|
||||
setIsLoading: (key: string, loading: boolean) =>
|
||||
set((state) => ({
|
||||
viewStates: {
|
||||
|
||||
Reference in New Issue
Block a user