@atlaskit/editor-plugin-loom 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +13 -0
- package/README.md +9 -0
- package/dist/cjs/commands.js +86 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/plugin.js +104 -0
- package/dist/cjs/pm-plugin.js +200 -0
- package/dist/cjs/ui/ToolbarButton.js +44 -0
- package/dist/es2019/commands.js +80 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/plugin.js +95 -0
- package/dist/es2019/pm-plugin.js +160 -0
- package/dist/es2019/ui/ToolbarButton.js +41 -0
- package/dist/esm/commands.js +80 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugin.js +94 -0
- package/dist/esm/pm-plugin.js +188 -0
- package/dist/esm/ui/ToolbarButton.js +37 -0
- package/dist/types/commands.d.ts +22 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/plugin.d.ts +12 -0
- package/dist/types/pm-plugin.d.ts +22 -0
- package/dist/types/ui/ToolbarButton.d.ts +178 -0
- package/dist/types-ts4.5/commands.d.ts +22 -0
- package/dist/types-ts4.5/index.d.ts +2 -0
- package/dist/types-ts4.5/plugin.d.ts +12 -0
- package/dist/types-ts4.5/pm-plugin.d.ts +22 -0
- package/dist/types-ts4.5/ui/ToolbarButton.d.ts +220 -0
- package/package.json +104 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
3
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
5
|
+
import { disableLoom, enableLoom, insertVideo } from './commands';
|
|
6
|
+
export let LoomPluginAction = /*#__PURE__*/function (LoomPluginAction) {
|
|
7
|
+
LoomPluginAction[LoomPluginAction["ENABLE"] = 0] = "ENABLE";
|
|
8
|
+
LoomPluginAction[LoomPluginAction["DISABLE"] = 1] = "DISABLE";
|
|
9
|
+
LoomPluginAction[LoomPluginAction["RECORD_VIDEO"] = 2] = "RECORD_VIDEO";
|
|
10
|
+
LoomPluginAction[LoomPluginAction["INSERT_VIDEO"] = 3] = "INSERT_VIDEO";
|
|
11
|
+
LoomPluginAction[LoomPluginAction["SET_ANALYTICS_FUNCTION"] = 4] = "SET_ANALYTICS_FUNCTION";
|
|
12
|
+
return LoomPluginAction;
|
|
13
|
+
}({});
|
|
14
|
+
export const loomPluginKey = new PluginKey('loom');
|
|
15
|
+
const LOOM_SDK_PUBLIC_APP_ID = 'e1cff63a-8ca2-4c2c-ad41-d61c54beb16a';
|
|
16
|
+
export const createPlugin = api => {
|
|
17
|
+
var _api$analytics;
|
|
18
|
+
const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
19
|
+
return new SafePlugin({
|
|
20
|
+
key: loomPluginKey,
|
|
21
|
+
state: {
|
|
22
|
+
init: () => ({
|
|
23
|
+
isEnabled: false,
|
|
24
|
+
loomButton: null,
|
|
25
|
+
isRecordingVideo: false,
|
|
26
|
+
error: undefined,
|
|
27
|
+
createAnalyticsEvent: undefined
|
|
28
|
+
}),
|
|
29
|
+
apply: (tr, pluginState) => {
|
|
30
|
+
var _tr$getMeta, _pluginState$loomButt;
|
|
31
|
+
const action = (_tr$getMeta = tr.getMeta(loomPluginKey)) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.type;
|
|
32
|
+
switch (action) {
|
|
33
|
+
case LoomPluginAction.SET_ANALYTICS_FUNCTION:
|
|
34
|
+
const {
|
|
35
|
+
createAnalyticsEvent
|
|
36
|
+
} = tr.getMeta(loomPluginKey);
|
|
37
|
+
return {
|
|
38
|
+
...pluginState,
|
|
39
|
+
createAnalyticsEvent
|
|
40
|
+
};
|
|
41
|
+
case LoomPluginAction.ENABLE:
|
|
42
|
+
const {
|
|
43
|
+
loomButton
|
|
44
|
+
} = tr.getMeta(loomPluginKey);
|
|
45
|
+
return {
|
|
46
|
+
...pluginState,
|
|
47
|
+
isEnabled: true,
|
|
48
|
+
loomButton
|
|
49
|
+
};
|
|
50
|
+
case LoomPluginAction.DISABLE:
|
|
51
|
+
const {
|
|
52
|
+
error
|
|
53
|
+
} = tr.getMeta(loomPluginKey);
|
|
54
|
+
return {
|
|
55
|
+
...pluginState,
|
|
56
|
+
isEnabled: false,
|
|
57
|
+
loomButton: null,
|
|
58
|
+
error
|
|
59
|
+
};
|
|
60
|
+
case LoomPluginAction.RECORD_VIDEO:
|
|
61
|
+
// Click the unmounted button in state that has the Loom SDK attached
|
|
62
|
+
pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$loomButt = pluginState.loomButton) === null || _pluginState$loomButt === void 0 ? void 0 : _pluginState$loomButt.click();
|
|
63
|
+
return {
|
|
64
|
+
...pluginState,
|
|
65
|
+
isRecordingVideo: true
|
|
66
|
+
};
|
|
67
|
+
case LoomPluginAction.INSERT_VIDEO:
|
|
68
|
+
return {
|
|
69
|
+
...pluginState,
|
|
70
|
+
isRecordingVideo: false
|
|
71
|
+
};
|
|
72
|
+
default:
|
|
73
|
+
return pluginState;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
view(editorView) {
|
|
78
|
+
const setupLoom = async () => {
|
|
79
|
+
// Asynchronously check if the Loom SDK is supported
|
|
80
|
+
// it hits a Loom API so could take a while
|
|
81
|
+
const {
|
|
82
|
+
isSupported,
|
|
83
|
+
setup
|
|
84
|
+
} = await import( /* webpackChunkName: "@atlaskit-internal_editor-loom-sdk" */'@loomhq/record-sdk');
|
|
85
|
+
const {
|
|
86
|
+
supported,
|
|
87
|
+
error
|
|
88
|
+
} = await isSupported();
|
|
89
|
+
if (!supported) {
|
|
90
|
+
// Keep plugin state update and analytics separate to avoid accidentally not updating
|
|
91
|
+
// plugin state due to collab-edit filtering out transactions with steps
|
|
92
|
+
api === null || api === void 0 ? void 0 : api.core.actions.execute(disableLoom({
|
|
93
|
+
error
|
|
94
|
+
}));
|
|
95
|
+
logException(new Error(error), {
|
|
96
|
+
location: 'editor-plugin-loom/sdk-initialisation'
|
|
97
|
+
});
|
|
98
|
+
// We're not combining the analytics steps into the enable / disable commands because the collab-edit plugin
|
|
99
|
+
// filters out any transactions with steps (even analytics) when it's initialising
|
|
100
|
+
const pluginState = loomPluginKey.getState(editorView.state);
|
|
101
|
+
fireAnalyticsEvent(pluginState === null || pluginState === void 0 ? void 0 : pluginState.createAnalyticsEvent)({
|
|
102
|
+
payload: {
|
|
103
|
+
action: ACTION.ERRORED,
|
|
104
|
+
actionSubject: ACTION_SUBJECT.LOOM,
|
|
105
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
106
|
+
attributes: {
|
|
107
|
+
error
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const {
|
|
114
|
+
configureButton
|
|
115
|
+
} = await setup({
|
|
116
|
+
publicAppId: LOOM_SDK_PUBLIC_APP_ID
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Hidden element to work around the SDK API
|
|
120
|
+
const loomButton = document.createElement('button');
|
|
121
|
+
const sdkButton = configureButton({
|
|
122
|
+
element: loomButton
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Attach insertion logic to the event handlers on the SDK
|
|
126
|
+
sdkButton.on('insert-click', async video => {
|
|
127
|
+
var _api$hyperlink;
|
|
128
|
+
const {
|
|
129
|
+
state,
|
|
130
|
+
dispatch
|
|
131
|
+
} = editorView;
|
|
132
|
+
const pos = editorView.state.selection.from;
|
|
133
|
+
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, pos,
|
|
134
|
+
// from === to, don't replace text to avoid accidental content loss
|
|
135
|
+
pos, video.sharedUrl, video.title, undefined, undefined, undefined, 'embed' // Convert to embed card instead of inline
|
|
136
|
+
)(state, dispatch);
|
|
137
|
+
api === null || api === void 0 ? void 0 : api.core.actions.execute(insertVideo({
|
|
138
|
+
editorAnalyticsAPI,
|
|
139
|
+
video
|
|
140
|
+
}));
|
|
141
|
+
});
|
|
142
|
+
api === null || api === void 0 ? void 0 : api.core.actions.execute(enableLoom({
|
|
143
|
+
loomButton
|
|
144
|
+
}));
|
|
145
|
+
// We're not combining the analytics steps into the enable / disable commands because the collab-edit plugin
|
|
146
|
+
// filters out any transactions with steps (even analytics) when it's initialising
|
|
147
|
+
const pluginState = loomPluginKey.getState(editorView.state);
|
|
148
|
+
fireAnalyticsEvent(pluginState === null || pluginState === void 0 ? void 0 : pluginState.createAnalyticsEvent)({
|
|
149
|
+
payload: {
|
|
150
|
+
action: ACTION.INITIALISED,
|
|
151
|
+
actionSubject: ACTION_SUBJECT.LOOM,
|
|
152
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
setupLoom();
|
|
157
|
+
return {};
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { injectIntl } from 'react-intl-next';
|
|
3
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
5
|
+
import { toolbarInsertBlockMessages } from '@atlaskit/editor-common/messages';
|
|
6
|
+
import { TOOLBAR_BUTTON, ToolbarButton } from '@atlaskit/editor-common/ui-menu';
|
|
7
|
+
import VideoCircleIcon from '@atlaskit/icon/glyph/video-circle';
|
|
8
|
+
import { recordVideo } from '../commands';
|
|
9
|
+
const LoomToolbarButton = ({
|
|
10
|
+
disabled,
|
|
11
|
+
api,
|
|
12
|
+
intl: {
|
|
13
|
+
formatMessage
|
|
14
|
+
}
|
|
15
|
+
}) => {
|
|
16
|
+
const {
|
|
17
|
+
loomState
|
|
18
|
+
} = useSharedPluginState(api, ['loom']);
|
|
19
|
+
if (!loomState) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const label = formatMessage(toolbarInsertBlockMessages.recordVideo);
|
|
23
|
+
return /*#__PURE__*/React.createElement(ToolbarButton, {
|
|
24
|
+
buttonId: TOOLBAR_BUTTON.RECORD_VIDEO,
|
|
25
|
+
onClick: () => {
|
|
26
|
+
var _api$analytics;
|
|
27
|
+
return api === null || api === void 0 ? void 0 : api.core.actions.execute(recordVideo({
|
|
28
|
+
inputMethod: INPUT_METHOD.TOOLBAR,
|
|
29
|
+
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
// Disable the icon while the SDK isn't initialised
|
|
33
|
+
,
|
|
34
|
+
disabled: disabled || !(loomState !== null && loomState !== void 0 && loomState.isEnabled),
|
|
35
|
+
title: label,
|
|
36
|
+
iconBefore: /*#__PURE__*/React.createElement(VideoCircleIcon, {
|
|
37
|
+
label: label
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
export default injectIntl(LoomToolbarButton);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { LoomPluginAction, loomPluginKey } from './pm-plugin';
|
|
3
|
+
export var enableLoom = function enableLoom(_ref) {
|
|
4
|
+
var loomButton = _ref.loomButton;
|
|
5
|
+
return function (_ref2) {
|
|
6
|
+
var tr = _ref2.tr;
|
|
7
|
+
tr.setMeta(loomPluginKey, {
|
|
8
|
+
type: LoomPluginAction.ENABLE,
|
|
9
|
+
loomButton: loomButton
|
|
10
|
+
});
|
|
11
|
+
return tr;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export var disableLoom = function disableLoom(_ref3) {
|
|
15
|
+
var error = _ref3.error;
|
|
16
|
+
return function (_ref4) {
|
|
17
|
+
var tr = _ref4.tr;
|
|
18
|
+
tr.setMeta(loomPluginKey, {
|
|
19
|
+
type: LoomPluginAction.DISABLE,
|
|
20
|
+
error: error
|
|
21
|
+
});
|
|
22
|
+
return tr;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export var recordVideo = function recordVideo(_ref5) {
|
|
26
|
+
var inputMethod = _ref5.inputMethod,
|
|
27
|
+
editorAnalyticsAPI = _ref5.editorAnalyticsAPI;
|
|
28
|
+
return function (_ref6) {
|
|
29
|
+
var tr = _ref6.tr;
|
|
30
|
+
tr.setMeta(loomPluginKey, {
|
|
31
|
+
type: LoomPluginAction.RECORD_VIDEO
|
|
32
|
+
});
|
|
33
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
|
|
34
|
+
action: ACTION.RECORD_VIDEO,
|
|
35
|
+
actionSubject: ACTION_SUBJECT.LOOM,
|
|
36
|
+
attributes: {
|
|
37
|
+
inputMethod: inputMethod
|
|
38
|
+
},
|
|
39
|
+
eventType: EVENT_TYPE.TRACK
|
|
40
|
+
})(tr);
|
|
41
|
+
return tr;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
export var recordVideoFailed = function recordVideoFailed(_ref7) {
|
|
45
|
+
var inputMethod = _ref7.inputMethod,
|
|
46
|
+
error = _ref7.error,
|
|
47
|
+
editorAnalyticsAPI = _ref7.editorAnalyticsAPI;
|
|
48
|
+
return function (_ref8) {
|
|
49
|
+
var tr = _ref8.tr;
|
|
50
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
|
|
51
|
+
action: ACTION.RECORD_VIDEO_FAILED,
|
|
52
|
+
actionSubject: ACTION_SUBJECT.LOOM,
|
|
53
|
+
attributes: {
|
|
54
|
+
inputMethod: inputMethod,
|
|
55
|
+
error: error
|
|
56
|
+
},
|
|
57
|
+
eventType: EVENT_TYPE.TRACK
|
|
58
|
+
})(tr);
|
|
59
|
+
return tr;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export var insertVideo = function insertVideo(_ref9) {
|
|
63
|
+
var editorAnalyticsAPI = _ref9.editorAnalyticsAPI,
|
|
64
|
+
video = _ref9.video;
|
|
65
|
+
return function (_ref10) {
|
|
66
|
+
var tr = _ref10.tr;
|
|
67
|
+
tr.setMeta(loomPluginKey, {
|
|
68
|
+
type: LoomPluginAction.INSERT_VIDEO
|
|
69
|
+
});
|
|
70
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
|
|
71
|
+
action: ACTION.INSERT_VIDEO,
|
|
72
|
+
actionSubject: ACTION_SUBJECT.LOOM,
|
|
73
|
+
eventType: EVENT_TYPE.TRACK,
|
|
74
|
+
attributes: {
|
|
75
|
+
duration: video.duration
|
|
76
|
+
}
|
|
77
|
+
})(tr);
|
|
78
|
+
return tr;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { loomPlugin } from './plugin';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { useLayoutEffect } from 'react';
|
|
2
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
3
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { toolbarInsertBlockMessages } from '@atlaskit/editor-common/messages';
|
|
5
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
6
|
+
import { IconLoom } from '@atlaskit/editor-common/quick-insert';
|
|
7
|
+
import { recordVideo, recordVideoFailed } from './commands';
|
|
8
|
+
import { createPlugin, LoomPluginAction, loomPluginKey } from './pm-plugin';
|
|
9
|
+
import LoomToolbarButton from './ui/ToolbarButton';
|
|
10
|
+
export var loomPlugin = function loomPlugin(_ref) {
|
|
11
|
+
var _api$analytics;
|
|
12
|
+
var api = _ref.api;
|
|
13
|
+
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
14
|
+
return {
|
|
15
|
+
name: 'loom',
|
|
16
|
+
usePluginHook: function usePluginHook(_ref2) {
|
|
17
|
+
var editorView = _ref2.editorView;
|
|
18
|
+
var _useAnalyticsEvents = useAnalyticsEvents(),
|
|
19
|
+
createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
|
|
20
|
+
useLayoutEffect(function () {
|
|
21
|
+
var dispatch = editorView.dispatch,
|
|
22
|
+
tr = editorView.state.tr;
|
|
23
|
+
tr.setMeta(loomPluginKey, {
|
|
24
|
+
type: LoomPluginAction.SET_ANALYTICS_FUNCTION,
|
|
25
|
+
createAnalyticsEvent: createAnalyticsEvent
|
|
26
|
+
});
|
|
27
|
+
dispatch(tr);
|
|
28
|
+
}, [createAnalyticsEvent, editorView]);
|
|
29
|
+
},
|
|
30
|
+
pmPlugins: function pmPlugins() {
|
|
31
|
+
return [{
|
|
32
|
+
name: 'loom',
|
|
33
|
+
plugin: function plugin() {
|
|
34
|
+
return createPlugin(api);
|
|
35
|
+
}
|
|
36
|
+
}];
|
|
37
|
+
},
|
|
38
|
+
getSharedState: function getSharedState(editorState) {
|
|
39
|
+
if (!editorState) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
return loomPluginKey.getState(editorState);
|
|
43
|
+
},
|
|
44
|
+
pluginsOptions: {
|
|
45
|
+
// Enable inserting Loom recordings through the slash command
|
|
46
|
+
quickInsert: function quickInsert(_ref3) {
|
|
47
|
+
var formatMessage = _ref3.formatMessage;
|
|
48
|
+
return [{
|
|
49
|
+
id: 'loom',
|
|
50
|
+
title: formatMessage(toolbarInsertBlockMessages.recordVideo),
|
|
51
|
+
description: formatMessage(toolbarInsertBlockMessages.recordVideoDescription),
|
|
52
|
+
keywords: ['loom', 'record', 'video'],
|
|
53
|
+
priority: 800,
|
|
54
|
+
icon: function icon() {
|
|
55
|
+
return /*#__PURE__*/React.createElement(IconLoom, null);
|
|
56
|
+
},
|
|
57
|
+
action: function action(insert, editorState) {
|
|
58
|
+
var _recordVideo;
|
|
59
|
+
var tr = insert(undefined);
|
|
60
|
+
var loomState = loomPluginKey.getState(editorState);
|
|
61
|
+
if (!(loomState !== null && loomState !== void 0 && loomState.isEnabled)) {
|
|
62
|
+
var _recordVideoFailed;
|
|
63
|
+
var errorMessage = loomState === null || loomState === void 0 ? void 0 : loomState.error;
|
|
64
|
+
logException(new Error(errorMessage), {
|
|
65
|
+
location: 'editor-plugin-loom/quick-insert-record-video'
|
|
66
|
+
});
|
|
67
|
+
return (_recordVideoFailed = recordVideoFailed({
|
|
68
|
+
inputMethod: INPUT_METHOD.QUICK_INSERT,
|
|
69
|
+
error: errorMessage,
|
|
70
|
+
editorAnalyticsAPI: editorAnalyticsAPI
|
|
71
|
+
})({
|
|
72
|
+
tr: tr
|
|
73
|
+
})) !== null && _recordVideoFailed !== void 0 ? _recordVideoFailed : false;
|
|
74
|
+
}
|
|
75
|
+
return (_recordVideo = recordVideo({
|
|
76
|
+
inputMethod: INPUT_METHOD.QUICK_INSERT,
|
|
77
|
+
editorAnalyticsAPI: editorAnalyticsAPI
|
|
78
|
+
})({
|
|
79
|
+
tr: tr
|
|
80
|
+
})) !== null && _recordVideo !== void 0 ? _recordVideo : false;
|
|
81
|
+
}
|
|
82
|
+
}];
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
// Enable inserting Loom recordings through main toolbar
|
|
86
|
+
primaryToolbarComponent: function primaryToolbarComponent(_ref4) {
|
|
87
|
+
var disabled = _ref4.disabled;
|
|
88
|
+
return /*#__PURE__*/React.createElement(LoomToolbarButton, {
|
|
89
|
+
disabled: disabled,
|
|
90
|
+
api: api
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
5
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
6
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
7
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
8
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
9
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
10
|
+
import { disableLoom, enableLoom, insertVideo } from './commands';
|
|
11
|
+
export var LoomPluginAction = /*#__PURE__*/function (LoomPluginAction) {
|
|
12
|
+
LoomPluginAction[LoomPluginAction["ENABLE"] = 0] = "ENABLE";
|
|
13
|
+
LoomPluginAction[LoomPluginAction["DISABLE"] = 1] = "DISABLE";
|
|
14
|
+
LoomPluginAction[LoomPluginAction["RECORD_VIDEO"] = 2] = "RECORD_VIDEO";
|
|
15
|
+
LoomPluginAction[LoomPluginAction["INSERT_VIDEO"] = 3] = "INSERT_VIDEO";
|
|
16
|
+
LoomPluginAction[LoomPluginAction["SET_ANALYTICS_FUNCTION"] = 4] = "SET_ANALYTICS_FUNCTION";
|
|
17
|
+
return LoomPluginAction;
|
|
18
|
+
}({});
|
|
19
|
+
export var loomPluginKey = new PluginKey('loom');
|
|
20
|
+
var LOOM_SDK_PUBLIC_APP_ID = 'e1cff63a-8ca2-4c2c-ad41-d61c54beb16a';
|
|
21
|
+
export var createPlugin = function createPlugin(api) {
|
|
22
|
+
var _api$analytics;
|
|
23
|
+
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
24
|
+
return new SafePlugin({
|
|
25
|
+
key: loomPluginKey,
|
|
26
|
+
state: {
|
|
27
|
+
init: function init() {
|
|
28
|
+
return {
|
|
29
|
+
isEnabled: false,
|
|
30
|
+
loomButton: null,
|
|
31
|
+
isRecordingVideo: false,
|
|
32
|
+
error: undefined,
|
|
33
|
+
createAnalyticsEvent: undefined
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
apply: function apply(tr, pluginState) {
|
|
37
|
+
var _tr$getMeta, _pluginState$loomButt;
|
|
38
|
+
var action = (_tr$getMeta = tr.getMeta(loomPluginKey)) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.type;
|
|
39
|
+
switch (action) {
|
|
40
|
+
case LoomPluginAction.SET_ANALYTICS_FUNCTION:
|
|
41
|
+
var _tr$getMeta2 = tr.getMeta(loomPluginKey),
|
|
42
|
+
createAnalyticsEvent = _tr$getMeta2.createAnalyticsEvent;
|
|
43
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
44
|
+
createAnalyticsEvent: createAnalyticsEvent
|
|
45
|
+
});
|
|
46
|
+
case LoomPluginAction.ENABLE:
|
|
47
|
+
var _tr$getMeta3 = tr.getMeta(loomPluginKey),
|
|
48
|
+
loomButton = _tr$getMeta3.loomButton;
|
|
49
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
50
|
+
isEnabled: true,
|
|
51
|
+
loomButton: loomButton
|
|
52
|
+
});
|
|
53
|
+
case LoomPluginAction.DISABLE:
|
|
54
|
+
var _tr$getMeta4 = tr.getMeta(loomPluginKey),
|
|
55
|
+
error = _tr$getMeta4.error;
|
|
56
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
57
|
+
isEnabled: false,
|
|
58
|
+
loomButton: null,
|
|
59
|
+
error: error
|
|
60
|
+
});
|
|
61
|
+
case LoomPluginAction.RECORD_VIDEO:
|
|
62
|
+
// Click the unmounted button in state that has the Loom SDK attached
|
|
63
|
+
pluginState === null || pluginState === void 0 || (_pluginState$loomButt = pluginState.loomButton) === null || _pluginState$loomButt === void 0 || _pluginState$loomButt.click();
|
|
64
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
65
|
+
isRecordingVideo: true
|
|
66
|
+
});
|
|
67
|
+
case LoomPluginAction.INSERT_VIDEO:
|
|
68
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
69
|
+
isRecordingVideo: false
|
|
70
|
+
});
|
|
71
|
+
default:
|
|
72
|
+
return pluginState;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
view: function view(editorView) {
|
|
77
|
+
var setupLoom = /*#__PURE__*/function () {
|
|
78
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
79
|
+
var _yield$import, isSupported, setup, _yield$isSupported, supported, error, _pluginState, _yield$setup, configureButton, loomButton, sdkButton, pluginState;
|
|
80
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
81
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
82
|
+
case 0:
|
|
83
|
+
_context2.next = 2;
|
|
84
|
+
return import( /* webpackChunkName: "@atlaskit-internal_editor-loom-sdk" */'@loomhq/record-sdk');
|
|
85
|
+
case 2:
|
|
86
|
+
_yield$import = _context2.sent;
|
|
87
|
+
isSupported = _yield$import.isSupported;
|
|
88
|
+
setup = _yield$import.setup;
|
|
89
|
+
_context2.next = 7;
|
|
90
|
+
return isSupported();
|
|
91
|
+
case 7:
|
|
92
|
+
_yield$isSupported = _context2.sent;
|
|
93
|
+
supported = _yield$isSupported.supported;
|
|
94
|
+
error = _yield$isSupported.error;
|
|
95
|
+
if (supported) {
|
|
96
|
+
_context2.next = 16;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
// Keep plugin state update and analytics separate to avoid accidentally not updating
|
|
100
|
+
// plugin state due to collab-edit filtering out transactions with steps
|
|
101
|
+
api === null || api === void 0 || api.core.actions.execute(disableLoom({
|
|
102
|
+
error: error
|
|
103
|
+
}));
|
|
104
|
+
logException(new Error(error), {
|
|
105
|
+
location: 'editor-plugin-loom/sdk-initialisation'
|
|
106
|
+
});
|
|
107
|
+
// We're not combining the analytics steps into the enable / disable commands because the collab-edit plugin
|
|
108
|
+
// filters out any transactions with steps (even analytics) when it's initialising
|
|
109
|
+
_pluginState = loomPluginKey.getState(editorView.state);
|
|
110
|
+
fireAnalyticsEvent(_pluginState === null || _pluginState === void 0 ? void 0 : _pluginState.createAnalyticsEvent)({
|
|
111
|
+
payload: {
|
|
112
|
+
action: ACTION.ERRORED,
|
|
113
|
+
actionSubject: ACTION_SUBJECT.LOOM,
|
|
114
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
115
|
+
attributes: {
|
|
116
|
+
error: error
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return _context2.abrupt("return");
|
|
121
|
+
case 16:
|
|
122
|
+
_context2.next = 18;
|
|
123
|
+
return setup({
|
|
124
|
+
publicAppId: LOOM_SDK_PUBLIC_APP_ID
|
|
125
|
+
});
|
|
126
|
+
case 18:
|
|
127
|
+
_yield$setup = _context2.sent;
|
|
128
|
+
configureButton = _yield$setup.configureButton;
|
|
129
|
+
// Hidden element to work around the SDK API
|
|
130
|
+
loomButton = document.createElement('button');
|
|
131
|
+
sdkButton = configureButton({
|
|
132
|
+
element: loomButton
|
|
133
|
+
}); // Attach insertion logic to the event handlers on the SDK
|
|
134
|
+
sdkButton.on('insert-click', /*#__PURE__*/function () {
|
|
135
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(video) {
|
|
136
|
+
var _api$hyperlink;
|
|
137
|
+
var state, dispatch, pos;
|
|
138
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
139
|
+
while (1) switch (_context.prev = _context.next) {
|
|
140
|
+
case 0:
|
|
141
|
+
state = editorView.state, dispatch = editorView.dispatch;
|
|
142
|
+
pos = editorView.state.selection.from;
|
|
143
|
+
api === null || api === void 0 || (_api$hyperlink = api.hyperlink) === null || _api$hyperlink === void 0 || _api$hyperlink.actions.insertLink(INPUT_METHOD.TYPEAHEAD, pos,
|
|
144
|
+
// from === to, don't replace text to avoid accidental content loss
|
|
145
|
+
pos, video.sharedUrl, video.title, undefined, undefined, undefined, 'embed' // Convert to embed card instead of inline
|
|
146
|
+
)(state, dispatch);
|
|
147
|
+
api === null || api === void 0 || api.core.actions.execute(insertVideo({
|
|
148
|
+
editorAnalyticsAPI: editorAnalyticsAPI,
|
|
149
|
+
video: video
|
|
150
|
+
}));
|
|
151
|
+
case 4:
|
|
152
|
+
case "end":
|
|
153
|
+
return _context.stop();
|
|
154
|
+
}
|
|
155
|
+
}, _callee);
|
|
156
|
+
}));
|
|
157
|
+
return function (_x) {
|
|
158
|
+
return _ref2.apply(this, arguments);
|
|
159
|
+
};
|
|
160
|
+
}());
|
|
161
|
+
api === null || api === void 0 || api.core.actions.execute(enableLoom({
|
|
162
|
+
loomButton: loomButton
|
|
163
|
+
}));
|
|
164
|
+
// We're not combining the analytics steps into the enable / disable commands because the collab-edit plugin
|
|
165
|
+
// filters out any transactions with steps (even analytics) when it's initialising
|
|
166
|
+
pluginState = loomPluginKey.getState(editorView.state);
|
|
167
|
+
fireAnalyticsEvent(pluginState === null || pluginState === void 0 ? void 0 : pluginState.createAnalyticsEvent)({
|
|
168
|
+
payload: {
|
|
169
|
+
action: ACTION.INITIALISED,
|
|
170
|
+
actionSubject: ACTION_SUBJECT.LOOM,
|
|
171
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
case 26:
|
|
175
|
+
case "end":
|
|
176
|
+
return _context2.stop();
|
|
177
|
+
}
|
|
178
|
+
}, _callee2);
|
|
179
|
+
}));
|
|
180
|
+
return function setupLoom() {
|
|
181
|
+
return _ref.apply(this, arguments);
|
|
182
|
+
};
|
|
183
|
+
}();
|
|
184
|
+
setupLoom();
|
|
185
|
+
return {};
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { injectIntl } from 'react-intl-next';
|
|
3
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
5
|
+
import { toolbarInsertBlockMessages } from '@atlaskit/editor-common/messages';
|
|
6
|
+
import { TOOLBAR_BUTTON, ToolbarButton } from '@atlaskit/editor-common/ui-menu';
|
|
7
|
+
import VideoCircleIcon from '@atlaskit/icon/glyph/video-circle';
|
|
8
|
+
import { recordVideo } from '../commands';
|
|
9
|
+
var LoomToolbarButton = function LoomToolbarButton(_ref) {
|
|
10
|
+
var disabled = _ref.disabled,
|
|
11
|
+
api = _ref.api,
|
|
12
|
+
formatMessage = _ref.intl.formatMessage;
|
|
13
|
+
var _useSharedPluginState = useSharedPluginState(api, ['loom']),
|
|
14
|
+
loomState = _useSharedPluginState.loomState;
|
|
15
|
+
if (!loomState) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
var label = formatMessage(toolbarInsertBlockMessages.recordVideo);
|
|
19
|
+
return /*#__PURE__*/React.createElement(ToolbarButton, {
|
|
20
|
+
buttonId: TOOLBAR_BUTTON.RECORD_VIDEO,
|
|
21
|
+
onClick: function onClick() {
|
|
22
|
+
var _api$analytics;
|
|
23
|
+
return api === null || api === void 0 ? void 0 : api.core.actions.execute(recordVideo({
|
|
24
|
+
inputMethod: INPUT_METHOD.TOOLBAR,
|
|
25
|
+
editorAnalyticsAPI: api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
// Disable the icon while the SDK isn't initialised
|
|
29
|
+
,
|
|
30
|
+
disabled: disabled || !(loomState !== null && loomState !== void 0 && loomState.isEnabled),
|
|
31
|
+
title: label,
|
|
32
|
+
iconBefore: /*#__PURE__*/React.createElement(VideoCircleIcon, {
|
|
33
|
+
label: label
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
export default injectIntl(LoomToolbarButton);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LoomVideo, SDKUnsupportedReasons } from '@loomhq/record-sdk';
|
|
2
|
+
import type { EditorAnalyticsAPI, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import type { EditorCommand } from '@atlaskit/editor-common/types';
|
|
4
|
+
export declare const enableLoom: ({ loomButton }: {
|
|
5
|
+
loomButton: HTMLButtonElement;
|
|
6
|
+
}) => EditorCommand;
|
|
7
|
+
export declare const disableLoom: ({ error }: {
|
|
8
|
+
error: SDKUnsupportedReasons | undefined;
|
|
9
|
+
}) => EditorCommand;
|
|
10
|
+
export declare const recordVideo: ({ inputMethod, editorAnalyticsAPI, }: {
|
|
11
|
+
inputMethod: INPUT_METHOD;
|
|
12
|
+
editorAnalyticsAPI: EditorAnalyticsAPI | undefined;
|
|
13
|
+
}) => EditorCommand;
|
|
14
|
+
export declare const recordVideoFailed: ({ inputMethod, error, editorAnalyticsAPI, }: {
|
|
15
|
+
inputMethod: INPUT_METHOD;
|
|
16
|
+
error: SDKUnsupportedReasons | undefined;
|
|
17
|
+
editorAnalyticsAPI: EditorAnalyticsAPI | undefined;
|
|
18
|
+
}) => EditorCommand;
|
|
19
|
+
export declare const insertVideo: ({ editorAnalyticsAPI, video, }: {
|
|
20
|
+
editorAnalyticsAPI: EditorAnalyticsAPI | undefined;
|
|
21
|
+
video: LoomVideo;
|
|
22
|
+
}) => EditorCommand;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
3
|
+
import type { HyperlinkPlugin } from '@atlaskit/editor-plugin-hyperlink';
|
|
4
|
+
import type { LoomPluginState } from './pm-plugin';
|
|
5
|
+
export type LoomPlugin = NextEditorPlugin<'loom', {
|
|
6
|
+
dependencies: [
|
|
7
|
+
OptionalPlugin<AnalyticsPlugin>,
|
|
8
|
+
HyperlinkPlugin
|
|
9
|
+
];
|
|
10
|
+
sharedState: LoomPluginState | undefined;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const loomPlugin: LoomPlugin;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SDKUnsupportedReasons } from '@loomhq/record-sdk';
|
|
2
|
+
import type { CreateUIAnalyticsEvent } from '@atlaskit/analytics-next';
|
|
3
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
5
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
+
import type { LoomPlugin } from './plugin';
|
|
7
|
+
export interface LoomPluginState {
|
|
8
|
+
isEnabled: boolean;
|
|
9
|
+
loomButton: HTMLButtonElement | null;
|
|
10
|
+
isRecordingVideo: boolean;
|
|
11
|
+
error: SDKUnsupportedReasons | undefined;
|
|
12
|
+
createAnalyticsEvent: CreateUIAnalyticsEvent | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare enum LoomPluginAction {
|
|
15
|
+
ENABLE = 0,
|
|
16
|
+
DISABLE = 1,
|
|
17
|
+
RECORD_VIDEO = 2,
|
|
18
|
+
INSERT_VIDEO = 3,
|
|
19
|
+
SET_ANALYTICS_FUNCTION = 4
|
|
20
|
+
}
|
|
21
|
+
export declare const loomPluginKey: PluginKey<LoomPluginState>;
|
|
22
|
+
export declare const createPlugin: (api: ExtractInjectionAPI<LoomPlugin> | undefined) => SafePlugin<LoomPluginState>;
|