@dsh-plus/image-studio 0.1.1 → 0.1.3
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/lib/client.js +175 -156
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -11
- package/package.json +12 -12
- package/src/client/panel/gallery.tsx +13 -13
- package/src/client/panel/panel.tsx +12 -13
- package/src/client/panel/picker.tsx +8 -14
- package/src/client/styles.ts +142 -125
- package/src/service.ts +5 -2
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
|
-
import {
|
|
2
|
+
import { Service } from "@deepseek-ai/cordis";
|
|
3
3
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
4
4
|
import { request } from "node:http";
|
|
5
5
|
import { request as request$1 } from "node:https";
|
|
@@ -996,18 +996,9 @@ function defaultIdCounter() {
|
|
|
996
996
|
}
|
|
997
997
|
//#endregion
|
|
998
998
|
//#region src/service.ts
|
|
999
|
-
/**
|
|
1000
|
-
* image-studio 服务主体:
|
|
1001
|
-
* - settings installSection(三组预设 + 并发/超时/代理/画廊上限);
|
|
1002
|
-
* - TaskRunner 并发生图:提交即排队,成功自动入画廊(元数据 + 图片落盘);
|
|
1003
|
-
* - 提供商预设按 id 即时 resolve credentials(不缓存);
|
|
1004
|
-
* - 端点:generate/tasks/gallery/images/credentials/providers(api.ts 注册)。
|
|
1005
|
-
* 红线:开发测试仅指向本地 mock,严禁真实调用产生费用。
|
|
1006
|
-
* @module image-studio/service
|
|
1007
|
-
*/
|
|
1008
999
|
/** 静态 schema 引用(installSection 用;避免循环 import config → service)。 */
|
|
1009
1000
|
var ImageStudioService = class extends Service {
|
|
1010
|
-
static
|
|
1001
|
+
static inject = ["credentials"];
|
|
1011
1002
|
current;
|
|
1012
1003
|
runner;
|
|
1013
1004
|
log;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plus/image-studio",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "dsh-plus service+ui plugin: 图像工作室——OpenAI Images 协议文生图/图生图,全参数开关化,双预设体系,并发生图任务与可二次编辑画廊",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -19,24 +19,24 @@
|
|
|
19
19
|
"src"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
22
|
+
"https-proxy-agent": "^9.1.0",
|
|
23
|
+
"@dsh-plus/shared": "0.1.13"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
27
|
-
"@deepseek-ai/dsh-client-ui-primitives": "
|
|
28
|
-
"@deepseek-ai/dsh-credentials": "
|
|
29
|
-
"@deepseek-ai/dsh-host-webserver": "
|
|
30
|
-
"@deepseek-ai/dsh-settings": "
|
|
27
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-alpha.2",
|
|
28
|
+
"@deepseek-ai/dsh-credentials": "^0.1.5-alpha.2",
|
|
29
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.5-alpha.2",
|
|
30
|
+
"@deepseek-ai/dsh-settings": "^0.1.5-alpha.2",
|
|
31
31
|
"@deepseek-ai/schemastery": "^3.18.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@deepseek-ai/cordis": "4.0.2",
|
|
35
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.5-alpha.
|
|
36
|
-
"@deepseek-ai/dsh-credentials": "0.1.5-alpha.
|
|
37
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.5-alpha.
|
|
38
|
-
"@deepseek-ai/dsh-session": "0.1.5-alpha.
|
|
39
|
-
"@deepseek-ai/dsh-settings": "0.1.5-alpha.
|
|
35
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.5-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-credentials": "0.1.5-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.5-alpha.2",
|
|
38
|
+
"@deepseek-ai/dsh-session": "0.1.5-alpha.2",
|
|
39
|
+
"@deepseek-ai/dsh-settings": "0.1.5-alpha.2",
|
|
40
40
|
"@deepseek-ai/schemastery": "3.18.2",
|
|
41
41
|
"@types/node": "26.4.0",
|
|
42
42
|
"@types/react": "~18.3.31",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* 请求参数回放、衍生链源图、下载/删除/二次编辑)。
|
|
4
4
|
* @module image-studio/client/panel/gallery
|
|
5
5
|
*/
|
|
6
|
+
import { Modal } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
6
7
|
import { IconDownload, IconRefreshOutline16, IconTrashOutline16 } from '@dsh-plus/shared/client'
|
|
7
8
|
import { type ReactElement, useState } from 'react'
|
|
8
9
|
import type { GalleryItem } from '../../gallery/store.ts'
|
|
@@ -52,18 +53,17 @@ function GalleryDetail(props: {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
const paramRows = Object.entries(item.params)
|
|
56
|
+
// 官方 Modal 承载(嵌套 portal:层级高于工作台,遮罩/Escape 由 Modal 处理)。
|
|
55
57
|
return (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
>
|
|
66
|
-
<div className="ims-detailHead">
|
|
58
|
+
<Modal
|
|
59
|
+
open
|
|
60
|
+
onClose={onClose}
|
|
61
|
+
title={item.prompt.slice(0, 40)}
|
|
62
|
+
headless
|
|
63
|
+
className="ims-detailModal"
|
|
64
|
+
>
|
|
65
|
+
<div className="ims-sub">
|
|
66
|
+
<div className="ims-subHead">
|
|
67
67
|
<span className="ims-detailMeta">
|
|
68
68
|
{t('gallery.detail.model')}:{item.model} · {t('gallery.detail.endpoint')}:
|
|
69
69
|
{item.endpoint} · {t('gallery.detail.time')}:{fmtTime(item.createdAt)}
|
|
@@ -127,7 +127,7 @@ function GalleryDetail(props: {
|
|
|
127
127
|
)}
|
|
128
128
|
</div>
|
|
129
129
|
</div>
|
|
130
|
-
<div className="ims-
|
|
130
|
+
<div className="ims-subFoot">
|
|
131
131
|
{error !== null ? (
|
|
132
132
|
<p className="ims-status ims-statusError" role="alert">
|
|
133
133
|
{error}
|
|
@@ -156,7 +156,7 @@ function GalleryDetail(props: {
|
|
|
156
156
|
)}
|
|
157
157
|
</div>
|
|
158
158
|
</div>
|
|
159
|
-
</
|
|
159
|
+
</Modal>
|
|
160
160
|
)
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* 响应式:桌面居中模态(≤1100px),≤767px 全屏抽屉(见 styles.ts)。
|
|
8
8
|
* @module image-studio/client/panel/panel
|
|
9
9
|
*/
|
|
10
|
+
import { Modal } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
10
11
|
import type { NamespaceSettingsApi, Scope } from '@dsh-plus/shared/client'
|
|
11
12
|
import { IconBrush, IconCloseOutline16, IconImage, IconSparkles } from '@dsh-plus/shared/client'
|
|
12
13
|
import {
|
|
@@ -103,8 +104,6 @@ export function StudioPanel(props: StudioPanelProps): ReactElement | null {
|
|
|
103
104
|
return () => clearInterval(timer)
|
|
104
105
|
}, [open, providers, reloadPresets, reloadGallery, reloadTasks])
|
|
105
106
|
|
|
106
|
-
if (!open) return null
|
|
107
|
-
|
|
108
107
|
// wire 的 params 与 ParamEntry 结构同源(kind 宽化为 string),边界处一次性窄化。
|
|
109
108
|
const catalog = (providers?.params ?? []) as unknown as readonly ParamEntry[]
|
|
110
109
|
const protocols = providers?.protocols ?? []
|
|
@@ -115,17 +114,17 @@ export function StudioPanel(props: StudioPanelProps): ReactElement | null {
|
|
|
115
114
|
{ key: 'gallery', label: t('tab.gallery'), icon: <IconImage size={15} /> },
|
|
116
115
|
]
|
|
117
116
|
|
|
117
|
+
// 官方 Modal 承载:portal 到 body(z-index 1000,移动端层叠/开关与外壳一致),
|
|
118
|
+
// 遮罩点击与 Escape 关闭由 Modal 处理;headless 模式自绘头部标签条。
|
|
118
119
|
return (
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
onClick={(event) => event.stopPropagation()}
|
|
128
|
-
>
|
|
120
|
+
<Modal
|
|
121
|
+
open={open}
|
|
122
|
+
onClose={() => studio.setOpen(false)}
|
|
123
|
+
title={t('panel.title')}
|
|
124
|
+
headless
|
|
125
|
+
className="ims-modal"
|
|
126
|
+
>
|
|
127
|
+
<div className="ims-panel">
|
|
129
128
|
<header className="ims-head">
|
|
130
129
|
<div className="ims-tabs" role="tablist" aria-label={t('panel.title')}>
|
|
131
130
|
{tabs.map((item) => (
|
|
@@ -215,6 +214,6 @@ export function StudioPanel(props: StudioPanelProps): ReactElement | null {
|
|
|
215
214
|
}}
|
|
216
215
|
/>
|
|
217
216
|
</div>
|
|
218
|
-
</
|
|
217
|
+
</Modal>
|
|
219
218
|
)
|
|
220
219
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* 扁平化全部画廊条目的图片,倒序排列;底部确认条显示已选数量。
|
|
4
4
|
* @module image-studio/client/panel/picker
|
|
5
5
|
*/
|
|
6
|
+
import { Modal } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
6
7
|
import { type ReactElement, useState } from 'react'
|
|
7
8
|
import type { GalleryItem } from '../../gallery/store.ts'
|
|
8
9
|
import { imageUrl } from '../api.ts'
|
|
@@ -56,19 +57,12 @@ export function ImagePicker(props: ImagePickerProps): ReactElement {
|
|
|
56
57
|
setSelected((current) => (current.includes(imageId) ? [] : [imageId]))
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
// 官方 Modal 承载(嵌套 portal:层级高于工作台,遮罩/Escape 由 Modal 处理)。
|
|
59
61
|
return (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
className="ims-picker"
|
|
65
|
-
role="dialog"
|
|
66
|
-
aria-modal="true"
|
|
67
|
-
aria-label={title}
|
|
68
|
-
onClick={(event) => event.stopPropagation()}
|
|
69
|
-
>
|
|
70
|
-
<div className="ims-pickerHead">
|
|
71
|
-
<h3 className="ims-pickerTitle">{title}</h3>
|
|
62
|
+
<Modal open onClose={onClose} title={title} headless className="ims-pickerModal">
|
|
63
|
+
<div className="ims-sub">
|
|
64
|
+
<div className="ims-subHead">
|
|
65
|
+
<h3 className="ims-subTitle">{title}</h3>
|
|
72
66
|
<button type="button" className="ims-btn ims-btnGhost" onClick={onClose}>
|
|
73
67
|
{t('common.close')}
|
|
74
68
|
</button>
|
|
@@ -98,7 +92,7 @@ export function ImagePicker(props: ImagePickerProps): ReactElement {
|
|
|
98
92
|
})}
|
|
99
93
|
</div>
|
|
100
94
|
)}
|
|
101
|
-
<div className="ims-
|
|
95
|
+
<div className="ims-subFoot">
|
|
102
96
|
<button
|
|
103
97
|
type="button"
|
|
104
98
|
className="ims-btn ims-btnPrimary"
|
|
@@ -112,6 +106,6 @@ export function ImagePicker(props: ImagePickerProps): ReactElement {
|
|
|
112
106
|
</button>
|
|
113
107
|
</div>
|
|
114
108
|
</div>
|
|
115
|
-
</
|
|
109
|
+
</Modal>
|
|
116
110
|
)
|
|
117
111
|
}
|