UNPKG

@atlaskit/editor-plugin-synced-block

Version:

SyncedBlock plugin for @atlaskit/editor-core

135 lines (133 loc) 5.9 kB
import { TextSelection } from '@atlaskit/editor-prosemirror/state'; import { FLAG_ID } from '../../types'; import { syncedBlockPluginKey } from '../main'; import { deferDispatch } from './utils'; const onRetry = (api, resourceId) => { return () => { var _api$core, _api$core2; api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.focus(); api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(({ tr }) => { var _api$syncedBlock, _api$syncedBlock$shar, _api$syncedBlock$shar2, _api$syncedBlock2; const pos = api === null || api === void 0 ? void 0 : (_api$syncedBlock = api.syncedBlock) === null || _api$syncedBlock === void 0 ? void 0 : (_api$syncedBlock$shar = _api$syncedBlock.sharedState.currentState()) === null || _api$syncedBlock$shar === void 0 ? void 0 : (_api$syncedBlock$shar2 = _api$syncedBlock$shar.retryCreationPosMap) === null || _api$syncedBlock$shar2 === void 0 ? void 0 : _api$syncedBlock$shar2.get(resourceId); const from = pos === null || pos === void 0 ? void 0 : pos.from; const to = pos === null || pos === void 0 ? void 0 : pos.to; if (from === undefined || to === undefined) { return tr; } tr.setSelection(TextSelection.create(tr.doc, from, to)).setMeta(syncedBlockPluginKey, { activeFlag: false }); api === null || api === void 0 ? void 0 : (_api$syncedBlock2 = api.syncedBlock) === null || _api$syncedBlock2 === void 0 ? void 0 : _api$syncedBlock2.commands.insertSyncedBlock()({ tr }); return tr; }); }; }; const getRevertCreationPos = (api, doc, resourceId) => { var _api$syncedBlock3, _api$syncedBlock3$sha, _api$syncedBlock3$sha2; const retryCreationPos = api === null || api === void 0 ? void 0 : (_api$syncedBlock3 = api.syncedBlock) === null || _api$syncedBlock3 === void 0 ? void 0 : (_api$syncedBlock3$sha = _api$syncedBlock3.sharedState.currentState()) === null || _api$syncedBlock3$sha === void 0 ? void 0 : (_api$syncedBlock3$sha2 = _api$syncedBlock3$sha.retryCreationPosMap) === null || _api$syncedBlock3$sha2 === void 0 ? void 0 : _api$syncedBlock3$sha2.get(resourceId); if (retryCreationPos) { return retryCreationPos; } // Fallback to find the positions in case BE call returns before plugin state becomes available // which is highly unlikely let currentPos; doc.descendants((node, pos) => { if (currentPos) { return false; } if (node.type.name === 'bodiedSyncBlock' && resourceId === node.attrs.resourceId) { currentPos = { from: pos, to: pos + node.nodeSize }; return false; } }); return currentPos; }; const buildRevertCreationTr = (tr, pos) => { var _tr$doc$nodeAt; const content = (_tr$doc$nodeAt = tr.doc.nodeAt(pos.from)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.content; if (content) { tr.replaceWith(pos.from, pos.to, content); const contentFrom = tr.mapping.map(pos.from); tr.setSelection(TextSelection.create(tr.doc, contentFrom, contentFrom + content.size)); } else { tr.delete(pos.from, pos.to); } return tr; }; /** * * Save the new bodiedSyncBlock to backend with empty content and handles revert (if failed) and retry flow */ export const handleBodiedSyncBlockCreation = (bodiedSyncBlockAdded, editorState, api) => { const syncBlockStore = syncedBlockPluginKey.getState(editorState).syncBlockStore; bodiedSyncBlockAdded.forEach(node => { if (node.from === undefined || node.to === undefined) { return; } const retryCreationPos = { from: node.from, to: node.to }; const resourceId = node.attrs.resourceId; deferDispatch(() => { var _api$core3; api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(({ tr }) => { return tr.setMeta(syncedBlockPluginKey, { retryCreationPos: { resourceId, pos: retryCreationPos } }); }); }); syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, node.node, success => { if (success) { var _api$core4, _api$core5; api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({ tr }) => { return tr.setMeta(syncedBlockPluginKey, { retryCreationPos: { resourceId, pos: undefined } }); }); api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.focus(); } else { var _api$core6; api === null || api === void 0 ? void 0 : (_api$core6 = api.core) === null || _api$core6 === void 0 ? void 0 : _api$core6.actions.execute(({ tr }) => { const revertCreationPos = getRevertCreationPos(api, tr.doc, resourceId); if (!revertCreationPos) { return tr; } const revertTr = buildRevertCreationTr(tr, revertCreationPos); return revertTr.setMeta('isConfirmedSyncBlockDeletion', true).setMeta('addToHistory', false).setMeta(syncedBlockPluginKey, { activeFlag: { id: FLAG_ID.CANNOT_CREATE_SYNC_BLOCK, onRetry: onRetry(api, resourceId), onDismissed: tr => tr.setMeta(syncedBlockPluginKey, { ...tr.getMeta(syncedBlockPluginKey), retryCreationPos: { resourceId, pos: undefined } }) } }); }); } }); }); };