feat: collaboration temps reel - edition simultanee (#62)
CI / lint (push) Successful in 1m1s
CI / security (push) Successful in 41s
CI / test (push) Successful in 1m47s
CI / build (push) Successful in 1m20s
CI / e2e (push) Successful in 10m36s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s

WebSocket /ws/collab/{vault}/{path} (rooms par fichier), relais Yjs/CRDT, awareness (curseurs colores + presence), persistance serveur debounce 2s, auth WS + check_vault_access, reconnexion automatique. Frontend frontend/js/collab.js, backend backend/collab.py. Tests: 17 backend (5 clients simultanes) + 10 frontend. Docs: CHANGELOG, ROADMAP, fiche features/collaboration.md, README FR/EN.
This commit is contained in:
2026-09-11 23:27:22 -04:00
parent 3f7b7847a5
commit 063b02e996
19 changed files with 1741 additions and 33 deletions
+14
View File
@@ -2772,6 +2772,20 @@ select {
.editor-filename-input:hover { border-color: var(--border); }
.editor-filename-input:focus { border-color: var(--ok); background: var(--bg-input); }
.editor-spacer { flex: 1; }
/* Collaboration temps réel (#62) — indicateur de présence */
.collab-presence { display: flex; align-items: center; gap: 6px; margin-right: 10px; }
.collab-status { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.collab-status-connected { background: var(--ok); }
.collab-status-connecting { background: var(--warn); animation: editor-pulse 1s infinite; }
.collab-status-disconnected { background: var(--err); animation: editor-pulse 0.8s infinite; }
.collab-avatars { display: flex; align-items: center; }
.collab-avatar { width: 20px; height: 20px; border-radius: 50%; color: #fff; font-size: 11px; font-weight: 600; display: flex; align-items: center; justify-content: center; margin-left: -6px; border: 2px solid var(--bg-secondary); }
.collab-avatar:first-child { margin-left: 0; }
.collab-avatar-self { box-shadow: 0 0 0 2px var(--bg-primary); }
.collab-count { font-size: 11px; color: var(--text-muted); min-width: 10px; }
/* Collaboration temps réel (#62) — curseurs distants CodeMirror */
.cm-remote-cursor { display: inline-block; width: 0; border-left: 2px solid; height: 1.2em; vertical-align: text-bottom; position: relative; margin-left: -1px; }
.cm-remote-cursor-label { position: absolute; top: -1.35em; left: -1px; padding: 1px 4px; border-radius: 3px 3px 3px 0; color: #fff; font-size: 10px; font-weight: 600; white-space: nowrap; pointer-events: none; z-index: 5; }
.editor-save-dot { display: flex; align-items: center; gap: 4px; font-size: 11px; padding: 0 4px; margin-right: 8px; }
.editor-btn + .editor-btn { margin-left: 6px; }
.editor-save-dot .dot { width: 6px; height: 6px; border-radius: 50%; }