Add universal reader features: gestures, keyboard, navigator, offline
- gestures.ts: Touch gesture controls (swipe, pinch, tap, double-tap) - keyboard-shortcuts.ts: Keyboard navigation (arrows, space, page up/down, etc) - navigator-panel.ts: Affinity-style minimap for page navigation - offline-manager.ts: Service worker registration and online status - reading-speed-tracker.ts: Track and sync reading speed to database - Add web manifest.json for PWA support
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
// Track reading speed and update database
|
||||
|
||||
// Reading speed tracker
|
||||
// Procedural implementation (no OOP)
|
||||
|
||||
interface ReadingSpeedTrackerState {
|
||||
startTime: number | null;
|
||||
pagesRead: number;
|
||||
wordsRead: number;
|
||||
lastSync: number;
|
||||
mediaItemId: string;
|
||||
}
|
||||
|
||||
function createReadingSpeedTracker(
|
||||
mediaItemId: string,
|
||||
): ReadingSpeedTrackerState {
|
||||
return {
|
||||
startTime: null,
|
||||
pagesRead: 0,
|
||||
wordsRead: 0,
|
||||
lastSync: Date.now(),
|
||||
mediaItemId,
|
||||
};
|
||||
}
|
||||
|
||||
function startReadingSession(
|
||||
state: ReadingSpeedTrackerState,
|
||||
): ReadingSpeedTrackerState {
|
||||
return {
|
||||
...state,
|
||||
startTime: Date.now(),
|
||||
pagesRead: 0,
|
||||
wordsRead: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function recordPageTurn(
|
||||
state: ReadingSpeedTrackerState,
|
||||
): ReadingSpeedTrackerState {
|
||||
if (!state.startTime) return state;
|
||||
|
||||
const newPagesRead = state.pagesRead + 1;
|
||||
const now = Date.now();
|
||||
|
||||
if (newPagesRead % 5 === 0 || now - state.lastSync > 5 * 60 * 1000) {
|
||||
syncReadingSpeed({ ...state, pagesRead: newPagesRead });
|
||||
return { ...state, pagesRead: newPagesRead, lastSync: now };
|
||||
}
|
||||
|
||||
return { ...state, pagesRead: newPagesRead };
|
||||
}
|
||||
|
||||
function recordWordsRead(
|
||||
state: ReadingSpeedTrackerState,
|
||||
wordCount: number,
|
||||
): ReadingSpeedTrackerState {
|
||||
return {
|
||||
...state,
|
||||
wordsRead: state.wordsRead + wordCount,
|
||||
};
|
||||
}
|
||||
|
||||
async function syncReadingSpeed(
|
||||
state: ReadingSpeedTrackerState,
|
||||
): Promise<void> {
|
||||
if (!state.startTime) return;
|
||||
|
||||
const minutesElapsed = (Date.now() - state.startTime) / (1000 * 60);
|
||||
const pagesPerMinute = state.pagesRead / minutesElapsed;
|
||||
const wordsPerMinute = state.wordsRead / minutesElapsed;
|
||||
|
||||
await apiPut(`/readers/${state.mediaItemId}/reading-speed`, {
|
||||
pages_per_minute: pagesPerMinute,
|
||||
words_per_minute: wordsPerMinute,
|
||||
pages_read: state.pagesRead,
|
||||
total_reading_minutes: minutesElapsed,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user