@linxin666/dsh-pet 0.3.22 → 0.3.24
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/README.i18n.yaml +2 -2
- package/README.md +2 -1
- package/README.zh.md +2 -1
- package/lib/client.js +71 -9
- package/lib/client.js.map +1 -1
- package/lib/index.js +14 -7
- package/lib/types/announce.d.ts +6 -6
- package/lib/types/announce.d.ts.map +1 -1
- package/lib/types/announce.js +5 -5
- package/lib/types/client/PetDockEntry.js +1 -1
- package/lib/types/client/PetSettingsCard.d.ts +4 -0
- package/lib/types/client/PetSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PetSettingsCard.js +3 -1
- package/lib/types/client/PetSprite.d.ts +1 -1
- package/lib/types/client/PetSprite.d.ts.map +1 -1
- package/lib/types/client/PetSprite.js +40 -7
- package/lib/types/client/locales.d.ts +4 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +4 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +2 -1
- package/lib/types/persist.d.ts +32 -0
- package/lib/types/persist.d.ts.map +1 -1
- package/lib/types/persist.js +37 -0
- package/lib/types/service.d.ts +3 -1
- package/lib/types/service.d.ts.map +1 -1
- package/lib/types/service.js +4 -2
- package/package.json +1 -1
- package/src/announce.ts +6 -6
- package/src/client/PetDockEntry.test.tsx +1 -1
- package/src/client/PetDockEntry.tsx +1 -1
- package/src/client/PetSettingsCard.tsx +16 -0
- package/src/client/PetSprite.test.tsx +1 -1
- package/src/client/PetSprite.tsx +40 -7
- package/src/client/gameplay-hud.test.tsx +1 -1
- package/src/client/locales.ts +4 -0
- package/src/client/pet-css.test.ts +14 -0
- package/src/client/pet-store.test.ts +1 -1
- package/src/client/pet.module.css +7 -4
- package/src/index.ts +2 -1
- package/src/persist.test.ts +53 -1
- package/src/persist.ts +46 -0
- package/src/service.ts +7 -1
package/lib/index.js
CHANGED
|
@@ -11,10 +11,10 @@ import { readFile } from "node:fs/promises";
|
|
|
11
11
|
/** Default freshness window. */
|
|
12
12
|
const ANNOUNCE_DEFAULT_TTL_MS = 1e4;
|
|
13
13
|
/**
|
|
14
|
-
* Hard TTL ceiling. A repeating announcer
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* Hard TTL ceiling. A repeating announcer declares its poll cadence as
|
|
15
|
+
* the TTL, so an always-on bubble stays continuous across polls; the
|
|
16
|
+
* ceiling means a source that dies unmounts its bubble within at most one
|
|
17
|
+
* missed refresh cycle rather than lingering forever.
|
|
18
18
|
*/
|
|
19
19
|
const ANNOUNCE_MAX_TTL_MS = 72e5;
|
|
20
20
|
/** Hard bounds: lengths and the TTL range (1 s .. 60 s). */
|
|
@@ -1391,10 +1391,13 @@ const defaultDisplayConfig = {
|
|
|
1391
1391
|
visible: true,
|
|
1392
1392
|
size: 160,
|
|
1393
1393
|
right: 24,
|
|
1394
|
-
bottom: 120
|
|
1394
|
+
bottom: 120,
|
|
1395
|
+
bubbleScale: 1
|
|
1395
1396
|
};
|
|
1396
1397
|
const DISPLAY_SIZE_MAX = 1024;
|
|
1397
1398
|
const DISPLAY_INSET_MAX = 1e4;
|
|
1399
|
+
/** Bubble typography bounds (issue #1549). */
|
|
1400
|
+
const BUBBLE_SCALE_MIN = .5;
|
|
1398
1401
|
/** Name constraints. */
|
|
1399
1402
|
const PET_NAME_MAX_LENGTH = 20;
|
|
1400
1403
|
function emptyPersist() {
|
|
@@ -1508,7 +1511,8 @@ function loadPetPersist(dir = petHomeDir()) {
|
|
|
1508
1511
|
visible: typeof rawDisplay.visible === "boolean" ? rawDisplay.visible : base.display.visible,
|
|
1509
1512
|
size: Math.round(Math.min(DISPLAY_SIZE_MAX, Math.max(32, finiteNum(rawDisplay.size, base.display.size)))),
|
|
1510
1513
|
right: Math.round(clamp(finiteNum(rawDisplay.right, base.display.right), DISPLAY_INSET_MAX)),
|
|
1511
|
-
bottom: Math.round(clamp(finiteNum(rawDisplay.bottom, base.display.bottom), DISPLAY_INSET_MAX))
|
|
1514
|
+
bottom: Math.round(clamp(finiteNum(rawDisplay.bottom, base.display.bottom), DISPLAY_INSET_MAX)),
|
|
1515
|
+
bubbleScale: Math.min(2, Math.max(BUBBLE_SCALE_MIN, finiteNum(rawDisplay.bubbleScale, base.display.bubbleScale)))
|
|
1512
1516
|
};
|
|
1513
1517
|
const petId = typeof parsed.petId === "string" && parsed.petId.trim() !== "" ? parsed.petId.trim() : base.petId;
|
|
1514
1518
|
const names = loadPetNames(parsed);
|
|
@@ -4882,7 +4886,7 @@ var PetService = class extends Service {
|
|
|
4882
4886
|
skin
|
|
4883
4887
|
};
|
|
4884
4888
|
}
|
|
4885
|
-
/** RPC: update display config (size / position).
|
|
4889
|
+
/** RPC: update display config (size / position / bubble scale). Pixel values are clamped to whole pixels. */
|
|
4886
4890
|
async setConfig(patch) {
|
|
4887
4891
|
const next = {
|
|
4888
4892
|
...this.ledger.snapshot.display,
|
|
@@ -4891,6 +4895,7 @@ var PetService = class extends Service {
|
|
|
4891
4895
|
next.size = Math.round(Math.min(DISPLAY_SIZE_MAX, Math.max(32, next.size)));
|
|
4892
4896
|
next.right = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, next.right)));
|
|
4893
4897
|
next.bottom = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, next.bottom)));
|
|
4898
|
+
next.bubbleScale = Math.min(2, Math.max(BUBBLE_SCALE_MIN, next.bubbleScale));
|
|
4894
4899
|
this.ledger.setDisplay(next);
|
|
4895
4900
|
this.flush();
|
|
4896
4901
|
this.syncSettingsFromPet();
|
|
@@ -4935,6 +4940,7 @@ var PetService = class extends Service {
|
|
|
4935
4940
|
next.size = Math.round(Math.min(DISPLAY_SIZE_MAX, Math.max(32, section.size)));
|
|
4936
4941
|
next.right = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, section.right)));
|
|
4937
4942
|
next.bottom = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, section.bottom)));
|
|
4943
|
+
next.bubbleScale = Math.min(2, Math.max(BUBBLE_SCALE_MIN, section.bubbleScale ?? next.bubbleScale));
|
|
4938
4944
|
this.ledger.setDisplay(next);
|
|
4939
4945
|
this.flush();
|
|
4940
4946
|
}
|
|
@@ -5808,6 +5814,7 @@ function makePetSettingsSchema(fallbackPetId) {
|
|
|
5808
5814
|
size: z.number().step(1).min(32).max(DISPLAY_SIZE_MAX).default(160),
|
|
5809
5815
|
right: z.number().step(1).min(0).max(DISPLAY_INSET_MAX).default(24),
|
|
5810
5816
|
bottom: z.number().step(1).min(0).max(DISPLAY_INSET_MAX).default(20),
|
|
5817
|
+
bubbleScale: z.number().step(.05).min(BUBBLE_SCALE_MIN).max(2).default(1),
|
|
5811
5818
|
petId: z.string().default(fallbackPetId),
|
|
5812
5819
|
enabled: z.boolean().default(true),
|
|
5813
5820
|
decorationEnabled: z.boolean().default(true)
|
package/lib/types/announce.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The pet announcement-bubble contract
|
|
2
|
+
* The pet announcement-bubble contract: a sibling plugin
|
|
3
3
|
* pushes one structured announcement through `pet.announce(...)`, the host
|
|
4
4
|
* validates it into a bounded payload, and the browser half renders it as a
|
|
5
5
|
* dedicated, specially styled bubble above the session bubble stack.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
/** One plugin-authored announcement bubble. */
|
|
12
12
|
export interface PetAnnouncement {
|
|
13
|
-
/** Authoring plugin's source tag (
|
|
13
|
+
/** Authoring plugin's source tag (its own package short name). */
|
|
14
14
|
source: string;
|
|
15
15
|
/** Bubble content kind: a spend estimate, an account balance, or a plan-quota status. */
|
|
16
16
|
kind: 'balance' | 'cost' | 'plan';
|
|
@@ -34,10 +34,10 @@ export interface PetAnnouncement {
|
|
|
34
34
|
/** Default freshness window. */
|
|
35
35
|
export declare const ANNOUNCE_DEFAULT_TTL_MS = 10000;
|
|
36
36
|
/**
|
|
37
|
-
* Hard TTL ceiling. A repeating announcer
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
37
|
+
* Hard TTL ceiling. A repeating announcer declares its poll cadence as
|
|
38
|
+
* the TTL, so an always-on bubble stays continuous across polls; the
|
|
39
|
+
* ceiling means a source that dies unmounts its bubble within at most one
|
|
40
|
+
* missed refresh cycle rather than lingering forever.
|
|
41
41
|
*/
|
|
42
42
|
export declare const ANNOUNCE_MAX_TTL_MS = 7200000;
|
|
43
43
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../../src/announce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,
|
|
1
|
+
{"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../../src/announce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAA;IACd,yFAAyF;IACzF,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAA;IACjC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAA;IACb,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,KAAK,CAAA;IAC3B,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAA;IACb,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;CACX;AAED,gCAAgC;AAChC,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,UAAY,CAAA;AAc5C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAgC1F;AAED,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAErF"}
|
package/lib/types/announce.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The pet announcement-bubble contract
|
|
2
|
+
* The pet announcement-bubble contract: a sibling plugin
|
|
3
3
|
* pushes one structured announcement through `pet.announce(...)`, the host
|
|
4
4
|
* validates it into a bounded payload, and the browser half renders it as a
|
|
5
5
|
* dedicated, specially styled bubble above the session bubble stack.
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
/** Default freshness window. */
|
|
12
12
|
export const ANNOUNCE_DEFAULT_TTL_MS = 10_000;
|
|
13
13
|
/**
|
|
14
|
-
* Hard TTL ceiling. A repeating announcer
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* Hard TTL ceiling. A repeating announcer declares its poll cadence as
|
|
15
|
+
* the TTL, so an always-on bubble stays continuous across polls; the
|
|
16
|
+
* ceiling means a source that dies unmounts its bubble within at most one
|
|
17
|
+
* missed refresh cycle rather than lingering forever.
|
|
18
18
|
*/
|
|
19
19
|
export const ANNOUNCE_MAX_TTL_MS = 7_200_000;
|
|
20
20
|
/** Hard bounds: lengths and the TTL range (1 s .. 60 s). */
|
|
@@ -18,7 +18,7 @@ import { PetRendererSwitch } from "./renderers/PetRendererSwitch.js";
|
|
|
18
18
|
import { createDragStream } from "./drag-stream.js";
|
|
19
19
|
import { GameplayHud } from "./gameplay-hud.js";
|
|
20
20
|
import styles from './pet.module.css';
|
|
21
|
-
const DEFAULT_DISPLAY = { visible: true, size: 160, right: 24, bottom: 20 };
|
|
21
|
+
const DEFAULT_DISPLAY = { visible: true, size: 160, right: 24, bottom: 20, bubbleScale: 1 };
|
|
22
22
|
/**
|
|
23
23
|
* Dock entry: while the pet is visible, mount the floating PetSprite (it
|
|
24
24
|
* portals itself onto document.body); while hidden, render the summon
|
|
@@ -23,6 +23,8 @@ export interface PetSettings {
|
|
|
23
23
|
right?: number;
|
|
24
24
|
/** Vertical inset from the viewport bottom edge, px. */
|
|
25
25
|
bottom?: number;
|
|
26
|
+
/** Bubble typography multiplier on the automatic size following (#1549). */
|
|
27
|
+
bubbleScale?: number;
|
|
26
28
|
/** Selected pet id (a registry entry). */
|
|
27
29
|
petId?: string;
|
|
28
30
|
/** Status-decoration master switch (pet-center M5, #567). */
|
|
@@ -40,6 +42,8 @@ export interface PetSettingsCardState extends CardShell {
|
|
|
40
42
|
right: CardFieldState;
|
|
41
43
|
/** Bottom inset. */
|
|
42
44
|
bottom: CardFieldState;
|
|
45
|
+
/** Bubble typography multiplier. */
|
|
46
|
+
bubbleScale: CardFieldState;
|
|
43
47
|
/** Selected pet. */
|
|
44
48
|
petId: CardFieldState;
|
|
45
49
|
/** Status-decoration master switch. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PetSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PetSettingsCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAA;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAIlE,OAAO,EAAoD,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAG1J,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,4BAA4B;IAC5B,OAAO,EAAE,cAAc,CAAA;IACvB,qBAAqB;IACrB,OAAO,EAAE,cAAc,CAAA;IACvB,iBAAiB;IACjB,IAAI,EAAE,cAAc,CAAA;IACpB,mBAAmB;IACnB,KAAK,EAAE,cAAc,CAAA;IACrB,oBAAoB;IACpB,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB;IACpB,KAAK,EAAE,cAAc,CAAA;IACrB,uCAAuC;IACvC,iBAAiB,EAAE,cAAc,CAAA;IACjC,wEAAwE;IACxE,UAAU,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACvD,+EAA+E;IAC/E,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAC7C;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,KAAK,EAAE;QACL,iEAAiE;QACjE,eAAe,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;KACrD,CAAA;CACF;AAQD,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;CAChB;AAiBD,2DAA2D;AAC3D,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAI3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,QAAQ,CAAQ;IACxB,oEAAoE;IACpE,OAAO,CAAC,YAAY,CAAoB;IAExC,uEAAuE;gBAC3D,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"PetSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PetSettingsCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAA;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAIlE,OAAO,EAAoD,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAG1J,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,4BAA4B;IAC5B,OAAO,EAAE,cAAc,CAAA;IACvB,qBAAqB;IACrB,OAAO,EAAE,cAAc,CAAA;IACvB,iBAAiB;IACjB,IAAI,EAAE,cAAc,CAAA;IACpB,mBAAmB;IACnB,KAAK,EAAE,cAAc,CAAA;IACrB,oBAAoB;IACpB,MAAM,EAAE,cAAc,CAAA;IACtB,oCAAoC;IACpC,WAAW,EAAE,cAAc,CAAA;IAC3B,oBAAoB;IACpB,KAAK,EAAE,cAAc,CAAA;IACrB,uCAAuC;IACvC,iBAAiB,EAAE,cAAc,CAAA;IACjC,wEAAwE;IACxE,UAAU,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACvD,+EAA+E;IAC/E,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAC7C;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,KAAK,EAAE;QACL,iEAAiE;QACjE,eAAe,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;KACrD,CAAA;CACF;AAQD,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;CAChB;AAiBD,2DAA2D;AAC3D,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAI3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,QAAQ,CAAQ;IACxB,oEAAoE;IACpE,OAAO,CAAC,YAAY,CAAoB;IAExC,uEAAuE;gBAC3D,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC;IAwB7C,2EAA2E;YAC7D,eAAe;IAU7B,0EAA0E;YAC5D,QAAQ;IAsBtB,OAAO,CAAC,UAAU;IAgBlB;;;OAGG;IACH,MAAM,IAAI,mBAAmB;IAI7B;;;OAGG;IACH,OAAO,IAAI,IAAI;CAShB;AAED,0DAA0D;AAC1D,MAAM,MAAM,oBAAoB,GAC9B,WAAW,CAAC,KAAK,CAAC,GAChB,UAAU,CAAC,mBAAmB,CAAC,CAAA;AAEnC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,+BAuH1D;AAED,8DAA8D;AAC9D,MAAM,MAAM,uBAAuB,GACjC,YAAY,CAAC,kBAAkB,CAAC,GAC9B,WAAW,CAAC,KAAK,CAAC,GAClB,UAAU,CAAC,mBAAmB,CAAC,CAAA;AAEnC,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,SAAS,CAO5E"}
|
|
@@ -41,6 +41,7 @@ export class PetSettingsCardController {
|
|
|
41
41
|
numberField('size'),
|
|
42
42
|
numberField('right'),
|
|
43
43
|
numberField('bottom'),
|
|
44
|
+
numberField('bubbleScale'),
|
|
44
45
|
choiceField('petId', this.petChoices),
|
|
45
46
|
]);
|
|
46
47
|
this.store = this.form.bind(() => this.projection());
|
|
@@ -105,6 +106,7 @@ export class PetSettingsCardController {
|
|
|
105
106
|
size: this.form.field('size'),
|
|
106
107
|
right: this.form.field('right'),
|
|
107
108
|
bottom: this.form.field('bottom'),
|
|
109
|
+
bubbleScale: this.form.field('bubbleScale'),
|
|
108
110
|
petId: this.form.field('petId'),
|
|
109
111
|
petChoices: this.petChoices.map(id => ({ value: id, label: this.petLabels.get(id) ?? id })),
|
|
110
112
|
petDiagnostics: this.diagnostics,
|
|
@@ -147,7 +149,7 @@ export function PetSettingsCard(props) {
|
|
|
147
149
|
invalidLabel: t('settings.invalidNumber'),
|
|
148
150
|
disabled,
|
|
149
151
|
};
|
|
150
|
-
return (_jsxs(PluginSettingsCard, { t: t, titleKey: "settings.title", descriptionKey: "settings.description", state: state, onSave: props.save, onDiscard: props.discard, alwaysOpen: true, children: [_jsx(BooleanField, { id: "settings-pet-enabled", label: t('settings.enabled'), hint: t('settings.enabledHint'), inheritLabel: t('settings.inherit'), onLabel: t('settings.on'), offLabel: t('settings.off'), ...fieldProps, ...state.enabled, onEdit: (text) => { props.edit('enabled', text); }, onReset: () => { props.resetField('enabled'); } }), _jsx(BooleanField, { id: "settings-pet-decoration", label: t('settings.decoration'), hint: t('settings.decorationHint'), inheritLabel: t('settings.inherit'), onLabel: t('settings.on'), offLabel: t('settings.off'), ...fieldProps, ...state.decorationEnabled, onEdit: (text) => { props.edit('decorationEnabled', text); }, onReset: () => { props.resetField('decorationEnabled'); } }), _jsx(ChoiceField, { id: "settings-pet-pet", label: t('settings.pet'), hint: t('settings.petHint'), inheritLabel: t('settings.inherit'), ...fieldProps, ...state.petId, choices: state.petChoices, onEdit: (text) => { props.edit('petId', text); }, onReset: () => { props.resetField('petId'); } }), state.petDiagnostics.length === 0 ? null : (_jsxs("li", { className: sectionCss.diagnostics, "data-dsh-part": "diagnostics", children: [_jsx("span", { className: sectionCss.diagnosticsTitle, children: t('settings.diagnosticsTitle') }), _jsx("ul", { children: state.petDiagnostics.map((diagnostic, index) => (_jsx("li", { "data-level": diagnostic.level, children: diagnostic.message }, index))) })] })), _jsx(BooleanField, { id: "settings-pet-visible", label: t('settings.visible'), hint: t('settings.visibleHint'), inheritLabel: t('settings.inherit'), onLabel: t('settings.on'), offLabel: t('settings.off'), ...fieldProps, ...state.visible, onEdit: (text) => { props.edit('visible', text); }, onReset: () => { props.resetField('visible'); } }), _jsx(ValueField, { id: "settings-pet-size", label: t('settings.size'), hint: t('settings.sizeHint'), numeric: true, ...fieldProps, ...state.size, onEdit: (text) => { props.edit('size', text); }, onReset: () => { props.resetField('size'); } }), _jsx(ValueField, { id: "settings-pet-right", label: t('settings.right'), hint: t('settings.rightHint'), numeric: true, ...fieldProps, ...state.right, onEdit: (text) => { props.edit('right', text); }, onReset: () => { props.resetField('right'); } }), _jsx(ValueField, { id: "settings-pet-bottom", label: t('settings.bottom'), hint: t('settings.bottomHint'), numeric: true, ...fieldProps, ...state.bottom, onEdit: (text) => { props.edit('bottom', text); }, onReset: () => { props.resetField('bottom'); } })] }));
|
|
152
|
+
return (_jsxs(PluginSettingsCard, { t: t, titleKey: "settings.title", descriptionKey: "settings.description", state: state, onSave: props.save, onDiscard: props.discard, alwaysOpen: true, children: [_jsx(BooleanField, { id: "settings-pet-enabled", label: t('settings.enabled'), hint: t('settings.enabledHint'), inheritLabel: t('settings.inherit'), onLabel: t('settings.on'), offLabel: t('settings.off'), ...fieldProps, ...state.enabled, onEdit: (text) => { props.edit('enabled', text); }, onReset: () => { props.resetField('enabled'); } }), _jsx(BooleanField, { id: "settings-pet-decoration", label: t('settings.decoration'), hint: t('settings.decorationHint'), inheritLabel: t('settings.inherit'), onLabel: t('settings.on'), offLabel: t('settings.off'), ...fieldProps, ...state.decorationEnabled, onEdit: (text) => { props.edit('decorationEnabled', text); }, onReset: () => { props.resetField('decorationEnabled'); } }), _jsx(ChoiceField, { id: "settings-pet-pet", label: t('settings.pet'), hint: t('settings.petHint'), inheritLabel: t('settings.inherit'), ...fieldProps, ...state.petId, choices: state.petChoices, onEdit: (text) => { props.edit('petId', text); }, onReset: () => { props.resetField('petId'); } }), state.petDiagnostics.length === 0 ? null : (_jsxs("li", { className: sectionCss.diagnostics, "data-dsh-part": "diagnostics", children: [_jsx("span", { className: sectionCss.diagnosticsTitle, children: t('settings.diagnosticsTitle') }), _jsx("ul", { children: state.petDiagnostics.map((diagnostic, index) => (_jsx("li", { "data-level": diagnostic.level, children: diagnostic.message }, index))) })] })), _jsx(BooleanField, { id: "settings-pet-visible", label: t('settings.visible'), hint: t('settings.visibleHint'), inheritLabel: t('settings.inherit'), onLabel: t('settings.on'), offLabel: t('settings.off'), ...fieldProps, ...state.visible, onEdit: (text) => { props.edit('visible', text); }, onReset: () => { props.resetField('visible'); } }), _jsx(ValueField, { id: "settings-pet-size", label: t('settings.size'), hint: t('settings.sizeHint'), numeric: true, ...fieldProps, ...state.size, onEdit: (text) => { props.edit('size', text); }, onReset: () => { props.resetField('size'); } }), _jsx(ValueField, { id: "settings-pet-right", label: t('settings.right'), hint: t('settings.rightHint'), numeric: true, ...fieldProps, ...state.right, onEdit: (text) => { props.edit('right', text); }, onReset: () => { props.resetField('right'); } }), _jsx(ValueField, { id: "settings-pet-bottom", label: t('settings.bottom'), hint: t('settings.bottomHint'), numeric: true, ...fieldProps, ...state.bottom, onEdit: (text) => { props.edit('bottom', text); }, onReset: () => { props.resetField('bottom'); } }), _jsx(ValueField, { id: "settings-pet-bubble-scale", label: t('settings.bubbleScale'), hint: t('settings.bubbleScaleHint'), numeric: true, ...fieldProps, ...state.bubbleScale, onEdit: (text) => { props.edit('bubbleScale', text); }, onReset: () => { props.resetField('bubbleScale'); } })] }));
|
|
151
153
|
}
|
|
152
154
|
/** Render the pet settings card as a first-level settings page. */
|
|
153
155
|
export function PetSettingsSection(props) {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { ReactNode, ReactPortal } from 'react';
|
|
12
12
|
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
13
|
-
import type
|
|
13
|
+
import { type PetDisplayConfig } from '../persist.ts';
|
|
14
14
|
import type { PetStateView } from '../service.ts';
|
|
15
15
|
import type { PetDefinition } from '../registry.ts';
|
|
16
16
|
import type { PetFeedback } from './pet-store.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PetSprite.d.ts","sourceRoot":"","sources":["../../../src/client/PetSprite.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAkE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"PetSprite.d.ts","sourceRoot":"","sources":["../../../src/client/PetSprite.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAkE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,8EAA8E;IAC9E,UAAU,EAAE,aAAa,CAAA;IACzB,qDAAqD;IACrD,OAAO,EAAE,gBAAgB,CAAA;IACzB,sCAAsC;IACtC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;IAC9C,uDAAuD;IACvD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,4DAA4D;IAC5D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,2DAA2D;IAC3D,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB;;;;OAIG;IACH,GAAG,CAAC,EAAE,SAAS,CAAA;IACf;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9D;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,qEAAqE;IACrE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,+CAA+C;IAC/C,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;CAC1B;AAkJD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAgmB5D"}
|
|
@@ -12,6 +12,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
12
12
|
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
13
13
|
import { createPortal } from 'react-dom';
|
|
14
14
|
import clsx from 'clsx';
|
|
15
|
+
import { bubbleScaleFor } from "../persist.js";
|
|
15
16
|
import { announcementFresh } from "../announce.js";
|
|
16
17
|
import { framePosition, rowOfTrack, trimTrack } from "./spritesheet.js";
|
|
17
18
|
import { createSequenceTimeline } from "./sequences.js";
|
|
@@ -205,16 +206,39 @@ export function PetSprite(props) {
|
|
|
205
206
|
useEffect(() => {
|
|
206
207
|
if (props.visual !== undefined)
|
|
207
208
|
return;
|
|
209
|
+
setImageReady(false);
|
|
208
210
|
let cancelled = false;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
let retryTimer;
|
|
212
|
+
let attempt = 0;
|
|
213
|
+
const maxAttempts = 3;
|
|
214
|
+
let activeImg = null;
|
|
215
|
+
const loadAtlas = () => {
|
|
216
|
+
const img = new Image();
|
|
217
|
+
activeImg = img;
|
|
218
|
+
img.onload = () => {
|
|
219
|
+
if (!cancelled)
|
|
220
|
+
setImageReady(true);
|
|
221
|
+
};
|
|
222
|
+
img.onerror = () => {
|
|
223
|
+
if (cancelled)
|
|
224
|
+
return;
|
|
225
|
+
if (attempt < maxAttempts) {
|
|
226
|
+
attempt += 1;
|
|
227
|
+
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 8000);
|
|
228
|
+
retryTimer = setTimeout(loadAtlas, delay);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
img.src = definition.atlasUrl;
|
|
213
232
|
};
|
|
214
|
-
|
|
233
|
+
loadAtlas();
|
|
215
234
|
return () => {
|
|
216
235
|
cancelled = true;
|
|
217
|
-
|
|
236
|
+
if (retryTimer !== undefined)
|
|
237
|
+
clearTimeout(retryTimer);
|
|
238
|
+
if (activeImg !== null) {
|
|
239
|
+
activeImg.onload = null;
|
|
240
|
+
activeImg.onerror = null;
|
|
241
|
+
}
|
|
218
242
|
};
|
|
219
243
|
}, [definition.atlasUrl, props.visual]);
|
|
220
244
|
// Frame loop: advance the current track and write background-position.
|
|
@@ -381,6 +405,9 @@ export function PetSprite(props) {
|
|
|
381
405
|
const pos = dragPos ?? { right: display.right, bottom: display.bottom };
|
|
382
406
|
const spriteWidth = Math.round(cell.width * spriteScale);
|
|
383
407
|
const spriteHeight = Math.round(cell.height * spriteScale);
|
|
408
|
+
// Bubble typography follows the sprite's own scale (#1549), bounded so a
|
|
409
|
+
// shrunk pet never carries unreadably small text.
|
|
410
|
+
const bubbleScale = bubbleScaleFor(display);
|
|
384
411
|
// Concurrent sessions share one bubble slot: only the display session
|
|
385
412
|
// speaks by default, and the rest hide behind a '+N' badge until the stack
|
|
386
413
|
// is hovered/pinned open. The legacy single 'bubble' is the fallback when
|
|
@@ -440,7 +467,13 @@ export function PetSprite(props) {
|
|
|
440
467
|
window.addEventListener('resize', updatePanelPlacement);
|
|
441
468
|
return () => window.removeEventListener('resize', updatePanelPlacement);
|
|
442
469
|
}, [hovered, renaming, pos.right, pos.bottom, display.size, bubblePresent, sessionBubbles.length, stackOpen, feedback]);
|
|
443
|
-
const float = (_jsxs("div", { ref: floatRef, className: styles.float, style: {
|
|
470
|
+
const float = (_jsxs("div", { ref: floatRef, className: styles.float, style: {
|
|
471
|
+
right: pos.right,
|
|
472
|
+
bottom: pos.bottom,
|
|
473
|
+
zIndex: 2147483000,
|
|
474
|
+
// Read by .bubble / .bubbleStatus in pet.module.css.
|
|
475
|
+
...{ '--pet-bubble-scale': String(bubbleScale) },
|
|
476
|
+
}, onPointerEnter: () => {
|
|
444
477
|
clearHideTimer();
|
|
445
478
|
setHovered(true);
|
|
446
479
|
}, onPointerLeave: (e) => {
|
|
@@ -65,6 +65,8 @@ export declare const zh: {
|
|
|
65
65
|
readonly 'settings.visibleHint': "关闭后宠物隐藏,可从聊天输入区重新召唤。";
|
|
66
66
|
readonly 'settings.size': "大小(px)";
|
|
67
67
|
readonly 'settings.sizeHint': "精灵单元高度,范围 32–1024。";
|
|
68
|
+
readonly 'settings.bubbleScale': "气泡字号倍率";
|
|
69
|
+
readonly 'settings.bubbleScaleHint': "状态、碎碎念与用量气泡的字号会随宠物大小自动缩放;这一项是在此基础上再乘一个倍率(0.5–2,默认 1)。字号本身不小于 10px、不大于 24px。";
|
|
68
70
|
readonly 'settings.right': "距右侧(px)";
|
|
69
71
|
readonly 'settings.rightHint': "距视口右边缘的水平内缩距离。";
|
|
70
72
|
readonly 'settings.bottom': "距底部(px)";
|
|
@@ -146,6 +148,8 @@ export declare const en: {
|
|
|
146
148
|
readonly 'settings.visibleHint': "When off, the pet hides; summon it again from the input row.";
|
|
147
149
|
readonly 'settings.size': "Size (px)";
|
|
148
150
|
readonly 'settings.sizeHint': "Sprite cell height, 32–1024.";
|
|
151
|
+
readonly 'settings.bubbleScale': "Bubble text multiplier";
|
|
152
|
+
readonly 'settings.bubbleScaleHint': "Status, whisper, and usage bubbles scale with the pet automatically; this multiplies that result (0.5–2, default 1). The rendered text stays between 10px and 24px.";
|
|
149
153
|
readonly 'settings.right': "Right inset (px)";
|
|
150
154
|
readonly 'settings.rightHint': "Horizontal inset from the viewport right edge.";
|
|
151
155
|
readonly 'settings.bottom': "Bottom inset (px)";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mDAAmD;AACnD,eAAO,MAAM,EAAE,QAAQ,CAAA;AAEvB,oBAAoB;AACpB,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mDAAmD;AACnD,eAAO,MAAM,EAAE,QAAQ,CAAA;AAEvB,oBAAoB;AACpB,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFL,CAAA;AAEV,oBAAoB;AACpB,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFL,CAAA;AAEV,oCAAoC;AACpC,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;AAEpC,qDAAqD;AACrD,MAAM,MAAM,eAAe,GAAG,MAAM,CAAA;AAEpC;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGnD;AAED;;;;;;;GAOG;AACH,wBAAgB,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAQvE;AAED,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,uBAAuB;QACvB,GAAG,EAAE,MAAM,CAAA;KACZ;CACF"}
|
|
@@ -67,6 +67,8 @@ export const zh = {
|
|
|
67
67
|
'settings.visibleHint': '关闭后宠物隐藏,可从聊天输入区重新召唤。',
|
|
68
68
|
'settings.size': '大小(px)',
|
|
69
69
|
'settings.sizeHint': '精灵单元高度,范围 32–1024。',
|
|
70
|
+
'settings.bubbleScale': '气泡字号倍率',
|
|
71
|
+
'settings.bubbleScaleHint': '状态、碎碎念与用量气泡的字号会随宠物大小自动缩放;这一项是在此基础上再乘一个倍率(0.5–2,默认 1)。字号本身不小于 10px、不大于 24px。',
|
|
70
72
|
'settings.right': '距右侧(px)',
|
|
71
73
|
'settings.rightHint': '距视口右边缘的水平内缩距离。',
|
|
72
74
|
'settings.bottom': '距底部(px)',
|
|
@@ -150,6 +152,8 @@ export const en = {
|
|
|
150
152
|
'settings.visibleHint': 'When off, the pet hides; summon it again from the input row.',
|
|
151
153
|
'settings.size': 'Size (px)',
|
|
152
154
|
'settings.sizeHint': 'Sprite cell height, 32\u20131024.',
|
|
155
|
+
'settings.bubbleScale': 'Bubble text multiplier',
|
|
156
|
+
'settings.bubbleScaleHint': 'Status, whisper, and usage bubbles scale with the pet automatically; this multiplies that result (0.5\u20132, default 1). The rendered text stays between 10px and 24px.',
|
|
153
157
|
'settings.right': 'Right inset (px)',
|
|
154
158
|
'settings.rightHint': 'Horizontal inset from the viewport right edge.',
|
|
155
159
|
'settings.bottom': 'Bottom inset (px)',
|
package/lib/types/index.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export declare function makePetSettingsSchema(fallbackPetId: string): z<Schemast
|
|
|
45
45
|
size: z<number, number>;
|
|
46
46
|
right: z<number, number>;
|
|
47
47
|
bottom: z<number, number>;
|
|
48
|
+
bubbleScale: z<number, number>;
|
|
48
49
|
petId: z<string, string>;
|
|
49
50
|
enabled: z<boolean, boolean>;
|
|
50
51
|
decorationEnabled: z<boolean, boolean>;
|
|
@@ -53,6 +54,7 @@ export declare function makePetSettingsSchema(fallbackPetId: string): z<Schemast
|
|
|
53
54
|
size: z<number, number>;
|
|
54
55
|
right: z<number, number>;
|
|
55
56
|
bottom: z<number, number>;
|
|
57
|
+
bubbleScale: z<number, number>;
|
|
56
58
|
petId: z<string, string>;
|
|
57
59
|
enabled: z<boolean, boolean>;
|
|
58
60
|
decorationEnabled: z<boolean, boolean>;
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,CAAC,MAAM,aAAa,CAAA;AAC3B,OAAO,EAAsC,KAAK,SAAS,EAA2B,MAAM,cAAc,CAAA;AAM1G,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAC9D,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,MAAM,GACP,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,KAAK,GACN,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC5E,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,mBAAmB,GACpB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9E,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,kBAAkB,GACnB,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,aAAa,EACb,QAAQ,EACR,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,gBAAgB,GACjB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAEpB,sEAAsE;AACtE,eAAO,MAAM,IAAI,QAAQ,CAAA;AAEzB,+DAA+D;AAC/D,eAAO,MAAM,MAAM,UAAgB,CAAA;AAEnC;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,CAAC,MAAM,aAAa,CAAA;AAC3B,OAAO,EAAsC,KAAK,SAAS,EAA2B,MAAM,cAAc,CAAA;AAM1G,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAC9D,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,MAAM,GACP,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,KAAK,GACN,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC5E,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,mBAAmB,GACpB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9E,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,kBAAkB,GACnB,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,aAAa,EACb,QAAQ,EACR,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,gBAAgB,GACjB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAEpB,sEAAsE;AACtE,eAAO,MAAM,IAAI,QAAQ,CAAA;AAEzB,+DAA+D;AAC/D,eAAO,MAAM,MAAM,UAAgB,CAAA;AAEnC;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM;;;;;;;;;;;;;;;;;;IAW1D;AAED,0EAA0E;AAC1E,eAAO,MAAM,KAAK,kBAA6C,CAAA;AAE/D,iBAAS,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,SAAc,GAAG,IAAI,CAkF7D"}
|
package/lib/types/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import z from 'schemastery';
|
|
|
14
14
|
import { PetService, PET_SETTINGS_NAMESPACE } from "./service.js";
|
|
15
15
|
import { makePetRoutes } from "./routes.js";
|
|
16
16
|
import { loadPetRegistry, petPackageRoot } from "./registry.js";
|
|
17
|
-
import { DISPLAY_INSET_MAX, DISPLAY_SIZE_MAX, DISPLAY_SIZE_MIN } from "./persist.js";
|
|
17
|
+
import { BUBBLE_SCALE_MAX, BUBBLE_SCALE_MIN, DISPLAY_INSET_MAX, DISPLAY_SIZE_MAX, DISPLAY_SIZE_MIN } from "./persist.js";
|
|
18
18
|
import { mountOnce } from "./mount-once.js";
|
|
19
19
|
export { PetService, MAX_SESSION_BUBBLES } from "./service.js";
|
|
20
20
|
export { AFFINITY_MAX, AFFINITY_RANKS, applyInteraction, applyTurnReward, emptyAffinity, rankOf, } from "./affinity.js";
|
|
@@ -42,6 +42,7 @@ export function makePetSettingsSchema(fallbackPetId) {
|
|
|
42
42
|
size: z.number().step(1).min(DISPLAY_SIZE_MIN).max(DISPLAY_SIZE_MAX).default(160),
|
|
43
43
|
right: z.number().step(1).min(0).max(DISPLAY_INSET_MAX).default(24),
|
|
44
44
|
bottom: z.number().step(1).min(0).max(DISPLAY_INSET_MAX).default(20),
|
|
45
|
+
bubbleScale: z.number().step(0.05).min(BUBBLE_SCALE_MIN).max(BUBBLE_SCALE_MAX).default(1),
|
|
45
46
|
petId: z.string().default(fallbackPetId),
|
|
46
47
|
enabled: z.boolean().default(true),
|
|
47
48
|
decorationEnabled: z.boolean().default(true),
|
package/lib/types/persist.d.ts
CHANGED
|
@@ -18,12 +18,44 @@ export interface PetDisplayConfig {
|
|
|
18
18
|
right: number;
|
|
19
19
|
/** Vertical inset from the viewport bottom edge, px. */
|
|
20
20
|
bottom: number;
|
|
21
|
+
/**
|
|
22
|
+
* Multiplier on the bubble typography's automatic size following (#1549).
|
|
23
|
+
* The rendered bubble scale is `size / 160 * bubbleScale`, bounded by
|
|
24
|
+
* {@link BUBBLE_FONT_MIN_PX}..{@link BUBBLE_FONT_MAX_PX}, so 1 keeps the
|
|
25
|
+
* 12px baseline the stylesheet was drawn for at the default 160px pet.
|
|
26
|
+
*/
|
|
27
|
+
bubbleScale: number;
|
|
21
28
|
}
|
|
22
29
|
export declare const defaultDisplayConfig: PetDisplayConfig;
|
|
23
30
|
/** Display value bounds (shared by load-time validation and setConfig). */
|
|
24
31
|
export declare const DISPLAY_SIZE_MIN = 32;
|
|
25
32
|
export declare const DISPLAY_SIZE_MAX = 1024;
|
|
26
33
|
export declare const DISPLAY_INSET_MAX = 10000;
|
|
34
|
+
/** Bubble typography bounds (issue #1549). */
|
|
35
|
+
export declare const BUBBLE_SCALE_MIN = 0.5;
|
|
36
|
+
export declare const BUBBLE_SCALE_MAX = 2;
|
|
37
|
+
/** Pixel size the bubble stylesheet was drawn for, at the default pet size. */
|
|
38
|
+
export declare const BUBBLE_BASE_FONT_PX = 12;
|
|
39
|
+
/** Pet size that baseline matches; other sizes scale the bubble with them. */
|
|
40
|
+
export declare const BUBBLE_BASE_SIZE_PX = 160;
|
|
41
|
+
/** Readability floor and layout ceiling of the scaled bubble text. */
|
|
42
|
+
export declare const BUBBLE_FONT_MIN_PX = 10;
|
|
43
|
+
export declare const BUBBLE_FONT_MAX_PX = 24;
|
|
44
|
+
/**
|
|
45
|
+
* Bubble typography scale for one display config (issue #1549): the bubble
|
|
46
|
+
* follows the pet's own size so a shrunk pet does not carry a full-size
|
|
47
|
+
* bubble, and the user's multiplier rides on top. The result is a CSS ratio
|
|
48
|
+
* against {@link BUBBLE_BASE_FONT_PX}, bounded so the text never drops below
|
|
49
|
+
* the readability floor or outgrows the pet. `bubbleScale` is optional at
|
|
50
|
+
* runtime: a host that predates the field (a rolling update, or any snapshot
|
|
51
|
+
* that omits it) falls back to the baseline, because a NaN ratio written into
|
|
52
|
+
* `--pet-bubble-scale` collapses every bubble's text to zero.
|
|
53
|
+
* @param display - display config; `bubbleScale` may be absent on older hosts.
|
|
54
|
+
* @returns the ratio written to `--pet-bubble-scale` (always finite).
|
|
55
|
+
*/
|
|
56
|
+
export declare function bubbleScaleFor(display: Pick<PetDisplayConfig, 'size'> & {
|
|
57
|
+
bubbleScale?: number;
|
|
58
|
+
}): number;
|
|
27
59
|
/** Everything persisted for the pet. */
|
|
28
60
|
export interface PetPersist {
|
|
29
61
|
/** Selected pet id (a registry entry; clamped at service startup). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../src/persist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAC/E,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAEpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEhE,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../src/persist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAC/E,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAEpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEhE,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,oBAAoB,EAAE,gBAMlC,CAAA;AAED,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,KAAK,CAAA;AAClC,eAAO,MAAM,gBAAgB,OAAO,CAAA;AACpC,eAAO,MAAM,iBAAiB,QAAS,CAAA;AAEvC,8CAA8C;AAC9C,eAAO,MAAM,gBAAgB,MAAM,CAAA;AACnC,eAAO,MAAM,gBAAgB,IAAI,CAAA;AACjC,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,MAAM,CAAA;AACtC,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,KAAK,CAAA;AACpC,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAEpC;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAWzG;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,aAAa,CAAA;IACvB,gCAAgC;IAChC,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,gBAAgB,CAAA;IACzB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;CAC3C;AAED,wBAAwB;AACxB,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC,wBAAgB,YAAY,IAAI,UAAU,CAUzC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAmFD,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAqB,GAAG,UAAU,CAuDrE;AAED,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,GAAE,MAAqB,GAAG,IAAI,CAMjF"}
|
package/lib/types/persist.js
CHANGED
|
@@ -16,11 +16,46 @@ export const defaultDisplayConfig = {
|
|
|
16
16
|
size: 160,
|
|
17
17
|
right: 24,
|
|
18
18
|
bottom: 120,
|
|
19
|
+
bubbleScale: 1,
|
|
19
20
|
};
|
|
20
21
|
/** Display value bounds (shared by load-time validation and setConfig). */
|
|
21
22
|
export const DISPLAY_SIZE_MIN = 32;
|
|
22
23
|
export const DISPLAY_SIZE_MAX = 1024;
|
|
23
24
|
export const DISPLAY_INSET_MAX = 10_000;
|
|
25
|
+
/** Bubble typography bounds (issue #1549). */
|
|
26
|
+
export const BUBBLE_SCALE_MIN = 0.5;
|
|
27
|
+
export const BUBBLE_SCALE_MAX = 2;
|
|
28
|
+
/** Pixel size the bubble stylesheet was drawn for, at the default pet size. */
|
|
29
|
+
export const BUBBLE_BASE_FONT_PX = 12;
|
|
30
|
+
/** Pet size that baseline matches; other sizes scale the bubble with them. */
|
|
31
|
+
export const BUBBLE_BASE_SIZE_PX = 160;
|
|
32
|
+
/** Readability floor and layout ceiling of the scaled bubble text. */
|
|
33
|
+
export const BUBBLE_FONT_MIN_PX = 10;
|
|
34
|
+
export const BUBBLE_FONT_MAX_PX = 24;
|
|
35
|
+
/**
|
|
36
|
+
* Bubble typography scale for one display config (issue #1549): the bubble
|
|
37
|
+
* follows the pet's own size so a shrunk pet does not carry a full-size
|
|
38
|
+
* bubble, and the user's multiplier rides on top. The result is a CSS ratio
|
|
39
|
+
* against {@link BUBBLE_BASE_FONT_PX}, bounded so the text never drops below
|
|
40
|
+
* the readability floor or outgrows the pet. `bubbleScale` is optional at
|
|
41
|
+
* runtime: a host that predates the field (a rolling update, or any snapshot
|
|
42
|
+
* that omits it) falls back to the baseline, because a NaN ratio written into
|
|
43
|
+
* `--pet-bubble-scale` collapses every bubble's text to zero.
|
|
44
|
+
* @param display - display config; `bubbleScale` may be absent on older hosts.
|
|
45
|
+
* @returns the ratio written to `--pet-bubble-scale` (always finite).
|
|
46
|
+
*/
|
|
47
|
+
export function bubbleScaleFor(display) {
|
|
48
|
+
// Guard the arithmetic, not just the clamp: Math.min/max propagate NaN, so a
|
|
49
|
+
// missing or non-finite field would otherwise reach the stylesheet.
|
|
50
|
+
const size = Number.isFinite(display.size) ? display.size : BUBBLE_BASE_SIZE_PX;
|
|
51
|
+
const multiplier = typeof display.bubbleScale === 'number' && Number.isFinite(display.bubbleScale)
|
|
52
|
+
? display.bubbleScale
|
|
53
|
+
: 1;
|
|
54
|
+
const scaled = (size / BUBBLE_BASE_SIZE_PX) * multiplier;
|
|
55
|
+
const min = BUBBLE_FONT_MIN_PX / BUBBLE_BASE_FONT_PX;
|
|
56
|
+
const max = BUBBLE_FONT_MAX_PX / BUBBLE_BASE_FONT_PX;
|
|
57
|
+
return Math.round(Math.min(max, Math.max(min, scaled)) * 100) / 100;
|
|
58
|
+
}
|
|
24
59
|
/** Name constraints. */
|
|
25
60
|
export const PET_NAME_MAX_LENGTH = 20;
|
|
26
61
|
export function emptyPersist() {
|
|
@@ -155,6 +190,8 @@ export function loadPetPersist(dir = petHomeDir()) {
|
|
|
155
190
|
size: Math.round(Math.min(DISPLAY_SIZE_MAX, Math.max(DISPLAY_SIZE_MIN, finiteNum(rawDisplay.size, base.display.size)))),
|
|
156
191
|
right: Math.round(clamp(finiteNum(rawDisplay.right, base.display.right), DISPLAY_INSET_MAX)),
|
|
157
192
|
bottom: Math.round(clamp(finiteNum(rawDisplay.bottom, base.display.bottom), DISPLAY_INSET_MAX)),
|
|
193
|
+
// Fractional on purpose: the multiplier is a ratio, not a pixel count.
|
|
194
|
+
bubbleScale: Math.min(BUBBLE_SCALE_MAX, Math.max(BUBBLE_SCALE_MIN, finiteNum(rawDisplay.bubbleScale, base.display.bubbleScale))),
|
|
158
195
|
};
|
|
159
196
|
const petId = typeof parsed.petId === 'string' && parsed.petId.trim() !== ''
|
|
160
197
|
? parsed.petId.trim()
|
package/lib/types/service.d.ts
CHANGED
|
@@ -57,6 +57,8 @@ export interface PetSettingsSection {
|
|
|
57
57
|
right: number;
|
|
58
58
|
/** Vertical inset from the viewport bottom edge, px. */
|
|
59
59
|
bottom: number;
|
|
60
|
+
/** Bubble typography multiplier (#1549); see PetDisplayConfig. */
|
|
61
|
+
bubbleScale?: number;
|
|
60
62
|
/** Master switch for the plugin (browser half + host routes). */
|
|
61
63
|
enabled?: boolean;
|
|
62
64
|
/**
|
|
@@ -332,7 +334,7 @@ export declare class PetService extends Service {
|
|
|
332
334
|
ok: false;
|
|
333
335
|
error: string;
|
|
334
336
|
}>;
|
|
335
|
-
/** RPC: update display config (size / position).
|
|
337
|
+
/** RPC: update display config (size / position / bubble scale). Pixel values are clamped to whole pixels. */
|
|
336
338
|
setConfig(patch: Partial<PetDisplayConfig>): Promise<{
|
|
337
339
|
ok: true;
|
|
338
340
|
display: PetDisplayConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGtD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACpF,OAAO,EAAwC,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAC1F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAS9C,OAAO,EAAgC,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}
|
package/lib/types/service.js
CHANGED
|
@@ -15,7 +15,7 @@ import { Service } from '@deepseek-ai/cordis';
|
|
|
15
15
|
import { announcementFresh, parseAnnouncement } from "./announce.js";
|
|
16
16
|
import { emptyProjectionRuntime, isActivityPhase, projectAssistantStreamFrame, projectOfficialEvent, } from "./event-projection.js";
|
|
17
17
|
import { PetLedger } from "./ledger.js";
|
|
18
|
-
import { DEFAULT_PET_NAME, DISPLAY_INSET_MAX, DISPLAY_SIZE_MAX, DISPLAY_SIZE_MIN, PET_NAME_MAX_LENGTH, loadPetPersist, petHomeDir, savePetPersist, } from "./persist.js";
|
|
18
|
+
import { DEFAULT_PET_NAME, DISPLAY_INSET_MAX, DISPLAY_SIZE_MAX, BUBBLE_SCALE_MAX, BUBBLE_SCALE_MIN, DISPLAY_SIZE_MIN, PET_NAME_MAX_LENGTH, loadPetPersist, petHomeDir, savePetPersist, } from "./persist.js";
|
|
19
19
|
import { DEFAULT_DECORATION_ID, decorationView, loadPetRegistry, petEntryView, petPackageRoot, } from "./registry.js";
|
|
20
20
|
import { WHISPER_TTL_MS } from "./chatter.js";
|
|
21
21
|
import { mergeVoicePacks } from "./voice-pack.js";
|
|
@@ -532,12 +532,13 @@ export class PetService extends Service {
|
|
|
532
532
|
this.flush();
|
|
533
533
|
return { ok: true, skin };
|
|
534
534
|
}
|
|
535
|
-
/** RPC: update display config (size / position).
|
|
535
|
+
/** RPC: update display config (size / position / bubble scale). Pixel values are clamped to whole pixels. */
|
|
536
536
|
async setConfig(patch) {
|
|
537
537
|
const next = { ...this.ledger.snapshot.display, ...patch };
|
|
538
538
|
next.size = Math.round(Math.min(DISPLAY_SIZE_MAX, Math.max(DISPLAY_SIZE_MIN, next.size)));
|
|
539
539
|
next.right = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, next.right)));
|
|
540
540
|
next.bottom = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, next.bottom)));
|
|
541
|
+
next.bubbleScale = Math.min(BUBBLE_SCALE_MAX, Math.max(BUBBLE_SCALE_MIN, next.bubbleScale));
|
|
541
542
|
this.ledger.setDisplay(next);
|
|
542
543
|
this.flush();
|
|
543
544
|
this.syncSettingsFromPet();
|
|
@@ -577,6 +578,7 @@ export class PetService extends Service {
|
|
|
577
578
|
next.size = Math.round(Math.min(DISPLAY_SIZE_MAX, Math.max(DISPLAY_SIZE_MIN, section.size)));
|
|
578
579
|
next.right = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, section.right)));
|
|
579
580
|
next.bottom = Math.round(Math.min(DISPLAY_INSET_MAX, Math.max(0, section.bottom)));
|
|
581
|
+
next.bubbleScale = Math.min(BUBBLE_SCALE_MAX, Math.max(BUBBLE_SCALE_MIN, section.bubbleScale ?? next.bubbleScale));
|
|
580
582
|
this.ledger.setDisplay(next);
|
|
581
583
|
this.flush();
|
|
582
584
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linxin666/dsh-pet",
|
|
3
3
|
"description": "Multi-pet companion plugin for the dsh web GUI: a registry-driven floating pet that reacts to model activity, with per-pet naming, petting/feeding interactions and an affinity score",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.24",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^22.19.0 || >=24.0.0"
|