joplock/app/items
igor 91f3863b8d
Some checks failed
Build and push Joplock image / build-and-push (push) Has been cancelled
feat(sync): detect and handle concurrent note edits across browsers
When the same note is open in multiple browsers, changes made in one
browser are now detected and surfaced in the other.

Server:
- itemService.noteFreshnessByUserIdAndJopId: cheap single-row probe
  returning {updatedTime, deletedTime} without decoding the note body
- GET /api/web/notes/:id/freshness: serves the probe, marked
  isHeartbeat:true so polling does not reset the session idle timer
- PUT /fragments/editor/:id conflict response now sends X-Note-Conflict:1
  header so the client can distinguish it from a real save success

Client:
- checkNoteFreshness() runs on every 30s connectivity ping tick and
  immediately on visibilitychange (tab focus)
- Clean editor: silently reloads the note fragment
- Dirty editor: shows a banner (same pattern as search-nav-bar) with
  'Use server version' and 'Overwrite with mine' buttons
- Deleted note: shows a 'deleted in another window' banner
- _activeEditorIsDirty() uses durable signals (_previewDirty,
  _pvSyncTimer, title contenteditable vs hidden input, formHash vs
  _savedHash) not the transient autosave-status text
- Banner is server-rendered inside the form (hidden attribute), reuses
  search-nav-bar CSS and buttons — no dynamic DOM creation
- htmx:afterRequest skips snapshotHash/setSaved when X-Note-Conflict:1
  is present, keeping the editor dirty and the conflict UI visible
- Service worker bumped to v25
2026-06-23 17:32:03 +12:00
..
itemService.js feat(sync): detect and handle concurrent note edits across browsers 2026-06-23 17:32:03 +12:00
itemWriteService.js fix mobile resume startup and editor targeting 2026-04-25 20:51:37 +12:00