rita-workspace 0.4.7 → 0.4.9
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.
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +87 -15
- package/dist/index.mjs +87 -15
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -323,12 +323,70 @@ function useWorkspaceLang() {
|
|
|
323
323
|
}
|
|
324
324
|
return { lang: context.lang, t: context.t };
|
|
325
325
|
}
|
|
326
|
+
var TAB_ID = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2);
|
|
327
|
+
var TABS_KEY = "rita-workspace-tabs";
|
|
328
|
+
var TAB_CHANNEL = "rita-workspace-tabs";
|
|
329
|
+
function getTabsMap() {
|
|
330
|
+
try {
|
|
331
|
+
return JSON.parse(localStorage.getItem(TABS_KEY) || "{}");
|
|
332
|
+
} catch {
|
|
333
|
+
return {};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function setTabDrawing(drawingId) {
|
|
337
|
+
const tabs = getTabsMap();
|
|
338
|
+
if (drawingId) {
|
|
339
|
+
tabs[TAB_ID] = drawingId;
|
|
340
|
+
} else {
|
|
341
|
+
delete tabs[TAB_ID];
|
|
342
|
+
}
|
|
343
|
+
localStorage.setItem(TABS_KEY, JSON.stringify(tabs));
|
|
344
|
+
}
|
|
345
|
+
function isDrawingOpenInOtherTab(drawingId) {
|
|
346
|
+
const tabs = getTabsMap();
|
|
347
|
+
return Object.entries(tabs).some(
|
|
348
|
+
([tabId, dId]) => tabId !== TAB_ID && dId === drawingId
|
|
349
|
+
);
|
|
350
|
+
}
|
|
326
351
|
function WorkspaceProvider({ children, lang = "en" }) {
|
|
327
352
|
const [workspace, setWorkspace] = (0, import_react.useState)(null);
|
|
328
353
|
const [drawings, setDrawings] = (0, import_react.useState)([]);
|
|
329
354
|
const [activeDrawing, setActiveDrawing2] = (0, import_react.useState)(null);
|
|
330
355
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
331
356
|
const [error, setError] = (0, import_react.useState)(null);
|
|
357
|
+
const [isDrawingConflict, setIsDrawingConflict] = (0, import_react.useState)(false);
|
|
358
|
+
(0, import_react.useEffect)(() => {
|
|
359
|
+
const drawingId = activeDrawing?.id || null;
|
|
360
|
+
setTabDrawing(drawingId);
|
|
361
|
+
if (drawingId) {
|
|
362
|
+
setIsDrawingConflict(isDrawingOpenInOtherTab(drawingId));
|
|
363
|
+
} else {
|
|
364
|
+
setIsDrawingConflict(false);
|
|
365
|
+
}
|
|
366
|
+
let channel = null;
|
|
367
|
+
try {
|
|
368
|
+
channel = new BroadcastChannel(TAB_CHANNEL);
|
|
369
|
+
channel.postMessage({ type: "drawing-changed", tabId: TAB_ID, drawingId });
|
|
370
|
+
channel.onmessage = (event) => {
|
|
371
|
+
if (event.data?.tabId !== TAB_ID && drawingId) {
|
|
372
|
+
setIsDrawingConflict(isDrawingOpenInOtherTab(drawingId));
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
} catch {
|
|
376
|
+
}
|
|
377
|
+
return () => {
|
|
378
|
+
channel?.close();
|
|
379
|
+
};
|
|
380
|
+
}, [activeDrawing?.id]);
|
|
381
|
+
(0, import_react.useEffect)(() => {
|
|
382
|
+
const onUnload = () => {
|
|
383
|
+
const tabs = getTabsMap();
|
|
384
|
+
delete tabs[TAB_ID];
|
|
385
|
+
localStorage.setItem(TABS_KEY, JSON.stringify(tabs));
|
|
386
|
+
};
|
|
387
|
+
window.addEventListener("beforeunload", onUnload);
|
|
388
|
+
return () => window.removeEventListener("beforeunload", onUnload);
|
|
389
|
+
}, []);
|
|
332
390
|
const t = getTranslations(lang);
|
|
333
391
|
(0, import_react.useEffect)(() => {
|
|
334
392
|
async function init() {
|
|
@@ -339,9 +397,23 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
339
397
|
const allDrawings = await getAllDrawings();
|
|
340
398
|
const wsDrawings = allDrawings.filter((d) => ws.drawingIds.includes(d.id));
|
|
341
399
|
setDrawings(wsDrawings);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
400
|
+
const lastDrawingId = sessionStorage.getItem("rita-workspace-tab-drawing");
|
|
401
|
+
let active = null;
|
|
402
|
+
if (lastDrawingId) {
|
|
403
|
+
active = wsDrawings.find((d) => d.id === lastDrawingId) || null;
|
|
404
|
+
if (!active) {
|
|
405
|
+
const fromDb = await getDrawing(lastDrawingId);
|
|
406
|
+
if (fromDb && ws.drawingIds.includes(fromDb.id)) {
|
|
407
|
+
active = fromDb;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (!active && wsDrawings.length > 0) {
|
|
412
|
+
active = wsDrawings[0];
|
|
413
|
+
}
|
|
414
|
+
if (active) {
|
|
415
|
+
setActiveDrawing2(active);
|
|
416
|
+
sessionStorage.setItem("rita-workspace-tab-drawing", active.id);
|
|
345
417
|
}
|
|
346
418
|
} catch (err) {
|
|
347
419
|
setError(err instanceof Error ? err.message : "Failed to load workspace");
|
|
@@ -357,10 +429,6 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
357
429
|
const allDrawings = await getAllDrawings();
|
|
358
430
|
const wsDrawings = allDrawings.filter((d) => workspace.drawingIds.includes(d.id));
|
|
359
431
|
setDrawings(wsDrawings);
|
|
360
|
-
if (workspace.activeDrawingId) {
|
|
361
|
-
const active = await getDrawing(workspace.activeDrawingId);
|
|
362
|
-
if (active) setActiveDrawing2(active);
|
|
363
|
-
}
|
|
364
432
|
} catch (err) {
|
|
365
433
|
}
|
|
366
434
|
}, [workspace]);
|
|
@@ -370,7 +438,6 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
370
438
|
const defaultName = `${t.newDrawing} ${drawings.length + 1}`;
|
|
371
439
|
const drawing = await createDrawing(name || defaultName);
|
|
372
440
|
await addDrawingToWorkspace(workspace.id, drawing.id);
|
|
373
|
-
await setActiveDrawing(workspace.id, drawing.id);
|
|
374
441
|
setDrawings((prev) => [...prev, drawing]);
|
|
375
442
|
setActiveDrawing2(drawing);
|
|
376
443
|
setWorkspace((prev) => prev ? {
|
|
@@ -378,6 +445,7 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
378
445
|
drawingIds: [...prev.drawingIds, drawing.id],
|
|
379
446
|
activeDrawingId: drawing.id
|
|
380
447
|
} : null);
|
|
448
|
+
sessionStorage.setItem("rita-workspace-tab-drawing", drawing.id);
|
|
381
449
|
return drawing;
|
|
382
450
|
} catch (err) {
|
|
383
451
|
setError(err instanceof Error ? err.message : "Failed to create drawing");
|
|
@@ -389,9 +457,9 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
389
457
|
try {
|
|
390
458
|
const drawing = await getDrawing(id);
|
|
391
459
|
if (drawing) {
|
|
392
|
-
await setActiveDrawing(workspace.id, id);
|
|
393
460
|
setActiveDrawing2(drawing);
|
|
394
461
|
setWorkspace((prev) => prev ? { ...prev, activeDrawingId: id } : null);
|
|
462
|
+
sessionStorage.setItem("rita-workspace-tab-drawing", id);
|
|
395
463
|
}
|
|
396
464
|
} catch (err) {
|
|
397
465
|
setError(err instanceof Error ? err.message : "Failed to switch drawing");
|
|
@@ -607,6 +675,7 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
607
675
|
activeDrawing,
|
|
608
676
|
isLoading,
|
|
609
677
|
error,
|
|
678
|
+
isDrawingConflict,
|
|
610
679
|
lang,
|
|
611
680
|
t,
|
|
612
681
|
createNewDrawing,
|
|
@@ -988,11 +1057,15 @@ var DrawingsDialog = ({
|
|
|
988
1057
|
const [position, setPosition] = (0, import_react5.useState)(null);
|
|
989
1058
|
const dragRef = (0, import_react5.useRef)(null);
|
|
990
1059
|
const dialogRef = (0, import_react5.useRef)(null);
|
|
1060
|
+
const prevOpenRef = (0, import_react5.useRef)(false);
|
|
991
1061
|
(0, import_react5.useEffect)(() => {
|
|
992
1062
|
if (open) {
|
|
993
1063
|
refreshDrawings();
|
|
994
|
-
|
|
1064
|
+
if (!prevOpenRef.current) {
|
|
1065
|
+
setPosition(null);
|
|
1066
|
+
}
|
|
995
1067
|
}
|
|
1068
|
+
prevOpenRef.current = open;
|
|
996
1069
|
}, [open, refreshDrawings]);
|
|
997
1070
|
const handleMouseDown = (0, import_react5.useCallback)((e) => {
|
|
998
1071
|
if (e.target.closest("button")) return;
|
|
@@ -1099,17 +1172,16 @@ var DrawingsDialog = ({
|
|
|
1099
1172
|
left: 0,
|
|
1100
1173
|
right: 0,
|
|
1101
1174
|
bottom: 0,
|
|
1102
|
-
backgroundColor:
|
|
1175
|
+
backgroundColor: "rgba(0, 0, 0, 0.4)",
|
|
1103
1176
|
display: position ? "block" : "flex",
|
|
1104
1177
|
alignItems: "center",
|
|
1105
1178
|
justifyContent: "center",
|
|
1106
|
-
zIndex: 9999
|
|
1107
|
-
pointerEvents: position ? "none" : "auto"
|
|
1179
|
+
zIndex: 9999
|
|
1108
1180
|
},
|
|
1109
1181
|
onClick: (e) => {
|
|
1110
|
-
if (
|
|
1182
|
+
if (e.target === e.currentTarget) onClose();
|
|
1111
1183
|
},
|
|
1112
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: dialogRef, className: "rita-workspace-dialog", style:
|
|
1184
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: dialogRef, className: "rita-workspace-dialog", style: dialogStyle, children: [
|
|
1113
1185
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1114
1186
|
"div",
|
|
1115
1187
|
{
|
package/dist/index.mjs
CHANGED
|
@@ -261,12 +261,70 @@ function useWorkspaceLang() {
|
|
|
261
261
|
}
|
|
262
262
|
return { lang: context.lang, t: context.t };
|
|
263
263
|
}
|
|
264
|
+
var TAB_ID = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2);
|
|
265
|
+
var TABS_KEY = "rita-workspace-tabs";
|
|
266
|
+
var TAB_CHANNEL = "rita-workspace-tabs";
|
|
267
|
+
function getTabsMap() {
|
|
268
|
+
try {
|
|
269
|
+
return JSON.parse(localStorage.getItem(TABS_KEY) || "{}");
|
|
270
|
+
} catch {
|
|
271
|
+
return {};
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function setTabDrawing(drawingId) {
|
|
275
|
+
const tabs = getTabsMap();
|
|
276
|
+
if (drawingId) {
|
|
277
|
+
tabs[TAB_ID] = drawingId;
|
|
278
|
+
} else {
|
|
279
|
+
delete tabs[TAB_ID];
|
|
280
|
+
}
|
|
281
|
+
localStorage.setItem(TABS_KEY, JSON.stringify(tabs));
|
|
282
|
+
}
|
|
283
|
+
function isDrawingOpenInOtherTab(drawingId) {
|
|
284
|
+
const tabs = getTabsMap();
|
|
285
|
+
return Object.entries(tabs).some(
|
|
286
|
+
([tabId, dId]) => tabId !== TAB_ID && dId === drawingId
|
|
287
|
+
);
|
|
288
|
+
}
|
|
264
289
|
function WorkspaceProvider({ children, lang = "en" }) {
|
|
265
290
|
const [workspace, setWorkspace] = useState(null);
|
|
266
291
|
const [drawings, setDrawings] = useState([]);
|
|
267
292
|
const [activeDrawing, setActiveDrawing2] = useState(null);
|
|
268
293
|
const [isLoading, setIsLoading] = useState(true);
|
|
269
294
|
const [error, setError] = useState(null);
|
|
295
|
+
const [isDrawingConflict, setIsDrawingConflict] = useState(false);
|
|
296
|
+
useEffect(() => {
|
|
297
|
+
const drawingId = activeDrawing?.id || null;
|
|
298
|
+
setTabDrawing(drawingId);
|
|
299
|
+
if (drawingId) {
|
|
300
|
+
setIsDrawingConflict(isDrawingOpenInOtherTab(drawingId));
|
|
301
|
+
} else {
|
|
302
|
+
setIsDrawingConflict(false);
|
|
303
|
+
}
|
|
304
|
+
let channel = null;
|
|
305
|
+
try {
|
|
306
|
+
channel = new BroadcastChannel(TAB_CHANNEL);
|
|
307
|
+
channel.postMessage({ type: "drawing-changed", tabId: TAB_ID, drawingId });
|
|
308
|
+
channel.onmessage = (event) => {
|
|
309
|
+
if (event.data?.tabId !== TAB_ID && drawingId) {
|
|
310
|
+
setIsDrawingConflict(isDrawingOpenInOtherTab(drawingId));
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
} catch {
|
|
314
|
+
}
|
|
315
|
+
return () => {
|
|
316
|
+
channel?.close();
|
|
317
|
+
};
|
|
318
|
+
}, [activeDrawing?.id]);
|
|
319
|
+
useEffect(() => {
|
|
320
|
+
const onUnload = () => {
|
|
321
|
+
const tabs = getTabsMap();
|
|
322
|
+
delete tabs[TAB_ID];
|
|
323
|
+
localStorage.setItem(TABS_KEY, JSON.stringify(tabs));
|
|
324
|
+
};
|
|
325
|
+
window.addEventListener("beforeunload", onUnload);
|
|
326
|
+
return () => window.removeEventListener("beforeunload", onUnload);
|
|
327
|
+
}, []);
|
|
270
328
|
const t = getTranslations(lang);
|
|
271
329
|
useEffect(() => {
|
|
272
330
|
async function init() {
|
|
@@ -277,9 +335,23 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
277
335
|
const allDrawings = await getAllDrawings();
|
|
278
336
|
const wsDrawings = allDrawings.filter((d) => ws.drawingIds.includes(d.id));
|
|
279
337
|
setDrawings(wsDrawings);
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
338
|
+
const lastDrawingId = sessionStorage.getItem("rita-workspace-tab-drawing");
|
|
339
|
+
let active = null;
|
|
340
|
+
if (lastDrawingId) {
|
|
341
|
+
active = wsDrawings.find((d) => d.id === lastDrawingId) || null;
|
|
342
|
+
if (!active) {
|
|
343
|
+
const fromDb = await getDrawing(lastDrawingId);
|
|
344
|
+
if (fromDb && ws.drawingIds.includes(fromDb.id)) {
|
|
345
|
+
active = fromDb;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (!active && wsDrawings.length > 0) {
|
|
350
|
+
active = wsDrawings[0];
|
|
351
|
+
}
|
|
352
|
+
if (active) {
|
|
353
|
+
setActiveDrawing2(active);
|
|
354
|
+
sessionStorage.setItem("rita-workspace-tab-drawing", active.id);
|
|
283
355
|
}
|
|
284
356
|
} catch (err) {
|
|
285
357
|
setError(err instanceof Error ? err.message : "Failed to load workspace");
|
|
@@ -295,10 +367,6 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
295
367
|
const allDrawings = await getAllDrawings();
|
|
296
368
|
const wsDrawings = allDrawings.filter((d) => workspace.drawingIds.includes(d.id));
|
|
297
369
|
setDrawings(wsDrawings);
|
|
298
|
-
if (workspace.activeDrawingId) {
|
|
299
|
-
const active = await getDrawing(workspace.activeDrawingId);
|
|
300
|
-
if (active) setActiveDrawing2(active);
|
|
301
|
-
}
|
|
302
370
|
} catch (err) {
|
|
303
371
|
}
|
|
304
372
|
}, [workspace]);
|
|
@@ -308,7 +376,6 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
308
376
|
const defaultName = `${t.newDrawing} ${drawings.length + 1}`;
|
|
309
377
|
const drawing = await createDrawing(name || defaultName);
|
|
310
378
|
await addDrawingToWorkspace(workspace.id, drawing.id);
|
|
311
|
-
await setActiveDrawing(workspace.id, drawing.id);
|
|
312
379
|
setDrawings((prev) => [...prev, drawing]);
|
|
313
380
|
setActiveDrawing2(drawing);
|
|
314
381
|
setWorkspace((prev) => prev ? {
|
|
@@ -316,6 +383,7 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
316
383
|
drawingIds: [...prev.drawingIds, drawing.id],
|
|
317
384
|
activeDrawingId: drawing.id
|
|
318
385
|
} : null);
|
|
386
|
+
sessionStorage.setItem("rita-workspace-tab-drawing", drawing.id);
|
|
319
387
|
return drawing;
|
|
320
388
|
} catch (err) {
|
|
321
389
|
setError(err instanceof Error ? err.message : "Failed to create drawing");
|
|
@@ -327,9 +395,9 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
327
395
|
try {
|
|
328
396
|
const drawing = await getDrawing(id);
|
|
329
397
|
if (drawing) {
|
|
330
|
-
await setActiveDrawing(workspace.id, id);
|
|
331
398
|
setActiveDrawing2(drawing);
|
|
332
399
|
setWorkspace((prev) => prev ? { ...prev, activeDrawingId: id } : null);
|
|
400
|
+
sessionStorage.setItem("rita-workspace-tab-drawing", id);
|
|
333
401
|
}
|
|
334
402
|
} catch (err) {
|
|
335
403
|
setError(err instanceof Error ? err.message : "Failed to switch drawing");
|
|
@@ -545,6 +613,7 @@ function WorkspaceProvider({ children, lang = "en" }) {
|
|
|
545
613
|
activeDrawing,
|
|
546
614
|
isLoading,
|
|
547
615
|
error,
|
|
616
|
+
isDrawingConflict,
|
|
548
617
|
lang,
|
|
549
618
|
t,
|
|
550
619
|
createNewDrawing,
|
|
@@ -926,11 +995,15 @@ var DrawingsDialog = ({
|
|
|
926
995
|
const [position, setPosition] = useState4(null);
|
|
927
996
|
const dragRef = useRef2(null);
|
|
928
997
|
const dialogRef = useRef2(null);
|
|
998
|
+
const prevOpenRef = useRef2(false);
|
|
929
999
|
useEffect3(() => {
|
|
930
1000
|
if (open) {
|
|
931
1001
|
refreshDrawings();
|
|
932
|
-
|
|
1002
|
+
if (!prevOpenRef.current) {
|
|
1003
|
+
setPosition(null);
|
|
1004
|
+
}
|
|
933
1005
|
}
|
|
1006
|
+
prevOpenRef.current = open;
|
|
934
1007
|
}, [open, refreshDrawings]);
|
|
935
1008
|
const handleMouseDown = useCallback2((e) => {
|
|
936
1009
|
if (e.target.closest("button")) return;
|
|
@@ -1037,17 +1110,16 @@ var DrawingsDialog = ({
|
|
|
1037
1110
|
left: 0,
|
|
1038
1111
|
right: 0,
|
|
1039
1112
|
bottom: 0,
|
|
1040
|
-
backgroundColor:
|
|
1113
|
+
backgroundColor: "rgba(0, 0, 0, 0.4)",
|
|
1041
1114
|
display: position ? "block" : "flex",
|
|
1042
1115
|
alignItems: "center",
|
|
1043
1116
|
justifyContent: "center",
|
|
1044
|
-
zIndex: 9999
|
|
1045
|
-
pointerEvents: position ? "none" : "auto"
|
|
1117
|
+
zIndex: 9999
|
|
1046
1118
|
},
|
|
1047
1119
|
onClick: (e) => {
|
|
1048
|
-
if (
|
|
1120
|
+
if (e.target === e.currentTarget) onClose();
|
|
1049
1121
|
},
|
|
1050
|
-
children: /* @__PURE__ */ jsxs4("div", { ref: dialogRef, className: "rita-workspace-dialog", style:
|
|
1122
|
+
children: /* @__PURE__ */ jsxs4("div", { ref: dialogRef, className: "rita-workspace-dialog", style: dialogStyle, children: [
|
|
1051
1123
|
/* @__PURE__ */ jsxs4(
|
|
1052
1124
|
"div",
|
|
1053
1125
|
{
|