create-pixi-vn 2.0.11 → 2.0.13
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/package.json +1 -1
- package/template-react-vite-muijoy/.vscode/tasks.json +18 -15
- package/template-react-vite-muijoy-ink/.vscode/extensions.json +2 -1
- package/template-react-vite-muijoy-ink/.vscode/settings.json +6 -1
- package/template-react-vite-muijoy-ink/.vscode/tasks.json +18 -15
- package/template-react-vite-muijoy-ink/_gitignore +1 -0
- package/template-react-vite-muijoy-ink/ink/second_part.ink +571 -0
- package/template-react-vite-muijoy-ink/ink/start.ink +214 -0
- package/template-react-vite-muijoy-ink/package-lock.json +230 -4
- package/template-react-vite-muijoy-ink/package.json +3 -1
- package/template-react-vite-muijoy-ink/src/App.tsx +25 -25
- package/template-react-vite-muijoy-ink/src/assets/index.ts +2 -4
- package/template-react-vite-muijoy-ink/src/assets/ink-manifest.gen.json +4 -1
- package/template-react-vite-muijoy-ink/src/content/ink/hashtag-commands.ts +38 -0
- package/template-react-vite-muijoy-ink/src/content/ink/text-replaces.ts +19 -0
- package/template-react-vite-muijoy-ink/src/lib/hooks/ink-hooks.tsx +12 -0
- package/template-react-vite-muijoy-ink/src/lib/i18n.ts +22 -1
- package/template-react-vite-muijoy-ink/src/pixi-vn-keys.gen.d.ts +2 -0
- package/template-react-vite-muijoy-ink/src/routes/__root.tsx +4 -0
- package/template-react-vite-muijoy-ink/vite.config.ts +6 -0
- package/template-react-vite-muijoy-ink-tauri/.assetpack.ts +9 -0
- package/template-react-vite-muijoy-ink-tauri/.vscode/extensions.json +5 -1
- package/template-react-vite-muijoy-ink-tauri/.vscode/launch.json +11 -0
- package/template-react-vite-muijoy-ink-tauri/.vscode/settings.json +6 -1
- package/template-react-vite-muijoy-ink-tauri/.vscode/tasks.json +61 -11
- package/template-react-vite-muijoy-ink-tauri/README.md +3 -3
- package/template-react-vite-muijoy-ink-tauri/_github/workflows/desktop.yml +188 -0
- package/template-react-vite-muijoy-ink-tauri/_github/workflows/mobile.yml +270 -0
- package/template-react-vite-muijoy-ink-tauri/_gitignore +11 -0
- package/template-react-vite-muijoy-ink-tauri/ink/second_part.ink +571 -0
- package/template-react-vite-muijoy-ink-tauri/ink/start.ink +214 -0
- package/template-react-vite-muijoy-ink-tauri/package-lock.json +480 -4
- package/template-react-vite-muijoy-ink-tauri/package.json +13 -2
- package/template-react-vite-muijoy-ink-tauri/src/App.tsx +25 -25
- package/template-react-vite-muijoy-ink-tauri/src/assets/index.ts +2 -4
- package/template-react-vite-muijoy-ink-tauri/src/assets/ink-manifest.gen.json +4 -1
- package/template-react-vite-muijoy-ink-tauri/src/components/menus/main-menu.tsx +16 -1
- package/template-react-vite-muijoy-ink-tauri/src/components/menus/settings/quick-menus.tsx +17 -1
- package/template-react-vite-muijoy-ink-tauri/src/components/menus/settings/system-controls.tsx +11 -1
- package/template-react-vite-muijoy-ink-tauri/src/content/ink/hashtag-commands.ts +55 -0
- package/template-react-vite-muijoy-ink-tauri/src/content/ink/text-replaces.ts +19 -0
- package/template-react-vite-muijoy-ink-tauri/src/lib/hooks/ink-hooks.tsx +12 -0
- package/template-react-vite-muijoy-ink-tauri/src/lib/hooks/quit-hooks.ts +24 -0
- package/template-react-vite-muijoy-ink-tauri/src/lib/i18n.ts +22 -1
- package/template-react-vite-muijoy-ink-tauri/src/lib/query/settings-query.ts +7 -1
- package/template-react-vite-muijoy-ink-tauri/src/lib/steam.ts +143 -0
- package/template-react-vite-muijoy-ink-tauri/src/pixi-vn-keys.gen.d.ts +2 -0
- package/template-react-vite-muijoy-ink-tauri/src/routes/__root.tsx +4 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/Cargo.toml +50 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/build.rs +46 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/capabilities/default.json +21 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/128x128.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/128x128@2x.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/32x32.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square107x107Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square142x142Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square150x150Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square284x284Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square30x30Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square310x310Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square44x44Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square71x71Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/Square89x89Logo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/StoreLogo.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/icon.icns +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/icon.ico +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/icons/icon.png +0 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/src/lib.rs +64 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/src/main.rs +6 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/src/steam.rs +238 -0
- package/template-react-vite-muijoy-ink-tauri/src-tauri/tauri.conf.json +50 -0
- package/template-react-vite-muijoy-ink-tauri/vite.config.ts +30 -0
- package/template-react-vite-muijoy-tauri/.assetpack.ts +9 -0
- package/template-react-vite-muijoy-tauri/.vscode/extensions.json +4 -1
- package/template-react-vite-muijoy-tauri/.vscode/launch.json +11 -0
- package/template-react-vite-muijoy-tauri/.vscode/tasks.json +61 -11
- package/template-react-vite-muijoy-tauri/README.md +3 -3
- package/template-react-vite-muijoy-tauri/_github/workflows/desktop.yml +188 -0
- package/template-react-vite-muijoy-tauri/_github/workflows/mobile.yml +270 -0
- package/template-react-vite-muijoy-tauri/_gitignore +10 -0
- package/template-react-vite-muijoy-tauri/package-lock.json +250 -0
- package/template-react-vite-muijoy-tauri/package.json +10 -1
- package/template-react-vite-muijoy-tauri/src/components/menus/main-menu.tsx +16 -1
- package/template-react-vite-muijoy-tauri/src/components/menus/settings/quick-menus.tsx +17 -1
- package/template-react-vite-muijoy-tauri/src/components/menus/settings/system-controls.tsx +11 -1
- package/template-react-vite-muijoy-tauri/src/lib/hooks/quit-hooks.ts +24 -0
- package/template-react-vite-muijoy-tauri/src/lib/query/settings-query.ts +7 -1
- package/template-react-vite-muijoy-tauri/src/lib/steam.ts +143 -0
- package/template-react-vite-muijoy-tauri/src-tauri/Cargo.toml +50 -0
- package/template-react-vite-muijoy-tauri/src-tauri/build.rs +46 -0
- package/template-react-vite-muijoy-tauri/src-tauri/capabilities/default.json +21 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/128x128.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/128x128@2x.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/32x32.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square107x107Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square142x142Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square150x150Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square284x284Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square30x30Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square310x310Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square44x44Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square71x71Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/Square89x89Logo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/StoreLogo.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/icon.icns +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/icon.ico +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/icons/icon.png +0 -0
- package/template-react-vite-muijoy-tauri/src-tauri/src/lib.rs +64 -0
- package/template-react-vite-muijoy-tauri/src-tauri/src/main.rs +6 -0
- package/template-react-vite-muijoy-tauri/src-tauri/src/steam.rs +238 -0
- package/template-react-vite-muijoy-tauri/src-tauri/tauri.conf.json +50 -0
- package/template-react-vite-muijoy-tauri/vite.config.ts +24 -0
- package/template-react-vite-muijoy-ink/src/content/labels/second.label.ts +0 -1207
- package/template-react-vite-muijoy-ink/src/content/labels/start.label.ts +0 -566
- package/template-react-vite-muijoy-ink-tauri/src/content/labels/second.label.ts +0 -1207
- package/template-react-vite-muijoy-ink-tauri/src/content/labels/start.label.ts +0 -566
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import generatedManifestJson from "@/assets/manifest.gen.json";
|
|
2
2
|
import { AUDIO_BUNDLE_NAME } from "@/constants";
|
|
3
|
-
import { secondPart } from "@/content/labels/second.label";
|
|
4
|
-
import { startLabel } from "@/content/labels/start.label";
|
|
5
3
|
import type { FileRouteTypes } from "@/routeTree.gen";
|
|
6
4
|
import type { AssetsManifest } from "@drincs/pixi-vn";
|
|
7
5
|
|
|
@@ -37,7 +35,7 @@ export const manifest: AssetsManifest = {
|
|
|
37
35
|
},
|
|
38
36
|
// labels
|
|
39
37
|
{
|
|
40
|
-
name:
|
|
38
|
+
name: "start",
|
|
41
39
|
assets: [
|
|
42
40
|
{
|
|
43
41
|
alias: "bg01-hallway",
|
|
@@ -46,7 +44,7 @@ export const manifest: AssetsManifest = {
|
|
|
46
44
|
],
|
|
47
45
|
},
|
|
48
46
|
{
|
|
49
|
-
name:
|
|
47
|
+
name: "second_part",
|
|
50
48
|
assets: [
|
|
51
49
|
{
|
|
52
50
|
alias: "bg02-dorm",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { RegisteredCharacters } from "@drincs/pixi-vn";
|
|
2
|
+
import { HashtagCommands } from "@drincs/pixi-vn-ink";
|
|
3
|
+
import zod from "zod";
|
|
4
|
+
|
|
5
|
+
HashtagCommands.add(
|
|
6
|
+
async (script, { navigate }) => {
|
|
7
|
+
await navigate({ to: script[1] });
|
|
8
|
+
return true;
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "navigate",
|
|
12
|
+
description: `Navigates to a specified route within the game.
|
|
13
|
+
|
|
14
|
+
\`\`\`ink
|
|
15
|
+
# navigate <route>
|
|
16
|
+
\`\`\``,
|
|
17
|
+
validation: zod.tuple([zod.literal("navigate"), zod.string()]),
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
HashtagCommands.add(
|
|
22
|
+
async (script) => {
|
|
23
|
+
const character = RegisteredCharacters.get(script[1]);
|
|
24
|
+
if (character) {
|
|
25
|
+
character.name = script[2];
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "character rename",
|
|
31
|
+
description: `Renames a character in the game.
|
|
32
|
+
|
|
33
|
+
\`\`\`ink
|
|
34
|
+
# rename <characterId> <newName>
|
|
35
|
+
\`\`\``,
|
|
36
|
+
validation: zod.tuple([zod.literal("rename"), zod.string(), zod.string()]),
|
|
37
|
+
},
|
|
38
|
+
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { RegisteredCharacters } from "@drincs/pixi-vn";
|
|
2
|
+
import { TextReplaces } from "@drincs/pixi-vn-ink";
|
|
3
|
+
|
|
4
|
+
TextReplaces.add((key) => RegisteredCharacters.get(key)?.name, {
|
|
5
|
+
name: "character name",
|
|
6
|
+
validation: "characterId",
|
|
7
|
+
type: "after-translation",
|
|
8
|
+
i18nInterpolation: true,
|
|
9
|
+
description: "Replaces a character ID with the character's name in the game.",
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
TextReplaces.add(() => "Stephanie", {
|
|
13
|
+
name: "steph_fullname",
|
|
14
|
+
validation: /steph_fullname/,
|
|
15
|
+
type: "after-translation",
|
|
16
|
+
i18nInterpolation: true,
|
|
17
|
+
description:
|
|
18
|
+
"Replaces the placeholder 'steph_fullname' with the full name of the character Stephanie.",
|
|
19
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { onInkTranslate } from "@drincs/pixi-vn-ink";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
|
|
5
|
+
export default function useInkInitialization() {
|
|
6
|
+
const { t } = useTranslation(["narration"]);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
onInkTranslate(t);
|
|
9
|
+
}, [t]);
|
|
10
|
+
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateJsonInkTranslation } from "@drincs/pixi-vn-ink";
|
|
1
2
|
import i18n, { type ReadCallback } from "i18next";
|
|
2
3
|
import LanguageDetector from "i18next-browser-languagedetector";
|
|
3
4
|
import ChainedBackend from "i18next-chained-backend";
|
|
@@ -44,9 +45,29 @@ function getLocalesResource(lng: string): Promise<Record<string, Record<string,
|
|
|
44
45
|
return import(`./../locales/${lng}.json`);
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
async function generateResourceToTranslate(lng: string): Promise<any> {
|
|
49
|
+
let res = await getLocalesResource(lng);
|
|
50
|
+
res = { ...res };
|
|
51
|
+
if (!res) {
|
|
52
|
+
res = {};
|
|
53
|
+
}
|
|
54
|
+
if (!res.narration) {
|
|
55
|
+
res.narration = {};
|
|
56
|
+
}
|
|
57
|
+
if (res.default) {
|
|
58
|
+
delete res.default;
|
|
59
|
+
}
|
|
60
|
+
const manifest = await import("@/assets/ink-manifest.gen.json");
|
|
61
|
+
for (const path of manifest.default) {
|
|
62
|
+
const element = await fetch(path).then((r) => r.json());
|
|
63
|
+
element && (await generateJsonInkTranslation(element, res.narration));
|
|
64
|
+
}
|
|
65
|
+
return res;
|
|
66
|
+
}
|
|
67
|
+
|
|
47
68
|
export async function downloadResourceToTranslate() {
|
|
48
69
|
const lng = i18n.options.fallbackLng?.toString() || "en";
|
|
49
|
-
const data = await
|
|
70
|
+
const data = await generateResourceToTranslate(lng);
|
|
50
71
|
const jsonString = JSON.stringify(data);
|
|
51
72
|
// download the save data as a JSON file
|
|
52
73
|
const blob = new Blob([jsonString], { type: "application/json" });
|
|
@@ -3,6 +3,7 @@ import { SettingsDialogue } from "@/components/menus/settings";
|
|
|
3
3
|
import { OfflineAllert } from "@/components/modals/error-allerts";
|
|
4
4
|
import { RootProvider } from "@/components/providers/root-provider";
|
|
5
5
|
import { INTERFACE_DATA_USE_QUERY_KEY } from "@/constants";
|
|
6
|
+
import useInkInitialization from "@/lib/hooks/ink-hooks";
|
|
6
7
|
import { useConfirmBackNavigation } from "@/lib/hooks/navigation-hooks";
|
|
7
8
|
import { useAutoSaveOnPageClose } from "@/lib/hooks/save-hooks";
|
|
8
9
|
import { useI18n } from "@/lib/i18n";
|
|
@@ -11,6 +12,7 @@ import { defineAssets } from "@/lib/utils/assets-utility";
|
|
|
11
12
|
import { initializeIndexedDB } from "@/lib/utils/db-utility";
|
|
12
13
|
import { loadRefreshSave } from "@/lib/utils/save-utility";
|
|
13
14
|
import type { RouterContext } from "@/router";
|
|
15
|
+
import { setupInkHmrListener } from "@drincs/pixi-vn-ink/vite-listener";
|
|
14
16
|
import { setupPixivnViteData } from "@drincs/pixi-vn/vite-listener";
|
|
15
17
|
import { TanStackDevtools } from "@tanstack/react-devtools";
|
|
16
18
|
import { hotkeysDevtoolsPlugin } from "@tanstack/react-hotkeys-devtools";
|
|
@@ -26,6 +28,7 @@ export const Route = createRootRouteWithContext<RouterContext>()({
|
|
|
26
28
|
// Game.onNavigate(async (to) => redirect({ to }));
|
|
27
29
|
await Promise.all([import("@/content"), initializeIndexedDB(), defineAssets(), useI18n()]);
|
|
28
30
|
await setupPixivnViteData();
|
|
31
|
+
await setupInkHmrListener();
|
|
29
32
|
if (location.pathname !== "/") {
|
|
30
33
|
const isRefreshSaveExist = await loadRefreshSave();
|
|
31
34
|
if (isRefreshSaveExist) {
|
|
@@ -43,6 +46,7 @@ export const Route = createRootRouteWithContext<RouterContext>()({
|
|
|
43
46
|
});
|
|
44
47
|
|
|
45
48
|
function RootComponent() {
|
|
49
|
+
useInkInitialization();
|
|
46
50
|
useAutoSaveOnPageClose();
|
|
47
51
|
useConfirmBackNavigation();
|
|
48
52
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AssetPack } from "@assetpack/core";
|
|
2
|
+
import { vitePluginInk } from "@drincs/pixi-vn-ink/vite";
|
|
2
3
|
import { vitePluginPixivn } from "@drincs/pixi-vn/vite";
|
|
3
4
|
import tailwindcss from "@tailwindcss/vite";
|
|
4
5
|
import { devtools } from "@tanstack/devtools-vite";
|
|
@@ -37,6 +38,11 @@ export default defineConfig(({ mode }) => ({
|
|
|
37
38
|
labels: "./src/content/labels/*.label.ts",
|
|
38
39
|
typeFilePath: "./src/pixi-vn-keys.gen.d.ts",
|
|
39
40
|
}),
|
|
41
|
+
vitePluginInk({
|
|
42
|
+
inkGlob: "./ink/**/*.ink",
|
|
43
|
+
inkJsonOutputPattern: "./public/ink-json/[path][name].gen.json",
|
|
44
|
+
inkJsonManifestPath: "./src/assets/ink-manifest.gen.json",
|
|
45
|
+
}),
|
|
40
46
|
VitePWA({
|
|
41
47
|
// generate icons with: npm run icon
|
|
42
48
|
includeAssets: ["favicon.ico", "apple-touch-icon-180x180.png"],
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { AssetPackConfig } from "@assetpack/core";
|
|
2
2
|
import { pixiPipes } from "@assetpack/core/pixi";
|
|
3
3
|
|
|
4
|
+
// TAURI_ENV_TARGET_TRIPLE is set by `tauri build` before running beforeBuildCommand
|
|
5
|
+
const isTauri = !!process.env.TAURI_ENV_TARGET_TRIPLE;
|
|
6
|
+
|
|
4
7
|
const config: AssetPackConfig = {
|
|
5
8
|
entry: "./src/assets",
|
|
6
9
|
output: "./public/assets",
|
|
@@ -11,6 +14,12 @@ const config: AssetPackConfig = {
|
|
|
11
14
|
output: "src/assets/manifest.gen.json",
|
|
12
15
|
createShortcuts: true,
|
|
13
16
|
},
|
|
17
|
+
// For Tauri: skip @0.5x mipmaps (unused on desktop, WebView handles DPR)
|
|
18
|
+
resolutions: isTauri ? { default: 1 } : undefined,
|
|
19
|
+
// For Tauri: raise WebP quality — files are local so bandwidth is not a concern
|
|
20
|
+
compression: isTauri
|
|
21
|
+
? { png: true, jpg: true, webp: { quality: 88, alphaQuality: 88 } }
|
|
22
|
+
: undefined,
|
|
14
23
|
}),
|
|
15
24
|
],
|
|
16
25
|
};
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
"ms-vscode.vscode-typescript-next",
|
|
4
4
|
"anseki.vscode-color",
|
|
5
5
|
"pflannery.vscode-versionlens",
|
|
6
|
-
"biomejs.biome"
|
|
6
|
+
"biomejs.biome",
|
|
7
|
+
"drincs-productions.pixi-vn-ink-vscode",
|
|
8
|
+
"tauri-apps.tauri-vscode",
|
|
9
|
+
"rust-lang.rust-analyzer",
|
|
10
|
+
"vadimcn.vscode-lldb"
|
|
7
11
|
]
|
|
8
12
|
}
|
|
@@ -17,6 +17,17 @@
|
|
|
17
17
|
"webRoot": "${workspaceFolder}",
|
|
18
18
|
"preLaunchTask": "Restart Vite Dev Server"
|
|
19
19
|
},
|
|
20
|
+
{
|
|
21
|
+
"type": "lldb",
|
|
22
|
+
"request": "launch",
|
|
23
|
+
"name": "Run as Desktop App (Dev)",
|
|
24
|
+
"program": "${workspaceFolder}/src-tauri/target/debug/my-app-package-name",
|
|
25
|
+
"args": [],
|
|
26
|
+
"cwd": "${workspaceFolder}",
|
|
27
|
+
"terminal": "console",
|
|
28
|
+
"preLaunchTask": "Cargo Build (Desktop Dev)",
|
|
29
|
+
"postDebugTask": "Stop Vite Desktop Server"
|
|
30
|
+
},
|
|
20
31
|
{
|
|
21
32
|
"name": "Debug Game Preview",
|
|
22
33
|
"request": "launch",
|
|
@@ -55,5 +55,10 @@
|
|
|
55
55
|
// does fetch when he does Pull
|
|
56
56
|
"git.fetchOnPull": true,
|
|
57
57
|
// move file
|
|
58
|
-
"js/ts.updateImportsOnFileMove.enabled": "always"
|
|
58
|
+
"js/ts.updateImportsOnFileMove.enabled": "always",
|
|
59
|
+
// ink
|
|
60
|
+
"ink.mainFile": "start.ink",
|
|
61
|
+
"ink.rootFolder": "ink",
|
|
62
|
+
"ink.markup": "Markdown",
|
|
63
|
+
"ink.engine": "pixi-vn"
|
|
59
64
|
}
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
"label": "Install Dependencies",
|
|
6
6
|
"type": "shell",
|
|
7
7
|
"command": "[ -d node_modules ] || npm i",
|
|
8
|
+
"windows": {
|
|
9
|
+
"command": "if (!(Test-Path node_modules)) { npm i }"
|
|
10
|
+
},
|
|
8
11
|
"runOptions": {
|
|
9
12
|
"runOn": "folderOpen"
|
|
10
13
|
},
|
|
@@ -18,8 +21,11 @@
|
|
|
18
21
|
{
|
|
19
22
|
"label": "Start Vite Dev Server",
|
|
20
23
|
"type": "shell",
|
|
21
|
-
"command": "
|
|
24
|
+
"command": "npm run dev",
|
|
22
25
|
"isBackground": true,
|
|
26
|
+
"runOptions": {
|
|
27
|
+
"runOn": "folderOpen"
|
|
28
|
+
},
|
|
23
29
|
"dependsOn": ["Install Dependencies"],
|
|
24
30
|
"dependsOrder": "sequence",
|
|
25
31
|
"problemMatcher": {
|
|
@@ -41,9 +47,12 @@
|
|
|
41
47
|
}
|
|
42
48
|
},
|
|
43
49
|
{
|
|
44
|
-
"label": "
|
|
50
|
+
"label": "Stop Vite Dev Server",
|
|
45
51
|
"type": "shell",
|
|
46
|
-
"command": "kill $(
|
|
52
|
+
"command": "kill $(lsof -ti:5173 -sTCP:LISTEN 2>/dev/null) 2>/dev/null; sleep 0.5; true",
|
|
53
|
+
"windows": {
|
|
54
|
+
"command": "$p = Get-NetTCPConnection -LocalPort 5173 -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique; $p | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }; Start-Sleep -Milliseconds 500"
|
|
55
|
+
},
|
|
47
56
|
"presentation": {
|
|
48
57
|
"reveal": "never",
|
|
49
58
|
"panel": "dedicated",
|
|
@@ -52,13 +61,41 @@
|
|
|
52
61
|
},
|
|
53
62
|
{
|
|
54
63
|
"label": "Restart Vite Dev Server",
|
|
55
|
-
"dependsOn": ["
|
|
64
|
+
"dependsOn": ["Stop Vite Dev Server", "Start Vite Dev Server"],
|
|
56
65
|
"dependsOrder": "sequence"
|
|
57
66
|
},
|
|
58
67
|
{
|
|
59
|
-
"label": "
|
|
68
|
+
"label": "Start Vite Preview Server",
|
|
60
69
|
"type": "shell",
|
|
61
|
-
"command": "
|
|
70
|
+
"command": "npm run preview",
|
|
71
|
+
"isBackground": true,
|
|
72
|
+
"dependsOn": ["Install Dependencies"],
|
|
73
|
+
"dependsOrder": "sequence",
|
|
74
|
+
"problemMatcher": {
|
|
75
|
+
"owner": "vite",
|
|
76
|
+
"pattern": {
|
|
77
|
+
"regexp": "^(?!x)x"
|
|
78
|
+
},
|
|
79
|
+
"background": {
|
|
80
|
+
"activeOnStart": true,
|
|
81
|
+
"beginsPattern": ".",
|
|
82
|
+
"endsPattern": "Local:\\s+http://localhost:4173/"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"presentation": {
|
|
86
|
+
"reveal": "always",
|
|
87
|
+
"panel": "dedicated",
|
|
88
|
+
"clear": false,
|
|
89
|
+
"close": true
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"label": "Stop Vite Preview Server",
|
|
94
|
+
"type": "shell",
|
|
95
|
+
"command": "kill $(lsof -ti:4173 -sTCP:LISTEN 2>/dev/null) 2>/dev/null; true",
|
|
96
|
+
"windows": {
|
|
97
|
+
"command": "$p = Get-NetTCPConnection -LocalPort 4173 -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique; $p | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }"
|
|
98
|
+
},
|
|
62
99
|
"presentation": {
|
|
63
100
|
"reveal": "never",
|
|
64
101
|
"panel": "dedicated",
|
|
@@ -66,9 +103,22 @@
|
|
|
66
103
|
}
|
|
67
104
|
},
|
|
68
105
|
{
|
|
69
|
-
"label": "
|
|
106
|
+
"label": "Cargo Build (Desktop Dev)",
|
|
70
107
|
"type": "shell",
|
|
71
|
-
"command": "
|
|
108
|
+
"command": "cargo build --manifest-path=./src-tauri/Cargo.toml --no-default-features",
|
|
109
|
+
"dependsOn": ["Start Vite Desktop Server"],
|
|
110
|
+
"presentation": {
|
|
111
|
+
"reveal": "always",
|
|
112
|
+
"panel": "dedicated",
|
|
113
|
+
"clear": true,
|
|
114
|
+
"close": true
|
|
115
|
+
},
|
|
116
|
+
"problemMatcher": ["$rustc"]
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"label": "Start Vite Desktop Server",
|
|
120
|
+
"type": "shell",
|
|
121
|
+
"command": "npm run dev",
|
|
72
122
|
"isBackground": true,
|
|
73
123
|
"dependsOn": ["Install Dependencies"],
|
|
74
124
|
"problemMatcher": {
|
|
@@ -79,7 +129,7 @@
|
|
|
79
129
|
"background": {
|
|
80
130
|
"activeOnStart": true,
|
|
81
131
|
"beginsPattern": ".",
|
|
82
|
-
"endsPattern": "
|
|
132
|
+
"endsPattern": "localhost:5173"
|
|
83
133
|
}
|
|
84
134
|
},
|
|
85
135
|
"presentation": {
|
|
@@ -90,9 +140,9 @@
|
|
|
90
140
|
}
|
|
91
141
|
},
|
|
92
142
|
{
|
|
93
|
-
"label": "Stop Vite
|
|
143
|
+
"label": "Stop Vite Desktop Server",
|
|
94
144
|
"type": "shell",
|
|
95
|
-
"command": "pkill -f 'vite' 2>/dev/null; pkill -f 'npm run
|
|
145
|
+
"command": "pkill -f 'vite' 2>/dev/null; pkill -f 'npm run dev' 2>/dev/null; exit 0",
|
|
96
146
|
"presentation": {
|
|
97
147
|
"reveal": "never",
|
|
98
148
|
"panel": "dedicated",
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
# my-app-project-name
|
|
2
|
-
|
|
3
|
-
my-app-description
|
|
1
|
+
# my-app-project-name
|
|
2
|
+
|
|
3
|
+
my-app-description
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
name: 'Build & Publish Desktop App'
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
# ── Create the release exactly once before the matrix starts ────────────────
|
|
10
|
+
create-release:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
outputs:
|
|
15
|
+
release_tag: ${{ github.ref_name }}
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: create release
|
|
20
|
+
run: |
|
|
21
|
+
gh release view "${{ github.ref_name }}" 2>/dev/null || \
|
|
22
|
+
gh release create "${{ github.ref_name }}" \
|
|
23
|
+
--title "App v$(jq -r '.version' src-tauri/tauri.conf.json)" \
|
|
24
|
+
--notes "See the assets to download this version and install." \
|
|
25
|
+
2>/dev/null || \
|
|
26
|
+
gh release view "${{ github.ref_name }}" > /dev/null
|
|
27
|
+
env:
|
|
28
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
29
|
+
|
|
30
|
+
# ── Build and upload per platform ───────────────────────────────────────────
|
|
31
|
+
publish-tauri:
|
|
32
|
+
needs: create-release
|
|
33
|
+
permissions:
|
|
34
|
+
contents: write
|
|
35
|
+
strategy:
|
|
36
|
+
fail-fast: false
|
|
37
|
+
matrix:
|
|
38
|
+
include:
|
|
39
|
+
- platform: 'macos-latest'
|
|
40
|
+
args: '--target aarch64-apple-darwin'
|
|
41
|
+
target: 'aarch64-apple-darwin'
|
|
42
|
+
arch: 'aarch64'
|
|
43
|
+
- platform: 'macos-latest'
|
|
44
|
+
args: '--target x86_64-apple-darwin'
|
|
45
|
+
target: 'x86_64-apple-darwin'
|
|
46
|
+
arch: 'x86_64'
|
|
47
|
+
- platform: 'ubuntu-22.04'
|
|
48
|
+
args: ''
|
|
49
|
+
target: ''
|
|
50
|
+
arch: 'x64'
|
|
51
|
+
- platform: 'windows-latest'
|
|
52
|
+
args: ''
|
|
53
|
+
target: ''
|
|
54
|
+
arch: 'x64'
|
|
55
|
+
|
|
56
|
+
runs-on: ${{ matrix.platform }}
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
|
|
60
|
+
- name: setup node
|
|
61
|
+
uses: actions/setup-node@v6
|
|
62
|
+
with:
|
|
63
|
+
node-version: lts/*
|
|
64
|
+
|
|
65
|
+
- name: install Rust stable
|
|
66
|
+
uses: dtolnay/rust-toolchain@stable
|
|
67
|
+
with:
|
|
68
|
+
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
|
69
|
+
|
|
70
|
+
- name: install dependencies (ubuntu only)
|
|
71
|
+
if: matrix.platform == 'ubuntu-22.04'
|
|
72
|
+
run: |
|
|
73
|
+
sudo apt-get update
|
|
74
|
+
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
|
75
|
+
|
|
76
|
+
- name: install frontend dependencies
|
|
77
|
+
run: npm i
|
|
78
|
+
|
|
79
|
+
- name: build app
|
|
80
|
+
uses: tauri-apps/tauri-action@v0
|
|
81
|
+
env:
|
|
82
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
83
|
+
with:
|
|
84
|
+
args: ${{ matrix.args }}
|
|
85
|
+
|
|
86
|
+
# ── Linux: .deb + .AppImage (AppImage is already portable) ─────────────
|
|
87
|
+
- name: upload artifacts (Linux)
|
|
88
|
+
if: matrix.platform == 'ubuntu-22.04'
|
|
89
|
+
env:
|
|
90
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
91
|
+
TAG: ${{ needs.create-release.outputs.release_tag }}
|
|
92
|
+
run: |
|
|
93
|
+
upload_file() {
|
|
94
|
+
local file="$1"
|
|
95
|
+
local limit=$((1900 * 1024 * 1024))
|
|
96
|
+
local size; size=$(stat -c%s "$file")
|
|
97
|
+
if [ "$size" -gt "$limit" ]; then
|
|
98
|
+
echo "Splitting $(basename "$file") (${size} bytes) into 1.9 GB parts..."
|
|
99
|
+
split -b 1900m "$file" "${file}.part"
|
|
100
|
+
for part in "${file}.part"*; do
|
|
101
|
+
gh release upload "$TAG" "$part" --clobber
|
|
102
|
+
done
|
|
103
|
+
else
|
|
104
|
+
gh release upload "$TAG" "$file" --clobber
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
find src-tauri/target/release/bundle -type f \
|
|
108
|
+
\( -name "*.deb" -o -name "*.AppImage" -o -name "*.rpm" \) |
|
|
109
|
+
while IFS= read -r f; do upload_file "$f"; done
|
|
110
|
+
|
|
111
|
+
# ── macOS: .dmg installer + portable .app.tar.gz ───────────────────────
|
|
112
|
+
- name: upload artifacts (macOS)
|
|
113
|
+
if: matrix.platform == 'macos-latest'
|
|
114
|
+
env:
|
|
115
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
116
|
+
TAG: ${{ needs.create-release.outputs.release_tag }}
|
|
117
|
+
run: |
|
|
118
|
+
BIN_NAME=$(grep '^name = ' src-tauri/Cargo.toml | head -1 | cut -d'"' -f2)
|
|
119
|
+
VERSION=$(jq -r '.version' src-tauri/tauri.conf.json)
|
|
120
|
+
ARCH="${{ matrix.arch }}"
|
|
121
|
+
BUNDLE_DIR="src-tauri/target/${{ matrix.target }}/release/bundle"
|
|
122
|
+
|
|
123
|
+
upload_file() {
|
|
124
|
+
local file="$1"
|
|
125
|
+
local limit=$((1900 * 1024 * 1024))
|
|
126
|
+
local size; size=$(stat -f%z "$file")
|
|
127
|
+
if [ "$size" -gt "$limit" ]; then
|
|
128
|
+
echo "Splitting $(basename "$file") (${size} bytes) into 1.9 GB parts..."
|
|
129
|
+
split -b 1900m "$file" "${file}.part"
|
|
130
|
+
for part in "${file}.part"*; do
|
|
131
|
+
gh release upload "$TAG" "$part" --clobber
|
|
132
|
+
done
|
|
133
|
+
else
|
|
134
|
+
gh release upload "$TAG" "$file" --clobber
|
|
135
|
+
fi
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# DMG installer
|
|
139
|
+
find "$BUNDLE_DIR/dmg" -name "*.dmg" |
|
|
140
|
+
while IFS= read -r f; do upload_file "$f"; done
|
|
141
|
+
|
|
142
|
+
# Portable: bundle .app into a tar.gz
|
|
143
|
+
APP_PATH=$(find "$BUNDLE_DIR/macos" -maxdepth 1 -name "*.app" | head -1)
|
|
144
|
+
PORTABLE="${BIN_NAME}_${VERSION}_macos_${ARCH}-portable.tar.gz"
|
|
145
|
+
tar -czf "$PORTABLE" -C "$(dirname "$APP_PATH")" "$(basename "$APP_PATH")"
|
|
146
|
+
upload_file "$PORTABLE"
|
|
147
|
+
|
|
148
|
+
# ── Windows: NSIS/.msi installers + portable .zip ──────────────────────
|
|
149
|
+
- name: upload artifacts (Windows)
|
|
150
|
+
if: matrix.platform == 'windows-latest'
|
|
151
|
+
shell: pwsh
|
|
152
|
+
env:
|
|
153
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
154
|
+
run: |
|
|
155
|
+
$tag = "${{ needs.create-release.outputs.release_tag }}"
|
|
156
|
+
$ver = (Get-Content src-tauri/tauri.conf.json | ConvertFrom-Json).version
|
|
157
|
+
$name = (Select-String -Path src-tauri/Cargo.toml `
|
|
158
|
+
-Pattern '^name = "(.+)"').Matches[0].Groups[1].Value
|
|
159
|
+
|
|
160
|
+
function Upload-File($Path, $Tag) {
|
|
161
|
+
$limitBytes = 1900 * 1MB
|
|
162
|
+
$item = Get-Item $Path
|
|
163
|
+
if ($item.Length -gt $limitBytes) {
|
|
164
|
+
Write-Host "Splitting $($item.Name) ($($item.Length) bytes) into 1.9 GB parts..."
|
|
165
|
+
$stream = [System.IO.File]::OpenRead($Path)
|
|
166
|
+
$buf = New-Object byte[] $limitBytes
|
|
167
|
+
$i = 0
|
|
168
|
+
while (($n = $stream.Read($buf, 0, $buf.Length)) -gt 0) {
|
|
169
|
+
$part = "$Path.part$($i.ToString('D3'))"
|
|
170
|
+
$data = if ($n -eq $buf.Length) { $buf } else { $buf[0..($n - 1)] }
|
|
171
|
+
[System.IO.File]::WriteAllBytes($part, $data)
|
|
172
|
+
gh release upload $Tag $part --clobber
|
|
173
|
+
$i++
|
|
174
|
+
}
|
|
175
|
+
$stream.Dispose()
|
|
176
|
+
} else {
|
|
177
|
+
gh release upload $Tag $Path --clobber
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
# NSIS and MSI installers
|
|
182
|
+
Get-ChildItem -Recurse src-tauri/target/release/bundle -Include "*.exe","*.msi" |
|
|
183
|
+
ForEach-Object { Upload-File $_.FullName $tag }
|
|
184
|
+
|
|
185
|
+
# Portable ZIP (single EXE, no installer)
|
|
186
|
+
$zip = "${name}_${ver}_windows_x64-portable.zip"
|
|
187
|
+
Compress-Archive -Path "src-tauri/target/release/$name.exe" -DestinationPath $zip
|
|
188
|
+
Upload-File $zip $tag
|