Consolidate MangaCircus app, scraper, and Compose baseline
This commit is contained in:
1 parent
cfb2d79103
commit
eef4ffa07c
103 files changed
+9316
-172
No files matched your search
@@ -0,0 +1,84 @@
|
||||
# Active Reading Clock
|
||||
|
||||
Current policy: relaxed personal estimates, implemented 2026-10-06. This is not an
|
||||
anti-cheat system, proof of comprehension, or a basis for competitive rewards.
|
||||
Enable it in User → Reading time. Disabled means no clock requests.
|
||||
|
||||
## What counts
|
||||
|
||||
Each chapter visit measures foreground, loaded-page viewing time. After viewing
|
||||
**at least 60% of eligible pages**, rounded up, the whole visit's active time counts,
|
||||
including time before reaching that threshold. It continues counting through the
|
||||
rest of the visit and is saved periodically and when leaving the reader.
|
||||
|
||||
- There is **no pages-per-second ceiling** and no skimming penalty.
|
||||
- A loaded image needs **100 ms cumulative visible exposure**. Flow exposure uses
|
||||
10% of the smaller of page/viewport area and samples scroll positions plus a
|
||||
50 ms timer. This detects brief views; it does not assess reading speed.
|
||||
- Only actually observed pages count. A scrollbar/slider jump does not credit
|
||||
all pages between the starting position and destination.
|
||||
- Hidden covers/extras are excluded from the denominator.
|
||||
- Source versions have separate visit coverage; qualifying time combines into
|
||||
existing chapter totals without changing reading identities.
|
||||
- Below-60% visits remain bounded diagnostic drafts, excluded from Reading Story,
|
||||
first/last-read duration, reread counts and chapter headline totals.
|
||||
- New navigation starts a fresh visit. Old coverage does not qualify later picture
|
||||
lookups. Separate sub-60% visits are not combined. Back/forward-cache restoration
|
||||
continues the same visit.
|
||||
|
||||
Example: view 12 of 20 pages, then leave → all active time from that visit counts.
|
||||
Jump to page 19, dwell, leave → no new reading total. Historical times are retained;
|
||||
this update neither deletes old measurements nor invents times for missed reads.
|
||||
|
||||
Intent cannot be inferred perfectly: slowly searching most of a chapter can look
|
||||
like reading. This rule filters quick-search-and-one-picture visits without
|
||||
penalizing honest fast readers. Ordinary read/unread progress is independent.
|
||||
|
||||
## Pauses and display
|
||||
|
||||
Pause when hidden/unfocused; resume on reader input after returning. Pause after
|
||||
**30 seconds** without activity (updated at the user's request on 2026-10-06). The first loaded page can start
|
||||
without an extra click. Mouse/pen motion, wheel, touch movement, momentum scrolling
|
||||
and keyboard controls—including held Up/Down arrows—refresh reader activity.
|
||||
|
||||
Loading wait stays separate. An unloaded neighbour no longer pauses the clock if
|
||||
another visible image is readable. Failed/unloaded images do not earn coverage.
|
||||
An end card pauses time. Other reader tabs/devices coordinate to avoid accidental
|
||||
duplicate clocks; this is not an anti-cheat score.
|
||||
|
||||
The toolbar shows **this visit's** time. Its panel shows pages viewed, the 60%
|
||||
requirement, whether the visit counts, saved chapter total, loading wait and
|
||||
pause/save-pending state. “Verified”, “rejects” and “skimming” labels are removed.
|
||||
|
||||
## Reliable saves and compatibility
|
||||
|
||||
New clients POST cumulative snapshots to authenticated `/api/reading/visit` every
|
||||
10 seconds, on attention changes, and using `sendBeacon` (keepalive fallback) on
|
||||
`pagehide`. Final snapshots dispatch even with an ordinary request in flight.
|
||||
Visit ID plus increasing sequence makes retries/out-of-order packets idempotent.
|
||||
Delayed saves avoid the legacy 12-second packet truncation. Final saves don't
|
||||
reclaim the next chapter's lease, nor do stale pulses reclaim an exited lease.
|
||||
|
||||
First/last duration keeps growing after qualification until departure. Late finals
|
||||
update their own receipt, not a newer visit. The latest eight visit receipts are
|
||||
retained per chapter; extremely old delayed requests after eviction are outside
|
||||
this bounded retry window. There is no durable offline queue: closing an offline
|
||||
tab or a browser/OS crash can still lose undelivered time. “Save pending” is explicit.
|
||||
|
||||
Legacy `/api/reading/pulse` remains for already-open old readers. Existing records
|
||||
and totals are retained. Reload open readers for this policy. On code rollback the
|
||||
separate new endpoint returns 404 instead of interpreting cumulative totals as
|
||||
legacy deltas. Refresh open readers after rollback as well.
|
||||
|
||||
## Privacy and verification
|
||||
|
||||
Only chapter/version IDs, visit/sequence IDs, cumulative active/loading/input-type
|
||||
times, viewed page indexes and exit flags are sent. No coordinates, key contents,
|
||||
recordings, screenshots or raw event stream are saved. Exposure geometry stays
|
||||
local. History is private to the user and existing export/reset controls remain.
|
||||
|
||||
`test/reading-visits.test.js` covers thresholds, historical preservation, fast
|
||||
slices, lookup exclusion, attention/loading, late/duplicate snapshots and delayed
|
||||
delivery. `node tools/test-compose.js --reading-ui` adds actual headless Edge
|
||||
mobile-layout QA with disposable users/generated images/isolated storage. It does
|
||||
not observe production readers or query image hosters.
|
||||
Reference in new issue
Block a user