create-pixi-vn 2.0.2 → 2.0.4

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.
Files changed (128) hide show
  1. package/index.js +1 -1
  2. package/package.json +5 -4
  3. package/template-react-vite-muijoy/package-lock.json +4 -4
  4. package/template-react-vite-muijoy/package.json +1 -1
  5. package/template-react-vite-muijoy/src/assets/ink-manifest.gen.json +1 -0
  6. package/template-react-vite-muijoy/src/components/menus/main-menu.tsx +1 -2
  7. package/template-react-vite-muijoy/src/components/menus/save-menu/save-slots.tsx +2 -2
  8. package/template-react-vite-muijoy/src/components/scrrens/narration/narration-cards.tsx +1 -1
  9. package/template-react-vite-muijoy/src/components/ui/image.tsx +7 -38
  10. package/template-react-vite-muijoy/src/content/labels/start.label.ts +2 -4
  11. package/template-react-vite-muijoy/src/pixi-vn-keys.gen.d.ts +20 -0
  12. package/template-react-vite-muijoy/vite.config.ts +1 -0
  13. package/template-react-vite-muijoy-ink/package-lock.json +3 -3
  14. package/template-react-vite-muijoy-ink/package.json +2 -2
  15. package/template-react-vite-muijoy-ink/src/components/menus/save-menu/save-slots.tsx +2 -2
  16. package/template-react-vite-muijoy-ink/src/components/scrrens/narration/narration-cards.tsx +1 -1
  17. package/template-react-vite-muijoy-ink/src/components/ui/image.tsx +7 -38
  18. package/template-react-vite-muijoy-ink/src/pixi-vn-keys.gen.d.ts +22 -0
  19. package/template-react-vite-muijoy-ink/vite.config.ts +1 -0
  20. package/template-react-vite-muijoy-ink-tauri/package-lock.json +3 -3
  21. package/template-react-vite-muijoy-ink-tauri/package.json +2 -2
  22. package/template-react-vite-muijoy-ink-tauri/src/components/menus/save-menu/save-slots.tsx +2 -2
  23. package/template-react-vite-muijoy-ink-tauri/src/components/scrrens/narration/narration-cards.tsx +1 -1
  24. package/template-react-vite-muijoy-ink-tauri/src/components/ui/image.tsx +7 -38
  25. package/template-react-vite-muijoy-ink-tauri/src/pixi-vn-keys.gen.d.ts +22 -0
  26. package/template-react-vite-muijoy-ink-tauri/vite.config.ts +1 -0
  27. package/template-react-vite-muijoy-tauri/package-lock.json +4 -4
  28. package/template-react-vite-muijoy-tauri/package.json +1 -1
  29. package/template-react-vite-muijoy-tauri/src/assets/ink-manifest.gen.json +1 -0
  30. package/template-react-vite-muijoy-tauri/src/components/menus/main-menu.tsx +1 -2
  31. package/template-react-vite-muijoy-tauri/src/components/menus/save-menu/save-slots.tsx +2 -2
  32. package/template-react-vite-muijoy-tauri/src/components/scrrens/narration/narration-cards.tsx +1 -1
  33. package/template-react-vite-muijoy-tauri/src/components/ui/image.tsx +7 -38
  34. package/template-react-vite-muijoy-tauri/src/content/labels/start.label.ts +2 -4
  35. package/template-react-vite-muijoy-tauri/src/pixi-vn-keys.gen.d.ts +20 -0
  36. package/template-react-vite-muijoy-tauri/vite.config.ts +1 -0
  37. package/template-react-vite-muijoy-electron/.eslintrc.cjs +0 -29
  38. package/template-react-vite-muijoy-electron/.vscode/extensions.json +0 -9
  39. package/template-react-vite-muijoy-electron/.vscode/launch.json +0 -32
  40. package/template-react-vite-muijoy-electron/.vscode/settings.json +0 -49
  41. package/template-react-vite-muijoy-electron/README.md +0 -207
  42. package/template-react-vite-muijoy-electron/_gitignore +0 -107
  43. package/template-react-vite-muijoy-electron/forge.config.cts +0 -73
  44. package/template-react-vite-muijoy-electron/forge.env.d.ts +0 -1
  45. package/template-react-vite-muijoy-electron/index.html +0 -13
  46. package/template-react-vite-muijoy-electron/ionic.config.json +0 -7
  47. package/template-react-vite-muijoy-electron/package-lock.json +0 -16984
  48. package/template-react-vite-muijoy-electron/package.json +0 -85
  49. package/template-react-vite-muijoy-electron/public/apple-touch-icon.png +0 -0
  50. package/template-react-vite-muijoy-electron/public/favicon.ico +0 -0
  51. package/template-react-vite-muijoy-electron/public/mask-icon.svg +0 -890
  52. package/template-react-vite-muijoy-electron/public/pixi-vn.svg +0 -23
  53. package/template-react-vite-muijoy-electron/public/pwa-192x192.png +0 -0
  54. package/template-react-vite-muijoy-electron/public/pwa-512x512.png +0 -0
  55. package/template-react-vite-muijoy-electron/public/robots.txt +0 -3
  56. package/template-react-vite-muijoy-electron/src/App.css +0 -42
  57. package/template-react-vite-muijoy-electron/src/App.tsx +0 -16
  58. package/template-react-vite-muijoy-electron/src/AppRoutes.tsx +0 -66
  59. package/template-react-vite-muijoy-electron/src/Home.tsx +0 -27
  60. package/template-react-vite-muijoy-electron/src/Imports.tsx +0 -34
  61. package/template-react-vite-muijoy-electron/src/atoms/autoInfoState.ts +0 -50
  62. package/template-react-vite-muijoy-electron/src/atoms/dialogueCardHeightState.ts +0 -23
  63. package/template-react-vite-muijoy-electron/src/atoms/dialogueCardImageWidthState.ts +0 -23
  64. package/template-react-vite-muijoy-electron/src/atoms/hideInterfaceState.ts +0 -6
  65. package/template-react-vite-muijoy-electron/src/atoms/nextStepLoadingState.ts +0 -6
  66. package/template-react-vite-muijoy-electron/src/atoms/openGameSaveScreenState.ts +0 -6
  67. package/template-react-vite-muijoy-electron/src/atoms/openHistoryScreenState.ts +0 -6
  68. package/template-react-vite-muijoy-electron/src/atoms/openSettingsState.ts +0 -6
  69. package/template-react-vite-muijoy-electron/src/atoms/saveLoadAlertState.ts +0 -26
  70. package/template-react-vite-muijoy-electron/src/atoms/saveScreenPageState.ts +0 -23
  71. package/template-react-vite-muijoy-electron/src/atoms/skipEnabledState.ts +0 -6
  72. package/template-react-vite-muijoy-electron/src/atoms/typewriterDelayState.ts +0 -23
  73. package/template-react-vite-muijoy-electron/src/atoms/typewriterIsAnimatedState.ts +0 -6
  74. package/template-react-vite-muijoy-electron/src/components/ChoiceButton.tsx +0 -19
  75. package/template-react-vite-muijoy-electron/src/components/DragHandleDivider.tsx +0 -40
  76. package/template-react-vite-muijoy-electron/src/components/MenuButton.tsx +0 -37
  77. package/template-react-vite-muijoy-electron/src/components/ModalConfirmation.tsx +0 -70
  78. package/template-react-vite-muijoy-electron/src/components/ModalDialog.tsx +0 -103
  79. package/template-react-vite-muijoy-electron/src/components/NextButton.tsx +0 -94
  80. package/template-react-vite-muijoy-electron/src/components/SettingButton.tsx +0 -44
  81. package/template-react-vite-muijoy-electron/src/components/SliderResizer.tsx +0 -53
  82. package/template-react-vite-muijoy-electron/src/components/TextMenuButton.tsx +0 -41
  83. package/template-react-vite-muijoy-electron/src/components/Typewriter.tsx +0 -335
  84. package/template-react-vite-muijoy-electron/src/components/TypographyShadow.tsx +0 -15
  85. package/template-react-vite-muijoy-electron/src/i18n.ts +0 -29
  86. package/template-react-vite-muijoy-electron/src/index.css +0 -9
  87. package/template-react-vite-muijoy-electron/src/interceptors/EventInterceptor.tsx +0 -49
  88. package/template-react-vite-muijoy-electron/src/interceptors/SkipAutoInterceptor.tsx +0 -67
  89. package/template-react-vite-muijoy-electron/src/main.tsx +0 -39
  90. package/template-react-vite-muijoy-electron/src/models/Character.ts +0 -86
  91. package/template-react-vite-muijoy-electron/src/models/GameSaveData.ts +0 -9
  92. package/template-react-vite-muijoy-electron/src/pixi-vn.d.ts +0 -36
  93. package/template-react-vite-muijoy-electron/src/providers/ThemeProvider.tsx +0 -165
  94. package/template-react-vite-muijoy-electron/src/screens/ChoiceMenu.tsx +0 -130
  95. package/template-react-vite-muijoy-electron/src/screens/GameSaveScreen.tsx +0 -274
  96. package/template-react-vite-muijoy-electron/src/screens/HistoryScreen.tsx +0 -155
  97. package/template-react-vite-muijoy-electron/src/screens/LoadingScreen.tsx +0 -40
  98. package/template-react-vite-muijoy-electron/src/screens/MainMenu.tsx +0 -98
  99. package/template-react-vite-muijoy-electron/src/screens/NarrationScreen.tsx +0 -220
  100. package/template-react-vite-muijoy-electron/src/screens/QuickTools.tsx +0 -168
  101. package/template-react-vite-muijoy-electron/src/screens/Settings.tsx +0 -536
  102. package/template-react-vite-muijoy-electron/src/screens/modals/SaveLoadAlert.tsx +0 -135
  103. package/template-react-vite-muijoy-electron/src/screens/modals/TextInput.tsx +0 -61
  104. package/template-react-vite-muijoy-electron/src/use_query/useQueryInterface.ts +0 -73
  105. package/template-react-vite-muijoy-electron/src/use_query/useQueryLastSave.ts +0 -18
  106. package/template-react-vite-muijoy-electron/src/use_query/useQuerySaves.ts +0 -18
  107. package/template-react-vite-muijoy-electron/src/utilities/actions-utility.ts +0 -10
  108. package/template-react-vite-muijoy-electron/src/utilities/component-utility.ts +0 -25
  109. package/template-react-vite-muijoy-electron/src/utilities/indexedDB-utility.ts +0 -196
  110. package/template-react-vite-muijoy-electron/src/utilities/navigate-utility.ts +0 -18
  111. package/template-react-vite-muijoy-electron/src/utilities/save-utility.ts +0 -125
  112. package/template-react-vite-muijoy-electron/src/values/characters.ts +0 -11
  113. package/template-react-vite-muijoy-electron/src/values/translations/strings_en.json +0 -60
  114. package/template-react-vite-muijoy-electron/src/vite-env.d.ts +0 -4
  115. package/template-react-vite-muijoy-electron/src-electron/icons/icon.icns +0 -0
  116. package/template-react-vite-muijoy-electron/src-electron/icons/icon.ico +0 -0
  117. package/template-react-vite-muijoy-electron/src-electron/icons/icon.png +0 -0
  118. package/template-react-vite-muijoy-electron/src-electron/index.css +0 -7
  119. package/template-react-vite-muijoy-electron/src-electron/main.ts +0 -59
  120. package/template-react-vite-muijoy-electron/src-electron/preload.ts +0 -2
  121. package/template-react-vite-muijoy-electron/src-electron/renderer.ts +0 -31
  122. package/template-react-vite-muijoy-electron/tsconfig.json +0 -32
  123. package/template-react-vite-muijoy-electron/tsconfig.node.json +0 -11
  124. package/template-react-vite-muijoy-electron/vite.base.config.ts +0 -93
  125. package/template-react-vite-muijoy-electron/vite.config.ts +0 -54
  126. package/template-react-vite-muijoy-electron/vite.main.config.ts +0 -9
  127. package/template-react-vite-muijoy-electron/vite.preload.config.ts +0 -9
  128. package/template-react-vite-muijoy-electron/vite.renderer.config.ts +0 -9
package/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import './dist/index.mjs'
3
+ import "./dist/index.mjs";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-pixi-vn",
3
3
  "description": "Create a new Pixi’VN project",
4
- "version": "2.0.2",
4
+ "version": "2.0.4",
5
5
  "type": "module",
6
6
  "license": "GPL-3.0",
7
7
  "author": "DRincs-Productions",
@@ -15,7 +15,6 @@
15
15
  "template-react-vite-muijoy",
16
16
  "template-react-vite-muijoy-ink",
17
17
  "template-react-vite-muijoy-ink-tauri",
18
- "template-react-vite-muijoy-electron",
19
18
  "template-react-vite-muijoy-tauri",
20
19
  "template-story-react-vite-muijoy",
21
20
  "template-story-react-vite-muijoy-ink",
@@ -33,7 +32,8 @@
33
32
  "dev": "unbuild --stub",
34
33
  "build": "unbuild",
35
34
  "typecheck": "tsc --noEmit",
36
- "prepublishOnly": "npm run build"
35
+ "prepublishOnly": "npm run build",
36
+ "format": "biome format --write"
37
37
  },
38
38
  "engines": {
39
39
  "node": "^18.0.0 || >=20.0.0"
@@ -45,9 +45,10 @@
45
45
  "bugs": {
46
46
  "url": "https://github.com/DRincs-Productions/pixi-vn/issues"
47
47
  },
48
- "homepage": "https://pixi-vn.web.app/",
48
+ "homepage": "https://pixi-vn.com/",
49
49
  "funding": "https://github.com/DRincs-Productions/pixi-vn?sponsor=1",
50
50
  "devDependencies": {
51
+ "@biomejs/biome": "latest",
51
52
  "@clack/prompts": "^1.0.0",
52
53
  "@types/minimist": "^1.2.5",
53
54
  "@types/node": "^25.9.1",
@@ -10,7 +10,7 @@
10
10
  "license": "GPL-3.0",
11
11
  "dependencies": {
12
12
  "@base-ui/react": "^1.5.0",
13
- "@drincs/pixi-vn": "^1.8.11",
13
+ "@drincs/pixi-vn": "^1.8.12",
14
14
  "@drincs/pixi-vn-spine": "^0.2.1",
15
15
  "@tailwindcss/vite": "^4.3.0",
16
16
  "@tanstack/react-devtools": "^0.10.5",
@@ -2113,9 +2113,9 @@
2113
2113
  }
2114
2114
  },
2115
2115
  "node_modules/@drincs/pixi-vn": {
2116
- "version": "1.8.11",
2117
- "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.11.tgz",
2118
- "integrity": "sha512-T7FuV/v8qevXq+edFdSLQKyJnQrRhDN4PUzlqw5qe0tDIXycTbr/MMnBNEYRuBMEYUMtoYZb0tmKHY/5Xh8q0Q==",
2116
+ "version": "1.8.12",
2117
+ "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.12.tgz",
2118
+ "integrity": "sha512-1Ff8mZ+hYQzpA2F/LAH37f6cfEewJcYtE4hjLcJRQCv2ql+ti12JAAzCUItopUt8VWEKFGY43J8XILAc66wfjA==",
2119
2119
  "license": "LGPL-2.1",
2120
2120
  "workspaces": [
2121
2121
  "sandbox"
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@base-ui/react": "^1.5.0",
22
- "@drincs/pixi-vn": "^1.8.11",
22
+ "@drincs/pixi-vn": "^1.8.13",
23
23
  "@drincs/pixi-vn-spine": "^0.2.1",
24
24
  "@tailwindcss/vite": "^4.3.0",
25
25
  "@tanstack/react-devtools": "^0.10.5",
@@ -4,7 +4,6 @@ import { Card, CardContent } from "@/components/ui/card";
4
4
  import { Spinner } from "@/components/ui/spinner";
5
5
  import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
6
6
  import { CANVAS_UI_LAYER_NAME, overlayTextShadowClass } from "@/constants";
7
- import { startLabel } from "@/content/labels/start.label";
8
7
  import { useSetSearchParamState } from "@/lib/hooks/navigation-hooks";
9
8
  import { useGameProps } from "@/lib/hooks/props-hooks";
10
9
  import { INTERFACE_DATA_USE_QUEY_KEY as INTERFACE_DATA_USE_QUERY_KEY } from "@/lib/query/interface-query";
@@ -144,7 +143,7 @@ export function MainMenu() {
144
143
  onClick={async () => {
145
144
  setLoading(true);
146
145
  await navigate({ to: "/game/narration" });
147
- Game.start(startLabel, gameProps)
146
+ Game.start("start", gameProps)
148
147
  .then(() =>
149
148
  queryClient.invalidateQueries({
150
149
  queryKey: [INTERFACE_DATA_USE_QUERY_KEY],
@@ -52,9 +52,9 @@ export function SaveSlot({ saveId }: { saveId: number }) {
52
52
  >
53
53
  <Image
54
54
  src={saveData.image}
55
+ layout="fullWidth"
55
56
  alt={saveData.name}
56
- className="absolute inset-0 size-full object-contain rounded-lg"
57
- style={{ pointerEvents: "none", userSelect: "none" }}
57
+ className="absolute inset-0 size-full object-contain rounded-lg pointer-events-none select-none"
58
58
  />
59
59
  {/* top-left metadata */}
60
60
  <div className="absolute top-2.5 left-2.5 flex flex-col gap-0.5 pointer-events-none">
@@ -128,7 +128,7 @@ export function Text({ paragraphRef }: { paragraphRef: RefObject<HTMLDivElement
128
128
  export function CharacterIcon({ alt, icon }: { icon: string; alt: string }) {
129
129
  return (
130
130
  <AspectRatio ratio={16 / 9}>
131
- <Image src={icon} alt={alt} className="h-full w-full object-cover" />
131
+ <Image src={icon} layout="fullWidth" alt={alt} className="h-full w-full object-cover" />
132
132
  </AspectRatio>
133
133
  );
134
134
  }
@@ -1,50 +1,19 @@
1
- import { getPixiJSAsset } from "@/lib/utils/assets-utility";
2
- import { Image as UnpicImage } from "@unpic/react";
3
- import type * as React from "react";
4
- import { useMemo } from "react";
1
+ import { useImageSrc } from "@/lib/hooks/image-hooks";
2
+ import { Image as UnpicImage, type ImageProps } from "@unpic/react";
3
+ import { ImageOff } from "lucide-react";
5
4
 
6
5
  export function Image({
7
6
  src,
8
7
  loading = "lazy",
9
- width,
10
- height,
11
8
  ...props
12
- }: React.ComponentProps<"img">) {
13
- const resolvedSrc = useMemo(() => {
14
- if (!src) {
15
- return undefined;
16
- }
17
- return getPixiJSAsset(src);
18
- }, [src]);
9
+ }: Omit<ImageProps, "src"> & { src?: ImageProps["src"] | null }) {
10
+ const resolvedSrc = useImageSrc(src);
19
11
 
20
12
  if (!resolvedSrc) {
21
- return null;
22
- }
23
-
24
- const parsedWidth =
25
- typeof width === "number" ? width : width ? Number.parseFloat(width) : undefined;
26
- const parsedHeight =
27
- typeof height === "number" ? height : height ? Number.parseFloat(height) : undefined;
28
-
29
- if (
30
- parsedWidth !== undefined &&
31
- parsedHeight !== undefined &&
32
- Number.isFinite(parsedWidth) &&
33
- Number.isFinite(parsedHeight) &&
34
- parsedWidth > 0 &&
35
- parsedHeight > 0
36
- ) {
37
13
  return (
38
- <UnpicImage
39
- src={resolvedSrc}
40
- width={parsedWidth}
41
- height={parsedHeight}
42
- layout="constrained"
43
- loading={loading}
44
- {...props}
45
- />
14
+ <ImageOff aria-label={props.alt ?? "Image unavailable"} className={props.className} />
46
15
  );
47
16
  }
48
17
 
49
- return <UnpicImage src={resolvedSrc} layout="fullWidth" loading={loading} {...props} />;
18
+ return <UnpicImage {...({ src: resolvedSrc, loading, ...props } as ImageProps)} />;
50
19
  }
@@ -1,7 +1,5 @@
1
1
  import { BGM_CHANNEL_NAME } from "@/constants";
2
2
  import { james, mc, sly, steph, steph_fullname } from "@/content/characters";
3
- import { animation01 } from "@/content/labels/animations.label";
4
- import { secondPart } from "@/content/labels/second.label";
5
3
  import {
6
4
  Assets,
7
5
  moveIn,
@@ -489,7 +487,7 @@ export const startLabel = newLabel(
489
487
  narration.dialogGlue = true;
490
488
  narration.dialogue = `and returns with a HUGE tinfoil-covered platter.`;
491
489
  await sound.play("sfx_whoosh", { delay: 0.1 });
492
- await narration.call(animation01, props);
490
+ await narration.call("animation_01", props);
493
491
  },
494
492
  async () => {
495
493
  await showImageContainer("james", [
@@ -555,7 +553,7 @@ export const startLabel = newLabel(
555
553
  moveOut("steph", { direction: "left", ease: "easeInOut", duration: 0.5, delay: 0.1 });
556
554
  narration.dialogue = `You want continue to the next part?`;
557
555
  narration.choices = [
558
- newChoiceOption("Yes, I want to continue", secondPart, {}, { type: "jump" }),
556
+ newChoiceOption("Yes, I want to continue", "second_part", {}, { type: "jump" }),
559
557
  newCloseChoiceOption("No, I want to stop here"),
560
558
  ];
561
559
  },
@@ -0,0 +1,20 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ // noinspection JSUnusedGlobalSymbols
4
+ // This file is auto-generated by @drincs/pixi-vn vite plugin. Do not edit manually.
5
+ declare module "@drincs/pixi-vn/characters" {
6
+ interface PixivnCharacterIds {
7
+ "mc": never;
8
+ "james": never;
9
+ "steph": never;
10
+ "sly": never;
11
+ }
12
+ }
13
+ declare module "@drincs/pixi-vn/narration" {
14
+ interface PixivnLabelIds {
15
+ "animation_01": never;
16
+ "second_part": never;
17
+ "start": never;
18
+ }
19
+ }
20
+ export {};
@@ -35,6 +35,7 @@ export default defineConfig({
35
35
  content: "./src/content/index.ts",
36
36
  characters: "./src/content/characters.ts",
37
37
  labels: "./src/content/labels/*.label.ts",
38
+ typeFilePath: "./src/pixi-vn-keys.gen.d.ts",
38
39
  }),
39
40
  VitePWA({
40
41
  // generate icons with: npm run icon
@@ -2115,9 +2115,9 @@
2115
2115
  }
2116
2116
  },
2117
2117
  "node_modules/@drincs/pixi-vn": {
2118
- "version": "1.8.11",
2119
- "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.11.tgz",
2120
- "integrity": "sha512-T7FuV/v8qevXq+edFdSLQKyJnQrRhDN4PUzlqw5qe0tDIXycTbr/MMnBNEYRuBMEYUMtoYZb0tmKHY/5Xh8q0Q==",
2118
+ "version": "1.8.12",
2119
+ "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.12.tgz",
2120
+ "integrity": "sha512-1Ff8mZ+hYQzpA2F/LAH37f6cfEewJcYtE4hjLcJRQCv2ql+ti12JAAzCUItopUt8VWEKFGY43J8XILAc66wfjA==",
2121
2121
  "license": "LGPL-2.1",
2122
2122
  "workspaces": [
2123
2123
  "sandbox"
@@ -19,8 +19,8 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@base-ui/react": "^1.5.0",
22
- "@drincs/pixi-vn": "^1.8.11",
23
- "@drincs/pixi-vn-ink": "^1.0.4",
22
+ "@drincs/pixi-vn": "^1.8.13",
23
+ "@drincs/pixi-vn-ink": "^1.0.5",
24
24
  "@drincs/pixi-vn-spine": "^0.2.1",
25
25
  "@tailwindcss/vite": "^4.3.0",
26
26
  "@tanstack/react-devtools": "^0.10.5",
@@ -52,9 +52,9 @@ export function SaveSlot({ saveId }: { saveId: number }) {
52
52
  >
53
53
  <Image
54
54
  src={saveData.image}
55
+ layout="fullWidth"
55
56
  alt={saveData.name}
56
- className="absolute inset-0 size-full object-contain rounded-lg"
57
- style={{ pointerEvents: "none", userSelect: "none" }}
57
+ className="absolute inset-0 size-full object-contain rounded-lg pointer-events-none select-none"
58
58
  />
59
59
  {/* top-left metadata */}
60
60
  <div className="absolute top-2.5 left-2.5 flex flex-col gap-0.5 pointer-events-none">
@@ -128,7 +128,7 @@ export function Text({ paragraphRef }: { paragraphRef: RefObject<HTMLDivElement
128
128
  export function CharacterIcon({ alt, icon }: { icon: string; alt: string }) {
129
129
  return (
130
130
  <AspectRatio ratio={16 / 9}>
131
- <Image src={icon} alt={alt} className="h-full w-full object-cover" />
131
+ <Image src={icon} layout="fullWidth" alt={alt} className="h-full w-full object-cover" />
132
132
  </AspectRatio>
133
133
  );
134
134
  }
@@ -1,50 +1,19 @@
1
- import { getPixiJSAsset } from "@/lib/utils/assets-utility";
2
- import { Image as UnpicImage } from "@unpic/react";
3
- import type * as React from "react";
4
- import { useMemo } from "react";
1
+ import { useImageSrc } from "@/lib/hooks/image-hooks";
2
+ import { Image as UnpicImage, type ImageProps } from "@unpic/react";
3
+ import { ImageOff } from "lucide-react";
5
4
 
6
5
  export function Image({
7
6
  src,
8
7
  loading = "lazy",
9
- width,
10
- height,
11
8
  ...props
12
- }: React.ComponentProps<"img">) {
13
- const resolvedSrc = useMemo(() => {
14
- if (!src) {
15
- return undefined;
16
- }
17
- return getPixiJSAsset(src);
18
- }, [src]);
9
+ }: Omit<ImageProps, "src"> & { src?: ImageProps["src"] | null }) {
10
+ const resolvedSrc = useImageSrc(src);
19
11
 
20
12
  if (!resolvedSrc) {
21
- return null;
22
- }
23
-
24
- const parsedWidth =
25
- typeof width === "number" ? width : width ? Number.parseFloat(width) : undefined;
26
- const parsedHeight =
27
- typeof height === "number" ? height : height ? Number.parseFloat(height) : undefined;
28
-
29
- if (
30
- parsedWidth !== undefined &&
31
- parsedHeight !== undefined &&
32
- Number.isFinite(parsedWidth) &&
33
- Number.isFinite(parsedHeight) &&
34
- parsedWidth > 0 &&
35
- parsedHeight > 0
36
- ) {
37
13
  return (
38
- <UnpicImage
39
- src={resolvedSrc}
40
- width={parsedWidth}
41
- height={parsedHeight}
42
- layout="constrained"
43
- loading={loading}
44
- {...props}
45
- />
14
+ <ImageOff aria-label={props.alt ?? "Image unavailable"} className={props.className} />
46
15
  );
47
16
  }
48
17
 
49
- return <UnpicImage src={resolvedSrc} layout="fullWidth" loading={loading} {...props} />;
18
+ return <UnpicImage {...({ src: resolvedSrc, loading, ...props } as ImageProps)} />;
50
19
  }
@@ -0,0 +1,22 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ // noinspection JSUnusedGlobalSymbols
4
+ // This file is auto-generated by @drincs/pixi-vn vite plugin. Do not edit manually.
5
+ declare module "@drincs/pixi-vn/characters" {
6
+ interface PixivnCharacterIds {
7
+ "mc": never;
8
+ "james": never;
9
+ "steph": never;
10
+ "sly": never;
11
+ }
12
+ }
13
+ declare module "@drincs/pixi-vn/narration" {
14
+ interface PixivnLabelIds {
15
+ "animation_01": never;
16
+ "second_part": never;
17
+ "start": never;
18
+ "start_|_c-0": never;
19
+ "start_|_c-1": never;
20
+ }
21
+ }
22
+ export {};
@@ -36,6 +36,7 @@ export default defineConfig({
36
36
  content: "./src/content/index.ts",
37
37
  characters: "./src/content/characters.ts",
38
38
  labels: "./src/content/labels/*.label.ts",
39
+ typeFilePath: "./src/pixi-vn-keys.gen.d.ts",
39
40
  }),
40
41
  vitePluginInk({
41
42
  inkGlob: "./ink/**/*.ink",
@@ -2119,9 +2119,9 @@
2119
2119
  }
2120
2120
  },
2121
2121
  "node_modules/@drincs/pixi-vn": {
2122
- "version": "1.8.11",
2123
- "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.11.tgz",
2124
- "integrity": "sha512-T7FuV/v8qevXq+edFdSLQKyJnQrRhDN4PUzlqw5qe0tDIXycTbr/MMnBNEYRuBMEYUMtoYZb0tmKHY/5Xh8q0Q==",
2122
+ "version": "1.8.12",
2123
+ "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.12.tgz",
2124
+ "integrity": "sha512-1Ff8mZ+hYQzpA2F/LAH37f6cfEewJcYtE4hjLcJRQCv2ql+ti12JAAzCUItopUt8VWEKFGY43J8XILAc66wfjA==",
2125
2125
  "license": "LGPL-2.1",
2126
2126
  "workspaces": [
2127
2127
  "sandbox"
@@ -24,8 +24,8 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@base-ui/react": "^1.5.0",
27
- "@drincs/pixi-vn": "^1.8.11",
28
- "@drincs/pixi-vn-ink": "^1.0.4",
27
+ "@drincs/pixi-vn": "^1.8.13",
28
+ "@drincs/pixi-vn-ink": "^1.0.5",
29
29
  "@drincs/pixi-vn-spine": "^0.2.1",
30
30
  "@tailwindcss/vite": "^4.3.0",
31
31
  "@tanstack/react-devtools": "^0.10.5",
@@ -52,9 +52,9 @@ export function SaveSlot({ saveId }: { saveId: number }) {
52
52
  >
53
53
  <Image
54
54
  src={saveData.image}
55
+ layout="fullWidth"
55
56
  alt={saveData.name}
56
- className="absolute inset-0 size-full object-contain rounded-lg"
57
- style={{ pointerEvents: "none", userSelect: "none" }}
57
+ className="absolute inset-0 size-full object-contain rounded-lg pointer-events-none select-none"
58
58
  />
59
59
  {/* top-left metadata */}
60
60
  <div className="absolute top-2.5 left-2.5 flex flex-col gap-0.5 pointer-events-none">
@@ -128,7 +128,7 @@ export function Text({ paragraphRef }: { paragraphRef: RefObject<HTMLDivElement
128
128
  export function CharacterIcon({ alt, icon }: { icon: string; alt: string }) {
129
129
  return (
130
130
  <AspectRatio ratio={16 / 9}>
131
- <Image src={icon} alt={alt} className="h-full w-full object-cover" />
131
+ <Image src={icon} layout="fullWidth" alt={alt} className="h-full w-full object-cover" />
132
132
  </AspectRatio>
133
133
  );
134
134
  }
@@ -1,50 +1,19 @@
1
- import { getPixiJSAsset } from "@/lib/utils/assets-utility";
2
- import { Image as UnpicImage } from "@unpic/react";
3
- import type * as React from "react";
4
- import { useMemo } from "react";
1
+ import { useImageSrc } from "@/lib/hooks/image-hooks";
2
+ import { Image as UnpicImage, type ImageProps } from "@unpic/react";
3
+ import { ImageOff } from "lucide-react";
5
4
 
6
5
  export function Image({
7
6
  src,
8
7
  loading = "lazy",
9
- width,
10
- height,
11
8
  ...props
12
- }: React.ComponentProps<"img">) {
13
- const resolvedSrc = useMemo(() => {
14
- if (!src) {
15
- return undefined;
16
- }
17
- return getPixiJSAsset(src);
18
- }, [src]);
9
+ }: Omit<ImageProps, "src"> & { src?: ImageProps["src"] | null }) {
10
+ const resolvedSrc = useImageSrc(src);
19
11
 
20
12
  if (!resolvedSrc) {
21
- return null;
22
- }
23
-
24
- const parsedWidth =
25
- typeof width === "number" ? width : width ? Number.parseFloat(width) : undefined;
26
- const parsedHeight =
27
- typeof height === "number" ? height : height ? Number.parseFloat(height) : undefined;
28
-
29
- if (
30
- parsedWidth !== undefined &&
31
- parsedHeight !== undefined &&
32
- Number.isFinite(parsedWidth) &&
33
- Number.isFinite(parsedHeight) &&
34
- parsedWidth > 0 &&
35
- parsedHeight > 0
36
- ) {
37
13
  return (
38
- <UnpicImage
39
- src={resolvedSrc}
40
- width={parsedWidth}
41
- height={parsedHeight}
42
- layout="constrained"
43
- loading={loading}
44
- {...props}
45
- />
14
+ <ImageOff aria-label={props.alt ?? "Image unavailable"} className={props.className} />
46
15
  );
47
16
  }
48
17
 
49
- return <UnpicImage src={resolvedSrc} layout="fullWidth" loading={loading} {...props} />;
18
+ return <UnpicImage {...({ src: resolvedSrc, loading, ...props } as ImageProps)} />;
50
19
  }
@@ -0,0 +1,22 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ // noinspection JSUnusedGlobalSymbols
4
+ // This file is auto-generated by @drincs/pixi-vn vite plugin. Do not edit manually.
5
+ declare module "@drincs/pixi-vn/characters" {
6
+ interface PixivnCharacterIds {
7
+ "mc": never;
8
+ "james": never;
9
+ "steph": never;
10
+ "sly": never;
11
+ }
12
+ }
13
+ declare module "@drincs/pixi-vn/narration" {
14
+ interface PixivnLabelIds {
15
+ "animation_01": never;
16
+ "second_part": never;
17
+ "start": never;
18
+ "start_|_c-0": never;
19
+ "start_|_c-1": never;
20
+ }
21
+ }
22
+ export {};
@@ -38,6 +38,7 @@ export default defineConfig({
38
38
  content: "./src/content/index.ts",
39
39
  characters: "./src/content/characters.ts",
40
40
  labels: "./src/content/labels/*.label.ts",
41
+ typeFilePath: "./src/pixi-vn-keys.gen.d.ts",
41
42
  }),
42
43
  vitePluginInk({
43
44
  inkGlob: "./ink/**/*.ink",
@@ -10,7 +10,7 @@
10
10
  "license": "GPL-3.0",
11
11
  "dependencies": {
12
12
  "@base-ui/react": "^1.5.0",
13
- "@drincs/pixi-vn": "^1.8.11",
13
+ "@drincs/pixi-vn": "^1.8.12",
14
14
  "@drincs/pixi-vn-spine": "^0.2.1",
15
15
  "@tailwindcss/vite": "^4.3.0",
16
16
  "@tanstack/react-devtools": "^0.10.5",
@@ -2117,9 +2117,9 @@
2117
2117
  }
2118
2118
  },
2119
2119
  "node_modules/@drincs/pixi-vn": {
2120
- "version": "1.8.11",
2121
- "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.11.tgz",
2122
- "integrity": "sha512-T7FuV/v8qevXq+edFdSLQKyJnQrRhDN4PUzlqw5qe0tDIXycTbr/MMnBNEYRuBMEYUMtoYZb0tmKHY/5Xh8q0Q==",
2120
+ "version": "1.8.12",
2121
+ "resolved": "https://registry.npmjs.org/@drincs/pixi-vn/-/pixi-vn-1.8.12.tgz",
2122
+ "integrity": "sha512-1Ff8mZ+hYQzpA2F/LAH37f6cfEewJcYtE4hjLcJRQCv2ql+ti12JAAzCUItopUt8VWEKFGY43J8XILAc66wfjA==",
2123
2123
  "license": "LGPL-2.1",
2124
2124
  "workspaces": [
2125
2125
  "sandbox"
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@base-ui/react": "^1.5.0",
27
- "@drincs/pixi-vn": "^1.8.11",
27
+ "@drincs/pixi-vn": "^1.8.13",
28
28
  "@drincs/pixi-vn-spine": "^0.2.1",
29
29
  "@tailwindcss/vite": "^4.3.0",
30
30
  "@tanstack/react-devtools": "^0.10.5",
@@ -4,7 +4,6 @@ import { Card, CardContent } from "@/components/ui/card";
4
4
  import { Spinner } from "@/components/ui/spinner";
5
5
  import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
6
6
  import { CANVAS_UI_LAYER_NAME, overlayTextShadowClass } from "@/constants";
7
- import { startLabel } from "@/content/labels/start.label";
8
7
  import { useSetSearchParamState } from "@/lib/hooks/navigation-hooks";
9
8
  import { useGameProps } from "@/lib/hooks/props-hooks";
10
9
  import { useQuit } from "@/lib/hooks/quit-hooks";
@@ -146,7 +145,7 @@ export function MainMenu() {
146
145
  onClick={async () => {
147
146
  setLoading(true);
148
147
  await navigate({ to: "/game/narration" });
149
- Game.start(startLabel, gameProps)
148
+ Game.start("start", gameProps)
150
149
  .then(() =>
151
150
  queryClient.invalidateQueries({
152
151
  queryKey: [INTERFACE_DATA_USE_QUERY_KEY],
@@ -52,9 +52,9 @@ export function SaveSlot({ saveId }: { saveId: number }) {
52
52
  >
53
53
  <Image
54
54
  src={saveData.image}
55
+ layout="fullWidth"
55
56
  alt={saveData.name}
56
- className="absolute inset-0 size-full object-contain rounded-lg"
57
- style={{ pointerEvents: "none", userSelect: "none" }}
57
+ className="absolute inset-0 size-full object-contain rounded-lg pointer-events-none select-none"
58
58
  />
59
59
  {/* top-left metadata */}
60
60
  <div className="absolute top-2.5 left-2.5 flex flex-col gap-0.5 pointer-events-none">
@@ -128,7 +128,7 @@ export function Text({ paragraphRef }: { paragraphRef: RefObject<HTMLDivElement
128
128
  export function CharacterIcon({ alt, icon }: { icon: string; alt: string }) {
129
129
  return (
130
130
  <AspectRatio ratio={16 / 9}>
131
- <Image src={icon} alt={alt} className="h-full w-full object-cover" />
131
+ <Image src={icon} layout="fullWidth" alt={alt} className="h-full w-full object-cover" />
132
132
  </AspectRatio>
133
133
  );
134
134
  }