@lvce-editor/chat-view 1.0.0 → 1.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.
@@ -486,7 +486,7 @@ const execute = (command, ...args) => {
486
486
 
487
487
  const Two$1 = '2.0';
488
488
  const callbacks = Object.create(null);
489
- const get$3 = id => {
489
+ const get$2 = id => {
490
490
  return callbacks[id];
491
491
  };
492
492
  const remove$1 = id => {
@@ -635,7 +635,7 @@ const warn = (...args) => {
635
635
  console.warn(...args);
636
636
  };
637
637
  const resolve = (id, response) => {
638
- const fn = get$3(id);
638
+ const fn = get$2(id);
639
639
  if (!fn) {
640
640
  console.log(response);
641
641
  warn(`callback ${id} may already be disposed`);
@@ -964,18 +964,21 @@ const create$3 = async ({
964
964
  return rpc;
965
965
  };
966
966
 
967
- const Button$1 = 'button';
968
- const Status = 'status';
969
-
970
- const MaskIcon = 'MaskIcon';
967
+ const Button$2 = 'button';
971
968
 
972
- const Button = 1;
969
+ const Button$1 = 1;
973
970
  const Div = 4;
974
971
  const Span = 8;
975
972
  const Text = 12;
973
+ const P = 50;
974
+ const TextArea = 62;
975
+ const Strong = 70;
976
976
  const Reference = 100;
977
977
 
978
+ const Key = 'event.key';
979
+ const ShiftKey = 'event.shiftKey';
978
980
  const TargetName = 'event.target.name';
981
+ const TargetValue = 'event.target.value';
979
982
 
980
983
  const ExtensionHostWorker = 44;
981
984
  const RendererWorker = 1;
@@ -1007,7 +1010,7 @@ const rpcs = Object.create(null);
1007
1010
  const set$3 = (id, rpc) => {
1008
1011
  rpcs[id] = rpc;
1009
1012
  };
1010
- const get$2 = id => {
1013
+ const get$1 = id => {
1011
1014
  return rpcs[id];
1012
1015
  };
1013
1016
  const remove = id => {
@@ -1018,18 +1021,18 @@ const remove = id => {
1018
1021
  const create$2 = rpcId => {
1019
1022
  return {
1020
1023
  async dispose() {
1021
- const rpc = get$2(rpcId);
1024
+ const rpc = get$1(rpcId);
1022
1025
  await rpc.dispose();
1023
1026
  },
1024
1027
  // @ts-ignore
1025
1028
  invoke(method, ...params) {
1026
- const rpc = get$2(rpcId);
1029
+ const rpc = get$1(rpcId);
1027
1030
  // @ts-ignore
1028
1031
  return rpc.invoke(method, ...params);
1029
1032
  },
1030
1033
  // @ts-ignore
1031
1034
  invokeAndTransfer(method, ...params) {
1032
- const rpc = get$2(rpcId);
1035
+ const rpc = get$1(rpcId);
1033
1036
  // @ts-ignore
1034
1037
  return rpc.invokeAndTransfer(method, ...params);
1035
1038
  },
@@ -1052,12 +1055,10 @@ const create$2 = rpcId => {
1052
1055
  };
1053
1056
 
1054
1057
  const {
1055
- invoke: invoke$1,
1056
1058
  set: set$2
1057
1059
  } = create$2(ExtensionHostWorker);
1058
1060
 
1059
1061
  const {
1060
- invoke,
1061
1062
  invokeAndTransfer,
1062
1063
  set: set$1
1063
1064
  } = create$2(RendererWorker);
@@ -1065,12 +1066,6 @@ const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
1065
1066
  const command = 'HandleMessagePort.handleMessagePort2';
1066
1067
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
1067
1068
  };
1068
- const activateByEvent$1 = (event, assetDir, platform) => {
1069
- return invoke('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
1070
- };
1071
- const getPreference = async key => {
1072
- return await invoke('Preferences.get', key);
1073
- };
1074
1069
 
1075
1070
  const toCommandId = key => {
1076
1071
  const dotIndex = key.indexOf('.');
@@ -1192,8 +1187,34 @@ const terminate = () => {
1192
1187
  globalThis.close();
1193
1188
  };
1194
1189
 
1190
+ const createDefaultState = () => {
1191
+ const defaultSessionId = 'session-1';
1192
+ return {
1193
+ assetDir: '',
1194
+ composerValue: '',
1195
+ errorCount: 0,
1196
+ ignoreNextInput: false,
1197
+ initial: true,
1198
+ lastSubmittedSessionId: '',
1199
+ nextMessageId: 1,
1200
+ nextSessionId: 2,
1201
+ platform: 0,
1202
+ renamingSessionId: '',
1203
+ selectedSessionId: defaultSessionId,
1204
+ sessions: [{
1205
+ id: defaultSessionId,
1206
+ messages: [],
1207
+ title: 'Chat 1'
1208
+ }],
1209
+ statusBarItemsLeft: [],
1210
+ statusBarItemsRight: [],
1211
+ uid: 0,
1212
+ warningCount: 0
1213
+ };
1214
+ };
1215
+
1195
1216
  const {
1196
- get: get$1,
1217
+ get,
1197
1218
  getCommandIds,
1198
1219
  registerCommands,
1199
1220
  set,
@@ -1203,20 +1224,16 @@ const {
1203
1224
 
1204
1225
  const create = (uid, uri, x, y, width, height, platform, assetDir) => {
1205
1226
  const state = {
1227
+ ...createDefaultState(),
1206
1228
  assetDir,
1207
- errorCount: 0,
1208
- initial: true,
1209
1229
  platform,
1210
- statusBarItemsLeft: [],
1211
- statusBarItemsRight: [],
1212
- uid,
1213
- warningCount: 0
1230
+ uid
1214
1231
  };
1215
1232
  set(uid, state, state);
1216
1233
  };
1217
1234
 
1218
1235
  const isEqual = (oldState, newState) => {
1219
- return oldState.statusBarItemsLeft === newState.statusBarItemsLeft && oldState.statusBarItemsRight === newState.statusBarItemsRight;
1236
+ return oldState.composerValue === newState.composerValue && oldState.ignoreNextInput === newState.ignoreNextInput && oldState.initial === newState.initial && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedSessionId === newState.selectedSessionId && oldState.sessions === newState.sessions;
1220
1237
  };
1221
1238
 
1222
1239
  const RenderItems = 4;
@@ -1240,66 +1257,201 @@ const diff2 = uid => {
1240
1257
  const {
1241
1258
  newState,
1242
1259
  oldState
1243
- } = get$1(uid);
1260
+ } = get(uid);
1244
1261
  const result = diff(oldState, newState);
1245
1262
  return result;
1246
1263
  };
1247
1264
 
1248
- const getMatchingItem = (itemsLeft, itemsRight, name) => {
1249
- for (const item of itemsLeft) {
1250
- if (item.name === name) {
1251
- return item;
1252
- }
1265
+ const CREATE_SESSION = 'create-session';
1266
+ const SESSION_PREFIX = 'session:';
1267
+ const RENAME_PREFIX = 'session-rename:';
1268
+ const DELETE_PREFIX = 'session-delete:';
1269
+ const getNextSelectedSessionId = (sessions, deletedId) => {
1270
+ if (sessions.length === 0) {
1271
+ return '';
1253
1272
  }
1254
- for (const item of itemsRight) {
1255
- if (item.name === name) {
1256
- return item;
1257
- }
1273
+ const index = sessions.findIndex(session => session.id === deletedId);
1274
+ if (index === -1) {
1275
+ return sessions[0].id;
1258
1276
  }
1259
- return undefined;
1277
+ const nextIndex = Math.min(index, sessions.length - 1);
1278
+ return sessions[nextIndex].id;
1260
1279
  };
1261
-
1262
- const handleClickExtensionStatusBarItem = async name => {
1263
- // @ts-ignore
1264
- await invoke$1(`ExtensionHostStatusBar.executeCommand`, name);
1280
+ const createSession = state => {
1281
+ const id = `session-${state.nextSessionId}`;
1282
+ const session = {
1283
+ id,
1284
+ messages: [],
1285
+ title: `Chat ${state.nextSessionId}`
1286
+ };
1287
+ return {
1288
+ ...state,
1289
+ nextSessionId: state.nextSessionId + 1,
1290
+ renamingSessionId: '',
1291
+ selectedSessionId: id,
1292
+ sessions: [...state.sessions, session]
1293
+ };
1265
1294
  };
1266
-
1267
- const handleClickNotification = async () => {
1268
- // TODO toggle notifications
1295
+ const selectSession = (state, id) => {
1296
+ const exists = state.sessions.some(session => session.id === id);
1297
+ if (!exists) {
1298
+ return state;
1299
+ }
1300
+ return {
1301
+ ...state,
1302
+ renamingSessionId: '',
1303
+ selectedSessionId: id
1304
+ };
1269
1305
  };
1270
-
1271
- const handleClickProblems = async () => {
1272
- // @ts-ignore
1273
- await invoke('Layout.showPanel');
1274
- // @ts-ignore
1275
- await invoke('Panel.toggleView', 'Problems');
1306
+ const startRename = (state, id) => {
1307
+ const session = state.sessions.find(item => item.id === id);
1308
+ if (!session) {
1309
+ return state;
1310
+ }
1311
+ return {
1312
+ ...state,
1313
+ composerValue: session.title,
1314
+ renamingSessionId: id,
1315
+ selectedSessionId: id
1316
+ };
1317
+ };
1318
+ const deleteSession = (state, id) => {
1319
+ const filtered = state.sessions.filter(session => session.id !== id);
1320
+ if (filtered.length === state.sessions.length) {
1321
+ return state;
1322
+ }
1323
+ if (filtered.length === 0) {
1324
+ const fallbackId = `session-${state.nextSessionId}`;
1325
+ const fallback = {
1326
+ id: fallbackId,
1327
+ messages: [],
1328
+ title: `Chat ${state.nextSessionId}`
1329
+ };
1330
+ return {
1331
+ ...state,
1332
+ nextSessionId: state.nextSessionId + 1,
1333
+ renamingSessionId: '',
1334
+ selectedSessionId: fallbackId,
1335
+ sessions: [fallback]
1336
+ };
1337
+ }
1338
+ return {
1339
+ ...state,
1340
+ renamingSessionId: state.renamingSessionId === id ? '' : state.renamingSessionId,
1341
+ selectedSessionId: getNextSelectedSessionId(filtered, id),
1342
+ sessions: filtered
1343
+ };
1276
1344
  };
1277
-
1278
- const Notifications = 'Notifications';
1279
- const Problems = 'Problems';
1280
-
1281
1345
  const handleClick = async (state, name) => {
1282
1346
  if (!name) {
1283
1347
  return state;
1284
1348
  }
1349
+ if (name === CREATE_SESSION) {
1350
+ return createSession(state);
1351
+ }
1352
+ if (name.startsWith(SESSION_PREFIX)) {
1353
+ const id = name.slice(SESSION_PREFIX.length);
1354
+ return selectSession(state, id);
1355
+ }
1356
+ if (name.startsWith(RENAME_PREFIX)) {
1357
+ const id = name.slice(RENAME_PREFIX.length);
1358
+ return startRename(state, id);
1359
+ }
1360
+ if (name.startsWith(DELETE_PREFIX)) {
1361
+ const id = name.slice(DELETE_PREFIX.length);
1362
+ return deleteSession(state, id);
1363
+ }
1364
+ return state;
1365
+ };
1366
+
1367
+ const handleInput = async (state, value) => {
1368
+ if (state.ignoreNextInput) {
1369
+ return {
1370
+ ...state,
1371
+ ignoreNextInput: false
1372
+ };
1373
+ }
1374
+ return {
1375
+ ...state,
1376
+ composerValue: value
1377
+ };
1378
+ };
1379
+
1380
+ const submitRename = state => {
1285
1381
  const {
1286
- statusBarItemsLeft,
1287
- statusBarItemsRight
1382
+ composerValue,
1383
+ renamingSessionId,
1384
+ sessions
1385
+ } = state;
1386
+ const title = composerValue.trim();
1387
+ if (!renamingSessionId || !title) {
1388
+ return {
1389
+ ...state,
1390
+ renamingSessionId: ''
1391
+ };
1392
+ }
1393
+ const updatedSessions = sessions.map(session => {
1394
+ if (session.id !== renamingSessionId) {
1395
+ return session;
1396
+ }
1397
+ return {
1398
+ ...session,
1399
+ title
1400
+ };
1401
+ });
1402
+ return {
1403
+ ...state,
1404
+ composerValue: '',
1405
+ ignoreNextInput: true,
1406
+ renamingSessionId: '',
1407
+ sessions: updatedSessions
1408
+ };
1409
+ };
1410
+ const submitMessage = state => {
1411
+ const {
1412
+ composerValue,
1413
+ nextMessageId,
1414
+ selectedSessionId,
1415
+ sessions
1288
1416
  } = state;
1289
- const item = getMatchingItem(statusBarItemsLeft, statusBarItemsRight, name);
1290
- if (!item) {
1417
+ const text = composerValue.trim();
1418
+ if (!text) {
1419
+ return {
1420
+ ...state,
1421
+ ignoreNextInput: true
1422
+ };
1423
+ }
1424
+ const updatedSessions = sessions.map(session => {
1425
+ if (session.id !== selectedSessionId) {
1426
+ return session;
1427
+ }
1428
+ const message = {
1429
+ id: `message-${nextMessageId}`,
1430
+ role: 'user',
1431
+ text
1432
+ };
1433
+ return {
1434
+ ...session,
1435
+ messages: [...session.messages, message]
1436
+ };
1437
+ });
1438
+ return {
1439
+ ...state,
1440
+ composerValue: '',
1441
+ ignoreNextInput: true,
1442
+ lastSubmittedSessionId: selectedSessionId,
1443
+ nextMessageId: nextMessageId + 1,
1444
+ sessions: updatedSessions
1445
+ };
1446
+ };
1447
+ const handleKeyDown = async (state, key, shiftKey) => {
1448
+ if (key !== 'Enter' || shiftKey) {
1291
1449
  return state;
1292
1450
  }
1293
- if (item.name === Notifications) {
1294
- await handleClickNotification();
1295
- } else if (item.name === Problems) {
1296
- await handleClickProblems();
1297
- } else {
1298
- await handleClickExtensionStatusBarItem(name);
1451
+ if (state.renamingSessionId) {
1452
+ return submitRename(state);
1299
1453
  }
1300
- // TODO
1301
- // sendExtensionWorker([/* statusBarItemHandleClick */ 7657, /* name */ name])
1302
- return state;
1454
+ return submitMessage(state);
1303
1455
  };
1304
1456
 
1305
1457
  const id = 7201;
@@ -1369,196 +1521,29 @@ const itemRightUpdate = (state, newItem) => {
1369
1521
  };
1370
1522
  };
1371
1523
 
1372
- const OnStatusBarItem = 'onStatusBarItem';
1373
-
1374
- const GetStatusBarItems = 'ExtensionHost.getStatusBarItems2';
1375
-
1376
- const activateByEvent = (event, assetDir, platform) => {
1377
- // @ts-ignore
1378
- return activateByEvent$1(event, assetDir, platform);
1379
- };
1380
-
1381
- const executeProviders = async ({
1382
- assetDir,
1383
- combineResults,
1384
- event,
1385
- method,
1386
- noProviderFoundMessage = 'No provider found',
1387
- noProviderFoundResult,
1388
- params,
1389
- platform
1390
- }) => {
1391
- await activateByEvent(event, assetDir, platform);
1392
- // @ts-ignore
1393
- const result = await invoke$1(method, ...params);
1394
- return result;
1395
- };
1396
-
1397
- const combineResults = results => {
1398
- return results.flat();
1399
- };
1400
- const getStatusBarItems$1 = (assetDir, platform) => {
1401
- return executeProviders({
1402
- assetDir,
1403
- combineResults,
1404
- event: OnStatusBarItem,
1405
- method: GetStatusBarItems,
1406
- noProviderFoundMessage: 'No status bar item provider found',
1407
- noProviderFoundResult: [],
1408
- params: [],
1409
- platform
1410
- });
1411
- };
1412
-
1413
- const ProblemsErrorIcon = 'ProblemsErrorIcon';
1414
- const ProblemsWarningIcon = 'ProblemsWarningIcon';
1415
- const StatusBarItem = 'StatusBarItem';
1416
- const StatusBarItemsLeft = 'StatusBarItemsLeft';
1417
- const StatusBarItemsRight = 'StatusBarItemsRight';
1418
-
1419
- const getProblemsAriaLabel = (errorCount, warningCount) => {
1420
- const parts = [];
1421
- if (errorCount > 0) {
1422
- parts.push(`${errorCount} ${errorCount === 1 ? 'Problem' : 'Problems'}`);
1423
- }
1424
- if (warningCount > 0) {
1425
- parts.push(`${warningCount} ${warningCount === 1 ? 'Warning' : 'Warnings'}`);
1524
+ const ensureSessions = state => {
1525
+ if (state.sessions.length > 0) {
1526
+ return state.sessions;
1426
1527
  }
1427
- if (parts.length === 0) {
1428
- return 'No Problems';
1429
- }
1430
- return parts.join(', ');
1431
- };
1432
- const getBuiltinStatusBarItems = async (errorCount, warningCount) => {
1433
- const extraItems = [{
1434
- ariaLabel: 'Notifications',
1435
- command: '',
1436
- // TODO should show notifications center
1437
- elements: [{
1438
- type: 'text',
1439
- value: 'Notifications'
1440
- }],
1441
- name: Notifications,
1442
- tooltip: 'Notifications'
1443
- }, {
1444
- ariaLabel: getProblemsAriaLabel(errorCount, warningCount),
1445
- command: '',
1446
- // TODO should show problems view
1447
- elements: [{
1448
- type: 'icon',
1449
- value: ProblemsErrorIcon
1450
- }, {
1451
- type: 'text',
1452
- value: `${errorCount}`
1453
- }, {
1454
- type: 'icon',
1455
- value: ProblemsWarningIcon
1456
- }, {
1457
- type: 'text',
1458
- value: `${warningCount}`
1459
- }],
1460
- name: Problems,
1461
- tooltip: 'Problems'
1528
+ const id = `session-${state.nextSessionId}`;
1529
+ return [{
1530
+ id,
1531
+ messages: [],
1532
+ title: `Chat ${state.nextSessionId}`
1462
1533
  }];
1463
- return extraItems;
1464
- };
1465
-
1466
- const toStatusBarItem = uiStatusBarItem => {
1467
- const elements = [];
1468
- if (uiStatusBarItem.icon) {
1469
- elements.push({
1470
- type: 'icon',
1471
- value: uiStatusBarItem.icon
1472
- });
1473
- }
1474
- if (uiStatusBarItem.text) {
1475
- elements.push({
1476
- type: 'text',
1477
- value: uiStatusBarItem.text
1478
- });
1479
- }
1480
- if (elements.length === 0) {
1481
- elements.push({
1482
- type: 'text',
1483
- value: ''
1484
- });
1485
- }
1486
- const ariaLabel = uiStatusBarItem.text || uiStatusBarItem.tooltip || uiStatusBarItem.name;
1487
- return {
1488
- ariaLabel,
1489
- command: uiStatusBarItem.command || undefined,
1490
- elements,
1491
- name: uiStatusBarItem.name,
1492
- tooltip: uiStatusBarItem.tooltip
1493
- };
1494
- };
1495
-
1496
- const getActualIcon = extensionHostStatusBarItem => {
1497
- if (extensionHostStatusBarItem.icon === 'branch') {
1498
- return 'Branch';
1499
- }
1500
- return extensionHostStatusBarItem.icon || '';
1501
- };
1502
- const toUiStatusBarItem = extensionHostStatusBarItem => {
1503
- return {
1504
- command: extensionHostStatusBarItem.command || '',
1505
- icon: getActualIcon(extensionHostStatusBarItem),
1506
- name: extensionHostStatusBarItem.id || extensionHostStatusBarItem.name || '',
1507
- text: extensionHostStatusBarItem.text || '',
1508
- tooltip: extensionHostStatusBarItem.tooltip || ''
1509
- };
1510
- };
1511
-
1512
- const toUiStatusBarItems = statusBarItems => {
1513
- if (!statusBarItems) {
1514
- return [];
1515
- }
1516
- return statusBarItems.map(toUiStatusBarItem);
1517
- };
1518
-
1519
- const getStatusBarItems = async (showItems, assetDir, platform, errorCount, warningCount) => {
1520
- if (!showItems) {
1521
- return [];
1522
- }
1523
- await activateByEvent('onSourceControl', assetDir, platform);
1524
- const extensionStatusBarItems = await getStatusBarItems$1(assetDir, platform);
1525
- const uiStatusBarItems = toUiStatusBarItems(extensionStatusBarItems);
1526
- const extraItems = await getBuiltinStatusBarItems(errorCount, warningCount);
1527
- return [...uiStatusBarItems.map(toStatusBarItem), ...extraItems];
1528
1534
  };
1529
-
1530
- const get = async key => {
1531
- return getPreference(key);
1532
- };
1533
-
1534
- const itemsVisible = async () => {
1535
- const statusBarItemsPreference = (await get('statusBar.itemsVisible')) ?? true;
1536
- return statusBarItemsPreference;
1537
- };
1538
-
1539
1535
  const loadContent = async state => {
1540
- const {
1541
- assetDir,
1542
- errorCount,
1543
- platform,
1544
- warningCount
1545
- } = state;
1546
- const statusBarItemsPreference = await itemsVisible();
1547
- const statusBarItems = await getStatusBarItems(statusBarItemsPreference, assetDir, platform, errorCount, warningCount);
1536
+ const sessions = ensureSessions(state);
1537
+ const selectedSessionId = sessions.some(session => session.id === state.selectedSessionId) ? state.selectedSessionId : sessions[0].id;
1548
1538
  return {
1549
1539
  ...state,
1550
- errorCount: 0,
1551
1540
  initial: false,
1552
- statusBarItemsLeft: [...statusBarItems],
1553
- statusBarItemsRight: [],
1554
- warningCount: 0
1541
+ nextSessionId: state.sessions.length === 0 ? state.nextSessionId + 1 : state.nextSessionId,
1542
+ selectedSessionId,
1543
+ sessions
1555
1544
  };
1556
1545
  };
1557
1546
 
1558
- const mergeClassNames = (...classNames) => {
1559
- return classNames.filter(Boolean).join(' ');
1560
- };
1561
-
1562
1547
  const text = data => {
1563
1548
  return {
1564
1549
  childCount: 0,
@@ -1855,104 +1840,158 @@ const diffTree = (oldNodes, newNodes) => {
1855
1840
  return removeTrailingNavigationPatches(patches);
1856
1841
  };
1857
1842
 
1843
+ const Actions = 'Actions';
1844
+ const TestActive = 'TestActive';
1845
+ const SideBarLocation = 'SideBarLocation';
1846
+ const Button = 'Button';
1847
+ const Editor = 'Editor';
1848
+ const EditorContent = 'EditorContent';
1849
+ const IconButton = 'IconButton';
1850
+ const Label = 'Label';
1851
+ const List = 'List';
1852
+ const ListItems = 'ListItems';
1853
+ const Markdown = 'Markdown';
1854
+ const Message = 'Message';
1855
+ const MultilineInputBox = 'MultilineInputBox';
1856
+ const Viewlet = 'Viewlet';
1857
+ const WelcomeMessage = 'WelcomeMessage';
1858
+
1859
+ const HandleInput = 4;
1858
1860
  const HandleClick = 11;
1861
+ const HandleKeyDown = 12;
1859
1862
 
1860
- const getTextVirtualDom = element => {
1863
+ const getSessionDom = (session, selectedSessionId) => {
1864
+ const selected = session.id === selectedSessionId;
1865
+ const sessionClassName = selected ? `${List} ${TestActive}` : List;
1861
1866
  return [{
1862
- childCount: 1,
1863
- className: 'StatusBarItemLabel',
1864
- type: Span
1865
- }, text(element.value)];
1866
- };
1867
- const getIconVirtualDom = element => {
1868
- return [{
1869
- childCount: 0,
1870
- className: mergeClassNames(MaskIcon, element.value),
1867
+ childCount: 2,
1868
+ className: sessionClassName,
1871
1869
  type: Div
1872
- }];
1873
- };
1874
- const getStatusBarItemElementVirtualDom = element => {
1875
- if (element.type === 'text') {
1876
- return getTextVirtualDom(element);
1877
- }
1878
- if (element.type === 'icon') {
1879
- return getIconVirtualDom(element);
1880
- }
1881
- return [];
1882
- };
1883
-
1884
- const getStatusBarItemVirtualDom = statusBarItem => {
1885
- const {
1886
- ariaLabel,
1887
- elements,
1888
- name,
1889
- tooltip
1890
- } = statusBarItem;
1891
- const elementNodes = elements.flatMap(getStatusBarItemElementVirtualDom);
1892
- const buttonNode = {
1893
- ariaLabel,
1894
- childCount: elements.length,
1895
- className: StatusBarItem,
1896
- name,
1897
- role: Button$1,
1898
- tabIndex: -1,
1899
- title: tooltip,
1900
- type: Button
1901
- };
1902
- return [buttonNode, ...elementNodes];
1903
- };
1904
-
1905
- const getStatusBarItemsVirtualDom = (items, className) => {
1906
- if (items.length === 0) {
1907
- return [];
1908
- }
1909
- return [{
1910
- childCount: items.length,
1911
- className,
1870
+ }, {
1871
+ childCount: 1,
1872
+ className: Button,
1873
+ name: `session:${session.id}`,
1874
+ role: Button$2,
1875
+ tabIndex: 0,
1876
+ type: Button$1
1877
+ }, text(session.title), {
1878
+ childCount: 2,
1879
+ className: Actions,
1912
1880
  type: Div
1913
- }, ...items.flatMap(getStatusBarItemVirtualDom)];
1914
- };
1915
-
1916
- const getStatusBarItemsLeftDom = statusBarItemsLeft => {
1917
- return getStatusBarItemsVirtualDom(statusBarItemsLeft, StatusBarItemsLeft);
1918
- };
1919
-
1920
- const getStatusBarItemsRightDom = statusBarItemsRight => {
1921
- return getStatusBarItemsVirtualDom(statusBarItemsRight, StatusBarItemsRight);
1922
- };
1923
-
1924
- const getChildCount = (leftCount, rightCount) => {
1925
- let count = 0;
1926
- if (leftCount > 0) {
1927
- count++;
1928
- }
1929
- if (rightCount > 0) {
1930
- count++;
1931
- }
1932
- return count;
1881
+ }, {
1882
+ childCount: 1,
1883
+ className: IconButton,
1884
+ name: `session-rename:${session.id}`,
1885
+ role: Button$2,
1886
+ tabIndex: 0,
1887
+ title: 'Rename chat session',
1888
+ type: Button$1
1889
+ }, text('Rename'), {
1890
+ childCount: 1,
1891
+ className: IconButton,
1892
+ name: `session-delete:${session.id}`,
1893
+ role: Button$2,
1894
+ tabIndex: 0,
1895
+ title: 'Delete chat session',
1896
+ type: Button$1
1897
+ }, text('Delete')];
1898
+ };
1899
+ const getMessagesDom = messages => {
1900
+ if (messages.length === 0) {
1901
+ return [{
1902
+ childCount: 1,
1903
+ className: WelcomeMessage,
1904
+ type: Div
1905
+ }, text('Start a conversation by typing below.')];
1906
+ }
1907
+ return messages.flatMap(message => {
1908
+ return [{
1909
+ childCount: 2,
1910
+ className: Message,
1911
+ type: Div
1912
+ }, {
1913
+ childCount: 1,
1914
+ className: Label,
1915
+ type: Strong
1916
+ }, text(message.role === 'user' ? 'You' : 'Assistant'), {
1917
+ childCount: 1,
1918
+ className: Markdown,
1919
+ type: P
1920
+ }, text(message.text)];
1921
+ });
1933
1922
  };
1934
- const getStatusBarVirtualDom = (statusBarItemsLeft, statusBarItemsRight) => {
1923
+ const getStatusBarVirtualDom = (sessions, selectedSessionId, composerValue) => {
1924
+ const selectedSession = sessions.find(session => session.id === selectedSessionId);
1925
+ const messages = selectedSession ? selectedSession.messages : [];
1926
+ const sessionNodes = sessions.flatMap(session => getSessionDom(session, selectedSessionId));
1927
+ const messagesNodes = getMessagesDom(messages);
1935
1928
  const dom = [{
1936
- childCount: getChildCount(statusBarItemsLeft.length, statusBarItemsRight.length),
1937
- className: 'StatusBar',
1929
+ childCount: 3,
1930
+ className: Viewlet,
1938
1931
  onClick: HandleClick,
1939
- role: Status,
1932
+ onInput: HandleInput,
1933
+ onKeyDown: HandleKeyDown,
1934
+ type: Div
1935
+ }, {
1936
+ childCount: 2,
1937
+ className: SideBarLocation,
1938
+ type: Div
1939
+ }, {
1940
+ childCount: 2,
1941
+ className: Actions,
1942
+ type: Div
1943
+ }, {
1944
+ childCount: 1,
1945
+ className: Label,
1946
+ type: Span
1947
+ }, text('Chats'), {
1948
+ childCount: 1,
1949
+ className: IconButton,
1950
+ name: 'create-session',
1951
+ role: Button$2,
1952
+ tabIndex: 0,
1953
+ title: 'New Chat',
1954
+ type: Button$1
1955
+ }, text('+'), {
1956
+ childCount: sessions.length,
1957
+ className: ListItems,
1958
+ type: Div
1959
+ }, ...sessionNodes, {
1960
+ childCount: 2,
1961
+ className: Editor,
1962
+ type: Div
1963
+ }, {
1964
+ childCount: Math.max(messagesNodes.length, 0),
1965
+ className: EditorContent,
1966
+ type: Div
1967
+ }, ...messagesNodes, {
1968
+ childCount: 1,
1969
+ className: Actions,
1940
1970
  type: Div
1941
- }, ...getStatusBarItemsLeftDom(statusBarItemsLeft), ...getStatusBarItemsRightDom(statusBarItemsRight)];
1971
+ }, {
1972
+ childCount: 0,
1973
+ className: MultilineInputBox,
1974
+ name: 'composer',
1975
+ placeholder: 'Type your message. Enter to send, Shift+Enter for newline.',
1976
+ rows: 4,
1977
+ type: TextArea,
1978
+ value: composerValue
1979
+ }];
1942
1980
  return dom;
1943
1981
  };
1944
1982
 
1945
1983
  const renderItems = (oldState, newState) => {
1946
1984
  const {
1985
+ composerValue,
1947
1986
  initial,
1948
- statusBarItemsLeft,
1949
- statusBarItemsRight,
1987
+ selectedSessionId,
1988
+ sessions,
1950
1989
  uid
1951
1990
  } = newState;
1952
1991
  if (initial) {
1953
1992
  return [SetDom2, uid, []];
1954
1993
  }
1955
- const dom = getStatusBarVirtualDom(statusBarItemsLeft, statusBarItemsRight);
1994
+ const dom = getStatusBarVirtualDom(sessions, selectedSessionId, composerValue);
1956
1995
  return [SetDom2, uid, dom];
1957
1996
  };
1958
1997
 
@@ -1990,7 +2029,7 @@ const render2 = (uid, diffResult) => {
1990
2029
  const {
1991
2030
  newState,
1992
2031
  oldState
1993
- } = get$1(uid);
2032
+ } = get(uid);
1994
2033
  set(uid, newState, newState);
1995
2034
  const commands = applyRender(oldState, newState, diffResult);
1996
2035
  return commands;
@@ -2000,6 +2039,12 @@ const renderEventListeners = () => {
2000
2039
  return [{
2001
2040
  name: HandleClick,
2002
2041
  params: ['handleClick', TargetName]
2042
+ }, {
2043
+ name: HandleInput,
2044
+ params: ['handleInput', TargetValue]
2045
+ }, {
2046
+ name: HandleKeyDown,
2047
+ params: ['handleKeyDown', Key, ShiftKey]
2003
2048
  }];
2004
2049
  };
2005
2050
 
@@ -2012,30 +2057,44 @@ const resize = (state, dimensions) => {
2012
2057
 
2013
2058
  const saveState = state => {
2014
2059
  const {
2060
+ composerValue,
2061
+ nextMessageId,
2062
+ nextSessionId,
2063
+ renamingSessionId,
2064
+ selectedSessionId,
2065
+ sessions,
2015
2066
  statusBarItemsLeft,
2016
2067
  statusBarItemsRight
2017
2068
  } = state;
2018
2069
  return {
2070
+ composerValue,
2019
2071
  itemsLeft: statusBarItemsLeft,
2020
- itemsRight: statusBarItemsRight
2072
+ itemsRight: statusBarItemsRight,
2073
+ nextMessageId,
2074
+ nextSessionId,
2075
+ renamingSessionId,
2076
+ selectedSessionId,
2077
+ sessions
2021
2078
  };
2022
2079
  };
2023
2080
 
2024
2081
  const commandMap = {
2025
- 'StatusBar.create': create,
2026
- 'StatusBar.diff2': diff2,
2027
- 'StatusBar.getCommandIds': getCommandIds,
2028
- 'StatusBar.handleClick': wrapCommand(handleClick),
2029
- 'StatusBar.initialize': initialize,
2030
- 'StatusBar.itemLeftUpdate': wrapCommand(itemLeftUpdate),
2031
- 'StatusBar.itemRightCreate': wrapCommand(itemRightCreate),
2032
- 'StatusBar.itemRightUpdate': wrapCommand(itemRightUpdate),
2033
- 'StatusBar.loadContent': wrapCommand(loadContent),
2034
- 'StatusBar.render2': render2,
2035
- 'StatusBar.renderEventListeners': renderEventListeners,
2036
- 'StatusBar.resize': wrapCommand(resize),
2037
- 'StatusBar.saveState': wrapGetter(saveState),
2038
- 'StatusBar.terminate': terminate
2082
+ 'Chat.create': create,
2083
+ 'Chat.diff2': diff2,
2084
+ 'Chat.getCommandIds': getCommandIds,
2085
+ 'Chat.handleClick': wrapCommand(handleClick),
2086
+ 'Chat.handleInput': wrapCommand(handleInput),
2087
+ 'Chat.handleKeyDown': wrapCommand(handleKeyDown),
2088
+ 'Chat.initialize': initialize,
2089
+ 'Chat.itemLeftUpdate': wrapCommand(itemLeftUpdate),
2090
+ 'Chat.itemRightCreate': wrapCommand(itemRightCreate),
2091
+ 'Chat.itemRightUpdate': wrapCommand(itemRightUpdate),
2092
+ 'Chat.loadContent': wrapCommand(loadContent),
2093
+ 'Chat.render2': render2,
2094
+ 'Chat.renderEventListeners': renderEventListeners,
2095
+ 'Chat.resize': wrapCommand(resize),
2096
+ 'Chat.saveState': wrapGetter(saveState),
2097
+ 'Chat.terminate': terminate
2039
2098
  };
2040
2099
 
2041
2100
  const listen = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",