dsh-plugin-image-workbench 1.1.5 → 1.1.6
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/LICENSE +21 -21
- package/README.en.md +5 -3
- package/README.md +7 -3
- package/client.js +241 -241
- package/cordis.patch.yml +14 -14
- package/host.js +51 -0
- package/install.mjs +333 -387
- package/package.json +3 -2
- package/scripts/fetch-style-images.mjs +104 -0
- package/scripts/vendor-snapshot.py +154 -154
- package/server/access.py +26 -26
- package/server/app.py +1329 -1329
- package/server/catalog.py +147 -147
- package/server/composer.py +391 -391
- package/server/drafts.py +158 -158
- package/server/history.py +575 -575
- package/server/imaging.py +172 -172
- package/server/pool.py +1335 -1335
- package/server/pool_admin.py +921 -921
- package/server/pool_service.py +1073 -1073
- package/server/requirements.txt +6 -6
- package/server/smoke_check.py +402 -402
- package/server/static/access.html +202 -202
- package/vendor/chatgpt2api/source/.env.example +82 -82
- package/vendor/chatgpt2api/source/.python-version +1 -1
- package/vendor/chatgpt2api/source/LICENSE +21 -21
- package/vendor/chatgpt2api/source/README.md +391 -391
- package/vendor/chatgpt2api/source/VERSION +1 -1
- package/vendor/chatgpt2api/source/api/__init__.py +2 -2
- package/vendor/chatgpt2api/source/api/accounts.py +537 -537
- package/vendor/chatgpt2api/source/api/ai.py +217 -217
- package/vendor/chatgpt2api/source/api/app.py +62 -62
- package/vendor/chatgpt2api/source/api/errors.py +46 -46
- package/vendor/chatgpt2api/source/api/image_inputs.py +309 -309
- package/vendor/chatgpt2api/source/api/image_tasks.py +120 -120
- package/vendor/chatgpt2api/source/api/support.py +134 -134
- package/vendor/chatgpt2api/source/api/system.py +365 -365
- package/vendor/chatgpt2api/source/assets/kunrouai.svg +50 -50
- package/vendor/chatgpt2api/source/config.default.json +108 -108
- package/vendor/chatgpt2api/source/main.py +9 -9
- package/vendor/chatgpt2api/source/pyproject.toml +27 -27
- package/vendor/chatgpt2api/source/scripts/init_proxy_config.py +186 -186
- package/vendor/chatgpt2api/source/scripts/migrate_storage.py +163 -163
- package/vendor/chatgpt2api/source/scripts/privoxy-warp.conf +13 -13
- package/vendor/chatgpt2api/source/scripts/test_outlook_token_mailbox.py +385 -385
- package/vendor/chatgpt2api/source/scripts/test_storage.py +129 -129
- package/vendor/chatgpt2api/source/scripts/verify_oauth_refresh.py +92 -92
- package/vendor/chatgpt2api/source/services/account_service.py +1757 -1757
- package/vendor/chatgpt2api/source/services/auth_service.py +253 -253
- package/vendor/chatgpt2api/source/services/backup_service.py +671 -671
- package/vendor/chatgpt2api/source/services/config.py +667 -667
- package/vendor/chatgpt2api/source/services/content_filter.py +242 -242
- package/vendor/chatgpt2api/source/services/cpa_service.py +315 -315
- package/vendor/chatgpt2api/source/services/editable_file_task_service.py +260 -260
- package/vendor/chatgpt2api/source/services/image_service.py +376 -376
- package/vendor/chatgpt2api/source/services/image_storage_service.py +405 -405
- package/vendor/chatgpt2api/source/services/image_tags_service.py +76 -76
- package/vendor/chatgpt2api/source/services/image_task_service.py +550 -550
- package/vendor/chatgpt2api/source/services/log_service.py +337 -337
- package/vendor/chatgpt2api/source/services/model_service.py +182 -182
- package/vendor/chatgpt2api/source/services/oauth_login_service.py +267 -267
- package/vendor/chatgpt2api/source/services/openai_backend_api.py +2763 -2763
- package/vendor/chatgpt2api/source/services/openai_oauth.py +32 -32
- package/vendor/chatgpt2api/source/services/protocol/__init__.py +2 -2
- package/vendor/chatgpt2api/source/services/protocol/anthropic_v1_messages.py +307 -307
- package/vendor/chatgpt2api/source/services/protocol/chat_completion_cache.py +238 -238
- package/vendor/chatgpt2api/source/services/protocol/conversation.py +1644 -1644
- package/vendor/chatgpt2api/source/services/protocol/error_response.py +124 -124
- package/vendor/chatgpt2api/source/services/protocol/openai_search.py +19 -19
- package/vendor/chatgpt2api/source/services/protocol/openai_v1_chat_complete.py +316 -316
- package/vendor/chatgpt2api/source/services/protocol/openai_v1_image_edit.py +86 -86
- package/vendor/chatgpt2api/source/services/protocol/openai_v1_image_generations.py +42 -42
- package/vendor/chatgpt2api/source/services/protocol/openai_v1_models.py +53 -53
- package/vendor/chatgpt2api/source/services/protocol/openai_v1_response.py +453 -453
- package/vendor/chatgpt2api/source/services/protocol/web_search_tool.py +160 -160
- package/vendor/chatgpt2api/source/services/proxy_service.py +648 -648
- package/vendor/chatgpt2api/source/services/storage/__init__.py +5 -5
- package/vendor/chatgpt2api/source/services/storage/base.py +38 -38
- package/vendor/chatgpt2api/source/services/storage/database_storage.py +194 -194
- package/vendor/chatgpt2api/source/services/storage/factory.py +104 -104
- package/vendor/chatgpt2api/source/services/storage/git_storage.py +183 -183
- package/vendor/chatgpt2api/source/services/storage/json_storage.py +95 -95
- package/vendor/chatgpt2api/source/services/sub2api_service.py +531 -531
- package/vendor/chatgpt2api/source/utils/helper.py +469 -469
- package/vendor/chatgpt2api/source/utils/image_tokens.py +346 -346
- package/vendor/chatgpt2api/source/utils/log.py +110 -110
- package/vendor/chatgpt2api/source/utils/pkce.py +19 -19
- package/vendor/chatgpt2api/source/utils/pow.py +207 -207
- package/vendor/chatgpt2api/source/utils/sentinel.py +159 -159
- package/vendor/chatgpt2api/source/utils/turnstile.py +184 -184
- package/vendor/chatgpt2api/source/uv.lock +904 -904
- package/vendor/chatgpt2api/source/web/bun.lock +1501 -1501
- package/vendor/chatgpt2api/source/web/components.json +24 -24
- package/vendor/chatgpt2api/source/web/eslint.config.mjs +17 -17
- package/vendor/chatgpt2api/source/web/next.config.ts +40 -40
- package/vendor/chatgpt2api/source/web/package.json +58 -58
- package/vendor/chatgpt2api/source/web/postcss.config.mjs +5 -5
- package/vendor/chatgpt2api/source/web/src/app/accounts/components/account-import-dialog.tsx +925 -925
- package/vendor/chatgpt2api/source/web/src/app/accounts/page.tsx +1307 -1307
- package/vendor/chatgpt2api/source/web/src/app/debug/components/chat-panel.tsx +224 -224
- package/vendor/chatgpt2api/source/web/src/app/debug/components/editable-file-panel.tsx +444 -444
- package/vendor/chatgpt2api/source/web/src/app/debug/components/ppt-panel.tsx +9 -9
- package/vendor/chatgpt2api/source/web/src/app/debug/components/psd-panel.tsx +9 -9
- package/vendor/chatgpt2api/source/web/src/app/debug/components/search-panel.tsx +172 -172
- package/vendor/chatgpt2api/source/web/src/app/debug/components/skill-panel.tsx +169 -169
- package/vendor/chatgpt2api/source/web/src/app/debug/components/types.ts +39 -39
- package/vendor/chatgpt2api/source/web/src/app/debug/page.tsx +59 -59
- package/vendor/chatgpt2api/source/web/src/app/globals.css +230 -230
- package/vendor/chatgpt2api/source/web/src/app/image/components/image-composer.tsx +542 -542
- package/vendor/chatgpt2api/source/web/src/app/image/components/image-results.tsx +554 -554
- package/vendor/chatgpt2api/source/web/src/app/image/components/image-sidebar.tsx +176 -176
- package/vendor/chatgpt2api/source/web/src/app/image/page.tsx +1799 -1799
- package/vendor/chatgpt2api/source/web/src/app/image-manager/page.tsx +732 -732
- package/vendor/chatgpt2api/source/web/src/app/layout.tsx +50 -50
- package/vendor/chatgpt2api/source/web/src/app/login/page.tsx +101 -101
- package/vendor/chatgpt2api/source/web/src/app/logs/page.tsx +356 -356
- package/vendor/chatgpt2api/source/web/src/app/page.tsx +30 -30
- package/vendor/chatgpt2api/source/web/src/app/settings/components/api-docs-card.tsx +341 -341
- package/vendor/chatgpt2api/source/web/src/app/settings/components/backup-settings-card.tsx +447 -447
- package/vendor/chatgpt2api/source/web/src/app/settings/components/base-url-card.tsx +71 -71
- package/vendor/chatgpt2api/source/web/src/app/settings/components/config-card.tsx +491 -491
- package/vendor/chatgpt2api/source/web/src/app/settings/components/cpa-pool-dialog.tsx +108 -108
- package/vendor/chatgpt2api/source/web/src/app/settings/components/cpa-pools-card.tsx +169 -169
- package/vendor/chatgpt2api/source/web/src/app/settings/components/import-browser-dialog.tsx +185 -185
- package/vendor/chatgpt2api/source/web/src/app/settings/components/proxy-runtime-card.tsx +379 -379
- package/vendor/chatgpt2api/source/web/src/app/settings/components/proxy-settings-card.tsx +127 -127
- package/vendor/chatgpt2api/source/web/src/app/settings/components/proxy-settings.tsx +200 -200
- package/vendor/chatgpt2api/source/web/src/app/settings/components/settings-header.tsx +12 -12
- package/vendor/chatgpt2api/source/web/src/app/settings/components/sub2api-connections.tsx +886 -886
- package/vendor/chatgpt2api/source/web/src/app/settings/components/third-party-apps-card.tsx +81 -81
- package/vendor/chatgpt2api/source/web/src/app/settings/components/user-keys-card.tsx +422 -422
- package/vendor/chatgpt2api/source/web/src/app/settings/page.tsx +135 -135
- package/vendor/chatgpt2api/source/web/src/app/settings/store.ts +1069 -1069
- package/vendor/chatgpt2api/source/web/src/components/date-range-filter.tsx +49 -49
- package/vendor/chatgpt2api/source/web/src/components/header-actions.tsx +24 -24
- package/vendor/chatgpt2api/source/web/src/components/image-lightbox.tsx +434 -434
- package/vendor/chatgpt2api/source/web/src/components/image-thumbnail.tsx +46 -46
- package/vendor/chatgpt2api/source/web/src/components/theme-script.tsx +18 -18
- package/vendor/chatgpt2api/source/web/src/components/theme-toggle.tsx +14 -14
- package/vendor/chatgpt2api/source/web/src/components/top-nav.tsx +263 -263
- package/vendor/chatgpt2api/source/web/src/components/ui/animated-theme-toggler.tsx +256 -256
- package/vendor/chatgpt2api/source/web/src/components/ui/badge.tsx +41 -41
- package/vendor/chatgpt2api/source/web/src/components/ui/button.tsx +59 -59
- package/vendor/chatgpt2api/source/web/src/components/ui/calendar.tsx +46 -46
- package/vendor/chatgpt2api/source/web/src/components/ui/card.tsx +61 -61
- package/vendor/chatgpt2api/source/web/src/components/ui/checkbox.tsx +27 -27
- package/vendor/chatgpt2api/source/web/src/components/ui/dia-text-reveal.tsx +267 -267
- package/vendor/chatgpt2api/source/web/src/components/ui/dialog.tsx +132 -132
- package/vendor/chatgpt2api/source/web/src/components/ui/field.tsx +13 -13
- package/vendor/chatgpt2api/source/web/src/components/ui/input.tsx +19 -19
- package/vendor/chatgpt2api/source/web/src/components/ui/label.tsx +24 -24
- package/vendor/chatgpt2api/source/web/src/components/ui/morphing-text.tsx +149 -149
- package/vendor/chatgpt2api/source/web/src/components/ui/popover.tsx +38 -38
- package/vendor/chatgpt2api/source/web/src/components/ui/select.tsx +175 -175
- package/vendor/chatgpt2api/source/web/src/components/ui/sheet.tsx +143 -143
- package/vendor/chatgpt2api/source/web/src/components/ui/table.tsx +29 -29
- package/vendor/chatgpt2api/source/web/src/components/ui/tabs.tsx +91 -91
- package/vendor/chatgpt2api/source/web/src/components/ui/text-3d-flip.tsx +269 -269
- package/vendor/chatgpt2api/source/web/src/components/ui/textarea.tsx +18 -18
- package/vendor/chatgpt2api/source/web/src/components/version-release-dialog.tsx +127 -127
- package/vendor/chatgpt2api/source/web/src/constants/common-env.ts +6 -6
- package/vendor/chatgpt2api/source/web/src/hooks/use-version-check.ts +85 -85
- package/vendor/chatgpt2api/source/web/src/lib/api.ts +926 -926
- package/vendor/chatgpt2api/source/web/src/lib/auth-session.ts +26 -26
- package/vendor/chatgpt2api/source/web/src/lib/release.ts +25 -25
- package/vendor/chatgpt2api/source/web/src/lib/request.ts +93 -93
- package/vendor/chatgpt2api/source/web/src/lib/use-auth-guard.ts +89 -89
- package/vendor/chatgpt2api/source/web/src/lib/utils.ts +6 -6
- package/vendor/chatgpt2api/source/web/src/store/auth.ts +112 -112
- package/vendor/chatgpt2api/source/web/src/store/editable-file-history.ts +33 -33
- package/vendor/chatgpt2api/source/web/src/store/image-conversations.ts +318 -318
- package/vendor/chatgpt2api/source/web/tsconfig.json +42 -42
|
@@ -1,127 +1,127 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { ReactNode } from "react";
|
|
4
|
-
|
|
5
|
-
import { Badge } from "@/components/ui/badge";
|
|
6
|
-
import { Button } from "@/components/ui/button";
|
|
7
|
-
import {
|
|
8
|
-
Dialog,
|
|
9
|
-
DialogContent,
|
|
10
|
-
DialogHeader,
|
|
11
|
-
DialogTitle,
|
|
12
|
-
} from "@/components/ui/dialog";
|
|
13
|
-
import webConfig from "@/constants/common-env";
|
|
14
|
-
import { useVersionCheck } from "@/hooks/use-version-check";
|
|
15
|
-
import { cn } from "@/lib/utils";
|
|
16
|
-
|
|
17
|
-
function typeVariant(type: string): "success" | "danger" | "info" | "violet" | "outline" {
|
|
18
|
-
if (type === "新增") return "success";
|
|
19
|
-
if (type === "修复") return "danger";
|
|
20
|
-
if (type === "调整") return "info";
|
|
21
|
-
if (type === "文档") return "violet";
|
|
22
|
-
return "outline";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function VersionReleaseDialog({ className }: { className?: string }) {
|
|
26
|
-
const {
|
|
27
|
-
open,
|
|
28
|
-
setOpen,
|
|
29
|
-
openReleaseModal,
|
|
30
|
-
latestVersion,
|
|
31
|
-
releases,
|
|
32
|
-
checking,
|
|
33
|
-
hasNewVersion,
|
|
34
|
-
checkLatestRelease,
|
|
35
|
-
} = useVersionCheck();
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<>
|
|
39
|
-
<button
|
|
40
|
-
type="button"
|
|
41
|
-
className={cn(
|
|
42
|
-
"relative px-1 py-1 text-[11px] font-medium text-stone-500 transition hover:text-stone-900 dark:text-stone-300 dark:hover:text-white",
|
|
43
|
-
className,
|
|
44
|
-
)}
|
|
45
|
-
onClick={openReleaseModal}
|
|
46
|
-
title="查看版本更新"
|
|
47
|
-
>
|
|
48
|
-
v{webConfig.appVersion}
|
|
49
|
-
{hasNewVersion ? (
|
|
50
|
-
<span className="absolute -top-1 -right-1 size-2 rounded-full bg-emerald-500" />
|
|
51
|
-
) : null}
|
|
52
|
-
</button>
|
|
53
|
-
<Dialog open={open} onOpenChange={setOpen}>
|
|
54
|
-
<DialogContent className="w-[min(94vw,680px)] rounded-2xl">
|
|
55
|
-
<DialogHeader>
|
|
56
|
-
<DialogTitle>版本更新</DialogTitle>
|
|
57
|
-
</DialogHeader>
|
|
58
|
-
<div className="grid grid-cols-2 gap-3">
|
|
59
|
-
<VersionCard label="当前版本" value={webConfig.appVersion} />
|
|
60
|
-
<VersionCard
|
|
61
|
-
label="最新版本"
|
|
62
|
-
value={latestVersion}
|
|
63
|
-
action={
|
|
64
|
-
<button
|
|
65
|
-
type="button"
|
|
66
|
-
className="text-[11px] text-stone-400 underline-offset-2 hover:text-stone-700 hover:underline dark:hover:text-stone-200"
|
|
67
|
-
onClick={() => void checkLatestRelease(true)}
|
|
68
|
-
>
|
|
69
|
-
{checking ? "检查中..." : "检查更新"}
|
|
70
|
-
</button>
|
|
71
|
-
}
|
|
72
|
-
/>
|
|
73
|
-
</div>
|
|
74
|
-
<div className="max-h-[56vh] space-y-5 overflow-y-auto pr-1">
|
|
75
|
-
{releases.map((release) => (
|
|
76
|
-
<div key={release.version} className="border-l border-stone-200 pl-4 dark:border-white/10">
|
|
77
|
-
<div className="flex flex-wrap items-center gap-2">
|
|
78
|
-
<span className="text-sm font-semibold text-stone-950 dark:text-stone-100">
|
|
79
|
-
{release.version === "Unreleased" ? "未发布" : release.version}
|
|
80
|
-
</span>
|
|
81
|
-
<span className="text-xs text-stone-500 dark:text-stone-400">{release.date}</span>
|
|
82
|
-
{release.version === latestVersion ? <Badge variant="success">最新</Badge> : null}
|
|
83
|
-
{release.version === webConfig.appVersion ? <Badge variant="outline">当前</Badge> : null}
|
|
84
|
-
</div>
|
|
85
|
-
<div className="mt-2 space-y-1.5">
|
|
86
|
-
{release.items.map((item, index) => (
|
|
87
|
-
<div key={index} className="flex items-start gap-2 text-sm leading-6 text-stone-700 dark:text-stone-300">
|
|
88
|
-
<Badge variant={typeVariant(item.type)} className="mt-0.5 shrink-0">
|
|
89
|
-
{item.type}
|
|
90
|
-
</Badge>
|
|
91
|
-
<span className="min-w-0 flex-1">{item.content}</span>
|
|
92
|
-
</div>
|
|
93
|
-
))}
|
|
94
|
-
</div>
|
|
95
|
-
</div>
|
|
96
|
-
))}
|
|
97
|
-
</div>
|
|
98
|
-
<Button variant="outline" size="sm" asChild>
|
|
99
|
-
<a href="https://github.com/basketikun/chatgpt2api" target="_blank" rel="noreferrer">
|
|
100
|
-
前往 GitHub 更新
|
|
101
|
-
</a>
|
|
102
|
-
</Button>
|
|
103
|
-
</DialogContent>
|
|
104
|
-
</Dialog>
|
|
105
|
-
</>
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function VersionCard({
|
|
110
|
-
label,
|
|
111
|
-
value,
|
|
112
|
-
action,
|
|
113
|
-
}: {
|
|
114
|
-
label: string;
|
|
115
|
-
value: string;
|
|
116
|
-
action?: ReactNode;
|
|
117
|
-
}) {
|
|
118
|
-
return (
|
|
119
|
-
<div className="rounded-xl border border-stone-200 bg-white/55 p-3 dark:border-white/10 dark:bg-white/5">
|
|
120
|
-
<div className="flex items-center justify-between gap-2">
|
|
121
|
-
<div className="text-xs text-stone-500 dark:text-stone-400">{label}</div>
|
|
122
|
-
{action}
|
|
123
|
-
</div>
|
|
124
|
-
<div className="mt-1 text-base font-semibold text-stone-950 dark:text-stone-100">{value}</div>
|
|
125
|
-
</div>
|
|
126
|
-
);
|
|
127
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
import { Badge } from "@/components/ui/badge";
|
|
6
|
+
import { Button } from "@/components/ui/button";
|
|
7
|
+
import {
|
|
8
|
+
Dialog,
|
|
9
|
+
DialogContent,
|
|
10
|
+
DialogHeader,
|
|
11
|
+
DialogTitle,
|
|
12
|
+
} from "@/components/ui/dialog";
|
|
13
|
+
import webConfig from "@/constants/common-env";
|
|
14
|
+
import { useVersionCheck } from "@/hooks/use-version-check";
|
|
15
|
+
import { cn } from "@/lib/utils";
|
|
16
|
+
|
|
17
|
+
function typeVariant(type: string): "success" | "danger" | "info" | "violet" | "outline" {
|
|
18
|
+
if (type === "新增") return "success";
|
|
19
|
+
if (type === "修复") return "danger";
|
|
20
|
+
if (type === "调整") return "info";
|
|
21
|
+
if (type === "文档") return "violet";
|
|
22
|
+
return "outline";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function VersionReleaseDialog({ className }: { className?: string }) {
|
|
26
|
+
const {
|
|
27
|
+
open,
|
|
28
|
+
setOpen,
|
|
29
|
+
openReleaseModal,
|
|
30
|
+
latestVersion,
|
|
31
|
+
releases,
|
|
32
|
+
checking,
|
|
33
|
+
hasNewVersion,
|
|
34
|
+
checkLatestRelease,
|
|
35
|
+
} = useVersionCheck();
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
<button
|
|
40
|
+
type="button"
|
|
41
|
+
className={cn(
|
|
42
|
+
"relative px-1 py-1 text-[11px] font-medium text-stone-500 transition hover:text-stone-900 dark:text-stone-300 dark:hover:text-white",
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
onClick={openReleaseModal}
|
|
46
|
+
title="查看版本更新"
|
|
47
|
+
>
|
|
48
|
+
v{webConfig.appVersion}
|
|
49
|
+
{hasNewVersion ? (
|
|
50
|
+
<span className="absolute -top-1 -right-1 size-2 rounded-full bg-emerald-500" />
|
|
51
|
+
) : null}
|
|
52
|
+
</button>
|
|
53
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
54
|
+
<DialogContent className="w-[min(94vw,680px)] rounded-2xl">
|
|
55
|
+
<DialogHeader>
|
|
56
|
+
<DialogTitle>版本更新</DialogTitle>
|
|
57
|
+
</DialogHeader>
|
|
58
|
+
<div className="grid grid-cols-2 gap-3">
|
|
59
|
+
<VersionCard label="当前版本" value={webConfig.appVersion} />
|
|
60
|
+
<VersionCard
|
|
61
|
+
label="最新版本"
|
|
62
|
+
value={latestVersion}
|
|
63
|
+
action={
|
|
64
|
+
<button
|
|
65
|
+
type="button"
|
|
66
|
+
className="text-[11px] text-stone-400 underline-offset-2 hover:text-stone-700 hover:underline dark:hover:text-stone-200"
|
|
67
|
+
onClick={() => void checkLatestRelease(true)}
|
|
68
|
+
>
|
|
69
|
+
{checking ? "检查中..." : "检查更新"}
|
|
70
|
+
</button>
|
|
71
|
+
}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
<div className="max-h-[56vh] space-y-5 overflow-y-auto pr-1">
|
|
75
|
+
{releases.map((release) => (
|
|
76
|
+
<div key={release.version} className="border-l border-stone-200 pl-4 dark:border-white/10">
|
|
77
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
78
|
+
<span className="text-sm font-semibold text-stone-950 dark:text-stone-100">
|
|
79
|
+
{release.version === "Unreleased" ? "未发布" : release.version}
|
|
80
|
+
</span>
|
|
81
|
+
<span className="text-xs text-stone-500 dark:text-stone-400">{release.date}</span>
|
|
82
|
+
{release.version === latestVersion ? <Badge variant="success">最新</Badge> : null}
|
|
83
|
+
{release.version === webConfig.appVersion ? <Badge variant="outline">当前</Badge> : null}
|
|
84
|
+
</div>
|
|
85
|
+
<div className="mt-2 space-y-1.5">
|
|
86
|
+
{release.items.map((item, index) => (
|
|
87
|
+
<div key={index} className="flex items-start gap-2 text-sm leading-6 text-stone-700 dark:text-stone-300">
|
|
88
|
+
<Badge variant={typeVariant(item.type)} className="mt-0.5 shrink-0">
|
|
89
|
+
{item.type}
|
|
90
|
+
</Badge>
|
|
91
|
+
<span className="min-w-0 flex-1">{item.content}</span>
|
|
92
|
+
</div>
|
|
93
|
+
))}
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
))}
|
|
97
|
+
</div>
|
|
98
|
+
<Button variant="outline" size="sm" asChild>
|
|
99
|
+
<a href="https://github.com/basketikun/chatgpt2api" target="_blank" rel="noreferrer">
|
|
100
|
+
前往 GitHub 更新
|
|
101
|
+
</a>
|
|
102
|
+
</Button>
|
|
103
|
+
</DialogContent>
|
|
104
|
+
</Dialog>
|
|
105
|
+
</>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function VersionCard({
|
|
110
|
+
label,
|
|
111
|
+
value,
|
|
112
|
+
action,
|
|
113
|
+
}: {
|
|
114
|
+
label: string;
|
|
115
|
+
value: string;
|
|
116
|
+
action?: ReactNode;
|
|
117
|
+
}) {
|
|
118
|
+
return (
|
|
119
|
+
<div className="rounded-xl border border-stone-200 bg-white/55 p-3 dark:border-white/10 dark:bg-white/5">
|
|
120
|
+
<div className="flex items-center justify-between gap-2">
|
|
121
|
+
<div className="text-xs text-stone-500 dark:text-stone-400">{label}</div>
|
|
122
|
+
{action}
|
|
123
|
+
</div>
|
|
124
|
+
<div className="mt-1 text-base font-semibold text-stone-950 dark:text-stone-100">{value}</div>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const webConfig = {
|
|
2
|
-
apiUrl: process.env.NODE_ENV === 'development' ? 'http://127.0.0.1:8000' : '',
|
|
3
|
-
appVersion: process.env.NEXT_PUBLIC_APP_VERSION || '0.0.0',
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export default webConfig
|
|
1
|
+
const webConfig = {
|
|
2
|
+
apiUrl: process.env.NODE_ENV === 'development' ? 'http://127.0.0.1:8000' : '',
|
|
3
|
+
appVersion: process.env.NEXT_PUBLIC_APP_VERSION || '0.0.0',
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export default webConfig
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useCallback, useMemo, useState } from "react";
|
|
4
|
-
import { toast } from "sonner";
|
|
5
|
-
|
|
6
|
-
import webConfig from "@/constants/common-env";
|
|
7
|
-
import { parseChangelog, type ReleaseInfo } from "@/lib/release";
|
|
8
|
-
|
|
9
|
-
const latestVersionUrl =
|
|
10
|
-
"https://raw.githubusercontent.com/basketikun/chatgpt2api/main/VERSION";
|
|
11
|
-
const latestChangelogUrl =
|
|
12
|
-
"https://raw.githubusercontent.com/basketikun/chatgpt2api/main/CHANGELOG.md";
|
|
13
|
-
|
|
14
|
-
function readLocalReleases(): ReleaseInfo[] {
|
|
15
|
-
return JSON.parse(process.env.NEXT_PUBLIC_APP_RELEASES || "[]");
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function toVersionParts(version: string) {
|
|
19
|
-
const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
20
|
-
return match ? match.slice(1).map(Number) : null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function isNewerVersion(latestVersion: string, currentVersion: string) {
|
|
24
|
-
const latest = toVersionParts(latestVersion);
|
|
25
|
-
const current = toVersionParts(currentVersion);
|
|
26
|
-
if (!latest || !current) return false;
|
|
27
|
-
return latest.some(
|
|
28
|
-
(value, index) =>
|
|
29
|
-
value > current[index] &&
|
|
30
|
-
latest.slice(0, index).every((part, prevIndex) => part === current[prevIndex]),
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function useVersionCheck() {
|
|
35
|
-
const currentVersion = webConfig.appVersion;
|
|
36
|
-
const localReleases = useMemo(readLocalReleases, []);
|
|
37
|
-
const [latestVersion, setLatestVersion] = useState(currentVersion);
|
|
38
|
-
const [releases, setReleases] = useState<ReleaseInfo[]>(localReleases);
|
|
39
|
-
const [checking, setChecking] = useState(false);
|
|
40
|
-
const [open, setOpen] = useState(false);
|
|
41
|
-
const hasNewVersion = isNewerVersion(latestVersion, currentVersion);
|
|
42
|
-
|
|
43
|
-
const checkLatestRelease = useCallback(
|
|
44
|
-
async (showMessage = false) => {
|
|
45
|
-
setChecking(true);
|
|
46
|
-
try {
|
|
47
|
-
const [versionResponse, changelogResponse] = await Promise.all([
|
|
48
|
-
fetch(latestVersionUrl),
|
|
49
|
-
fetch(latestChangelogUrl),
|
|
50
|
-
]);
|
|
51
|
-
if (!versionResponse.ok || !changelogResponse.ok) throw new Error();
|
|
52
|
-
const [version, changelog] = await Promise.all([
|
|
53
|
-
versionResponse.text(),
|
|
54
|
-
changelogResponse.text(),
|
|
55
|
-
]);
|
|
56
|
-
setLatestVersion(version.trim() || currentVersion);
|
|
57
|
-
if (changelog.trim()) setReleases(parseChangelog(changelog));
|
|
58
|
-
if (showMessage) toast.success("已获取最新版本信息");
|
|
59
|
-
} catch {
|
|
60
|
-
setLatestVersion(currentVersion);
|
|
61
|
-
setReleases(localReleases);
|
|
62
|
-
if (showMessage) toast.error("获取最新版本信息失败");
|
|
63
|
-
} finally {
|
|
64
|
-
setChecking(false);
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
[currentVersion, localReleases],
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const openReleaseModal = () => {
|
|
71
|
-
setOpen(true);
|
|
72
|
-
void checkLatestRelease();
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
open,
|
|
77
|
-
setOpen,
|
|
78
|
-
openReleaseModal,
|
|
79
|
-
latestVersion,
|
|
80
|
-
releases,
|
|
81
|
-
checking,
|
|
82
|
-
hasNewVersion,
|
|
83
|
-
checkLatestRelease,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
import { toast } from "sonner";
|
|
5
|
+
|
|
6
|
+
import webConfig from "@/constants/common-env";
|
|
7
|
+
import { parseChangelog, type ReleaseInfo } from "@/lib/release";
|
|
8
|
+
|
|
9
|
+
const latestVersionUrl =
|
|
10
|
+
"https://raw.githubusercontent.com/basketikun/chatgpt2api/main/VERSION";
|
|
11
|
+
const latestChangelogUrl =
|
|
12
|
+
"https://raw.githubusercontent.com/basketikun/chatgpt2api/main/CHANGELOG.md";
|
|
13
|
+
|
|
14
|
+
function readLocalReleases(): ReleaseInfo[] {
|
|
15
|
+
return JSON.parse(process.env.NEXT_PUBLIC_APP_RELEASES || "[]");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function toVersionParts(version: string) {
|
|
19
|
+
const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
20
|
+
return match ? match.slice(1).map(Number) : null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isNewerVersion(latestVersion: string, currentVersion: string) {
|
|
24
|
+
const latest = toVersionParts(latestVersion);
|
|
25
|
+
const current = toVersionParts(currentVersion);
|
|
26
|
+
if (!latest || !current) return false;
|
|
27
|
+
return latest.some(
|
|
28
|
+
(value, index) =>
|
|
29
|
+
value > current[index] &&
|
|
30
|
+
latest.slice(0, index).every((part, prevIndex) => part === current[prevIndex]),
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function useVersionCheck() {
|
|
35
|
+
const currentVersion = webConfig.appVersion;
|
|
36
|
+
const localReleases = useMemo(readLocalReleases, []);
|
|
37
|
+
const [latestVersion, setLatestVersion] = useState(currentVersion);
|
|
38
|
+
const [releases, setReleases] = useState<ReleaseInfo[]>(localReleases);
|
|
39
|
+
const [checking, setChecking] = useState(false);
|
|
40
|
+
const [open, setOpen] = useState(false);
|
|
41
|
+
const hasNewVersion = isNewerVersion(latestVersion, currentVersion);
|
|
42
|
+
|
|
43
|
+
const checkLatestRelease = useCallback(
|
|
44
|
+
async (showMessage = false) => {
|
|
45
|
+
setChecking(true);
|
|
46
|
+
try {
|
|
47
|
+
const [versionResponse, changelogResponse] = await Promise.all([
|
|
48
|
+
fetch(latestVersionUrl),
|
|
49
|
+
fetch(latestChangelogUrl),
|
|
50
|
+
]);
|
|
51
|
+
if (!versionResponse.ok || !changelogResponse.ok) throw new Error();
|
|
52
|
+
const [version, changelog] = await Promise.all([
|
|
53
|
+
versionResponse.text(),
|
|
54
|
+
changelogResponse.text(),
|
|
55
|
+
]);
|
|
56
|
+
setLatestVersion(version.trim() || currentVersion);
|
|
57
|
+
if (changelog.trim()) setReleases(parseChangelog(changelog));
|
|
58
|
+
if (showMessage) toast.success("已获取最新版本信息");
|
|
59
|
+
} catch {
|
|
60
|
+
setLatestVersion(currentVersion);
|
|
61
|
+
setReleases(localReleases);
|
|
62
|
+
if (showMessage) toast.error("获取最新版本信息失败");
|
|
63
|
+
} finally {
|
|
64
|
+
setChecking(false);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
[currentVersion, localReleases],
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const openReleaseModal = () => {
|
|
71
|
+
setOpen(true);
|
|
72
|
+
void checkLatestRelease();
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
open,
|
|
77
|
+
setOpen,
|
|
78
|
+
openReleaseModal,
|
|
79
|
+
latestVersion,
|
|
80
|
+
releases,
|
|
81
|
+
checking,
|
|
82
|
+
hasNewVersion,
|
|
83
|
+
checkLatestRelease,
|
|
84
|
+
};
|
|
85
|
+
}
|