UNPKG

@atlaskit/editor-plugin-collab-edit

Version:

Collab Edit plugin for @atlaskit/editor-core

86 lines (83 loc) • 4.51 kB
import { AnalyticsStep } from '@atlaskit/adf-schema/steps/analytics'; import { getSendableSelection } from '../actions'; import { pluginKey } from '../main/plugin-key'; export var sendTransaction = function sendTransaction(_ref) { var originalTransaction = _ref.originalTransaction, transactions = _ref.transactions, oldEditorState = _ref.oldEditorState, newEditorState = _ref.newEditorState, useNativePlugin = _ref.useNativePlugin, viewMode = _ref.viewMode, hideTelecursorOnLoad = _ref.hideTelecursorOnLoad, _ref$isSendHeld = _ref.isSendHeld, isSendHeld = _ref$isSendHeld === void 0 ? false : _ref$isSendHeld; return function (provider) { var docChangedTransaction = transactions.find(function (tr) { return tr.docChanged; }); var currentPluginState = pluginKey.getState(newEditorState); var trNoAnalytics = oldEditorState.tr; docChangedTransaction === null || docChangedTransaction === void 0 || docChangedTransaction.steps.forEach(function (step) { if (!(step instanceof AnalyticsStep)) { trNoAnalytics.step(step); } }); if (!(currentPluginState !== null && currentPluginState !== void 0 && currentPluginState.isReady)) { return; } var shouldSendStepForSynchronyCollabProvider = !originalTransaction.getMeta('isRemote') && // TODO: ED-8995 - We need to do this check to reduce the number of race conditions when working with tables. // This metadata is coming from the scaleTable command in table-resizing plugin !originalTransaction.getMeta('scaleTable') && trNoAnalytics.docChanged; // A streaming producer can hold the flush back so several of its frames accumulate in the // unconfirmed queue and collapse into one step before being sent. The steps are not // dropped: `sendableSteps` returns the whole queue, so the first unheld state update sends // everything that accumulated. Skipping `send` also skips `lockStepOrigins`, which is what // keeps the accumulated frames composable. // // Telepointer messages below are intentionally left alone — holding them would freeze // other participants' cursors for the length of the hold, and they carry no steps. if (!isSendHeld && (useNativePlugin || shouldSendStepForSynchronyCollabProvider)) { provider.send(trNoAnalytics, oldEditorState, newEditorState); } var prevPluginState = pluginKey.getState(oldEditorState); var _ref2 = prevPluginState || {}, prevActiveParticipants = _ref2.activeParticipants; var activeParticipants = currentPluginState.activeParticipants, sessionId = currentPluginState.sessionId; var selectionChanged = !oldEditorState.selection.eq(newEditorState.selection); var participantsChanged = prevActiveParticipants && !prevActiveParticipants.eq(activeParticipants); if (!sessionId || viewMode !== 'edit') { return; } // uiEvent is standard metdata (docs: https://prosemirror.net/docs/ref/#state.Transaction) var isPaste = (docChangedTransaction === null || docChangedTransaction === void 0 ? void 0 : docChangedTransaction.getMeta('uiEvent')) === 'paste'; // If this metadata is truthy then it means a selection bookmark might be declared as the meta value OR the transaction // doesn't want the tr.selection to be sent to remote users at all. var remoteSelectionBookmark = originalTransaction.getMeta('useSelectionBookmarkForRemote'); if (!!remoteSelectionBookmark) { if (remoteSelectionBookmark !== true && 'resolve' in remoteSelectionBookmark) { var selection = remoteSelectionBookmark.resolve(newEditorState.doc); var message = { type: 'telepointer', selection: getSendableSelection(selection), sessionId: sessionId }; provider.sendMessage(message); } } else if ( // Broadcast the position if the selection has changed, and the doc hasn't changed (it is mapped // by the receiver). // If we're pasting content though make an exception (as doc has changed) // as on a ranged selection it results in not clearing the ranged selection after the paste selectionChanged && (!docChangedTransaction || isPaste) || participantsChanged && !hideTelecursorOnLoad) { var _selection = getSendableSelection(newEditorState.selection); var _message = { type: 'telepointer', selection: _selection, sessionId: sessionId }; provider.sendMessage(_message); } }; };