@lvce-editor/main-area-worker 5.13.0 → 6.0.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.
@@ -1576,6 +1576,7 @@ const closeTab = (state, groupId, tabId) => {
1576
1576
  return {
1577
1577
  ...grp,
1578
1578
  activeTabId: newActiveTabId,
1579
+ isEmpty: newTabs.length === 0,
1579
1580
  tabs: newTabs
1580
1581
  };
1581
1582
  }
@@ -1705,10 +1706,41 @@ const handleClick = async (state, name) => {
1705
1706
  return state;
1706
1707
  };
1707
1708
 
1709
+ const closeEditorGroup = (state, groupId) => {
1710
+ const {
1711
+ layout
1712
+ } = state;
1713
+ const {
1714
+ activeGroupId,
1715
+ groups
1716
+ } = layout;
1717
+ const groupIndex = groups.findIndex(group => group.id === groupId);
1718
+ if (groupIndex === -1 || groups.length <= 1) {
1719
+ return state;
1720
+ }
1721
+ const remainingGroups = groups.filter(group => group.id !== groupId);
1722
+ const baseSize = Math.floor(100 / remainingGroups.length);
1723
+ const remainder = 100 % remainingGroups.length;
1724
+ const redistributedGroups = remainingGroups.map((group, index) => ({
1725
+ ...group,
1726
+ size: baseSize + (index === remainingGroups.length - 1 ? remainder : 0)
1727
+ }));
1728
+ const newActiveGroupId = activeGroupId === groupId ? remainingGroups[0].id : activeGroupId;
1729
+ return {
1730
+ ...state,
1731
+ layout: {
1732
+ ...layout,
1733
+ activeGroupId: newActiveGroupId,
1734
+ groups: redistributedGroups
1735
+ }
1736
+ };
1737
+ };
1738
+
1708
1739
  const getActiveGroup = (groups, activeGroupId) => {
1709
1740
  return groups.find(g => g.id === activeGroupId);
1710
1741
  };
1711
1742
 
1743
+ const Left = 'left';
1712
1744
  const Right = 'right';
1713
1745
 
1714
1746
  const splitEditorGroup$1 = (state, groupId, direction) => {
@@ -1723,7 +1755,7 @@ const splitEditorGroup$1 = (state, groupId, direction) => {
1723
1755
  return state;
1724
1756
  }
1725
1757
  const newGroupId = create$1();
1726
- const isHorizontalSplit = direction === Right;
1758
+ const isHorizontalSplit = direction === Left || direction === Right;
1727
1759
  const newLayoutDirection = isHorizontalSplit ? 'horizontal' : 'vertical';
1728
1760
  const updatedGroups = groups.map(group => {
1729
1761
  if (group.id === groupId) {
@@ -1739,12 +1771,16 @@ const splitEditorGroup$1 = (state, groupId, direction) => {
1739
1771
  activeTabId: undefined,
1740
1772
  focused: true,
1741
1773
  id: newGroupId,
1774
+ isEmpty: true,
1742
1775
  size: 50,
1743
1776
  tabs: []
1744
1777
  };
1745
1778
  let reorderedGroups;
1746
- {
1779
+ if (direction === Right || direction === 'down') {
1747
1780
  reorderedGroups = [...updatedGroups, newGroup];
1781
+ } else {
1782
+ const sourceIndex = updatedGroups.findIndex(group => group.id === groupId);
1783
+ reorderedGroups = [...updatedGroups.slice(0, sourceIndex), newGroup, ...updatedGroups.slice(sourceIndex)];
1748
1784
  }
1749
1785
  return {
1750
1786
  ...state,
@@ -1756,15 +1792,26 @@ const splitEditorGroup$1 = (state, groupId, direction) => {
1756
1792
  };
1757
1793
  };
1758
1794
 
1759
- const handleClickAction = async (state, action) => {
1795
+ const handleClickAction = async (state, action, rawGroupId) => {
1760
1796
  if (!action) {
1761
1797
  return state;
1762
1798
  }
1799
+ if (state.layout.activeGroupId === undefined) {
1800
+ return state;
1801
+ }
1763
1802
  const activeGroup = getActiveGroup(state.layout.groups, state.layout.activeGroupId);
1764
1803
  if (!activeGroup) {
1765
1804
  return state;
1766
1805
  }
1767
1806
  switch (action) {
1807
+ case 'close-group':
1808
+ if (rawGroupId) {
1809
+ const groupId = Number.parseInt(rawGroupId, 10);
1810
+ if (!Number.isNaN(groupId)) {
1811
+ return closeEditorGroup(state, groupId);
1812
+ }
1813
+ }
1814
+ return state;
1768
1815
  case 'split-right':
1769
1816
  return splitEditorGroup$1(state, activeGroup.id, Right);
1770
1817
  default:
@@ -1948,56 +1995,52 @@ const selectTab = async (state, groupIndex, index) => {
1948
1995
 
1949
1996
  // If new tab's viewlet isn't ready yet, trigger creation (idempotent)
1950
1997
  const newTab = newState.layout.groups[groupIndex].tabs[index];
1951
- if (!newTab.loadingState || newTab.loadingState === 'loading') {
1952
- try {
1953
- // Query RendererWorker for viewlet module ID
1954
- // @ts-ignore
1955
- const viewletModuleId = await invoke('Layout.getModuleId', newTab.uri);
1956
- if (viewletModuleId) {
1957
- // Calculate bounds: use main area bounds minus 35px for tab height
1958
- const TAB_HEIGHT = 35;
1959
- const bounds = {
1960
- height: newState.height - TAB_HEIGHT,
1961
- width: newState.width,
1962
- x: newState.x,
1963
- y: newState.y + TAB_HEIGHT
1964
- };
1965
- const createdState = createViewletForTab(newState, tabId, viewletModuleId, bounds);
1966
- newState = createdState;
1998
+ if (newTab.uri && (!newTab.loadingState || newTab.loadingState === 'loading')) {
1999
+ // Query RendererWorker for viewlet module ID
2000
+ // @ts-ignore
2001
+ const viewletModuleId = await invoke('Layout.getModuleId', newTab.uri);
2002
+ if (viewletModuleId) {
2003
+ // Calculate bounds: use main area bounds minus 35px for tab height
2004
+ const TAB_HEIGHT = 35;
2005
+ const bounds = {
2006
+ height: newState.height - TAB_HEIGHT,
2007
+ width: newState.width,
2008
+ x: newState.x,
2009
+ y: newState.y + TAB_HEIGHT
2010
+ };
2011
+ const createdState = createViewletForTab(newState, tabId);
2012
+ newState = createdState;
1967
2013
 
1968
- // Store updated state before creating viewlet
1969
- set(uid, state, newState);
2014
+ // Store updated state before creating viewlet
2015
+ set(uid, state, newState);
1970
2016
 
1971
- // Execute viewlet commands if any
1972
- if (switchCommands.length > 0) {
1973
- await executeViewletCommands(switchCommands);
1974
- }
2017
+ // Execute viewlet commands if any
2018
+ if (switchCommands.length > 0) {
2019
+ await executeViewletCommands(switchCommands);
2020
+ }
1975
2021
 
1976
- // Get the tab to extract editorUid for viewlet creation
1977
- const tabWithViewlet = findTabById(newState, tabId);
1978
- if (tabWithViewlet) {
1979
- const {
1980
- editorUid
1981
- } = tabWithViewlet.tab;
1982
- if (editorUid !== -1 && newTab.uri) {
1983
- // Create the actual viewlet instance
1984
- await createViewlet(viewletModuleId, editorUid, tabId, bounds, newTab.uri);
1985
-
1986
- // Mark viewlet as ready
1987
- newState = handleViewletReady(newState, editorUid);
1988
- set(uid, state, newState);
1989
- }
2022
+ // Get the tab to extract editorUid for viewlet creation
2023
+ const tabWithViewlet = findTabById(newState, tabId);
2024
+ if (tabWithViewlet) {
2025
+ const {
2026
+ editorUid
2027
+ } = tabWithViewlet.tab;
2028
+ if (editorUid !== -1 && newTab.uri) {
2029
+ // Create the actual viewlet instance
2030
+ await createViewlet(viewletModuleId, editorUid, tabId, bounds, newTab.uri);
2031
+
2032
+ // Mark viewlet as ready
2033
+ newState = handleViewletReady(newState, editorUid);
2034
+ set(uid, state, newState);
1990
2035
  }
2036
+ }
1991
2037
 
1992
- // Start loading content in the background if needed
1993
- if (needsLoading && tab.uri) {
1994
- const latestState = await startContentLoading(state, newState, tabId, tab.uri, requestId);
1995
- return latestState;
1996
- }
1997
- return newState;
2038
+ // Start loading content in the background if needed
2039
+ if (needsLoading && tab.uri) {
2040
+ const latestState = await startContentLoading(state, newState, tabId, tab.uri, requestId);
2041
+ return latestState;
1998
2042
  }
1999
- } catch {
2000
- // Viewlet creation is optional - silently ignore if RendererWorker isn't available
2043
+ return newState;
2001
2044
  }
2002
2045
  }
2003
2046
  set(uid, state, newState);
@@ -2024,6 +2067,44 @@ const handleClickTab = async (state, groupIndexRaw, indexRaw) => {
2024
2067
  return selectTab(state, groupIndex, index);
2025
2068
  };
2026
2069
 
2070
+ const handleResize = async (state, x, y, width, height) => {
2071
+ number(x);
2072
+ number(y);
2073
+ number(width);
2074
+ number(height);
2075
+ const newState = {
2076
+ ...state,
2077
+ height,
2078
+ width,
2079
+ x,
2080
+ y
2081
+ };
2082
+
2083
+ // Resize all editor children to their new bounds
2084
+ const {
2085
+ layout,
2086
+ tabHeight
2087
+ } = state;
2088
+ const {
2089
+ groups
2090
+ } = layout;
2091
+ const contentHeight = height - tabHeight;
2092
+ for (const group of groups) {
2093
+ for (const tab of group.tabs) {
2094
+ if (tab.editorUid !== -1) {
2095
+ // @ts-ignore
2096
+ await invoke('Viewlet.setBounds', tab.editorUid, {
2097
+ height: contentHeight,
2098
+ width,
2099
+ x,
2100
+ y: y + tabHeight
2101
+ });
2102
+ }
2103
+ }
2104
+ }
2105
+ return newState;
2106
+ };
2107
+
2027
2108
  const show2 = async (uid, menuId, x, y, args) => {
2028
2109
  await showContextMenu2(uid, menuId, x, y, args);
2029
2110
  };
@@ -2078,7 +2159,7 @@ const isValidTab = tab => {
2078
2159
  };
2079
2160
 
2080
2161
  const isValidEditorGroup = group => {
2081
- return group && typeof group.id === 'number' && Array.isArray(group.tabs) && group.tabs.every(isValidTab) && (group.activeTabId === undefined || typeof group.activeTabId === 'number') && typeof group.focused === 'boolean' && typeof group.size === 'number' && group.size > 0;
2162
+ return group && typeof group.id === 'number' && Array.isArray(group.tabs) && group.tabs.every(isValidTab) && (group.activeTabId === undefined || typeof group.activeTabId === 'number') && typeof group.focused === 'boolean' && typeof group.size === 'number' && group.size > 0 && typeof group.isEmpty === 'boolean';
2082
2163
  };
2083
2164
 
2084
2165
  const isValidMainAreaLayout = layout => {
@@ -2540,6 +2621,7 @@ const createEmptyGroup = (state, uri, requestId) => {
2540
2621
  activeTabId: newTab.id,
2541
2622
  focused: true,
2542
2623
  id: groupId,
2624
+ isEmpty: false,
2543
2625
  size: 100,
2544
2626
  tabs: [newTab]
2545
2627
  };
@@ -2566,10 +2648,12 @@ const openTab = (state, groupId, tab) => {
2566
2648
  } = layout;
2567
2649
  const updatedGroups = groups.map(group => {
2568
2650
  if (group.id === groupId) {
2651
+ const newTabs = [...group.tabs, newTab];
2569
2652
  return {
2570
2653
  ...group,
2571
2654
  activeTabId: newTab.id,
2572
- tabs: [...group.tabs, newTab]
2655
+ isEmpty: newTabs.length === 0,
2656
+ tabs: newTabs
2573
2657
  };
2574
2658
  }
2575
2659
  return group;
@@ -3363,7 +3447,7 @@ const renderEventListeners = () => {
3363
3447
  preventDefault: true
3364
3448
  }, {
3365
3449
  name: HandleClickAction,
3366
- params: ['handleClickAction', 'event.target.dataset.action']
3450
+ params: ['handleClickAction', 'event.target.dataset.action', 'event.target.dataset.groupId']
3367
3451
  }];
3368
3452
  };
3369
3453
 
@@ -3421,6 +3505,76 @@ const saveState = state => {
3421
3505
  };
3422
3506
  };
3423
3507
 
3508
+ const splitDown = (state, groupId) => {
3509
+ const {
3510
+ layout
3511
+ } = state;
3512
+ const {
3513
+ groups
3514
+ } = layout;
3515
+
3516
+ // If there are no groups, create an initial empty group first
3517
+ if (groups.length === 0) {
3518
+ const initialGroupId = create$1();
3519
+ const initialGroup = {
3520
+ activeTabId: undefined,
3521
+ focused: true,
3522
+ id: initialGroupId,
3523
+ isEmpty: true,
3524
+ size: 100,
3525
+ tabs: []
3526
+ };
3527
+ const stateWithInitialGroup = {
3528
+ ...state,
3529
+ layout: {
3530
+ ...layout,
3531
+ activeGroupId: initialGroupId,
3532
+ groups: [initialGroup]
3533
+ }
3534
+ };
3535
+ return splitEditorGroup$1(stateWithInitialGroup, initialGroupId, 'down');
3536
+ }
3537
+ const resolvedGroupId = groupId ?? state.layout.activeGroupId;
3538
+ if (!resolvedGroupId) {
3539
+ return state;
3540
+ }
3541
+ return splitEditorGroup$1(state, resolvedGroupId, 'down');
3542
+ };
3543
+
3544
+ const splitRight = (state, groupId) => {
3545
+ const {
3546
+ layout
3547
+ } = state;
3548
+ const {
3549
+ activeGroupId,
3550
+ groups
3551
+ } = layout;
3552
+
3553
+ // If there are no groups, create an initial empty group first
3554
+ if (groups.length === 0) {
3555
+ const initialGroupId = create$1();
3556
+ const initialGroup = {
3557
+ activeTabId: undefined,
3558
+ focused: true,
3559
+ id: initialGroupId,
3560
+ isEmpty: true,
3561
+ size: 100,
3562
+ tabs: []
3563
+ };
3564
+ const stateWithInitialGroup = {
3565
+ ...state,
3566
+ layout: {
3567
+ ...layout,
3568
+ activeGroupId: initialGroupId,
3569
+ groups: [initialGroup]
3570
+ }
3571
+ };
3572
+ return splitEditorGroup$1(stateWithInitialGroup, initialGroupId, Right);
3573
+ }
3574
+ const targetGroupId = groupId ?? activeGroupId ?? groups[0]?.id ?? 0;
3575
+ return splitEditorGroup$1(state, targetGroupId, Right);
3576
+ };
3577
+
3424
3578
  const commandMap = {
3425
3579
  'MainArea.closeAll': wrapCommand(closeAll$1),
3426
3580
  'MainArea.closeFocusedTab': wrapCommand(closeFocusedTab),
@@ -3433,6 +3587,7 @@ const commandMap = {
3433
3587
  'MainArea.handleClickAction': wrapCommand(handleClickAction),
3434
3588
  'MainArea.handleClickCloseTab': wrapCommand(handleClickCloseTab),
3435
3589
  'MainArea.handleClickTab': wrapCommand(handleClickTab),
3590
+ 'MainArea.handleResize': wrapCommand(handleResize),
3436
3591
  'MainArea.handleTabContextMenu': wrapCommand(handleTabContextMenu),
3437
3592
  'MainArea.handleWorkspaceChange': wrapCommand(handleWorkspaceChange),
3438
3593
  'MainArea.initialize': initialize,
@@ -3445,6 +3600,8 @@ const commandMap = {
3445
3600
  'MainArea.save': wrapCommand(save),
3446
3601
  'MainArea.saveState': wrapGetter(saveState),
3447
3602
  'MainArea.selectTab': wrapCommand(selectTab),
3603
+ 'MainArea.splitDown': wrapCommand(splitDown),
3604
+ 'MainArea.splitRight': wrapCommand(splitRight),
3448
3605
  'MainArea.terminate': terminate
3449
3606
  };
3450
3607
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-area-worker",
3
- "version": "5.13.0",
3
+ "version": "6.0.0",
4
4
  "description": "Main Area Worker",
5
5
  "repository": {
6
6
  "type": "git",