@glassly/engine 0.1.0-dev.116 → 0.1.0-dev.118

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.
@@ -1,9 +1,9 @@
1
1
  export const ENGINE_RELEASE_METADATA = Object.freeze({
2
2
  "schemaVersion": 1,
3
3
  "familyBaseVersion": "0.1.0",
4
- "releaseIdentity": "0.1.0-dev.116",
5
- "releaseSetId": "glassly-0.1.0-dev.116",
6
- "sourceCommit": "44f00017e6ef71e4355e46e1539e88a668759315",
4
+ "releaseIdentity": "0.1.0-dev.118",
5
+ "releaseSetId": "glassly-0.1.0-dev.118",
6
+ "sourceCommit": "0d17435b9ae30c250278111f663d9b9e74a83bb8",
7
7
  "otaManifestUrl": null,
8
8
  "otaManifestSha256": null
9
9
  });
@@ -1 +1 @@
1
- {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.1.0\",\n \"releaseIdentity\": \"0.1.0-dev.116\",\n \"releaseSetId\": \"glassly-0.1.0-dev.116\",\n \"sourceCommit\": \"44f00017e6ef71e4355e46e1539e88a668759315\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
1
+ {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.1.0\",\n \"releaseIdentity\": \"0.1.0-dev.118\",\n \"releaseSetId\": \"glassly-0.1.0-dev.118\",\n \"sourceCommit\": \"0d17435b9ae30c250278111f663d9b9e74a83bb8\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"effectiveCapabilities.d.ts","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAWA,OAAO,EAAqB,WAAW,EAAwB,KAAK,YAAY,EAAC,MAAM,UAAU,CAAA;AAMjG,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAI3D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAuBzE"}
1
+ {"version":3,"file":"effectiveCapabilities.d.ts","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAaA,OAAO,EAAqB,WAAW,EAAwB,KAAK,YAAY,EAAC,MAAM,UAAU,CAAA;AAOjG,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAI3D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CA0BzE"}
@@ -6,13 +6,16 @@
6
6
  * Native publishes the canvas into the glasses status (0 = none). Because
7
7
  * that path is phone-side rasterization, the stock firmware's container
8
8
  * pools (6 text / 4 image) don't bound a CFW frame either — element caps are
9
- * lifted alongside the canvas, bounded only to keep frames sane.
9
+ * lifted alongside the canvas, bounded only to keep frames sane. Firmware
10
+ * that draws vector shapes keeps 128 scene slots, so shape-heavy frames
11
+ * (a game board, a chart) get a larger shared text/shape budget.
10
12
  */
11
13
  import { useGlassesStore } from "../stores/glasses";
12
14
  import { ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities } from "../types";
13
15
  import { isGlasslyCfwFirmwareVersion } from "./CustomDashboardModel";
14
16
  const CFW_MAX_TEXT_ELEMENTS = 24;
15
17
  const CFW_MAX_IMAGE_ELEMENTS = 16;
18
+ const CFW_VECTOR_MAX_ELEMENTS = 120;
16
19
  export function runtimeSceneCanvas() {
17
20
  const { sceneCanvasWidth, sceneCanvasHeight } = useGlassesStore.getState();
18
21
  if (!sceneCanvasWidth || !sceneCanvasHeight || sceneCanvasWidth <= 0 || sceneCanvasHeight <= 0)
@@ -38,7 +41,7 @@ export function getEffectiveCapabilities(model) {
38
41
  ...base.display,
39
42
  width: canvas?.width ?? base.display.width,
40
43
  height: canvas?.height ?? base.display.height,
41
- maxTextElements: Math.max(base.display.maxTextElements ?? 0, CFW_MAX_TEXT_ELEMENTS),
44
+ maxTextElements: Math.max(base.display.maxTextElements ?? 0, vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_TEXT_ELEMENTS),
42
45
  maxImageElements: Math.max(base.display.maxImageElements ?? 0, CFW_MAX_IMAGE_ELEMENTS),
43
46
  ...(vector ? { shapes: ALL_DISPLAY_SHAPES, animation: true } : {}),
44
47
  },
@@ -1 +1 @@
1
- {"version":3,"file":"effectiveCapabilities.js","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAoB,MAAM,UAAU,CAAA;AACjG,OAAO,EAAC,2BAA2B,EAAC,MAAM,wBAAwB,CAAA;AAElE,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAChC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AAOjC,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACxE,IAAI,CAAC,gBAAgB,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,IAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3G,OAAO,EAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAC,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAkB;IACzD,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACxC,iFAAiF;IACjF,MAAM,MAAM,GAAG,KAAK,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,6EAA6E;IAC7E,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,GAAG,GAAG,KAAK,KAAK,WAAW,CAAC,EAAE,IAAI,2BAA2B,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,CAAA;IAC/G,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACnD,4EAA4E;IAC5E,qDAAqD;IACrD,MAAM,MAAM,GAAG,KAAK,KAAK,WAAW,CAAC,EAAE,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC,WAAW,KAAK,IAAI,CAAA;IAC1F,OAAO;QACL,GAAG,IAAI;QACP,OAAO,EAAE;YACP,GAAG,IAAI,CAAC,OAAO;YACf,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK;YAC1C,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM;YAC7C,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,EAAE,qBAAqB,CAAC;YACnF,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,EAAE,sBAAsB,CAAC;YACtF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE;KACF,CAAA;AACH,CAAC","sourcesContent":["/**\n * Effective device capabilities — the static model profile plus what the\n * connected firmware reports at runtime. The runtime override is the scene\n * canvas: Glassly CFW on the G2 rasterizes scenes phone-side straight into\n * the 640×480 panel, so the drawable canvas grows past stock's 576×288.\n * Native publishes the canvas into the glasses status (0 = none). Because\n * that path is phone-side rasterization, the stock firmware's container\n * pools (6 text / 4 image) don't bound a CFW frame either — element caps are\n * lifted alongside the canvas, bounded only to keep frames sane.\n */\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities, type Capabilities} from \"../types\"\nimport {isGlasslyCfwFirmwareVersion} from \"./CustomDashboardModel\"\n\nconst CFW_MAX_TEXT_ELEMENTS = 24\nconst CFW_MAX_IMAGE_ELEMENTS = 16\n\nexport interface SceneCanvasSize {\n width: number\n height: number\n}\n\nexport function runtimeSceneCanvas(): SceneCanvasSize | null {\n const {sceneCanvasWidth, sceneCanvasHeight} = useGlassesStore.getState()\n if (!sceneCanvasWidth || !sceneCanvasHeight || sceneCanvasWidth <= 0 || sceneCanvasHeight <= 0) return null\n return {width: sceneCanvasWidth, height: sceneCanvasHeight}\n}\n\nexport function getEffectiveCapabilities(model: DeviceTypes): Capabilities {\n const base = getModelCapabilities(model)\n // Only G2 CFW publishes a canvas; never let a stale value reshape another model.\n const canvas = model === DeviceTypes.G2 ? runtimeSceneCanvas() : null\n // The firmware marker lifts the caps even when no canvas has been published:\n // CFW classification rides the version string, and a G2 running Glassly CFW\n // always rasterizes phone-side regardless of whether native reported dims.\n const cfw = model === DeviceTypes.G2 && isGlasslyCfwFirmwareVersion(useGlassesStore.getState().firmwareVersion)\n if (!base.display || (!canvas && !cfw)) return base\n // Native reports whether the connected CFW draws vector shapes and animates\n // transitions on the glasses (firmware modes 16-18).\n const vector = model === DeviceTypes.G2 && useGlassesStore.getState().sceneVector === true\n return {\n ...base,\n display: {\n ...base.display,\n width: canvas?.width ?? base.display.width,\n height: canvas?.height ?? base.display.height,\n maxTextElements: Math.max(base.display.maxTextElements ?? 0, CFW_MAX_TEXT_ELEMENTS),\n maxImageElements: Math.max(base.display.maxImageElements ?? 0, CFW_MAX_IMAGE_ELEMENTS),\n ...(vector ? {shapes: ALL_DISPLAY_SHAPES, animation: true} : {}),\n },\n }\n}\n"]}
1
+ {"version":3,"file":"effectiveCapabilities.js","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAoB,MAAM,UAAU,CAAA;AACjG,OAAO,EAAC,2BAA2B,EAAC,MAAM,wBAAwB,CAAA;AAElE,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAChC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AACjC,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAOnC,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACxE,IAAI,CAAC,gBAAgB,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,IAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3G,OAAO,EAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAC,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAkB;IACzD,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACxC,iFAAiF;IACjF,MAAM,MAAM,GAAG,KAAK,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,6EAA6E;IAC7E,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,GAAG,GAAG,KAAK,KAAK,WAAW,CAAC,EAAE,IAAI,2BAA2B,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,CAAA;IAC/G,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACnD,4EAA4E;IAC5E,qDAAqD;IACrD,MAAM,MAAM,GAAG,KAAK,KAAK,WAAW,CAAC,EAAE,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC,WAAW,KAAK,IAAI,CAAA;IAC1F,OAAO;QACL,GAAG,IAAI;QACP,OAAO,EAAE;YACP,GAAG,IAAI,CAAC,OAAO;YACf,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK;YAC1C,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM;YAC7C,eAAe,EAAE,IAAI,CAAC,GAAG,CACvB,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,EACjC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CACzD;YACD,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,EAAE,sBAAsB,CAAC;YACtF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE;KACF,CAAA;AACH,CAAC","sourcesContent":["/**\n * Effective device capabilities — the static model profile plus what the\n * connected firmware reports at runtime. The runtime override is the scene\n * canvas: Glassly CFW on the G2 rasterizes scenes phone-side straight into\n * the 640×480 panel, so the drawable canvas grows past stock's 576×288.\n * Native publishes the canvas into the glasses status (0 = none). Because\n * that path is phone-side rasterization, the stock firmware's container\n * pools (6 text / 4 image) don't bound a CFW frame either — element caps are\n * lifted alongside the canvas, bounded only to keep frames sane. Firmware\n * that draws vector shapes keeps 128 scene slots, so shape-heavy frames\n * (a game board, a chart) get a larger shared text/shape budget.\n */\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities, type Capabilities} from \"../types\"\nimport {isGlasslyCfwFirmwareVersion} from \"./CustomDashboardModel\"\n\nconst CFW_MAX_TEXT_ELEMENTS = 24\nconst CFW_MAX_IMAGE_ELEMENTS = 16\nconst CFW_VECTOR_MAX_ELEMENTS = 120\n\nexport interface SceneCanvasSize {\n width: number\n height: number\n}\n\nexport function runtimeSceneCanvas(): SceneCanvasSize | null {\n const {sceneCanvasWidth, sceneCanvasHeight} = useGlassesStore.getState()\n if (!sceneCanvasWidth || !sceneCanvasHeight || sceneCanvasWidth <= 0 || sceneCanvasHeight <= 0) return null\n return {width: sceneCanvasWidth, height: sceneCanvasHeight}\n}\n\nexport function getEffectiveCapabilities(model: DeviceTypes): Capabilities {\n const base = getModelCapabilities(model)\n // Only G2 CFW publishes a canvas; never let a stale value reshape another model.\n const canvas = model === DeviceTypes.G2 ? runtimeSceneCanvas() : null\n // The firmware marker lifts the caps even when no canvas has been published:\n // CFW classification rides the version string, and a G2 running Glassly CFW\n // always rasterizes phone-side regardless of whether native reported dims.\n const cfw = model === DeviceTypes.G2 && isGlasslyCfwFirmwareVersion(useGlassesStore.getState().firmwareVersion)\n if (!base.display || (!canvas && !cfw)) return base\n // Native reports whether the connected CFW draws vector shapes and animates\n // transitions on the glasses (firmware modes 16-18).\n const vector = model === DeviceTypes.G2 && useGlassesStore.getState().sceneVector === true\n return {\n ...base,\n display: {\n ...base.display,\n width: canvas?.width ?? base.display.width,\n height: canvas?.height ?? base.display.height,\n maxTextElements: Math.max(\n base.display.maxTextElements ?? 0,\n vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_TEXT_ELEMENTS,\n ),\n maxImageElements: Math.max(base.display.maxImageElements ?? 0, CFW_MAX_IMAGE_ELEMENTS),\n ...(vector ? {shapes: ALL_DISPLAY_SHAPES, animation: true} : {}),\n },\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glassly/engine",
3
- "version": "0.1.0-dev.116",
3
+ "version": "0.1.0-dev.118",
4
4
  "description": "Glassly Engine — miniapp registry, WebView bridge, and miniapp store",
5
5
  "main": "build/index.js",
6
6
  "react-native": "src/index.ts",
@@ -97,17 +97,17 @@
97
97
  "registry": "https://registry.npmjs.org/"
98
98
  },
99
99
  "dependencies": {
100
- "@glassly/bluetooth-sdk": "0.1.0-dev.116",
101
- "@glassly/cloud-client": "0.1.0-dev.116",
102
- "@glassly/cloud-protocol": "0.1.0-dev.116",
103
- "@glassly/crust": "0.1.0-dev.116",
104
- "@glassly/miniapp": "0.1.0-dev.116",
100
+ "@glassly/bluetooth-sdk": "0.1.0-dev.118",
101
+ "@glassly/cloud-client": "0.1.0-dev.118",
102
+ "@glassly/cloud-protocol": "0.1.0-dev.118",
103
+ "@glassly/crust": "0.1.0-dev.118",
104
+ "@glassly/miniapp": "0.1.0-dev.118",
105
105
  "buffer": "^6.0.3",
106
106
  "events": "^3.3.0",
107
107
  "react-native-marked": "8.1.1",
108
108
  "semver": "^7.7.4",
109
109
  "typesafe-ts": "^1.7.1",
110
- "@glassly/llm-providers": "0.1.0-dev.116"
110
+ "@glassly/llm-providers": "0.1.0-dev.118"
111
111
  },
112
112
  "devDependencies": {
113
113
  "@glassly/llm-providers": "workspace:*",
@@ -12,9 +12,9 @@ export interface EngineReleaseMetadata {
12
12
  export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
13
13
  "schemaVersion": 1,
14
14
  "familyBaseVersion": "0.1.0",
15
- "releaseIdentity": "0.1.0-dev.116",
16
- "releaseSetId": "glassly-0.1.0-dev.116",
17
- "sourceCommit": "44f00017e6ef71e4355e46e1539e88a668759315",
15
+ "releaseIdentity": "0.1.0-dev.118",
16
+ "releaseSetId": "glassly-0.1.0-dev.118",
17
+ "sourceCommit": "0d17435b9ae30c250278111f663d9b9e74a83bb8",
18
18
  "otaManifestUrl": null,
19
19
  "otaManifestSha256": null
20
20
  })
@@ -6,7 +6,9 @@
6
6
  * Native publishes the canvas into the glasses status (0 = none). Because
7
7
  * that path is phone-side rasterization, the stock firmware's container
8
8
  * pools (6 text / 4 image) don't bound a CFW frame either — element caps are
9
- * lifted alongside the canvas, bounded only to keep frames sane.
9
+ * lifted alongside the canvas, bounded only to keep frames sane. Firmware
10
+ * that draws vector shapes keeps 128 scene slots, so shape-heavy frames
11
+ * (a game board, a chart) get a larger shared text/shape budget.
10
12
  */
11
13
  import {useGlassesStore} from "../stores/glasses"
12
14
  import {ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities, type Capabilities} from "../types"
@@ -14,6 +16,7 @@ import {isGlasslyCfwFirmwareVersion} from "./CustomDashboardModel"
14
16
 
15
17
  const CFW_MAX_TEXT_ELEMENTS = 24
16
18
  const CFW_MAX_IMAGE_ELEMENTS = 16
19
+ const CFW_VECTOR_MAX_ELEMENTS = 120
17
20
 
18
21
  export interface SceneCanvasSize {
19
22
  width: number
@@ -44,7 +47,10 @@ export function getEffectiveCapabilities(model: DeviceTypes): Capabilities {
44
47
  ...base.display,
45
48
  width: canvas?.width ?? base.display.width,
46
49
  height: canvas?.height ?? base.display.height,
47
- maxTextElements: Math.max(base.display.maxTextElements ?? 0, CFW_MAX_TEXT_ELEMENTS),
50
+ maxTextElements: Math.max(
51
+ base.display.maxTextElements ?? 0,
52
+ vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_TEXT_ELEMENTS,
53
+ ),
48
54
  maxImageElements: Math.max(base.display.maxImageElements ?? 0, CFW_MAX_IMAGE_ELEMENTS),
49
55
  ...(vector ? {shapes: ALL_DISPLAY_SHAPES, animation: true} : {}),
50
56
  },