@dao42/d42paas-front 0.4.5 → 0.4.6

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.
Files changed (66) hide show
  1. package/package.json +3 -2
  2. package/src/app.tsx +250 -0
  3. package/src/assets/code-brackets.svg +1 -0
  4. package/src/assets/colors.svg +1 -0
  5. package/src/assets/comments.svg +1 -0
  6. package/src/assets/direction.svg +1 -0
  7. package/src/assets/flow.svg +1 -0
  8. package/src/assets/plugin.svg +1 -0
  9. package/src/assets/repo.svg +1 -0
  10. package/src/assets/stackalt.svg +1 -0
  11. package/src/components/Avatar/index.tsx +27 -0
  12. package/src/components/CanvasHelper/index.tsx +89 -0
  13. package/src/components/Console/index.tsx +88 -0
  14. package/src/components/Editor/index.tsx +979 -0
  15. package/src/components/FileTree/index.tsx +477 -0
  16. package/src/components/LiveContent/index.tsx +221 -0
  17. package/src/components/LiveContent/video.tsx +213 -0
  18. package/src/components/LottieAnim/index.tsx +41 -0
  19. package/src/components/Message/index.tsx +64 -0
  20. package/src/components/Model/index.tsx +42 -0
  21. package/src/components/OutputBrowser/index.tsx +180 -0
  22. package/src/components/Skeleton/index.tsx +41 -0
  23. package/src/components/Tabs/index.tsx +23 -0
  24. package/src/components/Terminal/index.tsx +127 -0
  25. package/src/components/ToolBar/index.tsx +169 -0
  26. package/src/components/XTerm/index.tsx +113 -0
  27. package/src/components/index.tsx +4 -0
  28. package/src/components/loading/index.tsx +282 -0
  29. package/src/enum/FExtension.ts +168 -0
  30. package/src/helpers/collections/IoClient.tsx +314 -0
  31. package/src/helpers/collections/errorCatcher.tsx +0 -0
  32. package/src/helpers/collections/idb.tsx +186 -0
  33. package/src/helpers/collections/localStorage.tsx +13 -0
  34. package/src/helpers/collections/mock.tsx +30 -0
  35. package/src/helpers/collections/playgroundInit.tsx +311 -0
  36. package/src/helpers/collections/replay.tsx +168 -0
  37. package/src/helpers/collections/socket.tsx +6 -0
  38. package/src/helpers/collections/toast.tsx +19 -0
  39. package/src/helpers/collections/userTool.tsx +12 -0
  40. package/src/helpers/collections/util.tsx +4 -0
  41. package/src/helpers/index.tsx +6 -0
  42. package/src/helpers/monaco/monaco-ot-adapter.tsx +476 -0
  43. package/src/hooks/collections/useOT.tsx +38 -0
  44. package/src/hooks/index.tsx +1 -0
  45. package/src/pages/index.tsx +450 -0
  46. package/src/public/dev.html +35 -0
  47. package/src/public/index.html +45 -0
  48. package/src/public/sdkserver.html +35 -0
  49. package/src/stores/index.tsx +1 -0
  50. package/src/stores/oTStore.tsx +288 -0
  51. package/src/stories/BrowserWindow.tsx +30 -0
  52. package/src/stories/Console.tsx +46 -0
  53. package/src/stories/Editor.tsx +37 -0
  54. package/src/stories/FileTree.tsx +50 -0
  55. package/src/stories/Shell.tsx +53 -0
  56. package/src/stories/introduction.stories.mdx +193 -0
  57. package/src/stories/page.tsx +71 -0
  58. package/src/styles/collections/iconfont.scss +1 -0
  59. package/src/styles/collections/tabs-costumers.scss +20 -0
  60. package/src/styles/collections/tailwind.scss +3 -0
  61. package/src/styles/collections/tree-costumers.scss +53 -0
  62. package/src/styles/collections/utility.scss +10 -0
  63. package/src/styles/collections/xterm-costumers.scss +47 -0
  64. package/src/styles/index.scss +19 -0
  65. package/src/types/editor.d.ts +31 -0
  66. package/src/types/index.d.ts +158 -0
@@ -0,0 +1,30 @@
1
+ export const roleColors = (index: number) =>
2
+ [
3
+ '#d904c7',
4
+ '#49cf5b',
5
+ '#D9C589',
6
+ '#F27B13',
7
+ '#A0D9D9',
8
+ '#45858C',
9
+ '#8C311C',
10
+ '#4A5B8C',
11
+ '#8C4F2B',
12
+ '#34401A',
13
+ '#CAD959',
14
+ '#0476D9',
15
+ ][index];
16
+
17
+ export const avatarGenerator = (value: number, name: string) => {
18
+ const avatarSeries = [
19
+ 'initials',
20
+ 'avataaars',
21
+ 'big-ears',
22
+ 'bottts',
23
+ 'croodles',
24
+ 'personas',
25
+ 'micah',
26
+ ];
27
+ // return `https://avatars.dicebear.com/api/avataaars/${name}.svg`;
28
+ return `https://avatars.dicebear.com/api/human/${name}.svg`;
29
+ // return `https://avatars.dicebear.com/api/${avatarSeries[value]}/${name}.svg`;
30
+ };
@@ -0,0 +1,311 @@
1
+ import { omit } from 'lodash';
2
+ import {
3
+ oTStore,
4
+ T_UserInfo,
5
+ userListStore,
6
+ userStore,
7
+ } from '~/stores/oTStore';
8
+ import { avatarGenerator, roleColors } from './mock';
9
+ import { random as _random } from 'lodash';
10
+ import { IsMe, IsSameFile } from './userTool';
11
+ import { unstable_batchedUpdates } from 'react-dom';
12
+ import {
13
+ daopaasDB,
14
+ getLocalReplayFile,
15
+ setLocalMedia,
16
+ setLocalReplayFile,
17
+ setReplaySource,
18
+ } from './idb';
19
+ import { replay } from './replay';
20
+ import { Toast } from './toast';
21
+
22
+ const heartbeatTime = 1000 * 60 * 10;
23
+
24
+ const PlaygroundInit = ({ ticket, playgroundId, userId, io }) => {
25
+ unstable_batchedUpdates(() => {
26
+ // const io = useOT.getState().socket;
27
+ const setUserInfo = userStore.getState().setUserInfo;
28
+ const setUserList = userListStore.getState().setUserList;
29
+
30
+ // oTStore
31
+ const {
32
+ switchDoc,
33
+ setSenders,
34
+ setCRDTInfo,
35
+ setServerAck,
36
+ setCustomAck,
37
+ switchDocTree,
38
+ setPlaygroundInfo,
39
+ setDockerInfo,
40
+ setQueryObject,
41
+ setPlaygroundStatus,
42
+ setFromServer,
43
+ setDockerStatus,
44
+ appStatus,
45
+ setAppStatus,
46
+ setGlobalData,
47
+ } = oTStore.getState();
48
+
49
+ // setAppStatus('code');
50
+ // io.emit('appStatus', 'code');
51
+ window.clearCache = () => {
52
+ localStorage.clear();
53
+ indexedDB.deleteDatabase('daopaas').onsuccess = () => {
54
+ console.log('daopaas Deleted !');
55
+ };
56
+ io.emit('clearCache');
57
+ };
58
+ window.Toast = Toast;
59
+
60
+ setDockerInfo({
61
+ ...oTStore.getState().dockerInfo,
62
+ ticket,
63
+ });
64
+
65
+ // window.onerror = function (message, source, lineno, colno, error) {
66
+ // debugger;
67
+ // };
68
+
69
+ io.on('connect', () => {
70
+ console.log('已连接');
71
+ io.emit('checkSign', ticket);
72
+ setInterval(() => {
73
+ io.emit('heartbeat', '💗');
74
+ }, heartbeatTime);
75
+ });
76
+
77
+ io.on('clearCache', () => {
78
+ window.location.reload();
79
+ // io.disconnect();
80
+ });
81
+
82
+ io.on('appStatus', (data) => {
83
+ setAppStatus(data);
84
+ });
85
+
86
+ io.on('globalData', (data) => {
87
+ setGlobalData(data);
88
+ });
89
+
90
+ io.on('welcome', (data) => {
91
+ let originUser = userStore.getState().userInfo;
92
+ const userData = JSON.parse(data);
93
+ // const { coUsers } = userData;
94
+ const color = roleColors(userData.onlineCount - 1);
95
+ if (originUser.uuid === userData.uuid) {
96
+ originUser = omit(
97
+ {
98
+ ...userData,
99
+ color,
100
+ avatar: avatarGenerator(_random(0, 6), userData.uuid),
101
+ },
102
+ 'coUsers',
103
+ );
104
+ setUserInfo(originUser);
105
+ }
106
+
107
+ const userInfoList = [
108
+ originUser,
109
+ ...userData.coUsers
110
+ .filter((f) => f.uuid !== originUser.uuid)
111
+ .map((user) => {
112
+ return {
113
+ ...user,
114
+ avatar: avatarGenerator(_random(0, 6), user.uuid),
115
+ color: roleColors(user.onlineCount - 1),
116
+ };
117
+ }),
118
+ ];
119
+ setUserList(userInfoList);
120
+ });
121
+
122
+ io.on('playgroundInfo', (data) => {
123
+ const { playgroundInfo, crdt, dockerInfo } = JSON.parse(data);
124
+ setPlaygroundInfo(playgroundInfo);
125
+ setDockerInfo(dockerInfo);
126
+
127
+ dockerInfo.fileTree &&
128
+ switchDocTree({
129
+ data: dockerInfo.fileTree,
130
+ });
131
+ setCRDTInfo(crdt);
132
+ // setReplaySource(crdt);
133
+ });
134
+
135
+ io.on('playgroundStatus', (data) => {
136
+ setPlaygroundStatus(data);
137
+ });
138
+ io.on('dockerStatus', (data) => {
139
+ setDockerStatus(data || 'STOP');
140
+ });
141
+
142
+ io.on('fileContent', async (d) => {
143
+ const _d = JSON.parse(d) as D42_FrontType.CRDT;
144
+ // const editor = _d;
145
+
146
+ setCRDTInfo(_d);
147
+ setReplaySource(_d);
148
+ if (IsMe(_d?.userInfo)) {
149
+ switchDoc(_d.file);
150
+ (await daopaasDB).put('files', _d.file.value, _d.file.path);
151
+ if (!(await getLocalReplayFile(_d.file.path))) {
152
+ setLocalReplayFile(_d.file.path, _d.file.value);
153
+ }
154
+ // (await daopaasDB).put(
155
+ // 'replayFiles',
156
+ // _d.editor.doc.value,
157
+ // _d.editor.doc.path,
158
+ // );
159
+ console.log('serverRevision', _d.editor.revision);
160
+ }
161
+ });
162
+ io.on('terminal', (d) => {
163
+ const _d = JSON.parse(d) as D42_FrontType.CRDT;
164
+ setCRDTInfo(_d);
165
+ setReplaySource(_d);
166
+ });
167
+ io.on('editFile', (d) => {
168
+ const _d = JSON.parse(d);
169
+ setFromServer(true);
170
+ // setServerAck();
171
+
172
+ setCRDTInfo(_d);
173
+ setReplaySource(_d);
174
+ // console.log(_d.editor.revision);
175
+ });
176
+
177
+ io.on('saveFile', (d) => {
178
+ const _d = JSON.parse(d);
179
+
180
+ // setFileSaved(d);
181
+ // console.log(_d.editor.revision);
182
+ });
183
+ io.on('customAck', (d) => {
184
+ const _d = JSON.parse(d);
185
+ // console.log(_d);
186
+ setCRDTInfo(_d);
187
+ setReplaySource(_d);
188
+ setCustomAck();
189
+ });
190
+ io.on('serverAck', (d) => {
191
+ // 待确认逻辑
192
+ const _d = JSON.parse(d);
193
+ setReplaySource(_d);
194
+ setServerAck();
195
+ });
196
+
197
+ io.on('sender', (d) => {
198
+ setSenders([...oTStore.getState().senders, JSON.parse(d).sender]);
199
+ });
200
+
201
+ io.on('fileNode', (data) => {
202
+ const res = JSON.parse(data);
203
+
204
+ switchDocTree({
205
+ // data: res.data,
206
+ data: res,
207
+ });
208
+ });
209
+
210
+ io.on('console', (d) => {
211
+ const _d = JSON.parse(d) as D42_FrontType.CRDT;
212
+ setCRDTInfo(_d);
213
+ setReplaySource(_d);
214
+ });
215
+
216
+ io.on('mediaRecord', (d) => {
217
+ const _d = JSON.parse(d) as D42_FrontType.CRDT;
218
+ setLocalMedia(_d.timestamp, _d);
219
+ setCRDTInfo(_d);
220
+ setReplaySource(_d);
221
+ });
222
+
223
+ // 断联处理
224
+ io.on('disconnect', (reason) => {
225
+ console.log(reason, '连接断开');
226
+
227
+ if (reason === 'io server disconnect') {
228
+ // the disconnection was initiated by the server, you need to reconnect manually
229
+ return;
230
+ }
231
+ io.connect();
232
+ });
233
+
234
+ io.on('authorized_error', (error) => {
235
+ setTimeout(() => {
236
+ Toast.message({
237
+ type: 'error',
238
+ content: error,
239
+ placement: 'bottomEnd',
240
+ });
241
+ }, 2000);
242
+ });
243
+
244
+ io.on('connect_error', (error) => {
245
+ setTimeout(() => {
246
+ Toast.message({
247
+ type: 'error',
248
+ content: '连接错误, 重新连接中~~~请稍后',
249
+ placement: 'bottomEnd',
250
+ });
251
+ }, 2000);
252
+ io.connect();
253
+ // throw error;
254
+ });
255
+
256
+ io.on('connect_timeout', (timeout) => {
257
+ console.log(timeout, '连接超时');
258
+ io.connect();
259
+ // throw timeout + 'error';
260
+ });
261
+
262
+ io.on('error', (error) => {
263
+ setTimeout(() => {
264
+ Toast.message({
265
+ type: 'error',
266
+ content: '连接错误,重连中',
267
+ placement: 'bottomEnd',
268
+ });
269
+ }, 2000);
270
+ // console.log(error, '连接错误,重连中');
271
+ io.connect();
272
+ // throw error;
273
+ });
274
+
275
+ // io.on('reconnecting', (attemptNumber) => {
276
+ // console.log('重连中', attemptNumber);
277
+ // io.connect();
278
+ // });
279
+
280
+ io.on('reconnect_attempt', (attemptNumber) => {
281
+ console.log('重连中', '...', attemptNumber);
282
+ });
283
+
284
+ io.on('reconnect', (data) => {
285
+ // console.log('已重连~~');
286
+ Toast.message({
287
+ type: 'info',
288
+ content: '已成功重新连接!',
289
+ placement: 'topCenter',
290
+ });
291
+ // const userData = JSON.parse(data);
292
+ // const _u = {
293
+ // ...userData,
294
+ // color: roleColors(userData.onlineCount - 1),
295
+ // };
296
+
297
+ // // 进入房间user
298
+ // setUserStack(userData.coUsers);
299
+ // setUserInfo(_u);
300
+ // const co_user = {};
301
+ // Object.keys(userData.coUsers).forEach((user) => {
302
+ // // co_user[userData.coUsers[user['uuid']]] = userData.coUsers[user];
303
+ // co_user[userData.coUsers[user]['uuid']] = userData.coUsers[user];
304
+ // });
305
+ // localStorage.setItem('userStack', JSON.stringify(co_user));
306
+ // localStorage.setItem('userInfo', JSON.stringify(omit(_u, 'coUsers')));
307
+ });
308
+ });
309
+ };
310
+
311
+ export { PlaygroundInit };
@@ -0,0 +1,168 @@
1
+ import { oTStore } from '~/stores';
2
+
3
+ import { getLocalCRDTs, getLocalReplayFile } from './idb';
4
+ import { IsMe } from './userTool';
5
+ import { random } from 'lodash';
6
+ import { userStore } from '~/stores/oTStore';
7
+ import { useOT } from '~/hooks';
8
+ import { Toast } from './toast';
9
+
10
+ let index = 0;
11
+ const REPLAY_INTERVAL = 250;
12
+ let timer;
13
+ let timeOutT: NodeJS.Timeout;
14
+ const replayHandler = async () => {
15
+ const {
16
+ setAppStatus,
17
+ switchDoc,
18
+ switchDocTree,
19
+ setCRDTInfo,
20
+ dockerInfo,
21
+ doc,
22
+ } = oTStore.getState();
23
+ // const { userInfo } = userStore.getState();
24
+ // const { socket } = useOT.getState();
25
+ // const WHICH_ROLE = userInfo;
26
+ // switchDoc({
27
+ // value: '',
28
+ // path: '',
29
+ // });
30
+
31
+ switchDocTree({ data: dockerInfo.fileTree });
32
+
33
+ // setCRDTInfo({
34
+ // userInfo: {
35
+ // uuid: undefined,
36
+ // },
37
+ // timestamp: undefined,
38
+ // evtType: 'Terminal',
39
+ // doc: {
40
+ // action: 'Get',
41
+ // path: '',
42
+ // value: '',
43
+ // },
44
+ // });
45
+
46
+ // setAppStatus('replay');
47
+ // socket.emit('appStatus', 'replay');
48
+
49
+ // debugger;
50
+ const crdts: D42_FrontType.ReplaySource[] = await getLocalCRDTs();
51
+ // const filterData = crdts.filter((f) => IsMe(f.userInfo));
52
+ const filterData = crdts[index];
53
+ const cdata = ({ ...filterData } as unknown) as D42_FrontType.CRDT;
54
+
55
+ // for (const i in cdata) {
56
+ // if (i !== 'timestamp') {
57
+ // cdata[i] = cdata[i].get(WHICH_ROLE.uuid);
58
+ // }
59
+ // }
60
+
61
+ timeOutT = setTimeout(async () => {
62
+ if (!cdata.timestamp) {
63
+ clearTimeout(timeOutT);
64
+ // console.log(crdts);
65
+ // console.log(filterData);
66
+ replay('stop');
67
+ return;
68
+ }
69
+
70
+ if (cdata.file) {
71
+ const file = await getLocalReplayFile(cdata.file.path);
72
+
73
+ cdata.file.value = file;
74
+
75
+ if (doc.path !== cdata.file.path) {
76
+ switchDoc({
77
+ value: file,
78
+ path: cdata.file.path as string,
79
+ });
80
+ }
81
+ // setTimeout(() => {
82
+ setCRDTInfo({
83
+ ...cdata,
84
+ // userInfo: WHICH_ROLE,
85
+ });
86
+ // }, 0);
87
+ return;
88
+ }
89
+ // setTimeout(() => {
90
+ setCRDTInfo({
91
+ ...cdata,
92
+ // userInfo: WHICH_ROLE,
93
+ });
94
+ // }, 0);
95
+ }, 0);
96
+
97
+ index++;
98
+
99
+ return {};
100
+ };
101
+
102
+ export const replay = async (status?: 'stop' | 'disabled' | 'pause') => {
103
+ const { setAppStatus, switchDoc, doc, globalData } = oTStore.getState();
104
+ const { socket } = useOT.getState();
105
+
106
+ switch (status) {
107
+ case 'stop':
108
+ clearInterval(timer);
109
+ // switchDoc(doc);
110
+ // switchDoc({
111
+ // value: '',
112
+ // path: '',
113
+ // });
114
+ setAppStatus('code');
115
+
116
+ Toast.message({
117
+ type: 'info',
118
+ content: '播放完毕',
119
+ placement: 'topCenter',
120
+ });
121
+ index = 0;
122
+
123
+ break;
124
+
125
+ case 'disabled':
126
+ clearInterval(timer);
127
+ switchDoc({
128
+ value: '',
129
+ path: '',
130
+ });
131
+ setAppStatus('code');
132
+ // socket.emit('appStatus', 'code');
133
+ index = 0;
134
+
135
+ break;
136
+
137
+ case 'pause':
138
+ clearInterval(timer);
139
+ setAppStatus('pause');
140
+
141
+ break;
142
+
143
+ default:
144
+ // switchDoc({
145
+ // value: '',
146
+ // path: '',
147
+ // });
148
+ switchDoc({
149
+ value: '',
150
+ path: '',
151
+ });
152
+ clearInterval(timer);
153
+ // setAppStatus('code');
154
+ replayHandler();
155
+ // setAppStatus('replay');
156
+ setAppStatus('replay');
157
+ // socket.emit('appStatus', 'replay');
158
+
159
+ timer = setInterval(() => {
160
+ if (globalData.isRecording) {
161
+ throw 'dError: 录制过程中无法回放!';
162
+ }
163
+ replayHandler();
164
+ }, REPLAY_INTERVAL);
165
+
166
+ break;
167
+ }
168
+ };
@@ -0,0 +1,6 @@
1
+ // import { io, Socket } from 'socket.io-client';
2
+ // import { DefaultEventsMap } from 'socket.io-client/build/typed-events';
3
+
4
+ const socketHelper = (string) => string;
5
+
6
+ export { socketHelper };
@@ -0,0 +1,19 @@
1
+ // import { Message, MsgType } from '~/components/Message';
2
+ import { toaster, Notification, Message } from 'rsuite';
3
+ import React from 'react';
4
+
5
+ export class Toast {
6
+ static message(props) {
7
+ // debugger;
8
+ toaster.push(
9
+ <Message showIcon {...props}>
10
+ {props.content}
11
+ </Message>,
12
+ {
13
+ placement: props.placement || 'topCenter',
14
+ // ...props,
15
+ // container:()=> document.body,
16
+ },
17
+ );
18
+ }
19
+ }
@@ -0,0 +1,12 @@
1
+ import { oTStore } from '~/stores';
2
+ import { userStore } from '~/stores/oTStore';
3
+
4
+ export const IsMe = (userInfo) => {
5
+ const _u = userStore.getState().userInfo;
6
+ return _u.uuid === userInfo.uuid;
7
+ };
8
+
9
+ export const IsSameFile = (file) => {
10
+ const _f = oTStore.getState().doc;
11
+ return _f.path === file.path;
12
+ };
@@ -0,0 +1,4 @@
1
+ export const globalVal = (global) => {
2
+ global.d42 = window;
3
+ global.log = console.log;
4
+ };
@@ -0,0 +1,6 @@
1
+ export { socketHelper } from './collections/socket';
2
+ export { localStorageSpace } from './collections/localStorage';
3
+ export { avatarGenerator, roleColors } from './collections/mock';
4
+ export { globalVal } from './collections/util';
5
+ export { IsMe, IsSameFile } from './collections/userTool';
6
+ export { IoClient } from './collections/IoClient';