react-os-shell 0.1.10 → 0.1.11

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 (27) hide show
  1. package/dist/{Calculator-PTET7HM2.js → Calculator-IQQNLUEG.js} +4 -4
  2. package/dist/{Calculator-PTET7HM2.js.map → Calculator-IQQNLUEG.js.map} +1 -1
  3. package/dist/{Calendar-H6WA57K2.js → Calendar-B3L6PE3V.js} +3 -3
  4. package/dist/{Calendar-H6WA57K2.js.map → Calendar-B3L6PE3V.js.map} +1 -1
  5. package/dist/{CurrencyConverter-ZLZIO4TW.js → CurrencyConverter-5XMVYIYB.js} +4 -4
  6. package/dist/{CurrencyConverter-ZLZIO4TW.js.map → CurrencyConverter-5XMVYIYB.js.map} +1 -1
  7. package/dist/{Email-E3ZZUUON.js → Email-UQLMH622.js} +3 -3
  8. package/dist/{Email-E3ZZUUON.js.map → Email-UQLMH622.js.map} +1 -1
  9. package/dist/{Minesweeper-OBQCXZKI.js → Minesweeper-MD5ST4KN.js} +3 -3
  10. package/dist/{Minesweeper-OBQCXZKI.js.map → Minesweeper-MD5ST4KN.js.map} +1 -1
  11. package/dist/{Notepad-6L6BWIBG.js → Notepad-5VX7KKQS.js} +3 -3
  12. package/dist/{Notepad-6L6BWIBG.js.map → Notepad-5VX7KKQS.js.map} +1 -1
  13. package/dist/{PomodoroTimer-SDRN2GZD.js → PomodoroTimer-CVARINV5.js} +4 -4
  14. package/dist/{PomodoroTimer-SDRN2GZD.js.map → PomodoroTimer-CVARINV5.js.map} +1 -1
  15. package/dist/{Spreadsheet-N6CTEPJM.js → Spreadsheet-WHCIBSVA.js} +3 -3
  16. package/dist/{Spreadsheet-N6CTEPJM.js.map → Spreadsheet-WHCIBSVA.js.map} +1 -1
  17. package/dist/{Weather-QZJWPPUP.js → Weather-N6OWKTQ3.js} +4 -4
  18. package/dist/{Weather-QZJWPPUP.js.map → Weather-N6OWKTQ3.js.map} +1 -1
  19. package/dist/apps/index.js +9 -9
  20. package/dist/{chunk-ZR2DVGZI.js → chunk-CANJJID5.js} +37 -8
  21. package/dist/chunk-CANJJID5.js.map +1 -0
  22. package/dist/{chunk-4POBPSEW.js → chunk-WCA5UZYR.js} +3 -3
  23. package/dist/{chunk-4POBPSEW.js.map → chunk-WCA5UZYR.js.map} +1 -1
  24. package/dist/index.js +106 -48
  25. package/dist/index.js.map +1 -1
  26. package/package.json +1 -1
  27. package/dist/chunk-ZR2DVGZI.js.map +0 -1
package/dist/index.js CHANGED
@@ -7,8 +7,8 @@ export { toast_default as toast } from './chunk-WIJ45SYD.js';
7
7
  import { playStartup, soundsEnabled, getSoundConfig, SOUND_PACK_KEYS, SOUND_PACKS, SOUND_TYPES, SOUND_TYPE_LABELS, playLogout, setSoundForType, previewSound, setAllSounds } from './chunk-D7PYW2QS.js';
8
8
  import { useShellPrefs } from './chunk-TFGOLXGD.js';
9
9
  export { ShellPrefsProvider, useLocalStoragePrefs, useShellPrefs } from './chunk-TFGOLXGD.js';
10
- import { useWindowManager, glassStyle, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons, ModalActions, useModalActive } from './chunk-ZR2DVGZI.js';
11
- export { CancelButton, CopyButton, DocFavStar, GLASS_DIVIDER, GLASS_INPUT_BG, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, glassStyle, isEntityEntry, isPageEntry, setShellApiClient, setShellNavIcons, setShellWindowRegistry, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-ZR2DVGZI.js';
10
+ import { useWindowManager, glassStyle, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons, ModalActions, useModalActive } from './chunk-CANJJID5.js';
11
+ export { CancelButton, CopyButton, DocFavStar, GLASS_DIVIDER, GLASS_INPUT_BG, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, glassStyle, isEntityEntry, isPageEntry, setShellApiClient, setShellNavIcons, setShellWindowRegistry, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-CANJJID5.js';
12
12
  export { ConfirmProvider, confirm, confirmDestructive } from './chunk-RFTLYCSF.js';
13
13
  import { createContext, useState, useRef, useEffect, useCallback, useLayoutEffect, useContext, isValidElement, cloneElement, useSyncExternalStore } from 'react';
14
14
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -643,7 +643,7 @@ function StatusBadge({ status }) {
643
643
  }
644
644
 
645
645
  // src/version.ts
646
- var VERSION = "0.1.10" ;
646
+ var VERSION = "0.1.11" ;
647
647
  var APP_VERSION = VERSION;
648
648
 
649
649
  // src/changelog.ts
@@ -885,65 +885,107 @@ function Desktop({ profile }) {
885
885
  const desktopItems = favDocs.filter((d) => !d.folderId);
886
886
  const folderItems = (folderId) => favDocs.filter((d) => d.folderId === folderId);
887
887
  const [localPositions, setLocalPositions] = useState({});
888
- const dragElRef = useRef(null);
888
+ const dragEntriesRef = useRef([]);
889
889
  const startDrag = (type, idx, e) => {
890
890
  if (e.button !== 0) return;
891
- const items = type === "item" ? desktopItems : folders;
892
- const item = items[idx];
893
- const pos = type === "item" ? getItemPos(item, idx) : getFolderPos(item, idx);
894
- setDragging({ type, idx, startX: e.clientX, startY: e.clientY, origX: pos.right, origY: pos.top });
895
- dragElRef.current = e.target.closest("[data-desktop-icon]");
891
+ const primaryKey = `${type}-${idx}`;
892
+ const draggingMulti = selected.has(primaryKey) && selected.size > 1;
893
+ const keys = draggingMulti ? Array.from(selected) : [primaryKey];
894
+ const entries = [];
895
+ for (const key of keys) {
896
+ if (key.startsWith("item-")) {
897
+ const i = parseInt(key.slice(5), 10);
898
+ const itm = desktopItems[i];
899
+ if (!itm) continue;
900
+ const pos = getItemPos(itm, i);
901
+ const el = document.querySelector(`[data-desktop-icon="${key}"]`);
902
+ entries.push({ key, type: "item", idx: i, origX: pos.right, origY: pos.top, el });
903
+ } else if (key.startsWith("folder-")) {
904
+ const i = parseInt(key.slice(7), 10);
905
+ const f = folders[i];
906
+ if (!f) continue;
907
+ const pos = getFolderPos(f, i);
908
+ const el = document.querySelector(`[data-desktop-icon="${key}"]`);
909
+ entries.push({ key, type: "folder", idx: i, origX: pos.right, origY: pos.top, el });
910
+ }
911
+ }
912
+ dragEntriesRef.current = entries;
913
+ const primaryEntry = entries.find((e2) => e2.key === primaryKey) ?? entries[0];
914
+ if (!primaryEntry) return;
915
+ setDragging({ type, idx, startX: e.clientX, startY: e.clientY, origX: primaryEntry.origX, origY: primaryEntry.origY });
896
916
  e.preventDefault();
897
917
  };
898
918
  useEffect(() => {
899
919
  if (!dragging) return;
900
- const el = dragElRef.current;
920
+ const entries = dragEntriesRef.current;
901
921
  const move = (e) => {
902
- const nr = dragging.origX - (e.clientX - dragging.startX);
903
- const nt = dragging.origY + e.clientY - dragging.startY;
904
- if (el) {
905
- el.style.right = `${nr}px`;
906
- el.style.top = `${nt}px`;
907
- el.style.left = "auto";
908
- el.style.zIndex = "100";
909
- el.style.opacity = "0.7";
922
+ const dx = e.clientX - dragging.startX;
923
+ const dy = e.clientY - dragging.startY;
924
+ for (const entry of entries) {
925
+ if (!entry.el) continue;
926
+ entry.el.style.right = `${entry.origX - dx}px`;
927
+ entry.el.style.top = `${entry.origY + dy}px`;
928
+ entry.el.style.left = "auto";
929
+ entry.el.style.zIndex = "100";
930
+ entry.el.style.opacity = "0.7";
910
931
  }
911
932
  };
912
933
  const up = (e) => {
913
- let finalRight = dragging.origX - (e.clientX - dragging.startX);
914
- let finalTop = Math.max(0, dragging.origY + e.clientY - dragging.startY);
915
- if (snapEnabled) {
916
- const s = snapToGrid(finalRight, finalTop);
917
- finalRight = s.x;
918
- finalTop = s.y;
919
- }
920
- finalRight = Math.max(0, finalRight);
921
- if (el) {
922
- el.style.zIndex = "";
923
- el.style.opacity = "";
934
+ const dx = e.clientX - dragging.startX;
935
+ const dy = e.clientY - dragging.startY;
936
+ for (const entry of entries) {
937
+ if (!entry.el) continue;
938
+ entry.el.style.zIndex = "";
939
+ entry.el.style.opacity = "";
924
940
  }
925
- if (dragging.type === "item") {
926
- const droppedOnFolder = folders.find((f, fi) => {
927
- const fp = getFolderPos(f, fi);
928
- return Math.abs(finalRight - fp.right) < 40 && Math.abs(finalTop - fp.top) < 40;
929
- });
941
+ const computedPositions = entries.map((entry) => {
942
+ let finalRight = entry.origX - dx;
943
+ let finalTop = Math.max(0, entry.origY + dy);
944
+ if (snapEnabled) {
945
+ const s = snapToGrid(finalRight, finalTop);
946
+ finalRight = s.x;
947
+ finalTop = s.y;
948
+ }
949
+ finalRight = Math.max(0, finalRight);
950
+ return { entry, finalRight, finalTop };
951
+ });
952
+ const itemMoves = computedPositions.filter((p) => p.entry.type === "item");
953
+ if (itemMoves.length > 0) {
930
954
  const updated = [...favDocs];
931
- const desktopIdx = favDocs.indexOf(desktopItems[dragging.idx]);
932
- if (droppedOnFolder) {
933
- updated[desktopIdx] = { ...updated[desktopIdx], folderId: droppedOnFolder.id, x: void 0, y: void 0 };
934
- } else {
935
- updated[desktopIdx] = { ...updated[desktopIdx], x: finalRight, y: finalTop, folderId: void 0 };
936
- setLocalPositions((prev) => ({ ...prev, [`item-${desktopIdx}`]: { right: finalRight, top: finalTop } }));
955
+ const positionsPatch = {};
956
+ const singleItem = itemMoves.length === 1 && entries.length === 1 ? itemMoves[0] : null;
957
+ const droppedOnFolder = singleItem ? folders.find((f, fi) => {
958
+ const fp = getFolderPos(f, fi);
959
+ return Math.abs(singleItem.finalRight - fp.right) < 40 && Math.abs(singleItem.finalTop - fp.top) < 40;
960
+ }) : void 0;
961
+ for (const move2 of itemMoves) {
962
+ const desktopIdx = favDocs.indexOf(desktopItems[move2.entry.idx]);
963
+ if (desktopIdx === -1) continue;
964
+ if (droppedOnFolder) {
965
+ updated[desktopIdx] = { ...updated[desktopIdx], folderId: droppedOnFolder.id, x: void 0, y: void 0 };
966
+ } else {
967
+ updated[desktopIdx] = { ...updated[desktopIdx], x: move2.finalRight, y: move2.finalTop, folderId: void 0 };
968
+ positionsPatch[`item-${desktopIdx}`] = { right: move2.finalRight, top: move2.finalTop };
969
+ }
937
970
  }
938
971
  saveDocs(updated);
939
- } else {
972
+ if (Object.keys(positionsPatch).length > 0) {
973
+ setLocalPositions((prev) => ({ ...prev, ...positionsPatch }));
974
+ }
975
+ }
976
+ const folderMoves = computedPositions.filter((p) => p.entry.type === "folder");
977
+ if (folderMoves.length > 0) {
940
978
  const updated = [...folders];
941
- updated[dragging.idx] = { ...updated[dragging.idx], x: finalRight, y: finalTop };
942
- setLocalPositions((prev) => ({ ...prev, [`folder-${dragging.idx}`]: { right: finalRight, top: finalTop } }));
979
+ const positionsPatch = {};
980
+ for (const move2 of folderMoves) {
981
+ updated[move2.entry.idx] = { ...updated[move2.entry.idx], x: move2.finalRight, y: move2.finalTop };
982
+ positionsPatch[`folder-${move2.entry.idx}`] = { right: move2.finalRight, top: move2.finalTop };
983
+ }
943
984
  saveFolders(updated);
985
+ setLocalPositions((prev) => ({ ...prev, ...positionsPatch }));
944
986
  }
945
987
  setDragging(null);
946
- dragElRef.current = null;
988
+ dragEntriesRef.current = [];
947
989
  };
948
990
  window.addEventListener("pointermove", move);
949
991
  window.addEventListener("pointerup", up);
@@ -1233,7 +1275,7 @@ function Desktop({ profile }) {
1233
1275
  return /* @__PURE__ */ jsx(
1234
1276
  "div",
1235
1277
  {
1236
- "data-desktop-icon": true,
1278
+ "data-desktop-icon": `item-${i}`,
1237
1279
  style: { position: "absolute", right: pos.right, top: pos.top, zIndex: 1 },
1238
1280
  onPointerDown: (e) => {
1239
1281
  e.stopPropagation();
@@ -1241,7 +1283,15 @@ function Desktop({ profile }) {
1241
1283
  },
1242
1284
  onClick: (e) => {
1243
1285
  e.stopPropagation();
1244
- setSelected(/* @__PURE__ */ new Set([`item-${i}`]));
1286
+ if (e.shiftKey || e.metaKey || e.ctrlKey) {
1287
+ setSelected((prev) => {
1288
+ const next = new Set(prev);
1289
+ next.has(`item-${i}`) ? next.delete(`item-${i}`) : next.add(`item-${i}`);
1290
+ return next;
1291
+ });
1292
+ } else if (!selected.has(`item-${i}`)) {
1293
+ setSelected(/* @__PURE__ */ new Set([`item-${i}`]));
1294
+ }
1245
1295
  },
1246
1296
  onContextMenu: (e) => handleItemContextMenu(e, i),
1247
1297
  onDoubleClick: (e) => {
@@ -1261,7 +1311,7 @@ function Desktop({ profile }) {
1261
1311
  return /* @__PURE__ */ jsx(
1262
1312
  "div",
1263
1313
  {
1264
- "data-desktop-icon": true,
1314
+ "data-desktop-icon": `folder-${i}`,
1265
1315
  style: { position: "absolute", right: pos.right, top: pos.top, zIndex: 1 },
1266
1316
  onPointerDown: (e) => {
1267
1317
  e.stopPropagation();
@@ -1269,7 +1319,15 @@ function Desktop({ profile }) {
1269
1319
  },
1270
1320
  onClick: (e) => {
1271
1321
  e.stopPropagation();
1272
- setSelected(/* @__PURE__ */ new Set([`folder-${i}`]));
1322
+ if (e.shiftKey || e.metaKey || e.ctrlKey) {
1323
+ setSelected((prev) => {
1324
+ const next = new Set(prev);
1325
+ next.has(`folder-${i}`) ? next.delete(`folder-${i}`) : next.add(`folder-${i}`);
1326
+ return next;
1327
+ });
1328
+ } else if (!selected.has(`folder-${i}`)) {
1329
+ setSelected(/* @__PURE__ */ new Set([`folder-${i}`]));
1330
+ }
1273
1331
  },
1274
1332
  onContextMenu: (e) => handleFolderContextMenu(e, i),
1275
1333
  onDoubleClick: (e) => {