@atlaskit/editor-plugin-loom
Version:
Loom plugin for @atlaskit/editor-core
204 lines (202 loc) • 7.08 kB
JavaScript
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { logException } from '@atlaskit/editor-common/monitoring';
import { getQuickInsertItem } from '../ui/quickInsert';
import { LoomPluginAction, loomPluginKey } from './main';
export const enableLoom = ({
loomButton
}) => ({
tr
}) => {
tr.setMeta(loomPluginKey, {
type: LoomPluginAction.ENABLE,
loomButton
});
return tr;
};
export const disableLoom = ({
error
}) => ({
tr
}) => {
tr.setMeta(loomPluginKey, {
type: LoomPluginAction.DISABLE,
error
});
return tr;
};
export const recordVideo = ({
inputMethod,
editorAnalyticsAPI
}) => ({
tr
}) => {
tr.setMeta(loomPluginKey, {
type: LoomPluginAction.RECORD_VIDEO
});
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
action: ACTION.RECORD_VIDEO,
actionSubject: ACTION_SUBJECT.LOOM,
attributes: {
inputMethod
},
eventType: EVENT_TYPE.TRACK
})(tr);
return tr;
};
export const recordVideoFailed = ({
inputMethod,
error,
editorAnalyticsAPI
}) => ({
tr
}) => {
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
action: ACTION.RECORD_VIDEO_FAILED,
actionSubject: ACTION_SUBJECT.LOOM,
attributes: {
inputMethod,
error
},
eventType: EVENT_TYPE.TRACK
})(tr);
return tr;
};
export const insertVideo = ({
editorAnalyticsAPI,
video
}) => ({
tr
}) => {
tr.setMeta(loomPluginKey, {
type: LoomPluginAction.INSERT_VIDEO
});
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
action: ACTION.INSERT_VIDEO,
actionSubject: ACTION_SUBJECT.LOOM,
eventType: EVENT_TYPE.TRACK,
attributes: {
duration: video.duration
}
})(tr);
return tr;
};
const getPositions = (tr, posType) => {
const selection = tr.selection;
switch (posType) {
case 'current':
return {
from: selection.from,
to: selection.from
};
case 'start':
return {
from: 0,
to: 0
};
case 'end':
return {
from: tr.doc.content.size,
to: tr.doc.content.size
};
}
};
export const insertLoom = (editorView, api, video, positionType) => {
var _api$hyperlink$action, _api$hyperlink;
if (!editorView) {
return false;
}
const {
state,
dispatch
} = editorView;
const {
from,
to
} = getPositions(state.tr, positionType);
return (_api$hyperlink$action = api === null || api === void 0 ? void 0 : (_api$hyperlink = api.hyperlink) === null || _api$hyperlink === void 0 ? void 0 : _api$hyperlink.actions.insertLink(INPUT_METHOD.TYPEAHEAD, from, to, video.sharedUrl, video.title, undefined, undefined, undefined, 'embed' // Convert to embed card instead of inline
)(state, dispatch)) !== null && _api$hyperlink$action !== void 0 ? _api$hyperlink$action : false;
};
export const executeRecordVideo = api => {
var _api$core, _api$analytics;
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(recordVideo({
inputMethod: INPUT_METHOD.TOOLBAR,
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions
}));
};
export const setupLoom = async (loomProvider, api, editorView, initViaCommand) => {
var _api$core4, _api$analytics5;
const clientResult = await loomProvider.getClient();
if (clientResult.status === 'error') {
var _api$core2, _api$analytics2;
api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(disableLoom({
error: clientResult.message
}));
logException(new Error(clientResult.message), {
location: 'editor-plugin-loom/sdk-initialisation'
});
api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions.fireAnalyticsEvent({
action: ACTION.ERRORED,
actionSubject: ACTION_SUBJECT.LOOM,
eventType: EVENT_TYPE.OPERATIONAL,
attributes: {
error: clientResult.message
}
});
return {
error: clientResult.message
};
}
const {
attachToButton
} = clientResult.client;
// Hidden element to work around the SDK API
const loomButton = document.createElement('button');
attachToButton({
button: loomButton,
onInsert: video => {
var _api$hyperlink2, _api$core3, _api$analytics3;
if (!editorView) {
return;
}
const {
state,
dispatch
} = editorView;
const pos = state.selection.from;
api === null || api === void 0 ? void 0 : (_api$hyperlink2 = api.hyperlink) === null || _api$hyperlink2 === void 0 ? void 0 : _api$hyperlink2.actions.insertLink(INPUT_METHOD.TYPEAHEAD, pos,
// from === to, don't replace text to avoid accidental content loss
pos, video.sharedUrl, video.title, undefined, undefined, undefined, 'embed' // Convert to embed card instead of inline
)(state, dispatch);
api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(insertVideo({
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions,
video
}));
}
});
api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
tr
}) => {
enableLoom({
loomButton
})({
tr
});
if (initViaCommand) {
var _api$quickInsert, _api$analytics4;
api === null || api === void 0 ? void 0 : (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.commands.addQuickInsertItem(getQuickInsertItem(api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions))({
tr
});
}
return tr;
});
// We're not combining the analytics steps into the enable / disable commands because the collab-edit plugin
// filters out any transactions with steps (even analytics) when it's initialising.
// Even if `initViaCommand` is true, collab-edit might not be ready depending on when `initLoom` is called,
// hence the analytics step is added separately in both cases
api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions.fireAnalyticsEvent({
action: ACTION.INITIALISED,
actionSubject: ACTION_SUBJECT.LOOM,
eventType: EVENT_TYPE.OPERATIONAL
});
return {};
};