@dxos/plugin-deck 0.8.1-staging.391c573 → 0.8.1-staging.9eaf14f
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/lib/browser/{app-graph-builder-IYHAGFA3.mjs → app-graph-builder-VYZ4IWI3.mjs} +3 -3
- package/dist/lib/browser/{check-app-scheme-S3EYUPMF.mjs → check-app-scheme-SEYECDHI.mjs} +2 -2
- package/dist/lib/browser/{chunk-YCKJNTKG.mjs → chunk-6ZSOFCPP.mjs} +26 -6
- package/dist/lib/browser/chunk-6ZSOFCPP.mjs.map +7 -0
- package/dist/lib/browser/chunk-B4LOJUWW.mjs +24 -0
- package/dist/lib/browser/{chunk-Z23S33X6.mjs → chunk-FJBMNSUC.mjs} +638 -483
- package/dist/lib/browser/chunk-FJBMNSUC.mjs.map +7 -0
- package/dist/lib/browser/chunk-FLOVGNYB.mjs +81 -0
- package/dist/lib/browser/chunk-FLOVGNYB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-N7TEPFVR.mjs → chunk-NSATFAEE.mjs} +3 -3
- package/dist/lib/browser/{chunk-N7TEPFVR.mjs.map → chunk-NSATFAEE.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-FYKBOM3C.mjs → chunk-RJNCG4ND.mjs} +66 -40
- package/dist/lib/browser/chunk-RJNCG4ND.mjs.map +7 -0
- package/dist/lib/browser/{chunk-22AQ5IVX.mjs → chunk-XMCG42ID.mjs} +2 -3
- package/dist/lib/browser/chunk-XMCG42ID.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +14 -9
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-P5BVUQKU.mjs → intent-resolver-UDYKO2QW.mjs} +78 -88
- package/dist/lib/browser/intent-resolver-UDYKO2QW.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-root-EP4UF3KA.mjs → react-root-XLXN2VEW.mjs} +8 -10
- package/dist/lib/browser/react-root-XLXN2VEW.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-5B3RLJCD.mjs → react-surface-WNGMZL7I.mjs} +11 -10
- package/dist/lib/browser/react-surface-WNGMZL7I.mjs.map +7 -0
- package/dist/lib/browser/{settings-X3P2HKQJ.mjs → settings-HMDGSBGO.mjs} +5 -4
- package/dist/lib/browser/settings-HMDGSBGO.mjs.map +7 -0
- package/dist/lib/browser/{state-2MOTLKVR.mjs → state-7TN26M42.mjs} +7 -11
- package/dist/lib/browser/state-7TN26M42.mjs.map +7 -0
- package/dist/lib/browser/tools-SC6QEN7R.mjs +78 -0
- package/dist/lib/browser/tools-SC6QEN7R.mjs.map +7 -0
- package/dist/lib/browser/types.mjs +12 -6
- package/dist/lib/browser/{url-handler-MVHTKUYA.mjs → url-handler-ODG4B6NX.mjs} +7 -9
- package/dist/lib/browser/url-handler-ODG4B6NX.mjs.map +7 -0
- package/dist/types/src/DeckPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +36 -14
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-root.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts.map +1 -1
- package/dist/types/src/capabilities/state.d.ts +18 -6
- package/dist/types/src/capabilities/state.d.ts.map +1 -1
- package/dist/types/src/capabilities/tools.d.ts +1 -0
- package/dist/types/src/capabilities/tools.d.ts.map +1 -1
- package/dist/types/src/capabilities/url-handler.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Banner.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +1 -4
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/index.d.ts +1 -0
- package/dist/types/src/components/DeckLayout/index.d.ts.map +1 -1
- package/dist/types/src/components/DeckSettings/DeckSettings.d.ts +6 -0
- package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -0
- package/dist/types/src/components/DeckSettings/index.d.ts +2 -0
- package/dist/types/src/components/DeckSettings/index.d.ts.map +1 -0
- package/dist/types/src/components/Plank/Plank.d.ts +14 -0
- package/dist/types/src/components/Plank/Plank.d.ts.map +1 -0
- package/dist/types/src/components/Plank/Plank.stories.d.ts +8 -0
- package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -0
- package/dist/types/src/components/{DeckLayout → Plank}/PlankControls.d.ts +8 -1
- package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -0
- package/dist/types/src/components/{DeckLayout → Plank}/PlankError.d.ts +2 -2
- package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -0
- package/dist/types/src/components/Plank/PlankHeading.d.ts +20 -0
- package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -0
- package/dist/types/src/components/Plank/PlankLoading.d.ts.map +1 -0
- package/dist/types/src/components/Plank/index.d.ts +6 -0
- package/dist/types/src/components/Plank/index.d.ts.map +1 -0
- package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -0
- package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -0
- package/dist/types/src/components/Sidebar/SidebarButton.d.ts.map +1 -0
- package/dist/types/src/components/Sidebar/index.d.ts +4 -0
- package/dist/types/src/components/Sidebar/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/events.d.ts +0 -1
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/layout.d.ts +7 -1
- package/dist/types/src/layout.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -5
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +4 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +50 -48
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/set-active.d.ts +2 -2
- package/dist/types/src/util/set-active.d.ts.map +1 -1
- package/dist/types/src/util/useCompanions.d.ts +8 -0
- package/dist/types/src/util/useCompanions.d.ts.map +1 -0
- package/dist/types/src/util/useHoistStatusbar.d.ts.map +1 -1
- package/package.json +28 -29
- package/src/DeckPlugin.ts +0 -1
- package/src/capabilities/capabilities.ts +3 -4
- package/src/capabilities/intent-resolver.ts +63 -9
- package/src/capabilities/react-root.tsx +1 -9
- package/src/capabilities/react-surface.tsx +3 -4
- package/src/capabilities/settings.ts +7 -2
- package/src/capabilities/state.ts +4 -11
- package/src/capabilities/tools.ts +34 -22
- package/src/capabilities/url-handler.ts +2 -8
- package/src/components/DeckLayout/ActiveNode.tsx +2 -1
- package/src/components/DeckLayout/Banner.tsx +5 -3
- package/src/components/DeckLayout/ContentEmpty.tsx +1 -1
- package/src/components/DeckLayout/DeckLayout.tsx +58 -24
- package/src/components/DeckLayout/Fullscreen.tsx +1 -1
- package/src/components/DeckLayout/Toast.tsx +1 -1
- package/src/components/DeckLayout/index.ts +2 -0
- package/src/components/{LayoutSettings.tsx → DeckSettings/DeckSettings.tsx} +15 -10
- package/src/components/DeckSettings/index.ts +5 -0
- package/src/components/Plank/Plank.stories.tsx +43 -0
- package/src/components/Plank/Plank.tsx +230 -0
- package/src/components/{DeckLayout → Plank}/PlankControls.tsx +73 -27
- package/src/components/{DeckLayout → Plank}/PlankError.tsx +3 -3
- package/src/components/Plank/PlankHeading.tsx +207 -0
- package/src/components/Plank/index.ts +9 -0
- package/src/components/{DeckLayout → Sidebar}/ComplementarySidebar.tsx +65 -81
- package/src/components/Sidebar/index.ts +7 -0
- package/src/components/index.ts +1 -1
- package/src/events.ts +0 -1
- package/src/hooks/index.ts +0 -1
- package/src/index.ts +1 -0
- package/src/layout.ts +19 -2
- package/src/meta.ts +4 -4
- package/src/translations.ts +4 -0
- package/src/types.ts +81 -79
- package/src/util/index.ts +1 -0
- package/src/util/set-active.ts +2 -2
- package/src/util/useCompanions.ts +18 -0
- package/src/util/useHoistStatusbar.ts +2 -2
- package/dist/lib/browser/chunk-22AQ5IVX.mjs.map +0 -7
- package/dist/lib/browser/chunk-FYKBOM3C.mjs.map +0 -7
- package/dist/lib/browser/chunk-IZ5RPJ6T.mjs +0 -24
- package/dist/lib/browser/chunk-YCKJNTKG.mjs.map +0 -7
- package/dist/lib/browser/chunk-Z23S33X6.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-P5BVUQKU.mjs.map +0 -7
- package/dist/lib/browser/react-root-EP4UF3KA.mjs.map +0 -7
- package/dist/lib/browser/react-surface-5B3RLJCD.mjs.map +0 -7
- package/dist/lib/browser/settings-X3P2HKQJ.mjs.map +0 -7
- package/dist/lib/browser/state-2MOTLKVR.mjs.map +0 -7
- package/dist/lib/browser/tools-64LXGLYR.mjs +0 -59
- package/dist/lib/browser/tools-64LXGLYR.mjs.map +0 -7
- package/dist/lib/browser/url-handler-MVHTKUYA.mjs.map +0 -7
- package/dist/types/src/components/DeckLayout/ComplementarySidebar.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts +0 -15
- package/dist/types/src/components/DeckLayout/NodePlankHeading.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/Plank.d.ts +0 -13
- package/dist/types/src/components/DeckLayout/Plank.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/PlankControls.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/PlankError.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/PlankLoading.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/Sidebar.d.ts.map +0 -1
- package/dist/types/src/components/DeckLayout/SidebarButton.d.ts.map +0 -1
- package/dist/types/src/components/LayoutSettings.d.ts +0 -6
- package/dist/types/src/components/LayoutSettings.d.ts.map +0 -1
- package/dist/types/src/hooks/useNode.d.ts +0 -11
- package/dist/types/src/hooks/useNode.d.ts.map +0 -1
- package/src/components/DeckLayout/NodePlankHeading.tsx +0 -148
- package/src/components/DeckLayout/Plank.tsx +0 -149
- package/src/hooks/useNode.ts +0 -46
- /package/dist/lib/browser/{app-graph-builder-IYHAGFA3.mjs.map → app-graph-builder-VYZ4IWI3.mjs.map} +0 -0
- /package/dist/lib/browser/{check-app-scheme-S3EYUPMF.mjs.map → check-app-scheme-SEYECDHI.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-IZ5RPJ6T.mjs.map → chunk-B4LOJUWW.mjs.map} +0 -0
- /package/dist/types/src/components/{DeckLayout → Plank}/PlankLoading.d.ts +0 -0
- /package/dist/types/src/components/{DeckLayout → Sidebar}/ComplementarySidebar.d.ts +0 -0
- /package/dist/types/src/components/{DeckLayout → Sidebar}/Sidebar.d.ts +0 -0
- /package/dist/types/src/components/{DeckLayout → Sidebar}/SidebarButton.d.ts +0 -0
- /package/src/components/{DeckLayout → Plank}/PlankLoading.tsx +0 -0
- /package/src/components/{DeckLayout → Sidebar}/Sidebar.tsx +0 -0
- /package/src/components/{DeckLayout → Sidebar}/SidebarButton.tsx +0 -0
|
@@ -16,16 +16,26 @@ import {
|
|
|
16
16
|
chain,
|
|
17
17
|
} from '@dxos/app-framework';
|
|
18
18
|
import { getTypename, S } from '@dxos/echo-schema';
|
|
19
|
+
import { invariant } from '@dxos/invariant';
|
|
19
20
|
import { isReactiveObject } from '@dxos/live-object';
|
|
20
21
|
import { log } from '@dxos/log';
|
|
21
22
|
import { AttentionCapabilities } from '@dxos/plugin-attention';
|
|
23
|
+
import { type Node } from '@dxos/plugin-graph';
|
|
22
24
|
import { ObservabilityAction } from '@dxos/plugin-observability/types';
|
|
23
|
-
import { isNonNullable } from '@dxos/util';
|
|
25
|
+
import { byPosition, isNonNullable } from '@dxos/util';
|
|
24
26
|
|
|
25
27
|
import { DeckCapabilities } from './capabilities';
|
|
26
|
-
import { closeEntry, incrementPlank, openEntry } from '../layout';
|
|
28
|
+
import { closeEntry, createEntryId, incrementPlank, openEntry } from '../layout';
|
|
27
29
|
import { DECK_PLUGIN } from '../meta';
|
|
28
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
DeckAction,
|
|
32
|
+
type LayoutMode,
|
|
33
|
+
type DeckSettingsProps,
|
|
34
|
+
isLayoutMode,
|
|
35
|
+
getMode,
|
|
36
|
+
defaultDeck,
|
|
37
|
+
PLANK_COMPANION_TYPE,
|
|
38
|
+
} from '../types';
|
|
29
39
|
import { setActive } from '../util';
|
|
30
40
|
|
|
31
41
|
export default (context: PluginsContext) =>
|
|
@@ -201,7 +211,7 @@ export default (context: PluginsContext) =>
|
|
|
201
211
|
}
|
|
202
212
|
state.activeDeck = subject;
|
|
203
213
|
if (!state.decks[subject]) {
|
|
204
|
-
state.decks[subject] = {
|
|
214
|
+
state.decks[subject] = { ...defaultDeck };
|
|
205
215
|
}
|
|
206
216
|
});
|
|
207
217
|
|
|
@@ -239,13 +249,14 @@ export default (context: PluginsContext) =>
|
|
|
239
249
|
const previouslyOpenIds = new Set<string>(state.deck.solo ? [state.deck.solo] : state.deck.active);
|
|
240
250
|
batch(() => {
|
|
241
251
|
const next = state.deck.solo
|
|
242
|
-
? (subject as string[])
|
|
252
|
+
? (subject as string[]).map((id) => createEntryId(id, options?.variant))
|
|
243
253
|
: subject.reduce(
|
|
244
254
|
(acc, entryId) =>
|
|
245
255
|
openEntry(acc, entryId, {
|
|
246
256
|
key: options?.key,
|
|
247
257
|
positioning: options?.positioning ?? settings?.newPlankPositioning,
|
|
248
258
|
pivotId: options?.pivotId,
|
|
259
|
+
variant: options?.variant,
|
|
249
260
|
}),
|
|
250
261
|
state.deck.active,
|
|
251
262
|
);
|
|
@@ -262,13 +273,13 @@ export default (context: PluginsContext) =>
|
|
|
262
273
|
? [createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: newlyOpen[0] ?? subject[0] })]
|
|
263
274
|
: []),
|
|
264
275
|
createIntent(LayoutAction.Expose, { part: 'navigation', subject: newlyOpen[0] ?? subject[0] }),
|
|
265
|
-
...newlyOpen.map((
|
|
266
|
-
const active = graph?.findNode(
|
|
276
|
+
...newlyOpen.map((subjectId) => {
|
|
277
|
+
const active = graph?.findNode(subjectId)?.data;
|
|
267
278
|
const typename = isReactiveObject(active) ? getTypename(active) : undefined;
|
|
268
279
|
return createIntent(ObservabilityAction.SendEvent, {
|
|
269
280
|
name: 'navigation.activate',
|
|
270
281
|
properties: {
|
|
271
|
-
|
|
282
|
+
subjectId,
|
|
272
283
|
typename,
|
|
273
284
|
},
|
|
274
285
|
});
|
|
@@ -287,8 +298,16 @@ export default (context: PluginsContext) =>
|
|
|
287
298
|
const active = state.deck.solo ? [state.deck.solo] : state.deck.active;
|
|
288
299
|
const next = subject.reduce((acc, id) => closeEntry(acc, id), active);
|
|
289
300
|
const toAttend = setActive({ next, state, attention });
|
|
301
|
+
|
|
302
|
+
const clearCompanionIntents = subject
|
|
303
|
+
.filter((id) => state.deck.activeCompanions && id in state.deck.activeCompanions)
|
|
304
|
+
.map((primary) => createIntent(DeckAction.ChangeCompanion, { primary, companion: null }));
|
|
305
|
+
|
|
290
306
|
return {
|
|
291
|
-
intents:
|
|
307
|
+
intents: [
|
|
308
|
+
...clearCompanionIntents,
|
|
309
|
+
...(toAttend ? [createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: toAttend })] : []),
|
|
310
|
+
],
|
|
292
311
|
};
|
|
293
312
|
},
|
|
294
313
|
}),
|
|
@@ -321,11 +340,29 @@ export default (context: PluginsContext) =>
|
|
|
321
340
|
state.deck.plankSizing[data.id] = data.size;
|
|
322
341
|
},
|
|
323
342
|
}),
|
|
343
|
+
createResolver({
|
|
344
|
+
intent: DeckAction.ChangeCompanion,
|
|
345
|
+
resolve: (data) => {
|
|
346
|
+
const state = context.requestCapability(DeckCapabilities.MutableDeckState);
|
|
347
|
+
// TODO(thure): Reactivity only works when creating a lexically new `activeCompanions`… Are these not proxy objects?
|
|
348
|
+
if (data.companion === null) {
|
|
349
|
+
const { [data.primary]: _, ...nextActiveCompanions } = state.deck.activeCompanions ?? {};
|
|
350
|
+
state.deck.activeCompanions = nextActiveCompanions;
|
|
351
|
+
} else {
|
|
352
|
+
invariant(data.companion !== data.primary);
|
|
353
|
+
state.deck.activeCompanions = {
|
|
354
|
+
...state.deck.activeCompanions,
|
|
355
|
+
[data.primary]: data.companion,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
}),
|
|
324
360
|
createResolver({
|
|
325
361
|
intent: DeckAction.Adjust,
|
|
326
362
|
resolve: (adjustment) => {
|
|
327
363
|
const state = context.requestCapability(DeckCapabilities.MutableDeckState);
|
|
328
364
|
const attention = context.requestCapability(AttentionCapabilities.Attention);
|
|
365
|
+
const { graph } = context.requestCapability(Capabilities.AppGraph);
|
|
329
366
|
|
|
330
367
|
return batch(() => {
|
|
331
368
|
if (adjustment.type === 'increment-end' || adjustment.type === 'increment-start') {
|
|
@@ -336,6 +373,23 @@ export default (context: PluginsContext) =>
|
|
|
336
373
|
});
|
|
337
374
|
}
|
|
338
375
|
|
|
376
|
+
if (adjustment.type === 'companion') {
|
|
377
|
+
const node = graph.findNode(adjustment.id);
|
|
378
|
+
const [companion] = node
|
|
379
|
+
? graph
|
|
380
|
+
.nodes(node, { filter: (n): n is Node<any> => n.type === PLANK_COMPANION_TYPE })
|
|
381
|
+
.toSorted((a, b) => byPosition(a.properties, b.properties))
|
|
382
|
+
: [];
|
|
383
|
+
if (companion) {
|
|
384
|
+
return {
|
|
385
|
+
intents: [
|
|
386
|
+
// TODO(wittjosiah): This should remember the previously selected companion.
|
|
387
|
+
createIntent(DeckAction.ChangeCompanion, { primary: adjustment.id, companion: companion.id }),
|
|
388
|
+
],
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
339
393
|
if (adjustment.type === 'solo') {
|
|
340
394
|
const entryId = adjustment.id;
|
|
341
395
|
if (!state.deck.solo) {
|
|
@@ -9,14 +9,12 @@ import { Capabilities, contributes, useCapability } from '@dxos/app-framework';
|
|
|
9
9
|
import { DeckCapabilities } from './capabilities';
|
|
10
10
|
import { DeckLayout } from '../components';
|
|
11
11
|
import { DECK_PLUGIN } from '../meta';
|
|
12
|
-
import { type DeckSettingsProps } from '../types';
|
|
13
12
|
|
|
14
13
|
export default () =>
|
|
15
14
|
contributes(Capabilities.ReactRoot, {
|
|
16
15
|
id: DECK_PLUGIN,
|
|
17
16
|
root: () => {
|
|
18
17
|
const layout = useCapability(DeckCapabilities.MutableDeckState);
|
|
19
|
-
const settings = useCapability(Capabilities.SettingsStore).getStore<DeckSettingsProps>(DECK_PLUGIN)!.value;
|
|
20
18
|
|
|
21
19
|
const handleDismissToast = useCallback(
|
|
22
20
|
(id: string) => {
|
|
@@ -35,12 +33,6 @@ export default () =>
|
|
|
35
33
|
[layout.toasts],
|
|
36
34
|
);
|
|
37
35
|
|
|
38
|
-
return
|
|
39
|
-
<DeckLayout
|
|
40
|
-
showHints={settings.showHints}
|
|
41
|
-
overscroll={settings.overscroll}
|
|
42
|
-
onDismissToast={handleDismissToast}
|
|
43
|
-
/>
|
|
44
|
-
);
|
|
36
|
+
return <DeckLayout onDismissToast={handleDismissToast} />;
|
|
45
37
|
},
|
|
46
38
|
});
|
|
@@ -7,19 +7,18 @@ import React from 'react';
|
|
|
7
7
|
import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
|
|
8
8
|
import { SettingsStore } from '@dxos/local-storage';
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import { Banner } from '../components/DeckLayout/Banner';
|
|
10
|
+
import { DeckSettings, Banner } from '../components';
|
|
12
11
|
import { DECK_PLUGIN } from '../meta';
|
|
13
12
|
import { type DeckSettingsProps } from '../types';
|
|
14
13
|
|
|
15
14
|
export default () =>
|
|
16
15
|
contributes(Capabilities.ReactSurface, [
|
|
17
16
|
createSurface({
|
|
18
|
-
id: `${DECK_PLUGIN}/settings`,
|
|
17
|
+
id: `${DECK_PLUGIN}/plugin-settings`,
|
|
19
18
|
role: 'article',
|
|
20
19
|
filter: (data): data is { subject: SettingsStore<DeckSettingsProps> } =>
|
|
21
20
|
data.subject instanceof SettingsStore && data.subject.prefix === DECK_PLUGIN,
|
|
22
|
-
component: ({ data: { subject } }) => <
|
|
21
|
+
component: ({ data: { subject } }) => <DeckSettings settings={subject.value} />,
|
|
23
22
|
}),
|
|
24
23
|
createSurface({
|
|
25
24
|
id: `${DECK_PLUGIN}/banner`,
|
|
@@ -11,11 +11,16 @@ import { DeckSettingsSchema, type DeckSettingsProps } from '../types';
|
|
|
11
11
|
export default () => {
|
|
12
12
|
const settings = create<DeckSettingsProps>({
|
|
13
13
|
showHints: false,
|
|
14
|
+
enableDeck: true,
|
|
14
15
|
enableNativeRedirect: false,
|
|
15
|
-
enableStatusbar:
|
|
16
|
+
enableStatusbar: false,
|
|
16
17
|
newPlankPositioning: 'start',
|
|
17
18
|
overscroll: 'none',
|
|
18
19
|
});
|
|
19
20
|
|
|
20
|
-
return contributes(Capabilities.Settings, {
|
|
21
|
+
return contributes(Capabilities.Settings, {
|
|
22
|
+
schema: DeckSettingsSchema,
|
|
23
|
+
prefix: DECK_PLUGIN,
|
|
24
|
+
value: settings,
|
|
25
|
+
});
|
|
21
26
|
};
|
|
@@ -10,7 +10,7 @@ import { type SidebarState } from '@dxos/react-ui';
|
|
|
10
10
|
|
|
11
11
|
import { DeckCapabilities } from './capabilities';
|
|
12
12
|
import { DECK_PLUGIN } from '../meta';
|
|
13
|
-
import { getMode, type
|
|
13
|
+
import { getMode, type DeckState, type DeckPluginState, defaultDeck } from '../types';
|
|
14
14
|
|
|
15
15
|
const boolean = /true|false/;
|
|
16
16
|
|
|
@@ -32,7 +32,7 @@ const migrateSidebarState = () => {
|
|
|
32
32
|
export default () => {
|
|
33
33
|
migrateSidebarState();
|
|
34
34
|
|
|
35
|
-
const state = new LocalStorageStore<
|
|
35
|
+
const state = new LocalStorageStore<DeckPluginState>(DECK_PLUGIN, {
|
|
36
36
|
sidebarState: 'expanded',
|
|
37
37
|
complementarySidebarState: 'collapsed',
|
|
38
38
|
complementarySidebarPanel: undefined,
|
|
@@ -48,14 +48,7 @@ export default () => {
|
|
|
48
48
|
activeDeck: 'default',
|
|
49
49
|
previousDeck: 'default',
|
|
50
50
|
decks: {
|
|
51
|
-
default: {
|
|
52
|
-
initialized: false,
|
|
53
|
-
active: [],
|
|
54
|
-
inactive: [],
|
|
55
|
-
fullscreen: false,
|
|
56
|
-
solo: undefined,
|
|
57
|
-
plankSizing: {},
|
|
58
|
-
},
|
|
51
|
+
default: { ...defaultDeck },
|
|
59
52
|
},
|
|
60
53
|
get deck() {
|
|
61
54
|
const deck = this.decks[this.activeDeck];
|
|
@@ -70,7 +63,7 @@ export default () => {
|
|
|
70
63
|
.prop({ key: 'sidebarState', type: LocalStorageStore.enum<SidebarState>() })
|
|
71
64
|
.prop({ key: 'complementarySidebarState', type: LocalStorageStore.enum<SidebarState>() })
|
|
72
65
|
.prop({ key: 'complementarySidebarPanel', type: LocalStorageStore.string({ allowUndefined: true }) })
|
|
73
|
-
.prop({ key: 'decks', type: LocalStorageStore.json<Record<string,
|
|
66
|
+
.prop({ key: 'decks', type: LocalStorageStore.json<Record<string, DeckState>>() })
|
|
74
67
|
.prop({ key: 'activeDeck', type: LocalStorageStore.string() })
|
|
75
68
|
.prop({ key: 'previousDeck', type: LocalStorageStore.string() });
|
|
76
69
|
|
|
@@ -14,12 +14,14 @@ import { S } from '@dxos/echo-schema';
|
|
|
14
14
|
import { invariant } from '@dxos/invariant';
|
|
15
15
|
|
|
16
16
|
import { meta } from '../meta';
|
|
17
|
+
import { DeckAction } from '../types';
|
|
17
18
|
|
|
18
19
|
// TODO(burdon): Factor out.
|
|
19
20
|
declare global {
|
|
20
21
|
interface ToolContextExtensions {
|
|
21
22
|
dispatch?: PromiseIntentDispatcher;
|
|
22
23
|
pivotId?: string;
|
|
24
|
+
part?: 'deck' | 'dialog';
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -27,10 +29,9 @@ export default () =>
|
|
|
27
29
|
contributes(Capabilities.Tools, [
|
|
28
30
|
defineTool(meta.id, {
|
|
29
31
|
name: 'show',
|
|
30
|
-
// TODO(ZaymonFC): We should update the prompt to teach the LLM the difference between object ids and fully qualified ids.
|
|
31
32
|
description: `
|
|
32
|
-
Show an item
|
|
33
|
-
When supplying IDs
|
|
33
|
+
Show an item as a companion to an existing plank. This will make the item appear alongside the primary content.
|
|
34
|
+
When supplying IDs, they must be fully qualified like space:object.
|
|
34
35
|
`,
|
|
35
36
|
caption: 'Showing item...',
|
|
36
37
|
// TODO(wittjosiah): Refactor Layout/Navigation/Deck actions so that they can be used directly.
|
|
@@ -38,29 +39,40 @@ export default () =>
|
|
|
38
39
|
id: S.String.annotations({
|
|
39
40
|
description: 'The ID of the item to show.',
|
|
40
41
|
}),
|
|
41
|
-
pivotId: S.optional(
|
|
42
|
-
S.String.annotations({
|
|
43
|
-
description: 'The ID of the chat. If provided, the item will be added after the pivot item.',
|
|
44
|
-
}),
|
|
45
|
-
),
|
|
46
42
|
}),
|
|
47
43
|
execute: async ({ id }, { extensions }) => {
|
|
44
|
+
invariant(extensions?.pivotId, 'No pivot ID');
|
|
48
45
|
invariant(extensions?.dispatch, 'No intent dispatcher');
|
|
49
|
-
const { data, error } = await extensions.dispatch(
|
|
50
|
-
createIntent(LayoutAction.Open, {
|
|
51
|
-
subject: [id],
|
|
52
|
-
part: 'main',
|
|
53
|
-
options: {
|
|
54
|
-
pivotId: extensions.pivotId,
|
|
55
|
-
positioning: 'end',
|
|
56
|
-
},
|
|
57
|
-
}),
|
|
58
|
-
);
|
|
59
|
-
if (error) {
|
|
60
|
-
return ToolResult.Error(error.message);
|
|
61
|
-
}
|
|
62
46
|
|
|
63
|
-
|
|
47
|
+
if (extensions.part === 'deck') {
|
|
48
|
+
const { data, error } = await extensions.dispatch(
|
|
49
|
+
createIntent(DeckAction.ChangeCompanion, {
|
|
50
|
+
primary: extensions.pivotId,
|
|
51
|
+
companion: id,
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
if (error) {
|
|
55
|
+
return ToolResult.Error(error.message);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return ToolResult.Success(data);
|
|
59
|
+
} else {
|
|
60
|
+
const { data, error } = await extensions.dispatch(
|
|
61
|
+
createIntent(LayoutAction.Open, {
|
|
62
|
+
subject: [id],
|
|
63
|
+
part: 'main',
|
|
64
|
+
options: {
|
|
65
|
+
pivotId: extensions.pivotId,
|
|
66
|
+
positioning: 'end',
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
);
|
|
70
|
+
if (error) {
|
|
71
|
+
return ToolResult.Error(error.message);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return ToolResult.Success(data);
|
|
75
|
+
}
|
|
64
76
|
},
|
|
65
77
|
}),
|
|
66
78
|
]);
|
|
@@ -6,6 +6,7 @@ import { Capabilities, contributes, createIntent, LayoutAction, type PluginsCont
|
|
|
6
6
|
import { scheduledEffect } from '@dxos/echo-signals/core';
|
|
7
7
|
|
|
8
8
|
import { DeckCapabilities } from './capabilities';
|
|
9
|
+
import { defaultDeck } from '../types';
|
|
9
10
|
|
|
10
11
|
// TODO(wittjosiah): Cleanup the url handling. May justify introducing routing capabilities.
|
|
11
12
|
export default async (context: PluginsContext) => {
|
|
@@ -17,14 +18,7 @@ export default async (context: PluginsContext) => {
|
|
|
17
18
|
if (pathname === '/reset') {
|
|
18
19
|
state.activeDeck = 'default';
|
|
19
20
|
state.decks = {
|
|
20
|
-
default: {
|
|
21
|
-
initialized: false,
|
|
22
|
-
active: [],
|
|
23
|
-
inactive: [],
|
|
24
|
-
fullscreen: false,
|
|
25
|
-
solo: undefined,
|
|
26
|
-
plankSizing: {},
|
|
27
|
-
},
|
|
21
|
+
default: { ...defaultDeck },
|
|
28
22
|
};
|
|
29
23
|
window.location.pathname = '/';
|
|
30
24
|
return;
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
import { Surface, useAppGraph } from '@dxos/app-framework';
|
|
8
|
+
import { useNode } from '@dxos/plugin-graph';
|
|
8
9
|
import { useAttended } from '@dxos/react-ui-attention';
|
|
9
10
|
|
|
10
|
-
import {
|
|
11
|
+
import { useNodeActionExpander } from '../../hooks';
|
|
11
12
|
|
|
12
13
|
// TODO(burdon): Factor out to effect in plugin set document title.
|
|
13
14
|
export const ActiveNode = () => {
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework';
|
|
8
|
-
import { type ThemedClassName } from '@dxos/react-ui';
|
|
8
|
+
import { useTranslation, type ThemedClassName } from '@dxos/react-ui';
|
|
9
9
|
import { mx } from '@dxos/react-ui-theme';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { DECK_PLUGIN } from '../../meta';
|
|
12
|
+
import { CloseSidebarButton, ToggleSidebarButton } from '../Sidebar';
|
|
12
13
|
|
|
13
14
|
export const Banner = ({ variant, classNames }: ThemedClassName<{ variant?: 'topbar' | 'sidebar' }>) => {
|
|
15
|
+
const { t } = useTranslation(DECK_PLUGIN);
|
|
14
16
|
return (
|
|
15
17
|
<header
|
|
16
18
|
className={mx(
|
|
@@ -21,7 +23,7 @@ export const Banner = ({ variant, classNames }: ThemedClassName<{ variant?: 'top
|
|
|
21
23
|
)}
|
|
22
24
|
>
|
|
23
25
|
{variant === 'sidebar' ? <CloseSidebarButton /> : <ToggleSidebarButton />}
|
|
24
|
-
<span className='self-center grow mis-1'>
|
|
26
|
+
<span className='self-center grow mis-1'>{t('current app name', { ns: 'appkit' })}</span>
|
|
25
27
|
{variant === 'topbar' && (
|
|
26
28
|
<div role='none' className='absolute inset-0 pointer-events-none'>
|
|
27
29
|
<div role='none' className='grid bs-full pointer-fine:p-1 max-is-md mli-auto pointer-events-auto'>
|
|
@@ -6,8 +6,8 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework';
|
|
8
8
|
|
|
9
|
-
import { ToggleSidebarButton } from './SidebarButton';
|
|
10
9
|
import { layoutAppliesTopbar, useBreakpoints } from '../../util';
|
|
10
|
+
import { ToggleSidebarButton } from '../Sidebar';
|
|
11
11
|
import { fixedSidebarToggleStyles } from '../fragments';
|
|
12
12
|
|
|
13
13
|
export const ContentEmpty = () => {
|
|
@@ -6,9 +6,10 @@ import { untracked } from '@preact/signals-core';
|
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useRef, type UIEvent, Fragment, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
+
Capabilities,
|
|
9
10
|
LayoutAction,
|
|
10
|
-
createIntent,
|
|
11
11
|
Surface,
|
|
12
|
+
createIntent,
|
|
12
13
|
useCapability,
|
|
13
14
|
useIntentDispatcher,
|
|
14
15
|
usePluginManager,
|
|
@@ -27,32 +28,29 @@ import { Stack, StackContext, DEFAULT_HORIZONTAL_SIZE } from '@dxos/react-ui-sta
|
|
|
27
28
|
import { mainPaddingTransitions } from '@dxos/react-ui-theme';
|
|
28
29
|
|
|
29
30
|
import { ActiveNode } from './ActiveNode';
|
|
30
|
-
import { ComplementarySidebar } from './ComplementarySidebar';
|
|
31
31
|
import { ContentEmpty } from './ContentEmpty';
|
|
32
32
|
import { Fullscreen } from './Fullscreen';
|
|
33
|
-
import { Plank } from './Plank';
|
|
34
|
-
import { PlankContentError } from './PlankError';
|
|
35
|
-
import { Sidebar } from './Sidebar';
|
|
36
|
-
import { ToggleComplementarySidebarButton, ToggleSidebarButton } from './SidebarButton';
|
|
37
33
|
import { StatusBar } from './StatusBar';
|
|
38
34
|
import { Toast } from './Toast';
|
|
39
35
|
import { Topbar } from './Topbar';
|
|
40
36
|
import { DeckCapabilities } from '../../capabilities';
|
|
41
|
-
import {
|
|
37
|
+
import { DECK_PLUGIN } from '../../meta';
|
|
38
|
+
import { type DeckSettingsProps, getMode } from '../../types';
|
|
42
39
|
import { calculateOverscroll, layoutAppliesTopbar, useBreakpoints, useHoistStatusbar } from '../../util';
|
|
40
|
+
import { Plank, PlankContentError } from '../Plank';
|
|
41
|
+
import { ComplementarySidebar, Sidebar, ToggleComplementarySidebarButton, ToggleSidebarButton } from '../Sidebar';
|
|
43
42
|
import { fixedComplementarySidebarToggleStyles, fixedSidebarToggleStyles } from '../fragments';
|
|
44
43
|
|
|
45
44
|
export type DeckLayoutProps = {
|
|
46
|
-
overscroll: Overscroll;
|
|
47
|
-
showHints: boolean;
|
|
48
45
|
onDismissToast: (id: string) => void;
|
|
49
46
|
};
|
|
50
47
|
|
|
51
|
-
const PlankSeparator = ({
|
|
52
|
-
|
|
48
|
+
const PlankSeparator = ({ order }: { order: number }) =>
|
|
49
|
+
order > 0 ? <span role='separator' className='row-span-2 bg-deck is-4' style={{ gridColumn: order }} /> : null;
|
|
53
50
|
|
|
54
|
-
export const DeckLayout = ({
|
|
51
|
+
export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
55
52
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
53
|
+
const settings = useCapability(Capabilities.SettingsStore).getStore<DeckSettingsProps>(DECK_PLUGIN)!.value;
|
|
56
54
|
const context = useCapability(DeckCapabilities.MutableDeckState);
|
|
57
55
|
const {
|
|
58
56
|
sidebarState,
|
|
@@ -68,7 +66,7 @@ export const DeckLayout = ({ overscroll, showHints, onDismissToast }: DeckLayout
|
|
|
68
66
|
deck,
|
|
69
67
|
toasts,
|
|
70
68
|
} = context;
|
|
71
|
-
const { active, fullscreen, solo, plankSizing } = deck;
|
|
69
|
+
const { active, activeCompanions, fullscreen, solo, plankSizing } = deck;
|
|
72
70
|
const breakpoint = useBreakpoints();
|
|
73
71
|
const topbar = layoutAppliesTopbar(breakpoint);
|
|
74
72
|
const hoistStatusbar = useHoistStatusbar(breakpoint);
|
|
@@ -120,6 +118,15 @@ export const DeckLayout = ({ overscroll, showHints, onDismissToast }: DeckLayout
|
|
|
120
118
|
}
|
|
121
119
|
}, [isNotMobile, deck, dispatch]);
|
|
122
120
|
|
|
121
|
+
// If deck is disabled in settings, ensure that the layout is in solo mode.
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (!settings.enableDeck) {
|
|
124
|
+
void dispatch(
|
|
125
|
+
createIntent(LayoutAction.SetLayoutMode, { part: 'mode', subject: active[0], options: { mode: 'solo' } }),
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}, [settings.enableDeck, dispatch, active]);
|
|
129
|
+
|
|
123
130
|
/**
|
|
124
131
|
* Clear scroll restoration state if the window is resized
|
|
125
132
|
*/
|
|
@@ -156,11 +163,11 @@ export const DeckLayout = ({ overscroll, showHints, onDismissToast }: DeckLayout
|
|
|
156
163
|
const isEmpty = !solo && active.length === 0;
|
|
157
164
|
|
|
158
165
|
const padding = useMemo(() => {
|
|
159
|
-
if (!solo && overscroll === 'centering') {
|
|
166
|
+
if (!solo && settings.overscroll === 'centering') {
|
|
160
167
|
return calculateOverscroll(active.length);
|
|
161
168
|
}
|
|
162
169
|
return {};
|
|
163
|
-
}, [solo, overscroll, deck]);
|
|
170
|
+
}, [solo, settings.overscroll, deck]);
|
|
164
171
|
|
|
165
172
|
const mainPosition = useMemo(
|
|
166
173
|
() => [
|
|
@@ -187,6 +194,17 @@ export const DeckLayout = ({ overscroll, showHints, onDismissToast }: DeckLayout
|
|
|
187
194
|
);
|
|
188
195
|
const handlePopoverClose = useCallback(() => handlePopoverOpenChange(false), [handlePopoverOpenChange]);
|
|
189
196
|
|
|
197
|
+
const { order, itemsCount }: { order: Record<string, number>; itemsCount: number } = useMemo(() => {
|
|
198
|
+
return active.reduce(
|
|
199
|
+
(acc: { order: Record<string, number>; itemsCount: number }, entryId) => {
|
|
200
|
+
acc.order[entryId] = acc.itemsCount + 1;
|
|
201
|
+
acc.itemsCount += activeCompanions?.[entryId] ? 3 : 2;
|
|
202
|
+
return acc;
|
|
203
|
+
},
|
|
204
|
+
{ order: {}, itemsCount: 0 },
|
|
205
|
+
);
|
|
206
|
+
}, [active, activeCompanions]);
|
|
207
|
+
|
|
190
208
|
return (
|
|
191
209
|
<Popover.Root modal open={!!(popoverAnchorId && delayedPopoverVisibility)} onOpenChange={handlePopoverOpenChange}>
|
|
192
210
|
<ActiveNode />
|
|
@@ -249,18 +267,26 @@ export const DeckLayout = ({ overscroll, showHints, onDismissToast }: DeckLayout
|
|
|
249
267
|
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
250
268
|
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
251
269
|
<Stack
|
|
270
|
+
ref={deckRef}
|
|
252
271
|
orientation='horizontal'
|
|
253
272
|
size='contain'
|
|
254
273
|
classNames={['absolute inset-block-0 -inset-inline-px', mainPaddingTransitions]}
|
|
255
|
-
|
|
256
|
-
itemsCount={2 * (active.length ?? 0) - 1}
|
|
274
|
+
itemsCount={itemsCount - 1}
|
|
257
275
|
style={padding}
|
|
258
|
-
|
|
276
|
+
onScroll={handleScroll}
|
|
259
277
|
>
|
|
260
|
-
{active.map((entryId
|
|
278
|
+
{active.map((entryId) => (
|
|
261
279
|
<Fragment key={entryId}>
|
|
262
|
-
<PlankSeparator
|
|
263
|
-
<Plank
|
|
280
|
+
<PlankSeparator order={order[entryId] - 1} />
|
|
281
|
+
<Plank
|
|
282
|
+
id={entryId}
|
|
283
|
+
companionId={activeCompanions?.[entryId]}
|
|
284
|
+
part='deck'
|
|
285
|
+
order={order[entryId]}
|
|
286
|
+
active={active}
|
|
287
|
+
layoutMode={layoutMode}
|
|
288
|
+
settings={settings}
|
|
289
|
+
/>
|
|
264
290
|
</Fragment>
|
|
265
291
|
))}
|
|
266
292
|
</Stack>
|
|
@@ -273,15 +299,23 @@ export const DeckLayout = ({ overscroll, showHints, onDismissToast }: DeckLayout
|
|
|
273
299
|
{!topbar && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
274
300
|
{!topbar && <ToggleComplementarySidebarButton classNames={fixedComplementarySidebarToggleStyles} />}
|
|
275
301
|
<StackContext.Provider value={{ size: 'contain', orientation: 'horizontal', rail: true }}>
|
|
276
|
-
<Plank
|
|
302
|
+
<Plank
|
|
303
|
+
id={solo}
|
|
304
|
+
companionId={solo ? activeCompanions?.[solo] : undefined}
|
|
305
|
+
part='solo'
|
|
306
|
+
layoutMode={layoutMode}
|
|
307
|
+
settings={settings}
|
|
308
|
+
/>
|
|
277
309
|
</StackContext.Provider>
|
|
278
310
|
</div>
|
|
279
311
|
</Main.Content>
|
|
280
312
|
)}
|
|
281
313
|
|
|
282
|
-
{/*
|
|
314
|
+
{/* Topbar. */}
|
|
283
315
|
{topbar && <Topbar />}
|
|
284
|
-
|
|
316
|
+
|
|
317
|
+
{/* Status bar. */}
|
|
318
|
+
{hoistStatusbar && <StatusBar showHints={settings.showHints} />}
|
|
285
319
|
</Main.Root>
|
|
286
320
|
)}
|
|
287
321
|
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
import { Surface, useAppGraph } from '@dxos/app-framework';
|
|
8
|
+
import { useNode } from '@dxos/plugin-graph';
|
|
8
9
|
import { fixedInsetFlexLayout } from '@dxos/react-ui-theme';
|
|
9
10
|
|
|
10
11
|
import { Fallback } from './Fallback';
|
|
11
12
|
import { SURFACE_PREFIX } from './constants';
|
|
12
|
-
import { useNode } from '../../hooks';
|
|
13
13
|
|
|
14
14
|
export const Fullscreen = ({ id }: { id?: string }) => {
|
|
15
15
|
const { graph } = useAppGraph();
|