@glassly/engine 0.3.5-dev.790 → 0.3.5-dev.800
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/engine.d.ts +1 -0
- package/build/engine.d.ts.map +1 -1
- package/build/facades/miniapps.d.ts +2 -0
- package/build/facades/miniapps.d.ts.map +1 -1
- package/build/facades/miniapps.js +2 -0
- package/build/facades/miniapps.js.map +1 -1
- package/build/generated/releaseMetadata.js +3 -3
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/services/AppRegistry.d.ts +4 -1
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +16 -2
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +2 -0
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +22 -2
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/manifestActions.d.ts +4 -2
- package/build/services/manifestActions.d.ts.map +1 -1
- package/build/services/manifestActions.js +8 -3
- package/build/services/manifestActions.js.map +1 -1
- package/build/stores/apps.d.ts +6 -0
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +16 -1
- package/build/stores/apps.js.map +1 -1
- package/build/types/applet.d.ts +3 -1
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/package.json +7 -7
- package/src/facades/miniapps.ts +3 -0
- package/src/generated/releaseMetadata.ts +3 -3
- package/src/services/AppRegistry.ts +18 -3
- package/src/services/LocalMiniappRuntime.ts +24 -2
- package/src/services/manifestActions.ts +8 -3
- package/src/stores/apps.ts +23 -1
- package/src/types/applet.ts +3 -1
|
@@ -22,7 +22,7 @@ import {unzip} from "react-native-zip-archive"
|
|
|
22
22
|
import semver from "semver"
|
|
23
23
|
import {AsyncResult, Result, result as Res} from "typesafe-ts"
|
|
24
24
|
|
|
25
|
-
import type {AppletPermission, AppPermissionType, AppletType, ClientApp} from "../types/applet"
|
|
25
|
+
import type {AppletPermission, AppPermissionType, AppletType, ClientApp, DeclaredWidget} from "../types/applet"
|
|
26
26
|
import {HardwareRequirement, HardwareRequirementLevel, HardwareType} from "../types"
|
|
27
27
|
import {configuredDevHost} from "../utils/configuredDevHost"
|
|
28
28
|
import {storage} from "../utils/storage/storage"
|
|
@@ -776,7 +776,7 @@ class AppRegistry {
|
|
|
776
776
|
|
|
777
777
|
// Declared actions (for session.miniapps.list + invoke gating).
|
|
778
778
|
const actions = normalizeManifestActions(manifest?.actions)
|
|
779
|
-
const widgets = normalizeManifestWidgets(manifest?.widgets)
|
|
779
|
+
const widgets = withWidgetExpandChoices(lmaInfo.packageName, normalizeManifestWidgets(manifest?.widgets))
|
|
780
780
|
|
|
781
781
|
// Dev miniapps live in the same lmas/ tree as installed ones, but
|
|
782
782
|
// their version directory name starts with "dev-".
|
|
@@ -864,7 +864,9 @@ class AppRegistry {
|
|
|
864
864
|
permissions,
|
|
865
865
|
hardwareRequirements,
|
|
866
866
|
actions: normalizeManifestActions(rec.actions),
|
|
867
|
-
...(normalizeManifestWidgets(rec.widgets).length > 0
|
|
867
|
+
...(normalizeManifestWidgets(rec.widgets).length > 0
|
|
868
|
+
? {widgets: withWidgetExpandChoices(rec.packageName, normalizeManifestWidgets(rec.widgets))}
|
|
869
|
+
: {}),
|
|
868
870
|
isMiniappDev: true,
|
|
869
871
|
devUrl: rec.devUrl,
|
|
870
872
|
devPort: rec.devPort,
|
|
@@ -948,6 +950,19 @@ export function saveAlwaysOnOverride(packageName: string, status: boolean): void
|
|
|
948
950
|
storage.save(`${packageName}_always_on`, status)
|
|
949
951
|
}
|
|
950
952
|
|
|
953
|
+
/** Applies the wearer's tap-to-expand choice to each expandable widget; expansion is on until they turn it off. */
|
|
954
|
+
export function withWidgetExpandChoices(packageName: string, widgets: DeclaredWidget[]): DeclaredWidget[] {
|
|
955
|
+
return widgets.map((widget) => {
|
|
956
|
+
if (!widget.expandable) return widget
|
|
957
|
+
const res = storage.load<boolean>(`${packageName}_widget_expand_${widget.id}`)
|
|
958
|
+
return {...widget, expandOnTap: res.is_ok() ? res.value !== false : true}
|
|
959
|
+
})
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
export function saveWidgetExpandChoice(packageName: string, widgetId: string, expandOnTap: boolean): void {
|
|
963
|
+
storage.save(`${packageName}_widget_expand_${widgetId}`, expandOnTap)
|
|
964
|
+
}
|
|
965
|
+
|
|
951
966
|
export function getLocalAppScreenshot(packageName: string): string | undefined {
|
|
952
967
|
const key = `${packageName}_screenshot`
|
|
953
968
|
const res = storage.load<string>(key)
|
|
@@ -1824,6 +1824,9 @@ class LocalMiniappRuntime {
|
|
|
1824
1824
|
case MiniappRequestType.WIDGET_RESULT:
|
|
1825
1825
|
this.handleWidgetResult(packageName, payload)
|
|
1826
1826
|
break
|
|
1827
|
+
case MiniappRequestType.WIDGET_EXPANDABLE:
|
|
1828
|
+
this.handleWidgetExpandable(packageName, payload, requestId)
|
|
1829
|
+
break
|
|
1827
1830
|
case MiniappRequestType.SYSTEM_EXIT:
|
|
1828
1831
|
void this.handleSystemExit(packageName, requestId)
|
|
1829
1832
|
break
|
|
@@ -6371,7 +6374,7 @@ class LocalMiniappRuntime {
|
|
|
6371
6374
|
name: widget.name,
|
|
6372
6375
|
sizes: widget.sizes,
|
|
6373
6376
|
defaultSize: widget.defaultSize,
|
|
6374
|
-
expandable: widget.
|
|
6377
|
+
expandable: widget.expandOnTap,
|
|
6375
6378
|
running: app.running,
|
|
6376
6379
|
compatible: app.compatibility?.isCompatible !== false,
|
|
6377
6380
|
})
|
|
@@ -6580,6 +6583,25 @@ class LocalMiniappRuntime {
|
|
|
6580
6583
|
}
|
|
6581
6584
|
}
|
|
6582
6585
|
|
|
6586
|
+
/** Provider: read, or set with `expandable`, whether a tap expands one of its own `EX` widgets. */
|
|
6587
|
+
private handleWidgetExpandable(packageName: string, payload: Record<string, unknown>, requestId?: string): void {
|
|
6588
|
+
const widgetId = payload.widgetId as string | undefined
|
|
6589
|
+
const app = this.interopApps().find((a) => a.packageName === packageName)
|
|
6590
|
+
const widget = app && widgetId ? this.declaredWidget(app, widgetId) : undefined
|
|
6591
|
+
if (!widget?.expandable) {
|
|
6592
|
+
this.sendResult(packageName, requestId, false, undefined, {
|
|
6593
|
+
code: MiniappErrorCode.WIDGET_NOT_FOUND,
|
|
6594
|
+
message: `${packageName} has no widget "${widgetId ?? "(missing widgetId)"}" that lists EX`,
|
|
6595
|
+
})
|
|
6596
|
+
return
|
|
6597
|
+
}
|
|
6598
|
+
const expandable =
|
|
6599
|
+
typeof payload.expandable === "boolean"
|
|
6600
|
+
? useAppStatusStore.getState().setWidgetExpand(packageName, widget.id, payload.expandable)
|
|
6601
|
+
: widget.expandOnTap
|
|
6602
|
+
this.sendResult(packageName, requestId, true, {expandable})
|
|
6603
|
+
}
|
|
6604
|
+
|
|
6583
6605
|
/** Provider → host, one-shot: cache the frame for its view and push it to every host holding the widget. */
|
|
6584
6606
|
private handleWidgetUpdate(providerPackageName: string, payload: Record<string, unknown>): void {
|
|
6585
6607
|
const widgetId = payload.widgetId as string | undefined
|
|
@@ -6591,7 +6613,7 @@ class LocalMiniappRuntime {
|
|
|
6591
6613
|
const view: WidgetView = payload.view === "expanded" ? "expanded" : "card"
|
|
6592
6614
|
if (view === "expanded" && !widget.expandable) {
|
|
6593
6615
|
console.warn(
|
|
6594
|
-
`${LOG_TAG}: dropping expanded frame from ${providerPackageName}/${widgetId}: not
|
|
6616
|
+
`${LOG_TAG}: dropping expanded frame from ${providerPackageName}/${widgetId}: it does not list EX`,
|
|
6595
6617
|
)
|
|
6596
6618
|
return
|
|
6597
6619
|
}
|
|
@@ -84,9 +84,11 @@ const isWidgetSize = (value: unknown): value is DeclaredWidgetSize => (WIDGET_SI
|
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* Normalize manifest widgets for installed and dev-sideloaded bundles: an
|
|
87
|
-
* entry without an id, a name or a usable size is dropped, repeats of a
|
|
87
|
+
* entry without an id, a name or a usable card size is dropped, repeats of a
|
|
88
88
|
* size are folded, and a default size the widget does not offer becomes
|
|
89
|
-
* its first size.
|
|
89
|
+
* its first size. Listing `EX` makes a widget expandable; it is not a card
|
|
90
|
+
* size. Taps expand it until the wearer turns that off (AppRegistry applies
|
|
91
|
+
* the choice).
|
|
90
92
|
*/
|
|
91
93
|
export function normalizeManifestWidgets(raw: unknown): DeclaredWidget[] {
|
|
92
94
|
if (!Array.isArray(raw)) return []
|
|
@@ -103,12 +105,15 @@ export function normalizeManifestWidgets(raw: unknown): DeclaredWidget[] {
|
|
|
103
105
|
const sizes = Array.isArray(w.sizes) ? Array.from(new Set(w.sizes.filter(isWidgetSize))) : []
|
|
104
106
|
if (sizes.length === 0) continue
|
|
105
107
|
seen.add(w.id)
|
|
108
|
+
// `expandable: true` is how bundles from before `EX` said the same.
|
|
109
|
+
const expandable = (Array.isArray(w.sizes) && w.sizes.includes("EX")) || w.expandable === true
|
|
106
110
|
out.push({
|
|
107
111
|
id: w.id,
|
|
108
112
|
name: w.name,
|
|
109
113
|
sizes,
|
|
110
114
|
defaultSize: isWidgetSize(w.defaultSize) && sizes.includes(w.defaultSize) ? w.defaultSize : sizes[0],
|
|
111
|
-
expandable
|
|
115
|
+
expandable,
|
|
116
|
+
expandOnTap: expandable,
|
|
112
117
|
})
|
|
113
118
|
}
|
|
114
119
|
return out
|
package/src/stores/apps.ts
CHANGED
|
@@ -19,7 +19,7 @@ import {DeviceTypes} from "../types/enums"
|
|
|
19
19
|
import {getModelCapabilities} from "../types/hardware"
|
|
20
20
|
import {HardwareCompatibility, type CompatibilityResult} from "../utils/hardware/hardware"
|
|
21
21
|
import {storage} from "../utils/storage/storage"
|
|
22
|
-
import appRegistry, {saveAlwaysOnOverride} from "../services/AppRegistry"
|
|
22
|
+
import appRegistry, {saveAlwaysOnOverride, saveWidgetExpandChoice} from "../services/AppRegistry"
|
|
23
23
|
import localDisplayManager from "../services/LocalDisplayManager"
|
|
24
24
|
import {islandNotifications} from "../services/NotificationsEmitter"
|
|
25
25
|
import sttModelManager from "../services/STTModelManager"
|
|
@@ -103,6 +103,12 @@ interface AppStatusState {
|
|
|
103
103
|
* off leaves it running. Persists the wearer's choice beside the hidden flag.
|
|
104
104
|
*/
|
|
105
105
|
setAlwaysOn: (packageName: string, status: boolean) => Promise<void>
|
|
106
|
+
/**
|
|
107
|
+
* Whether a tap on one of the miniapp's dashboard widgets expands it to the
|
|
108
|
+
* full screen. Only widgets that list `EX` expand; false for the rest.
|
|
109
|
+
* Persists the choice and answers the setting now in force.
|
|
110
|
+
*/
|
|
111
|
+
setWidgetExpand: (packageName: string, widgetId: string, expandOnTap: boolean) => boolean
|
|
106
112
|
/** Replace the whole apps array. Hosts use this when their extra source changes. */
|
|
107
113
|
setApps: (apps: ClientApp[]) => void
|
|
108
114
|
}
|
|
@@ -587,6 +593,22 @@ export const useAppStatusStore = create<AppStatusState>((set, get) => ({
|
|
|
587
593
|
if (status && !app.running) await get().start(app, {skipNavigation: true})
|
|
588
594
|
},
|
|
589
595
|
|
|
596
|
+
setWidgetExpand: (packageName, widgetId, expandOnTap) => {
|
|
597
|
+
const app = get().apps.find((a) => a.packageName === packageName)
|
|
598
|
+
const widget = app?.widgets?.find((w) => w.id === widgetId)
|
|
599
|
+
if (!widget?.expandable) return false
|
|
600
|
+
if (widget.expandOnTap === expandOnTap) return expandOnTap
|
|
601
|
+
saveWidgetExpandChoice(packageName, widgetId, expandOnTap)
|
|
602
|
+
set((s) => ({
|
|
603
|
+
apps: s.apps.map((a) =>
|
|
604
|
+
a.packageName === packageName
|
|
605
|
+
? {...a, widgets: a.widgets?.map((w) => (w.id === widgetId ? {...w, expandOnTap} : w))}
|
|
606
|
+
: a,
|
|
607
|
+
),
|
|
608
|
+
}))
|
|
609
|
+
return expandOnTap
|
|
610
|
+
},
|
|
611
|
+
|
|
590
612
|
setApps: (apps) => set({apps}),
|
|
591
613
|
}))
|
|
592
614
|
|
package/src/types/applet.ts
CHANGED
|
@@ -97,8 +97,10 @@ export interface DeclaredWidget {
|
|
|
97
97
|
name: string
|
|
98
98
|
sizes: DeclaredWidgetSize[]
|
|
99
99
|
defaultSize: DeclaredWidgetSize
|
|
100
|
-
/**
|
|
100
|
+
/** Lists the `EX` size: a tap on the selected widget can expand it to the full screen. */
|
|
101
101
|
expandable: boolean
|
|
102
|
+
/** A tap expands it rather than activating the card: expandable, and the wearer left expansion on. */
|
|
103
|
+
expandOnTap: boolean
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
export interface ClientApp extends AppletInterface {
|