@lvce-editor/title-bar-worker 4.2.0 → 4.3.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.
@@ -1391,13 +1391,13 @@ const create$1 = () => {
1391
1391
  },
1392
1392
  diff(uid, modules, numbers) {
1393
1393
  const {
1394
- newState,
1395
- oldState
1394
+ oldState,
1395
+ scheduledState
1396
1396
  } = states[uid];
1397
1397
  const diffResult = [];
1398
1398
  for (let i = 0; i < modules.length; i++) {
1399
1399
  const fn = modules[i];
1400
- if (!fn(oldState, newState)) {
1400
+ if (!fn(oldState, scheduledState)) {
1401
1401
  diffResult.push(numbers[i]);
1402
1402
  }
1403
1403
  }
@@ -1415,17 +1415,16 @@ const create$1 = () => {
1415
1415
  return ids;
1416
1416
  },
1417
1417
  getKeys() {
1418
- return Object.keys(states).map(key => {
1419
- return Number.parseFloat(key);
1420
- });
1418
+ return Object.keys(states).map(Number);
1421
1419
  },
1422
1420
  registerCommands(commandMap) {
1423
1421
  Object.assign(commandMapRef, commandMap);
1424
1422
  },
1425
- set(uid, oldState, newState) {
1423
+ set(uid, oldState, newState, scheduledState) {
1426
1424
  states[uid] = {
1427
1425
  newState,
1428
- oldState
1426
+ oldState,
1427
+ scheduledState: scheduledState ?? newState
1429
1428
  };
1430
1429
  },
1431
1430
  wrapCommand(fn) {
@@ -1445,7 +1444,8 @@ const create$1 = () => {
1445
1444
  };
1446
1445
  states[uid] = {
1447
1446
  newState: latestNew,
1448
- oldState: latestOld.oldState
1447
+ oldState: latestOld.oldState,
1448
+ scheduledState: latestNew
1449
1449
  };
1450
1450
  };
1451
1451
  return wrapped;
@@ -1482,7 +1482,8 @@ const create$1 = () => {
1482
1482
  };
1483
1483
  states[uid] = {
1484
1484
  newState: latestNew,
1485
- oldState: latestOld.oldState
1485
+ oldState: latestOld.oldState,
1486
+ scheduledState: latestNew
1486
1487
  };
1487
1488
  return {
1488
1489
  error
@@ -1502,6 +1503,7 @@ const Remote = 3;
1502
1503
 
1503
1504
  const DEFAULT_UID = 1;
1504
1505
  const DEFAULT_APP_NAME = 'Lvce Editor';
1506
+ const DEFAULT_MAIN_AREA_UID$1 = 2;
1505
1507
  const createDefaultState = (uid = DEFAULT_UID) => ({
1506
1508
  appName: DEFAULT_APP_NAME,
1507
1509
  assetDir: '',
@@ -1520,6 +1522,7 @@ const createDefaultState = (uid = DEFAULT_UID) => ({
1520
1522
  labelLetterSpacing: 0,
1521
1523
  labelPadding: 8,
1522
1524
  layoutControlsEnabled: false,
1525
+ mainAreaUid: DEFAULT_MAIN_AREA_UID$1,
1523
1526
  menus: [],
1524
1527
  platform: Electron,
1525
1528
  title: '',
@@ -1858,6 +1861,14 @@ const getMenuIds = () => {
1858
1861
  return [Edit$2, File$3, Go$2, Help$3, OpenRecent$1, Run$2, Selection$2, Terminal$2, TitleBar$3, View$2, MenuIdTitleBarContextMenu, TitleBarContextMenu];
1859
1862
  };
1860
1863
 
1864
+ const hasActiveTextEditor = async mainAreaUid => {
1865
+ try {
1866
+ return await invoke('Main.hasActiveTextEditor', mainAreaUid);
1867
+ } catch {
1868
+ return false;
1869
+ }
1870
+ };
1871
+
1861
1872
  const getMenuEntries$e = () => {
1862
1873
  return [];
1863
1874
  };
@@ -1980,6 +1991,7 @@ const getMenuEntries$c = () => {
1980
1991
  * @enum {string}
1981
1992
  */
1982
1993
  const UiStrings = {
1994
+ AutoSave: 'Auto Save',
1983
1995
  Exit: 'Exit',
1984
1996
  NewFile: 'New File',
1985
1997
  NewWindow: 'New Window',
@@ -1988,6 +2000,9 @@ const UiStrings = {
1988
2000
  OpenRecent: 'Open Recent',
1989
2001
  Save: 'Save',
1990
2002
  SaveAll: 'Save All'};
2003
+ const autoSave = () => {
2004
+ return i18nString(UiStrings.AutoSave);
2005
+ };
1991
2006
  const newFile = () => {
1992
2007
  return i18nString(UiStrings.NewFile);
1993
2008
  };
@@ -2024,7 +2039,25 @@ const Terminal = 14;
2024
2039
  const TitleBar$1 = 15;
2025
2040
  const View = 16;
2026
2041
 
2027
- const getMenuEntries$b = platform => {
2042
+ const getAutoSave = async () => {
2043
+ try {
2044
+ return await invoke('Preferences.get', 'files.autoSave');
2045
+ } catch {
2046
+ return 'off';
2047
+ }
2048
+ };
2049
+ const isAutoSaveEnabled = autoSave => {
2050
+ return autoSave !== 'off';
2051
+ };
2052
+ const getSaveFlags = hasActiveTextEditor => {
2053
+ if (hasActiveTextEditor) {
2054
+ return None;
2055
+ }
2056
+ return Disabled;
2057
+ };
2058
+ const getMenuEntries$b = async (platform, autoSave$1, hasActiveTextEditor = false) => {
2059
+ const autoSaveValue = autoSave$1 ?? (await getAutoSave());
2060
+ const saveFlags = getSaveFlags(hasActiveTextEditor);
2028
2061
  const entries = [{
2029
2062
  command: 'Main.newFile',
2030
2063
  flags: None,
@@ -2052,14 +2085,19 @@ const getMenuEntries$b = platform => {
2052
2085
  label: openRecent()
2053
2086
  }, menuEntrySeparator, {
2054
2087
  command: 'Main.save',
2055
- flags: None,
2088
+ flags: saveFlags,
2056
2089
  id: 'save',
2057
2090
  label: save()
2058
2091
  }, {
2059
2092
  command: 'Main.saveAll',
2060
- flags: None,
2093
+ flags: saveFlags,
2061
2094
  id: 'saveAll',
2062
2095
  label: saveAll()
2096
+ }, menuEntrySeparator, {
2097
+ command: 'Preferences.toggleAutoSave',
2098
+ flags: isAutoSaveEnabled(autoSaveValue) ? Checked : Unchecked,
2099
+ id: 'autoSave',
2100
+ label: autoSave()
2063
2101
  }];
2064
2102
  if (platform === Electron) {
2065
2103
  entries.push(menuEntrySeparator, {
@@ -2113,20 +2151,37 @@ const getMenuEntries$9 = async platform => {
2113
2151
  return entries;
2114
2152
  };
2115
2153
 
2116
- const getRecentlyOpened = () => {
2117
- return invoke(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
2118
- };
2119
-
2120
- const File = 'file://';
2121
-
2122
- const getTitle$1 = (homeDir, uri) => {
2123
- if (!uri) {
2154
+ const DriveLetterProtocolRegex = /^[a-zA-Z]:$/;
2155
+ const normalizeUri = value => {
2156
+ try {
2157
+ const url = new URL(value);
2158
+ if (DriveLetterProtocolRegex.test(url.protocol)) {
2159
+ return '';
2160
+ }
2161
+ return url.href;
2162
+ } catch {
2124
2163
  return '';
2125
2164
  }
2126
- if (uri.startsWith(File)) {
2127
- return uri.slice(File.length);
2165
+ };
2166
+ const getRecentlyOpened = async () => {
2167
+ const recentlyOpened = await invoke(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
2168
+ if (!Array.isArray(recentlyOpened)) {
2169
+ return [];
2128
2170
  }
2129
- return uri;
2171
+ const seen = new Set();
2172
+ const uniqueUris = [];
2173
+ for (const item of recentlyOpened) {
2174
+ if (typeof item !== 'string') {
2175
+ continue;
2176
+ }
2177
+ const uri = normalizeUri(item);
2178
+ if (!uri || seen.has(uri)) {
2179
+ continue;
2180
+ }
2181
+ seen.add(uri);
2182
+ uniqueUris.push(uri);
2183
+ }
2184
+ return uniqueUris;
2130
2185
  };
2131
2186
 
2132
2187
  const moreDot = () => {
@@ -2136,13 +2191,43 @@ const clearRecentlyOpened = () => {
2136
2191
  return i18nString(ClearRecentlyOpened);
2137
2192
  };
2138
2193
 
2139
- const getHomeDir = () => {
2140
- return '';
2194
+ const File = 'file://';
2195
+
2196
+ const HomeDirRegex = /^\/(?:home|Users)\/[^/]+/;
2197
+ const startsWithHomeDir = (homeDir, path) => {
2198
+ return path === homeDir || path.startsWith(`${homeDir}/`);
2199
+ };
2200
+ const getPath = uri => {
2201
+ if (uri.startsWith(File)) {
2202
+ return uri.slice(File.length);
2203
+ }
2204
+ return uri;
2205
+ };
2206
+ const getHomeDir = uri => {
2207
+ const path = getPath(uri);
2208
+ const match = HomeDirRegex.exec(path);
2209
+ return match?.[0] || '';
2210
+ };
2211
+ const getTitle$1 = (homeDir, uri) => {
2212
+ if (!uri) {
2213
+ return '';
2214
+ }
2215
+ const path = getPath(uri);
2216
+ if (path !== uri) {
2217
+ if (homeDir && startsWithHomeDir(homeDir, path)) {
2218
+ return `~${path.slice(homeDir.length)}`;
2219
+ }
2220
+ return path;
2221
+ }
2222
+ // TODO tree shake this out in web
2223
+ if (homeDir && startsWithHomeDir(homeDir, uri)) {
2224
+ return `~${uri.slice(homeDir.length)}`;
2225
+ }
2226
+ return uri;
2141
2227
  };
2142
2228
 
2143
- const MAX_MENU_RECENT_ENTRIES = 10;
2144
2229
  const toMenuItem = folder => {
2145
- const homeDir = getHomeDir();
2230
+ const homeDir = getHomeDir(folder);
2146
2231
  const label = getTitle$1(homeDir, folder);
2147
2232
  return {
2148
2233
  args: [folder],
@@ -2151,6 +2236,8 @@ const toMenuItem = folder => {
2151
2236
  label
2152
2237
  };
2153
2238
  };
2239
+
2240
+ const MAX_MENU_RECENT_ENTRIES = 10;
2154
2241
  const getMenuEntries$8 = async () => {
2155
2242
  const allItems = await getRecentlyOpened();
2156
2243
  const itemsToShow = allItems.slice(0, MAX_MENU_RECENT_ENTRIES);
@@ -2429,12 +2516,13 @@ const getMenuEntries$1 = () => {
2429
2516
  }];
2430
2517
  };
2431
2518
 
2519
+ const DEFAULT_MAIN_AREA_UID = 2;
2432
2520
  const getMenuEntries2 = async (state, props) => {
2433
2521
  switch (props.menuId) {
2434
2522
  case Edit$2:
2435
2523
  return getMenuEntries$d();
2436
2524
  case File$3:
2437
- return getMenuEntries$b(props.platform);
2525
+ return getMenuEntries$b(props.platform, undefined, await hasActiveTextEditor(state.mainAreaUid ?? DEFAULT_MAIN_AREA_UID));
2438
2526
  case Go$2:
2439
2527
  return getMenuEntries$a();
2440
2528
  case Help$3:
@@ -2860,14 +2948,7 @@ const CONTEXT_MENU_PADDING = 8;
2860
2948
  const getMenuHeight = items => {
2861
2949
  let height = CONTEXT_MENU_PADDING;
2862
2950
  for (const item of items) {
2863
- switch (item.flags) {
2864
- case Separator$1:
2865
- height += CONTEXT_MENU_SEPARATOR_HEIGHT;
2866
- break;
2867
- default:
2868
- height += CONTEXT_MENU_ITEM_HEIGHT;
2869
- break;
2870
- }
2951
+ height += item.flags === Separator$1 ? CONTEXT_MENU_SEPARATOR_HEIGHT : CONTEXT_MENU_ITEM_HEIGHT;
2871
2952
  }
2872
2953
  return height;
2873
2954
  };
@@ -2912,7 +2993,7 @@ const getIndexToFocusPreviousStartingAt = (items, startIndex) => {
2912
2993
  return -1;
2913
2994
  };
2914
2995
  const getIndexToFocusPrevious = menu => {
2915
- const startIndex = menu.focusedIndex === -1 ? menu.items.length - 1 : menu.focusedIndex - 1;
2996
+ const startIndex = (menu.focusedIndex === -1 ? menu.items.length : menu.focusedIndex) - 1;
2916
2997
  return getIndexToFocusPreviousStartingAt(menu.items, startIndex);
2917
2998
  };
2918
2999
  const canBeFocused = item => {
@@ -3089,7 +3170,7 @@ const handleTitleBarContextMenu = async state => {
3089
3170
  * @returns The parsed title string
3090
3171
  */
3091
3172
  const parseTitleTemplate = (template, folderName, appName) => {
3092
- return template.replaceAll('${folderName}', folderName).replaceAll('${appName}', appName);
3173
+ return template.replaceAll('${folderName}', () => folderName).replaceAll('${appName}', () => appName);
3093
3174
  };
3094
3175
 
3095
3176
  const getTitle = (workspaceUri, titleTemplate, appName) => {
@@ -3234,7 +3315,7 @@ const loadContent2 = async state => {
3234
3315
 
3235
3316
  // TODO load preferences here
3236
3317
 
3237
- if (titleBarStyleCustom === false && platform === Electron$1) {
3318
+ if (!titleBarStyleCustom && platform === Electron$1) {
3238
3319
  return hydrate(state);
3239
3320
  }
3240
3321
  return {
@@ -3894,7 +3975,7 @@ const next = (items, index) => {
3894
3975
  return (index + 1) % items.length;
3895
3976
  };
3896
3977
  const previous = (items, index) => {
3897
- return index === 0 ? items.length - 1 : index - 1;
3978
+ return (index === 0 ? items.length : index) - 1;
3898
3979
  };
3899
3980
 
3900
3981
  const focusFirst = state => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/title-bar-worker",
3
- "version": "4.2.0",
3
+ "version": "4.3.0",
4
4
  "description": "Title Bar Worker",
5
5
  "repository": {
6
6
  "type": "git",