Skip to content

APP: segment-based reading progress tracker and continue-reading prompt#1697

Open
johan-bell wants to merge 50 commits into
mainfrom
912-app-add-continue-reading-query-to-homepage
Open

APP: segment-based reading progress tracker and continue-reading prompt#1697
johan-bell wants to merge 50 commits into
mainfrom
912-app-add-continue-reading-query-to-homepage

Conversation

@johan-bell

@johan-bell johan-bell commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Review

Status: Ready for review

Supersedes #923 — that PR was merged by mistake and main was reverted to 8d56696f. This is the rebased branch (9955287c) with segment-based tracking, continue prompt UX fix, and QA specs. Commit history from the old PR is on this branch; review thread starts fresh here.

Related issue: #912


Summary

  • Tracks article reading progress locally and surfaces in-progress articles on the homepage Continue Reading row.
  • Replaces block-level visibility with viewport-height segments so long paragraphs advance on mobile (Friday review concern).
  • Shows an in-article Continue reading prompt on return visits; scroll restore does not re-show the card after the user continues.

Changes

  • useReadingProgressTracker.ts — segment collection, visibility/skim/dwell gates, localStorage persistence, scroll restore with guard window
  • ContinueReadingPrompt.vue + SingleContent.vue — resume card; continuePromptHandled prevents prompt reappearing after Continue
  • ContinueReading.vue — homepage row from saved readingProgress
  • readingTime.ts — shared dwell and skim-cap math (language WPM)
  • docs/reading-progress-tracker.md + diagram — architecture and gate documentation
  • QA: readingProgressTracker.qa.spec.ts, ContinueReading.spec.ts, docs/qa/reading-progress-tracker-results.md (63 automated tests passing)
  • i18n seeds (eng/fra) for prompt and home.continue.read

Test plan

  • Phone: long single-paragraph article — progress advances segment by segment (does not stall)
  • Partial read → Home — Continue Reading row shows the article
  • Reopen article — prompt appears; Continue reading scrolls and card stays hidden; Start from top dismisses but keeps progress
  • Fast-fling scroll — little or no progress saved
  • Read short article to end — removed from readingProgress and homepage row
  • cd app && npm run test -- --run src/composables/useReadingProgressTracker.spec.ts src/qa/readingProgressTracker.qa.spec.ts src/components/HomePage/ContinueReading.spec.ts

@johan-bell

Copy link
Copy Markdown
Collaborator Author

Ready for Review column on the project board.

Supersedes #923 (mistaken merge; main reverted). This PR (#1697) is the rebased replacement — please use this for review, not the closed #923 thread.

@ivanslabbert ivanslabbert left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split documentation restructuring into separate issue

Comment thread api/src/db/seedingDocs/lang-eng.json Outdated
Comment thread api/src/db/seedingDocs/lang-fra.json Outdated
@johan-bell johan-bell force-pushed the 912-app-add-continue-reading-query-to-homepage branch from 3460c15 to a6aeca0 Compare June 18, 2026 16:38
@johan-bell johan-bell force-pushed the 912-app-add-continue-reading-query-to-homepage branch from 619e80f to 18358b5 Compare July 2, 2026 07:03
@johan-bell

Copy link
Copy Markdown
Collaborator Author

Hi @ivanslabbert @claude @MrDirkelz Reoganization of the docs has been removed from this PR and added to #1750

@johan-bell johan-bell self-assigned this Jul 2, 2026
@ivanslabbert

Copy link
Copy Markdown
Contributor

Review summary — 🟡 Approve with nits

  • Cross-package contracts: clean. No DTO/FTS/auth changes. The homepage "Continue" row uses mangoToDexie(db.docs, …) — a local Dexie query, not an API sync query — so no sync-*-index.json design doc / indexNameRegistry entry is required (app/src/components/HomePage/ContinueProgress.vue:34-52). Progress persists to localStorage (contentProgress key), not IndexedDB, so no db.upgrade.ts schema wiring needed. i18n strings added in both lang-eng.json and lang-fra.json.
  • Feature fulfilled. Segment splitting for long paragraphs (useReadingProgressTracker.ts:1913), the three gates (visibility ≥50% + block-end-in-viewport, skim/velocity cap, WPM-scaled dwell), localStorage persistence with 100%→remove, homepage ContinueProgress.vue row, and ContinueReadingPrompt.vue with continue/dismiss + continuePromptHandled guard (SingleContent.vue:3110-3171). ~1000 lines of unit tests; legacy mediaProgress/readingProgress keys migrated.
  • Nit — scroll-restore is approximate. restoreScrollPosition (useReadingProgressTracker.ts:2481) scrolls to percent × maxScroll, but percent is a word/height-weighted segment fraction, so the landing point won't exactly match the last-read segment. Acceptable.
  • Nit — "Continue" row scope broadened. ContinueProgress.vue surfaces any content with a reading or watching entry (old ContinueWatching was video-only). ContinueListening.vue is currently inert (contentIds → []), so no live duplication today — but once that TODO is wired, an audio item with progress could show in both rows. Worth confirming intended.
  • Nit — redundant writes. Each segment confirmation calls setReadingProgress, which both applyContentProgressList and persistContentProgress() (rewrites the whole ≤10-entry array). Harmless at this scale. readingProgressAsRef (globalConfig.ts:2836) is exported but only consumed by specs.
  • No blocking correctness bugs. Progress is max-guarded so it never regresses on re-setup/resize; --desktop-sidebar-w/--mobile-menu-h CSS vars are both published with sane fallbacks.

🤖 AI-assisted review summary (Claude Code). Read-only analysis of the PR diff — not a substitute for human review.

@ivanslabbert

Copy link
Copy Markdown
Contributor

Re-review — verdict: 🟡 Approve with nits (stands)

Re-reviewed the two new commits be01594 ("narrow continue row to reading progress") and 4466fb7 ("update expected localStorage value") against my earlier nits.

  • Nit Add API based on NestJS #2 (broadened continue-row scope / duplication risk) — RESOLVED. ContinueProgress.vue:31-38 now filters progressList to entries where entry.reading !== undefined before mapping contentIds, so video/media-only content no longer surfaces in the row — eliminating the future overlap with a wired-up watching/listening row. Locked in by spec (ContinueProgress.spec.ts:55 now asserts not.toContain for video-only progress). Narrowing does not hide legitimately in-progress reading content.
  • Test change 4466fb7 — SOUND. useReadingProgressTracker.spec.ts:731 changes expected contentProgress from "[]" to null — a direct consequence of the removeReadingProgress refactor (globalConfig.ts:648-654), where persistContentProgress() moved inside the if (!entry?.reading) return guard, so nothing is written when there's no reading entry. End state is equivalent (getReadingProgress === 0, no stored progress). Not masking a regression.
  • 🟡 Nit Add auth to CMS #3 (redundant writes / dead export) — PARTIALLY resolved. The redundant-write half is fixed: setReadingProgress early-returns when existing?.reading?.progress === clampedProgress (globalConfig.ts:637). readingProgressAsRef is still exported/populated (globalConfig.ts:339,342) with no non-spec consumer — still open, cosmetic.
  • 🔴 Nit Add unit test workflow for app #1 (approximate scroll-restore) — STILL OPEN. Neither commit touches restoreScrollPosition (useReadingProgressTracker.ts ~:2481); unchanged. Non-blocking.
  • New minor: the unchanged-progress early-return also skips touchContentProgressEntry (recency re-ordering), so revisiting content at the exact same progress value won't re-surface it to the top of the row. Any real scroll movement changes the value and re-touches — trivial, non-blocking.
  • Rebase recommended before merge. The PR's own diff (three-dot, ~25 files) is clean — no inflation — but the branch shares an old merge-base (2222a23e) and origin/main has advanced past it, so merging as-is would revert main's newer work. Please rebase onto current main.

🤖 AI-assisted re-review (Claude Code). Follow-up to an earlier automated review; read-only analysis of the delta since that review.

johan-bell added 22 commits July 6, 2026 15:26
…angoToDexie for content retrieval and improve filtering logic
Shared WPM resolution, word counting, and per-block dwell bounds keep
SingleContent estimates and the progress tracker on the same math.
Expose get/set/remove helpers and a reactive ref so Continue Reading can
subscribe to progress changes across tabs.
…tes.

Dwell accumulates per prose block only while the user is not skimming,
so fast scrolls do not count as read progress.
Replace scroll-depth tracking with the dwell-based composable on the prose
body and restore saved scroll position on return visits.
Show in-progress text articles from localStorage instead of recomputing
eligibility from scroll position alone.
Add a written guide and diagram for how visibility, scroll velocity, and
per-block dwell combine to power the Continue Reading row.
… reading progress tracker files. Update state declaration to use const for better clarity.
…ved reactivity. Clean up code formatting for better readability.
Scale the skim velocity threshold with language WPM and centralize idle and scroll-sample constants used by the tracker.
…ates.

Require block bottom in viewport, scale skim detection from language WPM, pause dwell after inactivity, and auto-restore scroll on article reopen.
Cover block-end eligibility, WPM-scaled velocity, idle pause, no-scroll progress, and scroll restore on mount.
Document block-end, WPM-scaled skim, idle pause, and auto-restore behavior across the markdown guide and draw.io diagram.
johan-bell and others added 28 commits July 6, 2026 15:26
… eligibility logic. Introduce new functions for estimating words per pixel and resolving active blocks. Update scroll velocity handling to use words per second instead of pixels per second, improving accuracy in tracking reading progress.
… for skim detection and block dwell logic. Introduce functions for estimating words per pixel and computing scroll velocity in words per second, improving clarity and accuracy in reading progress tracking.
…for resolving active blocks and computing scroll velocity in words per second. Enhance skim detection logic and update test cases to reflect changes in state management and velocity handling, ensuring accurate tracking of reading progress.
…ds per pixel and computing scroll velocity in words per second. Refactor existing tests to ensure accurate validation of skim detection and velocity calculations, enhancing overall test coverage and reliability.
…changes in block eligibility and skim detection logic. Clarify the calculation of reading speed in words per second and enhance descriptions of tracking behavior, including idle pauses and scroll restoration on article reopen.
…ext presence, regardless of video content. Update documentation to clarify tracking conditions and improve descriptions of functionality.
Split tall prose blocks into viewport-height segments so gate 1b works on mobile, show a resume card on article reopen, and fix tracker tests for jsdom.

Co-authored-by: Cursor <cursoragent@cursor.com>
… and update event emissions. The prompt now directly emits 'continue' and 'dismiss' events without intermediate state management. Update SingleContent page to handle prompt visibility based on user interaction.
Automated P0/P1 scenarios, ContinueReading homepage tests, and QA results doc for merge sign-off.

Co-authored-by: Cursor <cursoragent@cursor.com>
Restore overlay props and layout from the conflict resolution skipped during rebase.
Enhance the README for the reading progress tracker with detailed explanations of tracking mechanics, segment calculations, and gate conditions. Introduce a new diagram for visual representation of the tracking process. Update references in existing documentation to ensure consistency and clarity.
Introduce a new document listing socket.io message names and their descriptions for API and client communication. Additionally, add several architecture diagrams, including data flows, permission systems, and data models, to enhance understanding of the system's structure and interactions. Update the REST API documentation with a detailed overview and workflow diagram to clarify data synchronization processes.
Enhance clarity and organization of documentation by updating references to guides and architecture diagrams. Key changes include:
- Expanded descriptions in `CLAUDE.md` and `README.md` to include guides and index links.
- Updated paths in `permissions.service.ts` to reflect new diagram locations.
- Adjusted documentation in `app` and `cms` to point to the correct guides for translations and project automation.
- Created a new `README.md` in the `docs` directory to serve as an index for documentation.
- Archived historical schema upgrades in a new directory for better organization.

These updates aim to improve navigation and accessibility of project documentation.
This commit introduces significant changes to the content progress tracking system, merging reading and media progress into a unified structure stored under `contentProgress`. Key updates include:
- Renamed functions and variables to reflect the new content progress model.
- Migrated legacy `readingProgress` and `mediaProgress` data into the new format.
- Updated UI components to display content in progress under a single "Continue" section, replacing the previous "Continue Watching" and "Continue Reading" components.
- Enhanced tests to cover the new progress tracking logic and ensure proper functionality across components.

These changes aim to streamline the user experience and improve the maintainability of the codebase.
This commit updates the SingleContent test suite to incorporate better handling of content progress tracking. Key changes include:
- Added `removeReadingProgress` and `syncContentProgressFromStorage` to ensure proper state management during tests.
- Cleared local storage and reset timers in the `afterEach` hook for consistent test environments.
- Replaced `waitForExpect` with `flushPromises` and `nextTick` for more reliable asynchronous handling.

These improvements aim to enhance test reliability and maintainability.
Show max(reading%, watching%) without duration labels so the Continue row treats articles and video consistently.
Expose --desktop-sidebar-w so fixed overlays can align with the content column when the sidebar is expanded or collapsed.
Use a progress bar, X dismiss, flexible width for i18n, content-column centering on desktop, and spacing above the mobile nav.
Remove unused home.continue.watch/read keys and align the compact prompt action label with the meeting wording.
Move reading-progress docs back to docs/reading-progress-tracker.md and
restore main doc paths and cross-references. The broader docs reorg lives
on branch 1749-docs-reorganizing-documents-of-the-project.

Co-authored-by: Cursor <cursoragent@cursor.com>
…r skip

readingProgressAsRef duplicated contentProgressAsRef with no production
consumer (ContinueProgress.vue already derives its own reading-filtered
view) - removed it and its updater.

setReadingProgress's unchanged-progress early-return also skipped
touchContentProgressEntry, so revisiting content already at the same
progress wouldn't bump it back to the top of the continue-reading row.
Now only short-circuits when the entry is both unchanged AND already
most-recent, preserving the original redundant-write fix for the hot
scroll-tick path while still bumping recency on a genuine revisit.
@johan-bell johan-bell force-pushed the 912-app-add-continue-reading-query-to-homepage branch from 4466fb7 to 83fdd9b Compare July 6, 2026 13:39

@MrDirkelz MrDirkelz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, think we also looked at this before

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants