mjpic 1.0.22 → 1.0.23
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.md +37 -0
- package/dist/client/assets/{index-DORSlWYO.js → index-Cy470xj2.js} +40 -40
- package/dist/client/index.html +1 -1
- package/package.json +1 -1
- package/src/App.tsx +2 -1
- package/src/components/layout/Header.tsx +3 -2
- package/src/lib/runtime.ts +31 -0
- package/src/pages/Home.tsx +3 -2
- package/vite.config.ts +9 -0
package/dist/client/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<meta name="description" content="敏捷图片(mjpic)是一个轻量级网页版图片处理工具,设计灵感来源于光影魔术手。" />
|
|
8
8
|
<title>敏捷图片 (mjpic) - 轻量级网页版图片处理工具</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-Cy470xj2.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-C6nMBMvY.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
|
2
2
|
import Home from "@/pages/Home";
|
|
3
|
+
import { getRouterBasename } from "@/lib/runtime";
|
|
3
4
|
|
|
4
5
|
export default function App() {
|
|
5
6
|
return (
|
|
6
|
-
<Router>
|
|
7
|
+
<Router basename={getRouterBasename()}>
|
|
7
8
|
<Routes>
|
|
8
9
|
<Route path="/" element={<Home />} />
|
|
9
10
|
<Route path="/other" element={<div className="text-center text-xl">Other Page - Coming Soon</div>} />
|
|
@@ -4,6 +4,7 @@ import { FolderOpen, Save, Undo, Redo, Languages } from 'lucide-react';
|
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import Konva from 'konva';
|
|
6
6
|
import { SaveDialog } from '@/components/dialogs/SaveDialog';
|
|
7
|
+
import { apiUrl } from '@/lib/runtime';
|
|
7
8
|
|
|
8
9
|
interface HeaderProps {
|
|
9
10
|
stageRef: React.MutableRefObject<Konva.Stage | null>;
|
|
@@ -146,7 +147,7 @@ export const Header = ({ stageRef }: HeaderProps) => {
|
|
|
146
147
|
|
|
147
148
|
// Try to get current image path for CLI mode
|
|
148
149
|
try {
|
|
149
|
-
const response = await fetch('
|
|
150
|
+
const response = await fetch(apiUrl('api/current-image'));
|
|
150
151
|
const imageData = response.ok ? await response.json() : null;
|
|
151
152
|
if (imageData && imageData.path) {
|
|
152
153
|
setCurrentPath(imageData.path);
|
|
@@ -272,7 +273,7 @@ export const Header = ({ stageRef }: HeaderProps) => {
|
|
|
272
273
|
// If savePath is provided (from dialog), use it
|
|
273
274
|
if (savePath) {
|
|
274
275
|
// CLI Mode: Save to specific path
|
|
275
|
-
const saveRes = await fetch('
|
|
276
|
+
const saveRes = await fetch(apiUrl('api/image/save'), {
|
|
276
277
|
method: 'POST',
|
|
277
278
|
headers: { 'Content-Type': 'application/json' },
|
|
278
279
|
body: JSON.stringify({ data: dataUrl, filePath: savePath })
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const ABSOLUTE_URL_RE = /^[a-z]+:/i;
|
|
2
|
+
|
|
3
|
+
export const normalizeBasePath = (value?: string): string => {
|
|
4
|
+
const raw = (value || '/').trim();
|
|
5
|
+
if (!raw || raw === '/') return '/';
|
|
6
|
+
|
|
7
|
+
const stripped = raw.replace(/^\/+|\/+$/g, '');
|
|
8
|
+
return stripped ? `/${stripped}/` : '/';
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const getRouterBasename = (): string | undefined => {
|
|
12
|
+
const base = normalizeBasePath(import.meta.env.BASE_URL);
|
|
13
|
+
return base === '/' ? undefined : base.replace(/\/$/, '');
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const withBasePath = (path: string, base = import.meta.env.BASE_URL): string => {
|
|
17
|
+
if (!path) return normalizeBasePath(base);
|
|
18
|
+
if (ABSOLUTE_URL_RE.test(path) || path.startsWith('//') || path.startsWith('data:')) {
|
|
19
|
+
return path;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const normalizedBase = normalizeBasePath(base);
|
|
23
|
+
const normalizedPath = path.replace(/^\/+/, '');
|
|
24
|
+
|
|
25
|
+
return normalizedBase === '/' ? `/${normalizedPath}` : `${normalizedBase}${normalizedPath}`;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const apiUrl = (path: string): string => {
|
|
29
|
+
const apiBase = import.meta.env.VITE_API_BASE || import.meta.env.BASE_URL;
|
|
30
|
+
return withBasePath(path, apiBase);
|
|
31
|
+
};
|
package/src/pages/Home.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import { Sidebar } from '@/components/layout/Sidebar';
|
|
|
5
5
|
import { CanvasArea } from '@/components/layout/CanvasArea';
|
|
6
6
|
import { RightPanel } from '@/components/layout/RightPanel';
|
|
7
7
|
import { StatusBar } from '@/components/layout/StatusBar';
|
|
8
|
+
import { apiUrl } from '@/lib/runtime';
|
|
8
9
|
import Konva from 'konva';
|
|
9
10
|
|
|
10
11
|
export default function Home() {
|
|
@@ -36,7 +37,7 @@ export default function Home() {
|
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
useEffect(() => {
|
|
39
|
-
fetch('
|
|
40
|
+
fetch(apiUrl('api/current-image'))
|
|
40
41
|
.then(res => {
|
|
41
42
|
if (res.ok) return res.json();
|
|
42
43
|
throw new Error('No image');
|
|
@@ -46,7 +47,7 @@ export default function Home() {
|
|
|
46
47
|
// Extract filename from path
|
|
47
48
|
// Handle both Windows (\) and Unix (/) paths
|
|
48
49
|
const name = data.path.split(/[/\\]/).pop();
|
|
49
|
-
loadImage('
|
|
50
|
+
loadImage(apiUrl('api/image-content'), name, data.path);
|
|
50
51
|
}
|
|
51
52
|
})
|
|
52
53
|
.catch(() => {
|
package/vite.config.ts
CHANGED
|
@@ -2,8 +2,17 @@ import { defineConfig } from 'vite'
|
|
|
2
2
|
import react from '@vitejs/plugin-react'
|
|
3
3
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
4
4
|
|
|
5
|
+
const normalizeBasePath = (value?: string) => {
|
|
6
|
+
const raw = (value || '/').trim();
|
|
7
|
+
if (!raw || raw === '/') return '/';
|
|
8
|
+
|
|
9
|
+
const stripped = raw.replace(/^\/+|\/+$/g, '');
|
|
10
|
+
return stripped ? `/${stripped}/` : '/';
|
|
11
|
+
};
|
|
12
|
+
|
|
5
13
|
// https://vite.dev/config/
|
|
6
14
|
export default defineConfig({
|
|
15
|
+
base: normalizeBasePath(process.env.VITE_BASE_PATH),
|
|
7
16
|
plugins: [
|
|
8
17
|
react({
|
|
9
18
|
babel: {
|