Сократите техническую сложность, сосредоточившись на пользовательском опыте. Избегайте ненужного общего состояния при совместном редактировании.
Фреймворк Yjs добавляет передовые возможности совместного редактирования в ванильные текстовые редакторы Prosemirror. Он превращает процесс сохранить и закрыть в режим, в котором многие пользователи пишут все одновременно.
Ключевым элементом совместного редактирования является отображение курсоров других пользователей, чтобы можно было понять, почему появился новый фрагмент текста. И чтобы различать, кто именно внес изменения, каждый курсор должен иметь уникальный цвет.
Библиотека интеграции Prosemirror/Yjs, y-prosemirror, поставляется с модулем курсора, который сохраняет цвет каждого пользователя в общем состоянии (протокол осведомленности). Каждый подключенный пользователь берет реплицированные цвета и отображает курсоры.
При этом у нас были все компоненты для создания первоклассного совместного редактирования. И тут наступила реальность…
Выбор цвета оказался намного сложнее, чем мы предполагали. Например, что произойдет, если два пользователя присоединятся одновременно и выберут один и тот же цвет? Они оба выбирают новый цвет — или только один из них? Как они договариваются, кто из них выберет новый цвет? Сколько длится «присоединиться одновременно»? Повторное присоединение считается присоединением или пользователь должен сохранить цвет в этой ситуации? Что делать, если два пользователя с конфликтующими цветами воссоединятся? Здесь мы ответили на все сложные вопросы из учебников по распределенным системам.
Создание для пользователей — не наука
У нас был момент озарения, когда мы изменили нашу точку зрения с «распределенных систем» на «пользовательский опыт». Все стало яснее, когда мы спросили себя: «Если Алиса, Боб и Чарли работают в одном и том же документе, насколько важно, чтобы курсор Чарли был красным для Алисы и Боба?» Мы быстро поняли, что на пользовательский опыт не влияет, если Алиса видит Чарли как «красный курсор», а Боб видит его как «синий курсор».
Это означало, что на самом деле не было необходимости синхронизировать цвета между пользователями, что означало отсутствие сложных проблем с распределенной системой. Ага!
Итак, вот что у нас получилось: Каждый пользователь ведет упорядоченный список пользователей, которых он когда-либо видел подключающимися. На основе этого списка цвет выбирается из списка доступных цветов. Не удаляя отключенных пользователей, мы гарантируем, что каждый пользователь всегда будет использовать один и тот же цвет. Вот набросок:
const handleAwarenessChange = ({ added }) => { added.forEach(clientId => { if (!allClientIds.includes(clientId)) { allClientIds.push(clientId); } }); ... }); observable.on('change', handleAwarenessChange); function computeColor(clientId: number, allClientIds: number[]) { const nrConnected = allClientIds.indexOf(clientId); return COLORS[nrConnected % COLORS.length]; }
Удачного кодирования!
➡️ Вы хотите больше работать с Prosemirror & Yjs? NEXT ищет Prosemirror разработчика (удаленно, на полную ставку). Подайте заявку сейчас!