@ai-matrx/canvas 0.6.0 → 0.7.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.
- package/CHANGELOG.md +30 -0
- package/README.md +17 -2
- package/dist/index.cjs +76 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +76 -7
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +441 -199
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +77 -44
- package/dist/react.d.ts +77 -44
- package/dist/react.js +396 -153
- package/dist/react.js.map +1 -1
- package/dist/styles.css +88 -37
- package/dist/{toggleKind-DhDmWExm.d.cts → toggleKind-CAI7pndj.d.cts} +21 -2
- package/dist/{toggleKind-DhDmWExm.d.ts → toggleKind-CAI7pndj.d.ts} +21 -2
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-
|
|
2
|
-
export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as
|
|
1
|
+
import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-CAI7pndj.cjs';
|
|
2
|
+
export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as CANVAS_PANE_MIN_WIDTH, y as CANVAS_PHONE_MAX_WIDTH, z as CANVAS_STORAGE_KEY, A as CANVAS_WEB_LAYOUT_RULES, B as CanvasControllerOptions, D as CanvasErrorReport, E as CanvasErrorSink, F as CanvasKeyValueStore, G as CanvasKindVisibility, H as CanvasLayoutRules, I as CanvasNavigateInput, J as CanvasOpenInput, K as CanvasOpenTarget, L as CanvasOrientation, M as CanvasPersistencePort, N as CanvasPreferredTarget, O as CanvasPresentation, P as CanvasPresentationOrientation, Q as CanvasRect, R as CanvasSessionAttachReason, S as CanvasSessionDetachReason, T as CanvasSessionEvent, U as CanvasSessionHooks, V as CanvasSplitId, W as CanvasWindowCloseMode, X as CanvasWindowFrame, Y as CanvasWindowPorts, Z as ReduxStoreLike, _ as ToggleKindInput, $ as bindCanvasToReduxStore, a0 as canvasActions, a1 as canvasOrientation, a2 as canvasPresentation, a3 as canvasReducer, a4 as canvasWindowFrame, a5 as canvasWindowOfPane, a6 as clampDraggedCanvasWidth, a7 as consoleCanvasErrorSink, a8 as createCanvasController, a9 as createCanvasStore, aa as createInitialCanvasState, ab as createKeyValueCanvasPersistence, ac as createLocalStorageCanvasPersistence, ad as defaultCanvasWidth, ae as fitCanvasWidth, af as foldCanvasWindows, ag as isCanvasAction, ah as listCanvasWindowIds, ai as preferredFlowDirection, aj as resolveCanvasLayoutRules, ak as sanitizeCanvasSnapshot, al as selectCanvasKindVisibility, am as shouldStackSplit, an as toPersistableSnapshot, ao as toggleKind } from './toggleKind-CAI7pndj.cjs';
|
|
3
3
|
|
|
4
4
|
declare function canvasItemId(kind: string, key: string): CanvasItemId;
|
|
5
5
|
declare function parseCanvasItemId(id: CanvasItemId): {
|
|
@@ -73,7 +73,7 @@ declare function shareStructure<T>(prev: T, next: T): T;
|
|
|
73
73
|
* through `runCanvasCommand`, so both paths do exactly the same thing.
|
|
74
74
|
*/
|
|
75
75
|
|
|
76
|
-
type CanvasCommandId = "canvas.toggle" | "canvas.toggleFullscreen" | "canvas.exitFullscreen" | "canvas.closeTab" | "canvas.nextTab" | "canvas.previousTab" | "canvas.splitRight" | "canvas.splitDown";
|
|
76
|
+
type CanvasCommandId = "canvas.toggle" | "canvas.toggleFullscreen" | "canvas.exitFullscreen" | "canvas.closeTab" | "canvas.nextTab" | "canvas.previousTab" | "canvas.splitRight" | "canvas.splitDown" | "canvas.back" | "canvas.forward";
|
|
77
77
|
/**
|
|
78
78
|
* When a shortcut applies:
|
|
79
79
|
* - "presented": a canvas column is on screen in this window;
|
|
@@ -146,5 +146,14 @@ declare const selectCanvasWindowOfItem: typeof canvasWindowOfItem;
|
|
|
146
146
|
declare function selectCanvasItemHistory(s: CanvasState, itemId: CanvasItemId): readonly CanvasHistoryEntry[];
|
|
147
147
|
/** Whether a tab offers Back (it navigated in place). */
|
|
148
148
|
declare const selectCanvasCanGoBack: (s: CanvasState, itemId: CanvasItemId) => boolean;
|
|
149
|
+
/** Whether a tab offers Forward (it went Back and has not navigated elsewhere since). */
|
|
150
|
+
declare const selectCanvasCanGoForward: (s: CanvasState, itemId: CanvasItemId) => boolean;
|
|
151
|
+
/**
|
|
152
|
+
* The ONE pane a phone presents: the focused pane when it holds a tab, else
|
|
153
|
+
* the first pane that does (an empty pane is never presented over tabs that
|
|
154
|
+
* exist — the header and the body always describe the same pane), else the
|
|
155
|
+
* focused one.
|
|
156
|
+
*/
|
|
157
|
+
declare function selectCanvasPresentedPaneId(s: CanvasState, windowId?: CanvasWindowId): CanvasPaneId | null;
|
|
149
158
|
|
|
150
|
-
export { CANVAS_SHORTCUTS, CanvasAction, type CanvasCommandId, CanvasController, CanvasExtraWindow, CanvasHistoryEntry, CanvasItem, CanvasItemId, CanvasJson, type CanvasKeyInput, CanvasLayoutNode, CanvasPane, CanvasPaneId, type CanvasShortcut, type CanvasShortcutWhen, CanvasState, CanvasStoreBinding, CanvasWindowId, type RemoteCanvasStore, type RemoteCanvasStoreOptions, canvasItemId, canvasShortcutHint, canvasWindowId, canvasWindowOfItem, createRemoteCanvasStore, findNonJson, isCanvasJson, listPaneIds, matchesCanvasAccelerator, normalizeSizes, parseCanvasItemId, runCanvasCommand, selectCanvasActiveItem, selectCanvasCanGoBack, selectCanvasExtraWindow, selectCanvasFocusedPaneId, selectCanvasIsFullscreen, selectCanvasIsHydrated, selectCanvasIsOpen, selectCanvasItem, selectCanvasItemCount, selectCanvasItemHistory, selectCanvasLayout, selectCanvasPane, selectCanvasPaneCount, selectCanvasWidth, selectCanvasWindowItemCount, selectCanvasWindowOfItem, selectCanvasWindows, shareStructure };
|
|
159
|
+
export { CANVAS_SHORTCUTS, CanvasAction, type CanvasCommandId, CanvasController, CanvasExtraWindow, CanvasHistoryEntry, CanvasItem, CanvasItemId, CanvasJson, type CanvasKeyInput, CanvasLayoutNode, CanvasPane, CanvasPaneId, type CanvasShortcut, type CanvasShortcutWhen, CanvasState, CanvasStoreBinding, CanvasWindowId, type RemoteCanvasStore, type RemoteCanvasStoreOptions, canvasItemId, canvasShortcutHint, canvasWindowId, canvasWindowOfItem, createRemoteCanvasStore, findNonJson, isCanvasJson, listPaneIds, matchesCanvasAccelerator, normalizeSizes, parseCanvasItemId, runCanvasCommand, selectCanvasActiveItem, selectCanvasCanGoBack, selectCanvasCanGoForward, selectCanvasExtraWindow, selectCanvasFocusedPaneId, selectCanvasIsFullscreen, selectCanvasIsHydrated, selectCanvasIsOpen, selectCanvasItem, selectCanvasItemCount, selectCanvasItemHistory, selectCanvasLayout, selectCanvasPane, selectCanvasPaneCount, selectCanvasPresentedPaneId, selectCanvasWidth, selectCanvasWindowItemCount, selectCanvasWindowOfItem, selectCanvasWindows, shareStructure };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-
|
|
2
|
-
export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as
|
|
1
|
+
import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-CAI7pndj.js';
|
|
2
|
+
export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as CANVAS_PANE_MIN_WIDTH, y as CANVAS_PHONE_MAX_WIDTH, z as CANVAS_STORAGE_KEY, A as CANVAS_WEB_LAYOUT_RULES, B as CanvasControllerOptions, D as CanvasErrorReport, E as CanvasErrorSink, F as CanvasKeyValueStore, G as CanvasKindVisibility, H as CanvasLayoutRules, I as CanvasNavigateInput, J as CanvasOpenInput, K as CanvasOpenTarget, L as CanvasOrientation, M as CanvasPersistencePort, N as CanvasPreferredTarget, O as CanvasPresentation, P as CanvasPresentationOrientation, Q as CanvasRect, R as CanvasSessionAttachReason, S as CanvasSessionDetachReason, T as CanvasSessionEvent, U as CanvasSessionHooks, V as CanvasSplitId, W as CanvasWindowCloseMode, X as CanvasWindowFrame, Y as CanvasWindowPorts, Z as ReduxStoreLike, _ as ToggleKindInput, $ as bindCanvasToReduxStore, a0 as canvasActions, a1 as canvasOrientation, a2 as canvasPresentation, a3 as canvasReducer, a4 as canvasWindowFrame, a5 as canvasWindowOfPane, a6 as clampDraggedCanvasWidth, a7 as consoleCanvasErrorSink, a8 as createCanvasController, a9 as createCanvasStore, aa as createInitialCanvasState, ab as createKeyValueCanvasPersistence, ac as createLocalStorageCanvasPersistence, ad as defaultCanvasWidth, ae as fitCanvasWidth, af as foldCanvasWindows, ag as isCanvasAction, ah as listCanvasWindowIds, ai as preferredFlowDirection, aj as resolveCanvasLayoutRules, ak as sanitizeCanvasSnapshot, al as selectCanvasKindVisibility, am as shouldStackSplit, an as toPersistableSnapshot, ao as toggleKind } from './toggleKind-CAI7pndj.js';
|
|
3
3
|
|
|
4
4
|
declare function canvasItemId(kind: string, key: string): CanvasItemId;
|
|
5
5
|
declare function parseCanvasItemId(id: CanvasItemId): {
|
|
@@ -73,7 +73,7 @@ declare function shareStructure<T>(prev: T, next: T): T;
|
|
|
73
73
|
* through `runCanvasCommand`, so both paths do exactly the same thing.
|
|
74
74
|
*/
|
|
75
75
|
|
|
76
|
-
type CanvasCommandId = "canvas.toggle" | "canvas.toggleFullscreen" | "canvas.exitFullscreen" | "canvas.closeTab" | "canvas.nextTab" | "canvas.previousTab" | "canvas.splitRight" | "canvas.splitDown";
|
|
76
|
+
type CanvasCommandId = "canvas.toggle" | "canvas.toggleFullscreen" | "canvas.exitFullscreen" | "canvas.closeTab" | "canvas.nextTab" | "canvas.previousTab" | "canvas.splitRight" | "canvas.splitDown" | "canvas.back" | "canvas.forward";
|
|
77
77
|
/**
|
|
78
78
|
* When a shortcut applies:
|
|
79
79
|
* - "presented": a canvas column is on screen in this window;
|
|
@@ -146,5 +146,14 @@ declare const selectCanvasWindowOfItem: typeof canvasWindowOfItem;
|
|
|
146
146
|
declare function selectCanvasItemHistory(s: CanvasState, itemId: CanvasItemId): readonly CanvasHistoryEntry[];
|
|
147
147
|
/** Whether a tab offers Back (it navigated in place). */
|
|
148
148
|
declare const selectCanvasCanGoBack: (s: CanvasState, itemId: CanvasItemId) => boolean;
|
|
149
|
+
/** Whether a tab offers Forward (it went Back and has not navigated elsewhere since). */
|
|
150
|
+
declare const selectCanvasCanGoForward: (s: CanvasState, itemId: CanvasItemId) => boolean;
|
|
151
|
+
/**
|
|
152
|
+
* The ONE pane a phone presents: the focused pane when it holds a tab, else
|
|
153
|
+
* the first pane that does (an empty pane is never presented over tabs that
|
|
154
|
+
* exist — the header and the body always describe the same pane), else the
|
|
155
|
+
* focused one.
|
|
156
|
+
*/
|
|
157
|
+
declare function selectCanvasPresentedPaneId(s: CanvasState, windowId?: CanvasWindowId): CanvasPaneId | null;
|
|
149
158
|
|
|
150
|
-
export { CANVAS_SHORTCUTS, CanvasAction, type CanvasCommandId, CanvasController, CanvasExtraWindow, CanvasHistoryEntry, CanvasItem, CanvasItemId, CanvasJson, type CanvasKeyInput, CanvasLayoutNode, CanvasPane, CanvasPaneId, type CanvasShortcut, type CanvasShortcutWhen, CanvasState, CanvasStoreBinding, CanvasWindowId, type RemoteCanvasStore, type RemoteCanvasStoreOptions, canvasItemId, canvasShortcutHint, canvasWindowId, canvasWindowOfItem, createRemoteCanvasStore, findNonJson, isCanvasJson, listPaneIds, matchesCanvasAccelerator, normalizeSizes, parseCanvasItemId, runCanvasCommand, selectCanvasActiveItem, selectCanvasCanGoBack, selectCanvasExtraWindow, selectCanvasFocusedPaneId, selectCanvasIsFullscreen, selectCanvasIsHydrated, selectCanvasIsOpen, selectCanvasItem, selectCanvasItemCount, selectCanvasItemHistory, selectCanvasLayout, selectCanvasPane, selectCanvasPaneCount, selectCanvasWidth, selectCanvasWindowItemCount, selectCanvasWindowOfItem, selectCanvasWindows, shareStructure };
|
|
159
|
+
export { CANVAS_SHORTCUTS, CanvasAction, type CanvasCommandId, CanvasController, CanvasExtraWindow, CanvasHistoryEntry, CanvasItem, CanvasItemId, CanvasJson, type CanvasKeyInput, CanvasLayoutNode, CanvasPane, CanvasPaneId, type CanvasShortcut, type CanvasShortcutWhen, CanvasState, CanvasStoreBinding, CanvasWindowId, type RemoteCanvasStore, type RemoteCanvasStoreOptions, canvasItemId, canvasShortcutHint, canvasWindowId, canvasWindowOfItem, createRemoteCanvasStore, findNonJson, isCanvasJson, listPaneIds, matchesCanvasAccelerator, normalizeSizes, parseCanvasItemId, runCanvasCommand, selectCanvasActiveItem, selectCanvasCanGoBack, selectCanvasCanGoForward, selectCanvasExtraWindow, selectCanvasFocusedPaneId, selectCanvasIsFullscreen, selectCanvasIsHydrated, selectCanvasIsOpen, selectCanvasItem, selectCanvasItemCount, selectCanvasItemHistory, selectCanvasLayout, selectCanvasPane, selectCanvasPaneCount, selectCanvasPresentedPaneId, selectCanvasWidth, selectCanvasWindowItemCount, selectCanvasWindowOfItem, selectCanvasWindows, shareStructure };
|
package/dist/index.js
CHANGED
|
@@ -172,6 +172,8 @@ var canvasActions = {
|
|
|
172
172
|
navigate: (itemId, to) => ({ type: `${P}navigate`, payload: { itemId, to, now: Date.now() } }),
|
|
173
173
|
/** Returns a tab to what it showed before its last navigate. */
|
|
174
174
|
back: (itemId) => ({ type: `${P}back`, payload: { itemId, now: Date.now() } }),
|
|
175
|
+
/** Re-does the last Back (the step Back left), with that step's live body. */
|
|
176
|
+
forward: (itemId) => ({ type: `${P}forward`, payload: { itemId, now: Date.now() } }),
|
|
175
177
|
closeItem: (itemId) => ({ type: `${P}closeItem`, payload: { itemId } }),
|
|
176
178
|
closeOthers: (itemId) => ({ type: `${P}closeOthers`, payload: { itemId } }),
|
|
177
179
|
activate: (itemId) => ({ type: `${P}activate`, payload: { itemId } }),
|
|
@@ -372,6 +374,7 @@ function newItem(kind, key, title, data, now, steps) {
|
|
|
372
374
|
const id = canvasItemId(kind, key);
|
|
373
375
|
const history = steps?.history ?? [];
|
|
374
376
|
const kept = steps?.kept ?? [];
|
|
377
|
+
const forward = steps?.forward ?? [];
|
|
375
378
|
return {
|
|
376
379
|
id,
|
|
377
380
|
kind,
|
|
@@ -383,7 +386,8 @@ function newItem(kind, key, title, data, now, steps) {
|
|
|
383
386
|
// A reused instance is the SAME live body coming back (Back, or returning to a kept step).
|
|
384
387
|
instance: steps?.instance ?? `${now.toString(36)}:${id}`,
|
|
385
388
|
...history.length > 0 ? { history: history.slice(-CANVAS_HISTORY_LIMIT) } : {},
|
|
386
|
-
...kept.length > 0 ? { kept: kept.slice(-CANVAS_KEEP_ALIVE_DEPTH) } : {}
|
|
389
|
+
...kept.length > 0 ? { kept: kept.slice(-CANVAS_KEEP_ALIVE_DEPTH) } : {},
|
|
390
|
+
...forward.length > 0 ? { forward: forward.slice(-CANVAS_HISTORY_LIMIT) } : {}
|
|
387
391
|
};
|
|
388
392
|
}
|
|
389
393
|
function historyEntry(item) {
|
|
@@ -429,12 +433,14 @@ function sanitizeHistory(raw) {
|
|
|
429
433
|
function sanitizeItem(item) {
|
|
430
434
|
const history = sanitizeHistory(item.history);
|
|
431
435
|
const kept = sanitizeHistory(item.kept).slice(-CANVAS_KEEP_ALIVE_DEPTH);
|
|
432
|
-
const
|
|
436
|
+
const forward = sanitizeHistory(item.forward);
|
|
437
|
+
const { history: _history, kept: _kept, forward: _forward, instance, ...rest } = item;
|
|
433
438
|
return {
|
|
434
439
|
...rest,
|
|
435
440
|
...typeof instance === "string" && instance ? { instance } : {},
|
|
436
441
|
...history.length > 0 ? { history } : {},
|
|
437
|
-
...kept.length > 0 ? { kept } : {}
|
|
442
|
+
...kept.length > 0 ? { kept } : {},
|
|
443
|
+
...forward.length > 0 ? { forward } : {}
|
|
438
444
|
};
|
|
439
445
|
}
|
|
440
446
|
function clampWidth(width) {
|
|
@@ -625,6 +631,9 @@ function canvasReducer(state = createInitialCanvasState(), action) {
|
|
|
625
631
|
const keptIndex = keptAll.findIndex((entry) => canvasItemId(entry.kind, entry.key) === targetId);
|
|
626
632
|
const revived = keptIndex >= 0 ? keptAll[keptIndex] : void 0;
|
|
627
633
|
const kept = keptAll.filter((_, i) => i !== keptIndex);
|
|
634
|
+
const forwardAll = current.forward ?? [];
|
|
635
|
+
const nextForward = forwardAll[forwardAll.length - 1];
|
|
636
|
+
const forward = nextForward && canvasItemId(nextForward.kind, nextForward.key) === targetId ? forwardAll.slice(0, -1) : [];
|
|
628
637
|
return replaceInPlace(
|
|
629
638
|
state,
|
|
630
639
|
current,
|
|
@@ -634,7 +643,7 @@ function canvasReducer(state = createInitialCanvasState(), action) {
|
|
|
634
643
|
to.title !== void 0 ? to.title : revived?.title ?? null,
|
|
635
644
|
to.data !== void 0 ? to.data : revived?.data ?? null,
|
|
636
645
|
now,
|
|
637
|
-
{ history, kept, instance: revived?.instance }
|
|
646
|
+
{ history, kept, forward, instance: revived?.instance }
|
|
638
647
|
)
|
|
639
648
|
);
|
|
640
649
|
}
|
|
@@ -650,10 +659,36 @@ function canvasReducer(state = createInitialCanvasState(), action) {
|
|
|
650
659
|
return focusExisting(canvasReducer(state, canvasActions.closeItem(itemId)), targetId);
|
|
651
660
|
}
|
|
652
661
|
const kept = [...(current.kept ?? []).filter((k) => canvasItemId(k.kind, k.key) !== itemId), historyEntry(current)];
|
|
662
|
+
const forward = [...current.forward ?? [], historyEntry(current)];
|
|
653
663
|
return replaceInPlace(
|
|
654
664
|
state,
|
|
655
665
|
current,
|
|
656
|
-
newItem(entry.kind, entry.key, entry.title, entry.data, now, { history: history.slice(0, -1), kept, instance: entry.instance })
|
|
666
|
+
newItem(entry.kind, entry.key, entry.title, entry.data, now, { history: history.slice(0, -1), kept, forward, instance: entry.instance })
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
case `${P}forward`: {
|
|
670
|
+
const { itemId, now } = action.payload;
|
|
671
|
+
const current = state.items[itemId];
|
|
672
|
+
const forwardAll = current?.forward ?? [];
|
|
673
|
+
const entry = forwardAll[forwardAll.length - 1];
|
|
674
|
+
if (!current || !entry || !paneOf(state, itemId)) return state;
|
|
675
|
+
const targetId = canvasItemId(entry.kind, entry.key);
|
|
676
|
+
if (targetId === itemId) return state;
|
|
677
|
+
if (state.items[targetId]) {
|
|
678
|
+
return focusExisting(canvasReducer(state, canvasActions.closeItem(itemId)), targetId);
|
|
679
|
+
}
|
|
680
|
+
const keptAll = current.kept ?? [];
|
|
681
|
+
const revived = keptAll.find((k) => canvasItemId(k.kind, k.key) === targetId);
|
|
682
|
+
const kept = keptAll.filter((k) => canvasItemId(k.kind, k.key) !== targetId);
|
|
683
|
+
return replaceInPlace(
|
|
684
|
+
state,
|
|
685
|
+
current,
|
|
686
|
+
newItem(entry.kind, entry.key, entry.title, entry.data, now, {
|
|
687
|
+
history: [...current.history ?? [], historyEntry(current)],
|
|
688
|
+
kept,
|
|
689
|
+
forward: forwardAll.slice(0, -1),
|
|
690
|
+
instance: revived?.instance ?? entry.instance
|
|
691
|
+
})
|
|
657
692
|
);
|
|
658
693
|
}
|
|
659
694
|
case `${P}closeItem`: {
|
|
@@ -982,6 +1017,7 @@ function toPersistableSnapshot(state, isRestorable) {
|
|
|
982
1017
|
}
|
|
983
1018
|
|
|
984
1019
|
// src/core/rules.ts
|
|
1020
|
+
var CANVAS_PANE_MIN_WIDTH = 280;
|
|
985
1021
|
var CANVAS_WEB_LAYOUT_RULES = {
|
|
986
1022
|
defaultWidth: CANVAS_DEFAULT_WIDTH,
|
|
987
1023
|
minWidth: CANVAS_MIN_WIDTH,
|
|
@@ -989,7 +1025,9 @@ var CANVAS_WEB_LAYOUT_RULES = {
|
|
|
989
1025
|
// Split down 70/30 like the desktop: what opens below (notifications, a feed) is the smaller pane.
|
|
990
1026
|
stackSplit: 0.7,
|
|
991
1027
|
sideSplit: 0.5,
|
|
992
|
-
|
|
1028
|
+
// A pane narrower than this cannot show a header (Back, a readable tab, "+", the menu, close) and a
|
|
1029
|
+
// body side by side with another: a split right that would go under it stacks instead.
|
|
1030
|
+
paneMinWidth: CANVAS_PANE_MIN_WIDTH
|
|
993
1031
|
};
|
|
994
1032
|
var CANVAS_DESKTOP_LAYOUT_RULES = {
|
|
995
1033
|
defaultWidth: { fraction: 0.36 },
|
|
@@ -1036,6 +1074,9 @@ var CANVAS_SHORTCUTS = [
|
|
|
1036
1074
|
{ id: "canvas.toggleFullscreen", accelerator: "CmdOrCtrl+Shift+Enter", when: "canvas-focus", label: "Expand canvas", web: true },
|
|
1037
1075
|
{ id: "canvas.splitRight", accelerator: "CmdOrCtrl+Alt+\\", when: "canvas-focus", label: "Split right", web: true },
|
|
1038
1076
|
{ id: "canvas.splitDown", accelerator: "CmdOrCtrl+Alt+Shift+\\", when: "canvas-focus", label: "Split down", web: true },
|
|
1077
|
+
// Browsers own ⌘[ / ⌘] for their own history: data for a desktop host (and the header's Back / Forward).
|
|
1078
|
+
{ id: "canvas.back", accelerator: "CmdOrCtrl+[", when: "canvas-focus", label: "Back", web: false },
|
|
1079
|
+
{ id: "canvas.forward", accelerator: "CmdOrCtrl+]", when: "canvas-focus", label: "Forward", web: false },
|
|
1039
1080
|
{ id: "canvas.closeTab", accelerator: "CmdOrCtrl+W", when: "canvas-focus", label: "Close tab", web: false },
|
|
1040
1081
|
{ id: "canvas.nextTab", accelerator: "Ctrl+Tab", when: "canvas-focus", label: "Next tab", web: false },
|
|
1041
1082
|
{ id: "canvas.previousTab", accelerator: "Ctrl+Shift+Tab", when: "canvas-focus", label: "Previous tab", web: false }
|
|
@@ -1085,11 +1126,17 @@ function runCanvasCommand(controller, id, windowId = controller.windowId) {
|
|
|
1085
1126
|
if (!frame2?.isOpen || !pane) return false;
|
|
1086
1127
|
controller.splitPane(pane.id, id === "canvas.splitRight" ? "horizontal" : "vertical", pane.itemIds.length > 1 ? pane.activeItemId ?? void 0 : void 0);
|
|
1087
1128
|
return true;
|
|
1129
|
+
case "canvas.back":
|
|
1130
|
+
if (!frame2?.isOpen || !pane?.activeItemId) return false;
|
|
1131
|
+
return controller.back(pane.activeItemId) !== null;
|
|
1132
|
+
case "canvas.forward":
|
|
1133
|
+
if (!frame2?.isOpen || !pane?.activeItemId) return false;
|
|
1134
|
+
return controller.forward(pane.activeItemId) !== null;
|
|
1088
1135
|
default:
|
|
1089
1136
|
return false;
|
|
1090
1137
|
}
|
|
1091
1138
|
}
|
|
1092
|
-
var CODE_FOR = { "\\": "Backslash", Tab: "Tab", Escape: "Escape", Enter: "Enter" };
|
|
1139
|
+
var CODE_FOR = { "\\": "Backslash", "[": "BracketLeft", "]": "BracketRight", Tab: "Tab", Escape: "Escape", Enter: "Enter" };
|
|
1093
1140
|
function matchesCanvasAccelerator(input, accelerator, isMac) {
|
|
1094
1141
|
const parts = accelerator.split("+");
|
|
1095
1142
|
const key = parts.pop() ?? "";
|
|
@@ -1206,6 +1253,13 @@ function view(shared, windowId) {
|
|
|
1206
1253
|
dispatch(canvasActions.back(itemId));
|
|
1207
1254
|
return canvasItemId(entry.kind, entry.key);
|
|
1208
1255
|
},
|
|
1256
|
+
forward(itemId) {
|
|
1257
|
+
const forward = store.getState().items[itemId]?.forward ?? [];
|
|
1258
|
+
const entry = forward[forward.length - 1];
|
|
1259
|
+
if (!entry) return null;
|
|
1260
|
+
dispatch(canvasActions.forward(itemId));
|
|
1261
|
+
return canvasItemId(entry.kind, entry.key);
|
|
1262
|
+
},
|
|
1209
1263
|
newTab(paneId) {
|
|
1210
1264
|
const state = store.getState();
|
|
1211
1265
|
const frame2 = canvasWindowFrame(state, windowId);
|
|
@@ -1489,6 +1543,16 @@ function selectCanvasItemHistory(s, itemId) {
|
|
|
1489
1543
|
return s.items[itemId]?.history ?? NO_HISTORY;
|
|
1490
1544
|
}
|
|
1491
1545
|
var selectCanvasCanGoBack = (s, itemId) => (s.items[itemId]?.history?.length ?? 0) > 0;
|
|
1546
|
+
var selectCanvasCanGoForward = (s, itemId) => (s.items[itemId]?.forward?.length ?? 0) > 0;
|
|
1547
|
+
function selectCanvasPresentedPaneId(s, windowId) {
|
|
1548
|
+
const f = frame(s, windowId);
|
|
1549
|
+
if (!f) return null;
|
|
1550
|
+
const ids = listPaneIds(f.layout);
|
|
1551
|
+
const holds = (id) => (s.panes[id]?.itemIds.length ?? 0) > 0;
|
|
1552
|
+
const focused = ids.find((id) => id === f.focusedPaneId);
|
|
1553
|
+
if (focused && holds(focused)) return focused;
|
|
1554
|
+
return ids.find(holds) ?? focused ?? ids[0] ?? null;
|
|
1555
|
+
}
|
|
1492
1556
|
|
|
1493
1557
|
// src/core/presentation.ts
|
|
1494
1558
|
var CANVAS_PHONE_MAX_WIDTH = 767;
|
|
@@ -1538,7 +1602,9 @@ function toggleKind(controller, input) {
|
|
|
1538
1602
|
const before = selectCanvasKindVisibility(controller.getState(), input.kind, key);
|
|
1539
1603
|
if (before === "visible") {
|
|
1540
1604
|
if ((input.whenVisible ?? "close") === "close") {
|
|
1605
|
+
const windowId = canvasWindowOfItem(controller.getState(), itemId);
|
|
1541
1606
|
controller.close(itemId);
|
|
1607
|
+
if (windowId && selectCanvasWindowItemCount(controller.getState(), windowId) === 0) controller.hide(windowId);
|
|
1542
1608
|
} else {
|
|
1543
1609
|
controller.hide(canvasWindowOfItem(controller.getState(), itemId) ?? void 0);
|
|
1544
1610
|
}
|
|
@@ -1569,6 +1635,7 @@ export {
|
|
|
1569
1635
|
CANVAS_MIN_SPLIT_FRACTION,
|
|
1570
1636
|
CANVAS_MIN_WIDTH,
|
|
1571
1637
|
CANVAS_NARROW_WIDTH,
|
|
1638
|
+
CANVAS_PANE_MIN_WIDTH,
|
|
1572
1639
|
CANVAS_PHONE_MAX_WIDTH,
|
|
1573
1640
|
CANVAS_SHORTCUTS,
|
|
1574
1641
|
CANVAS_STORAGE_KEY,
|
|
@@ -1609,6 +1676,7 @@ export {
|
|
|
1609
1676
|
sanitizeCanvasSnapshot,
|
|
1610
1677
|
selectCanvasActiveItem,
|
|
1611
1678
|
selectCanvasCanGoBack,
|
|
1679
|
+
selectCanvasCanGoForward,
|
|
1612
1680
|
selectCanvasExtraWindow,
|
|
1613
1681
|
selectCanvasFocusedPaneId,
|
|
1614
1682
|
selectCanvasIsFullscreen,
|
|
@@ -1621,6 +1689,7 @@ export {
|
|
|
1621
1689
|
selectCanvasLayout,
|
|
1622
1690
|
selectCanvasPane,
|
|
1623
1691
|
selectCanvasPaneCount,
|
|
1692
|
+
selectCanvasPresentedPaneId,
|
|
1624
1693
|
selectCanvasWidth,
|
|
1625
1694
|
selectCanvasWindowItemCount,
|
|
1626
1695
|
selectCanvasWindowOfItem,
|