summaryrefslogtreecommitdiff
path: root/src/main/overleafSocket.ts
diff options
context:
space:
mode:
authorhaoyuren <13851610112@163.com>2026-03-12 18:11:10 -0500
committerhaoyuren <13851610112@163.com>2026-03-12 18:11:10 -0500
commita0dd3d7ac642111faeaefd02c5a452898b9c6d49 (patch)
tree2f435e189bd38505b9793b78de51b3a1c282f1c6 /src/main/overleafSocket.ts
parentb116335f9dbde4f483c0b2b8e7bfca5d321c5dfc (diff)
Add collaborator cursors and project chat
Collaborator cursors: - Real-time cursor positions via clientTracking Socket.IO events - CM6 extension renders colored cursor widgets with name labels - Throttled cursor position broadcasting (300ms) - Connected users count in toolbar and status bar Project chat: - Chat panel in right sidebar (toggleable) - Load message history via REST API - Send messages with real-time delivery via Socket.IO new-chat-message - Auto-scroll, avatars, timestamps Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/main/overleafSocket.ts')
-rw-r--r--src/main/overleafSocket.ts18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/main/overleafSocket.ts b/src/main/overleafSocket.ts
index f825c4c..52ac20f 100644
--- a/src/main/overleafSocket.ts
+++ b/src/main/overleafSocket.ts
@@ -92,6 +92,10 @@ export class OverleafSocket extends EventEmitter {
return this._projectData
}
+ get publicId(): string | null {
+ return this._projectData?.publicId || null
+ }
+
private setState(s: ConnectionState) {
this._state = s
this.emit('connectionState', s)
@@ -270,6 +274,20 @@ export class OverleafSocket extends EventEmitter {
this.ws?.send(encodeEvent('applyOtUpdate', [docId, { doc: docId, op: ops, v: version, hash, lastV: version }]))
}
+ /** Get list of connected users with their cursor positions */
+ async getConnectedUsers(): Promise<unknown[]> {
+ const result = await this.emitWithAck('clientTracking.getConnectedUsers', []) as unknown[]
+ // result format: [error, usersArray]
+ const err = result[0]
+ if (err) throw new Error(`getConnectedUsers failed: ${JSON.stringify(err)}`)
+ return (result[1] as unknown[]) || []
+ }
+
+ /** Send our cursor position */
+ updateCursorPosition(docId: string, row: number, column: number): void {
+ this.ws?.send(encodeEvent('clientTracking.updatePosition', [{ row, column, doc_id: docId }]))
+ }
+
disconnect() {
this.shouldReconnect = false
this.stopHeartbeat()