@lvce-editor/main-area-worker 8.13.0 → 8.15.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.
@@ -88,7 +88,13 @@ const terminate = () => {
88
88
  };
89
89
 
90
90
  const getGroupIndexById = (state, groupId) => {
91
- return state.layout.groups.findIndex(group => group.id === groupId);
91
+ const {
92
+ layout
93
+ } = state;
94
+ const {
95
+ groups
96
+ } = layout;
97
+ return groups.findIndex(group => group.id === groupId);
92
98
  };
93
99
 
94
100
  const redistributeSizesWithRounding = groups => {
@@ -181,7 +187,13 @@ const closeTab = (state, groupId, tabId) => {
181
187
  };
182
188
 
183
189
  const getFocusedGroup = state => {
184
- return state.layout.groups.find(group => group.focused);
190
+ const {
191
+ layout
192
+ } = state;
193
+ const {
194
+ groups
195
+ } = layout;
196
+ return groups.find(group => group.focused);
185
197
  };
186
198
 
187
199
  const closeActiveEditor = state => {
@@ -1669,6 +1681,7 @@ const copyPath$1 = async (state, path) => {
1669
1681
 
1670
1682
  const copyRelativePath$1 = async (state, path) => {
1671
1683
  string(path);
1684
+ // TODO use clipboard worker
1672
1685
  const relativePath = await invoke('Workspace.pathBaseName', path);
1673
1686
  await invoke('ClipBoard.writeText', relativePath);
1674
1687
  return state;
@@ -2344,6 +2357,11 @@ const handleClickTogglePreview = async state => {
2344
2357
  return state;
2345
2358
  };
2346
2359
 
2360
+ const CloseGroup = 'close-group';
2361
+ const RetryOpen = 'retry-open';
2362
+ const SplitRight = 'split-right';
2363
+ const TogglePreview$1 = 'toggle-preview';
2364
+
2347
2365
  const getBasename$1 = uri => {
2348
2366
  const lastSlashIndex = uri.lastIndexOf('/');
2349
2367
  if (lastSlashIndex === -1) {
@@ -2364,7 +2382,7 @@ const getLabel = uri => {
2364
2382
  return getBasename$1(uri);
2365
2383
  };
2366
2384
 
2367
- const createEmptyGroup = (state, uri, requestId) => {
2385
+ const createEmptyGroup = (state, uri, requestId, preview = false) => {
2368
2386
  const {
2369
2387
  layout
2370
2388
  } = state;
@@ -2382,6 +2400,7 @@ const createEmptyGroup = (state, uri, requestId) => {
2382
2400
  icon: '',
2383
2401
  id: tabId,
2384
2402
  isDirty: false,
2403
+ isPreview: preview,
2385
2404
  language: '',
2386
2405
  loadingState: 'loading',
2387
2406
  title,
@@ -2406,8 +2425,12 @@ const createEmptyGroup = (state, uri, requestId) => {
2406
2425
  };
2407
2426
 
2408
2427
  const openTab = (state, groupId, tab) => {
2409
- const newTab = 'id' in tab && tab.id !== undefined ? tab : {
2428
+ const normalizedTab = {
2410
2429
  ...tab,
2430
+ isPreview: tab.isPreview ?? false
2431
+ };
2432
+ const newTab = 'id' in normalizedTab && normalizedTab.id !== undefined ? normalizedTab : {
2433
+ ...normalizedTab,
2411
2434
  id: create$1()
2412
2435
  };
2413
2436
  const {
@@ -2437,7 +2460,7 @@ const openTab = (state, groupId, tab) => {
2437
2460
  };
2438
2461
  };
2439
2462
 
2440
- const ensureActiveGroup = (state, uri) => {
2463
+ const ensureActiveGroup = (state, uri, preview = false) => {
2441
2464
  // Find the active group (by activeGroupId or focused flag)
2442
2465
  const {
2443
2466
  layout
@@ -2449,11 +2472,49 @@ const ensureActiveGroup = (state, uri) => {
2449
2472
  const activeGroup = activeGroupId === undefined ? groups.find(group => group.focused) : groups.find(group => group.id === activeGroupId);
2450
2473
 
2451
2474
  // Generate a request ID for content loading
2452
- getNextRequestId();
2475
+ const requestId = getNextRequestId();
2453
2476
 
2454
2477
  // If no active group exists, create one
2455
2478
  let newState;
2456
2479
  if (activeGroup) {
2480
+ const activeTab = activeGroup.tabs.find(tab => tab.id === activeGroup.activeTabId);
2481
+ if (activeTab?.isPreview) {
2482
+ const title = getLabel(uri);
2483
+ const updatedGroups = groups.map(group => {
2484
+ if (group.id !== activeGroup.id) {
2485
+ return group;
2486
+ }
2487
+ const updatedTabs = group.tabs.map(tab => {
2488
+ if (tab.id !== activeTab.id) {
2489
+ return tab;
2490
+ }
2491
+ return {
2492
+ ...tab,
2493
+ errorMessage: '',
2494
+ icon: '',
2495
+ isDirty: false,
2496
+ isPreview: preview,
2497
+ language: '',
2498
+ loadingState: 'loading',
2499
+ title,
2500
+ uri
2501
+ };
2502
+ });
2503
+ return {
2504
+ ...group,
2505
+ tabs: updatedTabs
2506
+ };
2507
+ });
2508
+ return {
2509
+ ...state,
2510
+ layout: {
2511
+ ...layout,
2512
+ activeGroupId: activeGroup.id,
2513
+ groups: updatedGroups
2514
+ }
2515
+ };
2516
+ }
2517
+
2457
2518
  // Create a new tab with the URI in the active group
2458
2519
  const title = getLabel(uri);
2459
2520
  const tabId = create$1();
@@ -2465,6 +2526,7 @@ const ensureActiveGroup = (state, uri) => {
2465
2526
  icon: '',
2466
2527
  id: tabId,
2467
2528
  isDirty: false,
2529
+ isPreview: preview,
2468
2530
  language: '',
2469
2531
  loadingState: 'loading',
2470
2532
  title,
@@ -2472,7 +2534,7 @@ const ensureActiveGroup = (state, uri) => {
2472
2534
  };
2473
2535
  newState = openTab(state, activeGroup.id, newTab);
2474
2536
  } else {
2475
- newState = createEmptyGroup(state, uri);
2537
+ newState = createEmptyGroup(state, uri, requestId, preview);
2476
2538
  }
2477
2539
  return newState;
2478
2540
  };
@@ -2674,6 +2736,7 @@ const openUri = async (state, options) => {
2674
2736
  uid
2675
2737
  } = state;
2676
2738
  const uri = getOptionUriOptions(options);
2739
+ const preview = typeof options === 'string' ? false : options.preview ?? false;
2677
2740
 
2678
2741
  // Check if a tab with this URI already exists in the passed-in state
2679
2742
  const existingTab = findTabByUri(state, uri);
@@ -2721,7 +2784,7 @@ const openUri = async (state, options) => {
2721
2784
  tabId = existingTab.tab.id;
2722
2785
  } else {
2723
2786
  // Add tab to state BEFORE any async calls to prevent race conditions
2724
- stateWithTab = ensureActiveGroup(currentState, uri);
2787
+ stateWithTab = ensureActiveGroup(currentState, uri, preview);
2725
2788
  tabId = getActiveTabId(stateWithTab);
2726
2789
  }
2727
2790
 
@@ -2936,17 +2999,17 @@ const handleClickAction = async (state, action, rawGroupId) => {
2936
2999
  return state;
2937
3000
  }
2938
3001
  switch (action) {
2939
- case 'close-group':
3002
+ case CloseGroup:
2940
3003
  if (rawGroupId) {
2941
3004
  const groupId = Number.parseInt(rawGroupId, 10);
2942
3005
  return closeEditorGroup$1(state, groupId);
2943
3006
  }
2944
3007
  return state;
2945
- case 'retry-open':
3008
+ case RetryOpen:
2946
3009
  return retryOpen(state);
2947
- case 'split-right':
3010
+ case SplitRight:
2948
3011
  return splitEditorGroup$1(state, activeGroup.id, Right);
2949
- case 'toggle-preview':
3012
+ case TogglePreview$1:
2950
3013
  return handleClickTogglePreview(state);
2951
3014
  default:
2952
3015
  return state;
@@ -3023,6 +3086,7 @@ const IconButton = 'IconButton';
3023
3086
  const MainTab = 'MainTab';
3024
3087
  const MainTabs = 'MainTabs';
3025
3088
  const MainTabModified = 'MainTabModified';
3089
+ const MainTabPreview = 'MainTabPreview';
3026
3090
  const MainTabSelected = 'MainTabSelected';
3027
3091
 
3028
3092
  const newFile = async state => {
@@ -3085,6 +3149,7 @@ const newFile = async state => {
3085
3149
  icon: '',
3086
3150
  id: tabId,
3087
3151
  isDirty: false,
3152
+ isPreview: false,
3088
3153
  language: 'plaintext',
3089
3154
  loadingState: 'loading',
3090
3155
  title: 'Untitled',
@@ -3442,10 +3507,13 @@ const handleUriChange = async (state, oldUri, newUri) => {
3442
3507
  };
3443
3508
 
3444
3509
  const handleWorkspaceChange = state => {
3510
+ const {
3511
+ layout
3512
+ } = state;
3445
3513
  return {
3446
3514
  ...state,
3447
3515
  layout: {
3448
- ...state.layout,
3516
+ ...layout,
3449
3517
  activeGroupId: undefined,
3450
3518
  groups: []
3451
3519
  }
@@ -3475,7 +3543,7 @@ const initialize = async () => {
3475
3543
  };
3476
3544
 
3477
3545
  const isValidTab = tab => {
3478
- return tab && typeof tab.id === 'number' && typeof tab.title === 'string' && typeof tab.isDirty === 'boolean' && typeof tab.editorUid === 'number' && typeof tab.icon === 'string' && (tab.editorType === 'text' || tab.editorType === 'custom');
3546
+ return tab && typeof tab.id === 'number' && typeof tab.title === 'string' && typeof tab.isDirty === 'boolean' && typeof tab.isPreview === 'boolean' && typeof tab.editorUid === 'number' && typeof tab.icon === 'string' && (tab.editorType === 'text' || tab.editorType === 'custom');
3479
3547
  };
3480
3548
 
3481
3549
  const isValidEditorGroup = group => {
@@ -3512,23 +3580,31 @@ const tryRestoreLayout = savedState => {
3512
3580
  const {
3513
3581
  layout
3514
3582
  } = savedState;
3515
- if (!isValidMainAreaLayout(layout)) {
3583
+ if (!layout || typeof layout !== 'object') {
3584
+ return undefined;
3585
+ }
3586
+ const rawLayout = layout;
3587
+ if (!Array.isArray(rawLayout.groups)) {
3516
3588
  return undefined;
3517
3589
  }
3518
3590
 
3519
3591
  // Normalize all tabs to have editorUid: -1 so SelectTab will create viewlets
3520
3592
  // Mark all restored tabs as not dirty
3521
3593
  const normalizedLayout = {
3522
- ...layout,
3523
- groups: layout.groups.map(group => ({
3594
+ ...rawLayout,
3595
+ groups: rawLayout.groups.map(group => ({
3524
3596
  ...group,
3525
- tabs: group.tabs.map(tab => ({
3597
+ tabs: Array.isArray(group?.tabs) ? group.tabs.map(tab => ({
3526
3598
  ...tab,
3527
3599
  editorUid: -1,
3528
- isDirty: false
3529
- }))
3600
+ isDirty: false,
3601
+ isPreview: typeof tab?.isPreview === 'boolean' ? tab.isPreview : false
3602
+ })) : []
3530
3603
  }))
3531
3604
  };
3605
+ if (!isValidMainAreaLayout(normalizedLayout)) {
3606
+ return undefined;
3607
+ }
3532
3608
  return normalizedLayout;
3533
3609
  };
3534
3610
 
@@ -3817,6 +3893,28 @@ const getMenuEntries = async (state, props) => {
3817
3893
  }
3818
3894
  };
3819
3895
 
3896
+ const openUris = async (state, uris) => {
3897
+ if (uris.length === 0) {
3898
+ return state;
3899
+ }
3900
+ if (uris.length === 1) {
3901
+ return openUri(state, uris[0]);
3902
+ }
3903
+ let currentState = await openUri(state, uris[0]);
3904
+ const firstTab = findTabByUri(currentState, uris[0]);
3905
+ for (const uri of uris.slice(1)) {
3906
+ const existingTab = findTabByUri(currentState, uri);
3907
+ if (existingTab) {
3908
+ continue;
3909
+ }
3910
+ currentState = ensureActiveGroup(currentState, uri);
3911
+ }
3912
+ if (!firstTab) {
3913
+ return currentState;
3914
+ }
3915
+ return switchTab(currentState, firstTab.groupId, firstTab.tab.id);
3916
+ };
3917
+
3820
3918
  const refresh = state => {
3821
3919
  return {
3822
3920
  ...state
@@ -4169,7 +4267,8 @@ const renderError = errorMessage => {
4169
4267
  }, text(`Error: ${errorMessage}`), {
4170
4268
  childCount: 1,
4171
4269
  className: `${Button} ${ButtonSecondary}`,
4172
- 'data-action': 'retry-open',
4270
+ 'data-action': RetryOpen,
4271
+ name: RetryOpen,
4173
4272
  onClick: HandleClickAction,
4174
4273
  type: Button$2
4175
4274
  }, text('Retry')];
@@ -4261,6 +4360,9 @@ const renderTab = (tab, isActive, tabIndex, groupIndex) => {
4261
4360
  if (tab.isDirty) {
4262
4361
  className += ' ' + MainTabModified;
4263
4362
  }
4363
+ if (tab.isPreview) {
4364
+ className += ' ' + MainTabPreview;
4365
+ }
4264
4366
  return [{
4265
4367
  'aria-selected': isActive,
4266
4368
  childCount: 3,
@@ -4313,9 +4415,9 @@ const renderEditorGroupActions = (group, groupIndex, splitButtonEnabled) => {
4313
4415
  ariaLabel: 'Preview',
4314
4416
  childCount: 1,
4315
4417
  className: IconButton,
4316
- 'data-action': 'toggle-preview',
4418
+ 'data-action': TogglePreview$1,
4317
4419
  'data-groupId': String(group.id),
4318
- name: 'toggle-preview',
4420
+ name: TogglePreview$1,
4319
4421
  onClick: HandleClickAction,
4320
4422
  title: togglePreview(),
4321
4423
  type: Button$2
@@ -4329,8 +4431,9 @@ const renderEditorGroupActions = (group, groupIndex, splitButtonEnabled) => {
4329
4431
  buttons.push({
4330
4432
  childCount: 1,
4331
4433
  className: EditorGroupActionButton + ' ' + SplitEditorGroupButton,
4332
- 'data-action': 'split-right',
4434
+ 'data-action': SplitRight,
4333
4435
  'data-groupId': String(group.id),
4436
+ name: SplitRight,
4334
4437
  onClick: HandleClickAction,
4335
4438
  title: splitEditorGroup(),
4336
4439
  type: Button$2
@@ -4363,7 +4466,7 @@ const renderEmptyGroupCloseButton = (group, groupIndex) => {
4363
4466
  childCount: 1,
4364
4467
  className: EmptyGroupCloseButton,
4365
4468
  'data-groupId': String(group.id),
4366
- name: 'close-group',
4469
+ name: CloseGroup,
4367
4470
  onClick: HandleClickAction,
4368
4471
  title: closeEditorGroup(),
4369
4472
  type: Button$2
@@ -4723,6 +4826,7 @@ const commandMap = {
4723
4826
  'MainArea.loadContent': wrapCommand(loadContent),
4724
4827
  'MainArea.newFile': wrapCommand(newFile),
4725
4828
  'MainArea.openUri': wrapCommand(openUri),
4829
+ 'MainArea.openUris': wrapCommand(openUris),
4726
4830
  'MainArea.refresh': wrapCommand(refresh),
4727
4831
  'MainArea.render2': render2,
4728
4832
  'MainArea.renderEventListeners': renderEventListeners,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-area-worker",
3
- "version": "8.13.0",
3
+ "version": "8.15.0",
4
4
  "description": "Main Area Worker",
5
5
  "repository": {
6
6
  "type": "git",