@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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
- import { Context, Service } from "@deepseek-ai/cordis";
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 [Context.inject] = ["credentials"];
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.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
- "@dsh-plus/shared": "0.1.12",
23
- "https-proxy-agent": "^9.1.0"
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.1",
36
- "@deepseek-ai/dsh-credentials": "0.1.5-alpha.1",
37
- "@deepseek-ai/dsh-host-webserver": "0.1.5-alpha.1",
38
- "@deepseek-ai/dsh-session": "0.1.5-alpha.1",
39
- "@deepseek-ai/dsh-settings": "0.1.5-alpha.1",
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
- // biome-ignore lint/a11y/noStaticElementInteractions: 背板点击关闭是指针便利交互,键盘用户走关闭/取消按钮(同 web-terminal 既有约定)
57
- <div className="ims-detailBackdrop" role="presentation" onClick={onClose}>
58
- {/* biome-ignore lint/a11y/useKeyWithClickEvents: 阻断冒泡仅防误触背板关闭,无实际点击行为 */}
59
- <div
60
- className="ims-detail"
61
- role="dialog"
62
- aria-modal="true"
63
- aria-label={item.prompt.slice(0, 40)}
64
- onClick={(event) => event.stopPropagation()}
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-detailFoot">
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
- </div>
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
- // biome-ignore lint/a11y/noStaticElementInteractions: 背板点击关闭是指针便利交互,键盘用户走关闭/取消按钮(同 web-terminal 既有约定)
120
- <div className="ims-backdrop" role="presentation" onClick={() => studio.setOpen(false)}>
121
- {/* biome-ignore lint/a11y/useKeyWithClickEvents: 阻断冒泡仅防误触背板关闭,无实际点击行为 */}
122
- <div
123
- className="ims-panel"
124
- role="dialog"
125
- aria-modal="true"
126
- aria-label={t('panel.title')}
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
- </div>
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
- // biome-ignore lint/a11y/noStaticElementInteractions: 背板点击关闭是指针便利交互,键盘用户走关闭/取消按钮(同 web-terminal 既有约定)
61
- <div className="ims-pickerBackdrop" role="presentation" onClick={onClose}>
62
- {/* biome-ignore lint/a11y/useKeyWithClickEvents: 阻断冒泡仅防误触背板关闭,无实际点击行为 */}
63
- <div
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-pickerFoot">
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
- </div>
109
+ </Modal>
116
110
  )
117
111
  }