@glassly/engine 0.3.4-dev.704 → 0.3.5-dev.705
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/build/generated/releaseMetadata.js +4 -4
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/services/AppRegistry.d.ts +3 -1
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +5 -2
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +32 -0
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +332 -1
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +2 -0
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/MiniappWidgetMode.d.ts +24 -0
- package/build/services/MiniappWidgetMode.d.ts.map +1 -0
- package/build/services/MiniappWidgetMode.js +58 -0
- package/build/services/MiniappWidgetMode.js.map +1 -0
- package/build/services/manifestActions.d.ts +8 -1
- package/build/services/manifestActions.d.ts.map +1 -1
- package/build/services/manifestActions.js +29 -0
- package/build/services/manifestActions.js.map +1 -1
- package/build/services/widgetPlacements.d.ts +43 -0
- package/build/services/widgetPlacements.d.ts.map +1 -0
- package/build/services/widgetPlacements.js +83 -0
- package/build/services/widgetPlacements.js.map +1 -0
- package/build/stores/apps.d.ts +3 -1
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +37 -11
- package/build/stores/apps.js.map +1 -1
- package/build/types/applet.d.ts +16 -0
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/package.json +7 -7
- package/src/generated/releaseMetadata.ts +4 -4
- package/src/index.ts +1 -0
- package/src/services/AppRegistry.ts +8 -2
- package/src/services/LocalMiniappRuntime.ts +362 -2
- package/src/services/MiniappLauncher.ts +3 -0
- package/src/services/MiniappWidgetMode.ts +62 -0
- package/src/services/manifestActions.ts +29 -1
- package/src/services/widgetPlacements.ts +121 -0
- package/src/stores/apps.ts +45 -11
- package/src/types/applet.ts +18 -0
package/src/stores/apps.ts
CHANGED
|
@@ -26,6 +26,7 @@ import sttModelManager from "../services/STTModelManager"
|
|
|
26
26
|
import {miniappLauncher} from "../services/MiniappLauncher"
|
|
27
27
|
import {isMiniappsPaused, onMiniappsPauseChange} from "../services/MiniappPauseCoordinator"
|
|
28
28
|
import {miniappRunningRegistry} from "../services/MiniappRunningRegistry"
|
|
29
|
+
import {miniappWidgetMode} from "../services/MiniappWidgetMode"
|
|
29
30
|
import {defaultHiddenStatus, isGatedByDevTools, isGatedUntilPaired, resolveHiddenStatus} from "./appVisibility"
|
|
30
31
|
import {SETTINGS, useSettingsStore} from "./settings"
|
|
31
32
|
import BluetoothSdk from "@glassly/bluetooth-sdk"
|
|
@@ -373,16 +374,21 @@ export const useAppStatusStore = create<AppStatusState>((set, get) => ({
|
|
|
373
374
|
|
|
374
375
|
// If the tapped app is already running, this is a re-open: the nav/foreground
|
|
375
376
|
// above already drove the animation, and there's nothing to spawn. Short-
|
|
376
|
-
// circuit before the spawn pipeline.
|
|
377
|
-
|
|
377
|
+
// circuit before the spawn pipeline. An app running only for its widget
|
|
378
|
+
// is promoted instead: it keeps its context and takes the foreground.
|
|
379
|
+
if (app.running && !app.widgetOnly) {
|
|
378
380
|
saveLastOpenTime(packageName)
|
|
379
381
|
return true
|
|
380
382
|
}
|
|
383
|
+
if (app.widgetOnly) miniappWidgetMode.setWidgetOnly(packageName, false)
|
|
381
384
|
|
|
382
385
|
// Only-one rules: one standard app in the foreground, one dashboard
|
|
383
|
-
// drawing the overlay. Starting another stops the one running.
|
|
386
|
+
// drawing the overlay. Starting another stops the one running. Widget-only
|
|
387
|
+
// peers hold no foreground, so they stay.
|
|
384
388
|
if (app.type === "standard" || app.type === "dashboard") {
|
|
385
|
-
const runningPeers = state.apps.filter(
|
|
389
|
+
const runningPeers = state.apps.filter(
|
|
390
|
+
(a) => a.running && !a.widgetOnly && a.type === app.type && a.packageName !== packageName,
|
|
391
|
+
)
|
|
386
392
|
for (const r of runningPeers) {
|
|
387
393
|
await get().stop(r.packageName)
|
|
388
394
|
}
|
|
@@ -429,6 +435,22 @@ export const useAppStatusStore = create<AppStatusState>((set, get) => ({
|
|
|
429
435
|
return
|
|
430
436
|
}
|
|
431
437
|
|
|
438
|
+
// A placed widget provider is the dashboard's to keep: closing it from
|
|
439
|
+
// the tray takes its card and its frame, and it runs on in widget mode.
|
|
440
|
+
if (app.local && app.running && miniappWidgetMode.isPlaced(packageName)) {
|
|
441
|
+
if (!app.widgetOnly) {
|
|
442
|
+
miniappWidgetMode.setWidgetOnly(packageName, true)
|
|
443
|
+
localDisplayManager.onUnmount(packageName)
|
|
444
|
+
set((s) => ({
|
|
445
|
+
foregroundedPackage: s.foregroundedPackage === packageName ? null : s.foregroundedPackage,
|
|
446
|
+
apps: s.apps.map((a) =>
|
|
447
|
+
a.packageName === packageName ? {...a, screenshot: undefined, foregrounded: false, loading: false} : a,
|
|
448
|
+
),
|
|
449
|
+
}))
|
|
450
|
+
}
|
|
451
|
+
return
|
|
452
|
+
}
|
|
453
|
+
|
|
432
454
|
set((s) => ({
|
|
433
455
|
apps: s.apps.map((a) =>
|
|
434
456
|
a.packageName === packageName ? {...a, running: false, screenshot: undefined, loading: false} : a,
|
|
@@ -494,7 +516,8 @@ export const useAppStatusStore = create<AppStatusState>((set, get) => ({
|
|
|
494
516
|
stopAll: () => {
|
|
495
517
|
return Res.try_async(async () => {
|
|
496
518
|
// Always On apps stay up; they stop one at a time from the switcher.
|
|
497
|
-
|
|
519
|
+
// Widget-only apps have no card to close; they are the dashboard's.
|
|
520
|
+
const running = get().apps.filter((a) => a.running && !a.alwaysOn && !a.widgetOnly)
|
|
498
521
|
for (const a of running) {
|
|
499
522
|
await get().stop(a.packageName)
|
|
500
523
|
}
|
|
@@ -578,15 +601,17 @@ function projectLocalRunningState(): void {
|
|
|
578
601
|
if (!app.local) return app
|
|
579
602
|
const next = running.has(app.packageName)
|
|
580
603
|
const paused = next && pausedNow
|
|
581
|
-
|
|
604
|
+
const widgetOnly = next && miniappWidgetMode.isWidgetOnly(app.packageName)
|
|
605
|
+
if (app.running === next && (app.paused ?? false) === paused && (app.widgetOnly ?? false) === widgetOnly) return app
|
|
582
606
|
changed = true
|
|
583
|
-
return {...app, running: next, paused}
|
|
607
|
+
return {...app, running: next, paused, widgetOnly}
|
|
584
608
|
})
|
|
585
609
|
if (changed) {
|
|
586
610
|
useAppStatusStore.setState({apps: updated})
|
|
587
611
|
}
|
|
588
612
|
}
|
|
589
613
|
miniappRunningRegistry.subscribe(projectLocalRunningState)
|
|
614
|
+
miniappWidgetMode.subscribe(projectLocalRunningState)
|
|
590
615
|
onMiniappsPauseChange(projectLocalRunningState)
|
|
591
616
|
|
|
592
617
|
// The display-manager's core (foreground) slot is DERIVED state: always the
|
|
@@ -596,7 +621,7 @@ onMiniappsPauseChange(projectLocalRunningState)
|
|
|
596
621
|
// sites, so no launch/stop path can forget to claim or release the slot.
|
|
597
622
|
// onCoreAppChange is idempotent, so firing on every store write is free.
|
|
598
623
|
useAppStatusStore.subscribe((state) => {
|
|
599
|
-
const core = state.apps.find((a) => a.running && (a.type === "standard" || !a.type))
|
|
624
|
+
const core = state.apps.find((a) => a.running && !a.widgetOnly && (a.type === "standard" || !a.type))
|
|
600
625
|
localDisplayManager.onCoreAppChange(core?.packageName ?? null)
|
|
601
626
|
})
|
|
602
627
|
|
|
@@ -657,10 +682,16 @@ export const useStopAll = () => useAppStatusStore((state) => state.stopAll)
|
|
|
657
682
|
export const useInstall = () => useAppStatusStore((state) => state.install)
|
|
658
683
|
export const useUninstall = () => useAppStatusStore((state) => state.uninstall)
|
|
659
684
|
|
|
660
|
-
/** Every running app
|
|
685
|
+
/** Every running app with a card in the app switcher tray: widget-only apps have none. */
|
|
661
686
|
export const useActiveApps = () => {
|
|
662
687
|
const apps = useApps()
|
|
663
|
-
return useMemo(() => apps.filter((app) => app.running), [apps])
|
|
688
|
+
return useMemo(() => apps.filter((app) => app.running && !app.widgetOnly), [apps])
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/** Apps running only for a widget the dashboard placed; the switcher's Widgets pill lists them. */
|
|
692
|
+
export const useWidgetApps = () => {
|
|
693
|
+
const apps = useApps()
|
|
694
|
+
return useMemo(() => apps.filter((app) => app.running && app.widgetOnly), [apps])
|
|
664
695
|
}
|
|
665
696
|
|
|
666
697
|
/** Always On apps whose background task is running, card or no card. */
|
|
@@ -690,7 +721,10 @@ export const useBackgroundApps = () => {
|
|
|
690
721
|
|
|
691
722
|
export const useActiveForegroundApp = () => {
|
|
692
723
|
const apps = useApps()
|
|
693
|
-
return useMemo(
|
|
724
|
+
return useMemo(
|
|
725
|
+
() => apps.find((app) => (app.type === "standard" || !app.type) && app.running && !app.widgetOnly) ?? null,
|
|
726
|
+
[apps],
|
|
727
|
+
)
|
|
694
728
|
}
|
|
695
729
|
|
|
696
730
|
/**
|
package/src/types/applet.ts
CHANGED
|
@@ -89,6 +89,16 @@ export interface DeclaredAction {
|
|
|
89
89
|
visibility?: "public" | "system"
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
export type DeclaredWidgetSize = "XS" | "SM" | "MD" | "LG"
|
|
93
|
+
|
|
94
|
+
/** A dashboard widget a miniapp declares in `miniapp.json` and serves through `session.widgets`. */
|
|
95
|
+
export interface DeclaredWidget {
|
|
96
|
+
id: string
|
|
97
|
+
name: string
|
|
98
|
+
sizes: DeclaredWidgetSize[]
|
|
99
|
+
defaultSize: DeclaredWidgetSize
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
export interface ClientApp extends AppletInterface {
|
|
93
103
|
offline: boolean
|
|
94
104
|
offlineRoute: string
|
|
@@ -124,4 +134,12 @@ export interface ClientApp extends AppletInterface {
|
|
|
124
134
|
isMiniappDev?: boolean
|
|
125
135
|
/** Manifest-declared actions (for session.miniapps.list + invoke gating). */
|
|
126
136
|
actions?: DeclaredAction[]
|
|
137
|
+
/** Manifest-declared dashboard widgets. */
|
|
138
|
+
widgets?: DeclaredWidget[]
|
|
139
|
+
/**
|
|
140
|
+
* Running only because a host placed one of its widgets: no card in the
|
|
141
|
+
* app switcher, no frame of its own on the glasses. Opening the app from
|
|
142
|
+
* the home screen promotes it to a normal run.
|
|
143
|
+
*/
|
|
144
|
+
widgetOnly?: boolean
|
|
127
145
|
}
|