Skip to content

Commit 1a726c0

Browse files
feat: Follow a Collaborator's Viewport (#681)
Co-authored-by: FelixTJDietrich <felix_dietrich@gmx.de>
1 parent 2887b9e commit 1a726c0

12 files changed

Lines changed: 624 additions & 37 deletions

File tree

docs/library/api/collaboration.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,26 @@ Any Yjs-compatible transport works. The standalone server uses a custom WebSocke
3030
- [`y-indexeddb`](https://github.com/yjs/y-indexeddb) for offline persistence (layered alongside any other transport)
3131
- Any HTTP/3 stream or BroadcastChannel if your room is browser-local
3232

33-
## Awareness (cursors, selections)
33+
## Awareness (cursors, selections, follow)
3434

35-
Awareness state — who's online, where their cursor is, what they have selected — rides on the same channel as document updates. The editor manages awareness internally; you don't need to wire anything beyond `sendBroadcastMessage` / `receiveBroadcastedMessage`.
35+
Awareness state — who's online, where their cursor is, what they have selected, and where their viewport sits — rides on the same channel as document updates. The editor manages awareness internally; you don't need to wire anything beyond `sendBroadcastMessage` / `receiveBroadcastedMessage`.
36+
37+
The presence bar, cursors, selection highlights, and viewport-following are toggled per-feature on the `collaboration` option:
38+
39+
```ts
40+
const editor = new ApollonEditor(container, {
41+
collaboration: {
42+
enabled: true,
43+
user: { name: "Ada", color: "#1c7ed6" },
44+
showPresence: true, // avatar bar (top-right)
45+
showCursors: true, // live remote cursors
46+
showSelectionHighlights: true, // highlight peers' selected elements
47+
showFollow: true, // click a peer's avatar to mirror their viewport
48+
},
49+
})
50+
```
51+
52+
When `showFollow` is on, clicking a collaborator's avatar follows their viewport. The follower sees the editor framed in that person's color and a banner naming them with a **Stop** button; the followed user sees a "followed by N" badge. Any local pan/zoom hands control back and stops following.
3653

3754
## Server-side integration
3855

library/lib/apollon-editor.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const normalizeCollaborationOptions = (options?: Apollon.ApollonOptions) => {
5353
showCursors: collaboration?.showCursors ?? showVisualsByDefault,
5454
showSelectionHighlights:
5555
collaboration?.showSelectionHighlights ?? showVisualsByDefault,
56+
showFollow: collaboration?.showFollow ?? showVisualsByDefault,
5657
}
5758
}
5859

@@ -61,11 +62,15 @@ const disabledCollaboration = {
6162
showPresence: false,
6263
showCursors: false,
6364
showSelectionHighlights: false,
65+
showFollow: false,
6466
}
6567

6668
const noopCollaborationAwareness = {
6769
setLocalAwarenessCursor: () => {},
6870
setLocalAwarenessSelectedElement: () => {},
71+
setLocalAwarenessViewport: () => {},
72+
setLocalAwarenessFollowing: () => {},
73+
getAwarenessStates: () => new Map(),
6974
subscribeToAwarenessChanges: () => () => {},
7075
subscribeToCollaboratorChanges: () => () => {},
7176
getLocalAwarenessClientId: () => 0,
@@ -197,6 +202,11 @@ export class ApollonEditor {
197202
this.syncManager.setLocalAwarenessCursor,
198203
setLocalAwarenessSelectedElement:
199204
this.syncManager.setLocalAwarenessSelectedElement,
205+
setLocalAwarenessViewport:
206+
this.syncManager.setLocalAwarenessViewport,
207+
setLocalAwarenessFollowing:
208+
this.syncManager.setLocalAwarenessFollowing,
209+
getAwarenessStates: this.syncManager.getAwarenessStates,
200210
subscribeToAwarenessChanges:
201211
this.syncManager.subscribeToAwarenessChanges,
202212
subscribeToCollaboratorChanges:

0 commit comments

Comments
 (0)