Path: blob/master/src/packages/frontend/editors/slate/cursors/broadcast.ts
1697 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45// Broadcast of own cursor.67// NOTE: We use plural "cursors" here in the optimistic hope that8// we'll somehow implement a notion of multiple cursors for slate.9// Hmm, that already exists for a single code cell, doesn't it, due10// to codemirror.1112import { debounce } from "lodash";13import * as CodeMirror from "codemirror";14import { useCallback, useRef } from "react";15import { Point } from "slate";16import { ReactEditor } from "../slate-react";17import { slatePointToMarkdownPosition } from "../sync";1819// Cursor broadcast can be expensive since we convert the cursor20// from slate coordinates to markdown coordinates each time,21// and we currently do this by converting the entire slate22// document to markdown, which can take a few ms.23const UPDATE_DEBOUNCE_MS = 1500;2425interface Options {26editor: ReactEditor;27broadcastCursors: (locs: any[]) => void;28}2930export const useBroadcastCursors: (Options) => () => void = ({31editor,32broadcastCursors,33}) => {34const focusPointRef = useRef<Point | undefined>(undefined);35const markdownPositionRef = useRef<CodeMirror.Position | undefined>(36undefined37);3839const update = useCallback(40debounce(() => {41markdownPositionRef.current = slatePointToMarkdownPosition(42editor,43focusPointRef.current44);45if (46markdownPositionRef.current != null &&47focusPointRef.current != null48) {49const { line, ch } = markdownPositionRef.current;50broadcastCursors([{ x: ch, y: line }]);51}52}, UPDATE_DEBOUNCE_MS),53[]54);5556const onChange = () => {57if (!ReactEditor.isFocused(editor)) return;58const newFocus = editor.selection?.focus;59if (newFocus == null) return;60if (61focusPointRef.current != null &&62Point.equals(newFocus, focusPointRef.current)63) {64// cursor didn't change (or not collapsed)65return;66}67focusPointRef.current = newFocus;68// update/broadcast out cursor position.69update();70};7172return onChange;73};747576