@lokvis/ui-react 0.2.1 → 0.2.2
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/dist/components/AssetPanel.d.ts.map +1 -1
- package/dist/components/AssetPanel.js +14 -14
- package/dist/components/AssetPanel.js.map +1 -1
- package/dist/components/Canvas.d.ts +4 -4
- package/dist/components/Canvas.d.ts.map +1 -1
- package/dist/components/Canvas.js +8 -8
- package/dist/components/Canvas.js.map +1 -1
- package/dist/components/CommandPalette.d.ts +7 -7
- package/dist/components/CommandPalette.d.ts.map +1 -1
- package/dist/components/CommandPalette.js +10 -10
- package/dist/components/CommandPalette.js.map +1 -1
- package/dist/components/CompareSlider.d.ts +6 -6
- package/dist/components/CompareSlider.d.ts.map +1 -1
- package/dist/components/CompareSlider.js +7 -7
- package/dist/components/CompareSlider.js.map +1 -1
- package/dist/components/DownloadPanel.d.ts +3 -3
- package/dist/components/DownloadPanel.d.ts.map +1 -1
- package/dist/components/DownloadPanel.js +9 -9
- package/dist/components/DownloadPanel.js.map +1 -1
- package/dist/components/ErrorBanner.d.ts +2 -2
- package/dist/components/ErrorBanner.d.ts.map +1 -1
- package/dist/components/ErrorBanner.js +3 -3
- package/dist/components/ErrorBanner.js.map +1 -1
- package/dist/components/ExifPanel.d.ts +1 -1
- package/dist/components/ExifPanel.d.ts.map +1 -1
- package/dist/components/ExifPanel.js +2 -2
- package/dist/components/ExifPanel.js.map +1 -1
- package/dist/components/GlobalDropzone.d.ts +5 -5
- package/dist/components/GlobalDropzone.d.ts.map +1 -1
- package/dist/components/GlobalDropzone.js +6 -6
- package/dist/components/GlobalDropzone.js.map +1 -1
- package/dist/components/HistoryPanel.d.ts +2 -2
- package/dist/components/HistoryPanel.d.ts.map +1 -1
- package/dist/components/HistoryPanel.js +23 -23
- package/dist/components/HistoryPanel.js.map +1 -1
- package/dist/components/Inspector.d.ts.map +1 -1
- package/dist/components/Inspector.js +6 -6
- package/dist/components/Inspector.js.map +1 -1
- package/dist/components/ParamForm.d.ts.map +1 -1
- package/dist/components/ParamForm.js +7 -7
- package/dist/components/ParamForm.js.map +1 -1
- package/dist/components/PipelineBar.d.ts.map +1 -1
- package/dist/components/PipelineBar.js +13 -13
- package/dist/components/PipelineBar.js.map +1 -1
- package/dist/components/ProgressBar.d.ts +4 -4
- package/dist/components/ProgressBar.d.ts.map +1 -1
- package/dist/components/ProgressBar.js +8 -8
- package/dist/components/ProgressBar.js.map +1 -1
- package/dist/components/StatusBar.d.ts +3 -3
- package/dist/components/StatusBar.d.ts.map +1 -1
- package/dist/components/StatusBar.js +11 -11
- package/dist/components/StatusBar.js.map +1 -1
- package/dist/components/ThemeToggle.d.ts +4 -4
- package/dist/components/ThemeToggle.d.ts.map +1 -1
- package/dist/components/ThemeToggle.js +7 -7
- package/dist/components/ThemeToggle.js.map +1 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +2 -2
- package/dist/components/Toolbar.js.map +1 -1
- package/dist/components/WorkflowEditor.d.ts +6 -6
- package/dist/components/WorkflowEditor.d.ts.map +1 -1
- package/dist/components/WorkflowEditor.js +25 -25
- package/dist/components/WorkflowEditor.js.map +1 -1
- package/dist/components/WorkflowTemplates.d.ts +2 -2
- package/dist/components/WorkflowTemplates.d.ts.map +1 -1
- package/dist/components/WorkflowTemplates.js +3 -3
- package/dist/components/WorkflowTemplates.js.map +1 -1
- package/dist/components/Workspace.d.ts +22 -22
- package/dist/components/Workspace.d.ts.map +1 -1
- package/dist/components/Workspace.js +30 -30
- package/dist/components/Workspace.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/components/AssetPanel.tsx +263 -263
- package/src/components/Canvas.tsx +174 -174
- package/src/components/CommandPalette.tsx +242 -242
- package/src/components/CompareSlider.tsx +163 -163
- package/src/components/DownloadPanel.tsx +203 -203
- package/src/components/ErrorBanner.tsx +64 -64
- package/src/components/ExifPanel.tsx +154 -154
- package/src/components/GlobalDropzone.tsx +170 -170
- package/src/components/HistoryPanel.tsx +219 -219
- package/src/components/Inspector.tsx +136 -136
- package/src/components/ParamForm.tsx +136 -136
- package/src/components/PipelineBar.tsx +98 -98
- package/src/components/ProgressBar.tsx +78 -78
- package/src/components/StatusBar.tsx +148 -148
- package/src/components/ThemeToggle.tsx +98 -98
- package/src/components/Toolbar.tsx +65 -65
- package/src/components/WorkflowEditor.tsx +321 -321
- package/src/components/WorkflowTemplates.tsx +77 -77
- package/src/components/Workspace.tsx +223 -223
- package/src/css-modules.d.ts +3 -0
- package/src/index.ts +4 -0
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* - cursor 当前位置高亮,cursor 之后的条目标灰(redo 分支)
|
|
8
8
|
*
|
|
9
9
|
* W9.1: 支持 `variant` 切换布局方向
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* - `vertical`(默认):侧栏垂直布局,适合嵌入左/右栏
|
|
11
|
+
* - `horizontal`:底部横条布局,作为底部 history bar 使用
|
|
12
12
|
*
|
|
13
13
|
* 数据来自 history-slice(store 单一来源),由 runtime-slice 的
|
|
14
14
|
* history:changed 订阅自动更新,组件无需自行订阅事件。
|
|
@@ -21,234 +21,234 @@ import { Icon } from '@lokvis/ui-core';
|
|
|
21
21
|
import { useWorkspaceStore } from '../store/index.js';
|
|
22
22
|
|
|
23
23
|
export interface HistoryPanelProps {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
className?: string;
|
|
25
|
+
/** 布局方向(W9.1):vertical 侧栏,horizontal 底部横条 */
|
|
26
|
+
variant?: 'vertical' | 'horizontal';
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export function HistoryPanel({ className = '', variant = 'vertical' }: HistoryPanelProps) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
const entries = useWorkspaceStore((s) => s.historyEntries);
|
|
31
|
+
const cursor = useWorkspaceStore((s) => s.historyCursor);
|
|
32
|
+
const workflowId = useWorkspaceStore((s) => s.historyWorkflowId);
|
|
33
|
+
const undo = useWorkspaceStore((s) => s.undo);
|
|
34
|
+
const redo = useWorkspaceStore((s) => s.redo);
|
|
35
|
+
const jumpTo = useWorkspaceStore((s) => s.jumpToHistory);
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
const canUndo = cursor >= 0;
|
|
38
|
+
const canRedo = cursor < entries.length - 1;
|
|
39
|
+
const horizontal = variant === 'horizontal';
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
41
|
+
const undoBtn = (
|
|
42
|
+
<button
|
|
43
|
+
type="button"
|
|
44
|
+
onClick={() => void undo()}
|
|
45
|
+
disabled={!canUndo}
|
|
46
|
+
aria-label="Undo"
|
|
47
|
+
className="rounded p-1 text-[var(--lokvis-fg-muted)] transition-colors hover:bg-[var(--lokvis-surface-muted)] hover:text-[var(--lokvis-fg-muted)] disabled:cursor-not-allowed disabled:opacity-30"
|
|
48
|
+
>
|
|
49
|
+
<Icon size={13}>
|
|
50
|
+
<path d="M9 14L4 9l5-5" />
|
|
51
|
+
<path d="M4 9h11a4 4 0 0 1 0 8h-3" />
|
|
52
|
+
</Icon>
|
|
53
|
+
</button>
|
|
54
|
+
);
|
|
55
|
+
const redoBtn = (
|
|
56
|
+
<button
|
|
57
|
+
type="button"
|
|
58
|
+
onClick={() => void redo()}
|
|
59
|
+
disabled={!canRedo}
|
|
60
|
+
aria-label="Redo"
|
|
61
|
+
className="rounded p-1 text-[var(--lokvis-fg-muted)] transition-colors hover:bg-[var(--lokvis-surface-muted)] hover:text-[var(--lokvis-fg-muted)] disabled:cursor-not-allowed disabled:opacity-30"
|
|
62
|
+
>
|
|
63
|
+
<Icon size={13}>
|
|
64
|
+
<path d="M15 14l5-5-5-5" />
|
|
65
|
+
<path d="M20 9H9a4 4 0 0 0 0 8h3" />
|
|
66
|
+
</Icon>
|
|
67
|
+
</button>
|
|
68
|
+
);
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
const headerEl = (
|
|
71
|
+
<div
|
|
72
|
+
className={`flex shrink-0 items-center justify-between px-3 ${
|
|
73
|
+
horizontal ? 'h-full border-r border-[var(--lokvis-border)]' : 'h-10 border-b border-[var(--lokvis-border)]'
|
|
74
|
+
}`}
|
|
75
|
+
>
|
|
76
|
+
<span className="text-[11px] font-semibold uppercase tracking-wider text-[var(--lokvis-fg-subtle)]">
|
|
77
|
+
History
|
|
78
|
+
</span>
|
|
79
|
+
<div className="flex items-center gap-0.5">
|
|
80
|
+
{undoBtn}
|
|
81
|
+
{redoBtn}
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
86
|
+
// 空状态
|
|
87
|
+
if (!workflowId || entries.length === 0) {
|
|
88
|
+
return (
|
|
89
|
+
<aside
|
|
90
|
+
className={`flex shrink-0 ${
|
|
91
|
+
horizontal
|
|
92
|
+
? 'h-12 flex-row items-center border-t border-[var(--lokvis-border)]'
|
|
93
|
+
: 'w-48 flex-col border-r border-[var(--lokvis-border)]'
|
|
94
|
+
} ${className}`}
|
|
95
|
+
aria-label="History panel"
|
|
96
|
+
>
|
|
97
|
+
{headerEl}
|
|
98
|
+
<p className="px-3 text-[10px] text-[var(--lokvis-fg-subtle)]">No history yet</p>
|
|
99
|
+
</aside>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
103
|
+
if (horizontal) {
|
|
104
|
+
// 横向布局:header | entries(横向滚动)
|
|
105
|
+
return (
|
|
106
|
+
<aside
|
|
107
|
+
className={`flex h-12 shrink-0 items-stretch border-t border-[var(--lokvis-border)] ${className}`}
|
|
108
|
+
aria-label="History panel"
|
|
109
|
+
>
|
|
110
|
+
{headerEl}
|
|
111
|
+
<ol className="flex flex-1 items-center gap-1 overflow-x-auto px-2">
|
|
112
|
+
{/* 初始状态项 */}
|
|
113
|
+
<li className="shrink-0">
|
|
114
|
+
<button
|
|
115
|
+
type="button"
|
|
116
|
+
onClick={() => void jumpTo(-1)}
|
|
117
|
+
className={`flex items-center gap-1.5 rounded px-2 py-1 text-[10px] transition-colors ${
|
|
118
|
+
cursor === -1
|
|
119
|
+
? 'bg-[var(--lokvis-primary)]/10 text-[var(--lokvis-primary)] ring-1 ring-[var(--lokvis-primary)]/40'
|
|
120
|
+
: 'text-[var(--lokvis-fg-muted)] hover:bg-[var(--lokvis-surface)]'
|
|
121
|
+
}`}
|
|
122
|
+
>
|
|
123
|
+
<span className="h-1.5 w-1.5 shrink-0 rounded-full bg-[var(--lokvis-fg-subtle)]" aria-hidden="true" />
|
|
124
|
+
<span className="truncate">Initial</span>
|
|
125
|
+
</button>
|
|
126
|
+
</li>
|
|
127
|
+
{entries.map((entry, i) => {
|
|
128
|
+
const isCurrent = i === cursor;
|
|
129
|
+
const isRedoBranch = i > cursor;
|
|
130
|
+
return (
|
|
131
|
+
<li key={entry.id} className="shrink-0">
|
|
132
|
+
<button
|
|
133
|
+
type="button"
|
|
134
|
+
onClick={() => void jumpTo(i)}
|
|
135
|
+
aria-current={isCurrent ? 'step' : undefined}
|
|
136
|
+
className={`flex items-center gap-1.5 rounded px-2 py-1 text-[10px] transition-colors ${
|
|
137
|
+
isCurrent
|
|
138
|
+
? 'bg-[var(--lokvis-primary)]/10 text-[var(--lokvis-primary)] ring-1 ring-[var(--lokvis-primary)]/40'
|
|
139
|
+
: isRedoBranch
|
|
140
|
+
? 'text-[var(--lokvis-fg-subtle)] hover:bg-[var(--lokvis-surface)]'
|
|
141
|
+
: 'text-[var(--lokvis-fg-muted)] hover:bg-[var(--lokvis-surface)]'
|
|
142
|
+
}`}
|
|
143
|
+
>
|
|
144
|
+
<span
|
|
145
|
+
className={`h-1.5 w-1.5 shrink-0 rounded-full ${
|
|
146
|
+
isCurrent
|
|
147
|
+
? 'bg-[var(--lokvis-primary)]'
|
|
148
|
+
: isRedoBranch
|
|
149
|
+
? 'bg-[var(--lokvis-border)]'
|
|
150
|
+
: 'bg-[var(--lokvis-fg-subtle)]'
|
|
151
|
+
}`}
|
|
152
|
+
aria-hidden="true"
|
|
153
|
+
/>
|
|
154
|
+
<span className="truncate font-medium">{describeHistoryEntry(entry)}</span>
|
|
155
|
+
</button>
|
|
156
|
+
</li>
|
|
157
|
+
);
|
|
158
|
+
})}
|
|
159
|
+
</ol>
|
|
160
|
+
</aside>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
163
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
164
|
+
// 垂直布局(原实现)
|
|
165
|
+
return (
|
|
166
|
+
<aside
|
|
167
|
+
className={`flex w-48 shrink-0 flex-col border-r border-[var(--lokvis-border)] ${className}`}
|
|
168
|
+
aria-label="History panel"
|
|
169
|
+
>
|
|
170
|
+
{headerEl}
|
|
171
|
+
<div className="flex-1 overflow-y-auto px-2 py-2">
|
|
172
|
+
<ol className="space-y-0.5">
|
|
173
|
+
{/* 初始状态项(index=-1) */}
|
|
174
|
+
<li>
|
|
175
|
+
<button
|
|
176
|
+
type="button"
|
|
177
|
+
onClick={() => void jumpTo(-1)}
|
|
178
|
+
className={`flex w-full items-center gap-1.5 rounded px-2 py-1 text-left text-[10px] transition-colors ${
|
|
179
|
+
cursor === -1
|
|
180
|
+
? 'bg-[var(--lokvis-primary)]/10 text-[var(--lokvis-primary)] ring-1 ring-[var(--lokvis-primary)]/40'
|
|
181
|
+
: 'text-[var(--lokvis-fg-muted)] hover:bg-[var(--lokvis-surface)]'
|
|
182
|
+
}`}
|
|
183
|
+
>
|
|
184
|
+
<span className="h-1.5 w-1.5 shrink-0 rounded-full bg-[var(--lokvis-fg-subtle)]" aria-hidden="true" />
|
|
185
|
+
<span className="truncate">Initial</span>
|
|
186
|
+
</button>
|
|
187
|
+
</li>
|
|
188
|
+
{entries.map((entry, i) => {
|
|
189
|
+
const isCurrent = i === cursor;
|
|
190
|
+
const isRedoBranch = i > cursor;
|
|
191
|
+
return (
|
|
192
|
+
<li key={entry.id}>
|
|
193
|
+
<button
|
|
194
|
+
type="button"
|
|
195
|
+
onClick={() => void jumpTo(i)}
|
|
196
|
+
aria-current={isCurrent ? 'step' : undefined}
|
|
197
|
+
className={`flex w-full items-start gap-1.5 rounded px-2 py-1 text-left text-[10px] transition-colors ${
|
|
198
|
+
isCurrent
|
|
199
|
+
? 'bg-[var(--lokvis-primary)]/10 text-[var(--lokvis-primary)] ring-1 ring-[var(--lokvis-primary)]/40'
|
|
200
|
+
: isRedoBranch
|
|
201
|
+
? 'text-[var(--lokvis-fg-subtle)] hover:bg-[var(--lokvis-surface)]'
|
|
202
|
+
: 'text-[var(--lokvis-fg-muted)] hover:bg-[var(--lokvis-surface)]'
|
|
203
|
+
}`}
|
|
204
|
+
>
|
|
205
|
+
<span
|
|
206
|
+
className={`mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full ${
|
|
207
|
+
isCurrent
|
|
208
|
+
? 'bg-[var(--lokvis-primary)]'
|
|
209
|
+
: isRedoBranch
|
|
210
|
+
? 'bg-[var(--lokvis-border)]'
|
|
211
|
+
: 'bg-[var(--lokvis-fg-subtle)]'
|
|
212
|
+
}`}
|
|
213
|
+
aria-hidden="true"
|
|
214
|
+
/>
|
|
215
|
+
<div className="min-w-0 flex-1">
|
|
216
|
+
<div className="truncate font-medium">
|
|
217
|
+
{describeHistoryEntry(entry)}
|
|
218
|
+
</div>
|
|
219
|
+
<div className="text-[9px] text-[var(--lokvis-fg-subtle)]">
|
|
220
|
+
{new Date(entry.timestamp).toLocaleTimeString()}
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
</button>
|
|
224
|
+
</li>
|
|
225
|
+
);
|
|
226
|
+
})}
|
|
227
|
+
</ol>
|
|
228
|
+
</div>
|
|
229
|
+
</aside>
|
|
230
|
+
);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
/** 把 HistoryEntry 摘要为可读标签(capability 简称 + 关键参数) */
|
|
234
234
|
function describeHistoryEntry(entry: HistoryEntry): string {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
235
|
+
// image.resize → Resize;image.watermark → Watermark
|
|
236
|
+
const short = entry.capability.replace(/^image\./, '');
|
|
237
|
+
const cap = short.charAt(0).toUpperCase() + short.slice(1);
|
|
238
|
+
const params = entry.params ?? {};
|
|
239
|
+
// 摘取 1-2 个关键参数作为提示
|
|
240
|
+
const hints: string[] = [];
|
|
241
|
+
if (typeof params.width === 'number' || typeof params.width === 'string') {
|
|
242
|
+
hints.push(`${params.width}w`);
|
|
243
|
+
}
|
|
244
|
+
if (typeof params.quality === 'number') {
|
|
245
|
+
hints.push(`q${params.quality}`);
|
|
246
|
+
}
|
|
247
|
+
if (typeof params.format === 'string') {
|
|
248
|
+
hints.push(String(params.format));
|
|
249
|
+
}
|
|
250
|
+
if (typeof params.text === 'string' && params.text) {
|
|
251
|
+
hints.push(`"${String(params.text).slice(0, 8)}"`);
|
|
252
|
+
}
|
|
253
|
+
return hints.length > 0 ? `${cap} (${hints.join(' ')})` : cap;
|
|
254
254
|
}
|