dsh-plugin 2.3.0 → 2.3.1
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/client/client.js +367 -325
- package/client/client.js.map +1 -1
- package/package.json +1 -1
- package/src/client/components/catalog/PluginCard.tsx +26 -6
- package/src/client/components/views/InstalledView.tsx +62 -24
- package/src/client/locales.ts +6 -0
- package/src/client/styles/InstalledView.module.css +72 -19
- package/src/client/styles/List.module.css +33 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "A community plugin marketplace for DeepSeek Harness, built to the official plugin spec — browse, search and install 10000+ human-curated community plugins without leaving the app. · DeepSeek Harness 社区插件市场(遵循官方开发规范):10000+ 人工精选社区插件,每日更新。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -39,11 +39,25 @@ export function PluginCard({ plugin: p, copied, installedName, installedVersion,
|
|
|
39
39
|
const pendingUntil = isInstalled && !update ? updatePendingUntil(p) : null
|
|
40
40
|
// 版本号展示:已安装 → 当前已装版本(最能反映用户状态);未安装 → 目录最新版本
|
|
41
41
|
const versionShown = isInstalled ? installedVersion(p) : p.version
|
|
42
|
+
// 目录只下发作者 GitHub 账号,缺省时从仓库地址推导
|
|
43
|
+
const author = p.ownerSlug ?? repo.split('/')[0]?.toLowerCase() ?? ''
|
|
42
44
|
|
|
43
45
|
return h('div', { className: styles.card },
|
|
44
46
|
h('div', { className: styles.cardMain },
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
// 第一行只放名称 + 版本 + 更新状态:这三样是判断「这是什么、我装没装、要不要更新」的全部依据,
|
|
48
|
+
// 必须始终可见;长仓库名在此行内省略号收尾,不把版本与更新徽标挤出去
|
|
49
|
+
h('div', { className: styles.cardTitleRow },
|
|
50
|
+
// 名称本身是通往主站详情页的链接:悬停变色即可点,省掉「先找按钮再点」的一步。
|
|
51
|
+
// 无仓库地址时退回纯文本(没有可跳转的目标)
|
|
52
|
+
repo
|
|
53
|
+
? h('a', {
|
|
54
|
+
className: styles.cardTitle,
|
|
55
|
+
href: pluginDetailUrl(p, langPath),
|
|
56
|
+
target: '_blank',
|
|
57
|
+
rel: 'noopener noreferrer',
|
|
58
|
+
title: p.description ?? '',
|
|
59
|
+
}, p.displayName ?? p.slug)
|
|
60
|
+
: h('div', { className: styles.cardTitle, title: p.description ?? '' }, p.displayName ?? p.slug),
|
|
47
61
|
// 版本号紧跟插件名称:有版本才显示(无 release 的仓库不展示版本号)
|
|
48
62
|
versionShown ? h('span', { className: styles.versionBadge, title: t('version') }, versionShown) : null,
|
|
49
63
|
// 已安装且有更新:醒目提示(有 release 比版本号、无 release 比仓库最近更新时间)
|
|
@@ -51,11 +65,17 @@ export function PluginCard({ plugin: p, copied, installedName, installedVersion,
|
|
|
51
65
|
pendingUntil !== null
|
|
52
66
|
? h('span', { className: styles.updateBadge, title: t('updatePendingHint') }, t('updatePending', { time: clockTime(pendingUntil) }))
|
|
53
67
|
: null,
|
|
54
|
-
p.category ? h('span', { className: styles.categoryBadge }, categoryLabel(CATEGORY_LABELS, p.category, langKey)) : null,
|
|
55
|
-
p.compatibility?.status === 'verified'
|
|
56
|
-
? h('span', { className: styles.verified }, t('verified'))
|
|
57
|
-
: null,
|
|
58
68
|
),
|
|
69
|
+
// 作者与分类同属背景信息:单独一行,不与名称抢宽度,也不参与是否要装/更新的判断
|
|
70
|
+
(author || p.category || p.compatibility?.status === 'verified')
|
|
71
|
+
? h('div', { className: styles.cardBadgeRow },
|
|
72
|
+
author ? h('span', { className: styles.authorBadge, title: t('author') }, `@${author}`) : null,
|
|
73
|
+
p.category ? h('span', { className: styles.categoryBadge }, categoryLabel(CATEGORY_LABELS, p.category, langKey)) : null,
|
|
74
|
+
p.compatibility?.status === 'verified'
|
|
75
|
+
? h('span', { className: styles.verified }, t('verified'))
|
|
76
|
+
: null,
|
|
77
|
+
)
|
|
78
|
+
: null,
|
|
59
79
|
// 描述始终显示:站点英文数据缺翻译时 description 回退成中文也照常展示 ——
|
|
60
80
|
// 描述是了解插件的第一入口,语言不一致也不该省略。
|
|
61
81
|
p.description ? h('p', { className: styles.desc }, p.description) : null,
|
|
@@ -17,7 +17,8 @@ import styles from '../../styles/InstalledView.module.css'
|
|
|
17
17
|
import type { LocaleId, Translate } from '../../types.ts'
|
|
18
18
|
import type { InstalledItem } from '../../logic/installed.ts'
|
|
19
19
|
import { CATEGORY_LABELS, categoryLabel } from '../../logic/constants.ts'
|
|
20
|
-
import { clockTime } from '../../logic/format.ts'
|
|
20
|
+
import { clockTime, fmtStars } from '../../logic/format.ts'
|
|
21
|
+
import { pluginSiteUrl } from '../../logic/urls.ts'
|
|
21
22
|
import { SortArrowIcon } from '../ui/icons.tsx'
|
|
22
23
|
|
|
23
24
|
const INSTALLED_SORTS = ['sortName', 'sortInstalledAt', 'sortStars', 'sortForks'] as const
|
|
@@ -101,9 +102,20 @@ function InstalledRow({ item, t, langKey, canReveal, revealLabel, pendingRestart
|
|
|
101
102
|
: item.dshCapable ? t('statusInactive')
|
|
102
103
|
: t('exampleHint'),
|
|
103
104
|
}),
|
|
104
|
-
// 主信息:名称 + 已装版本 +
|
|
105
|
+
// 主信息:名称 + 已装版本 + 有更新徽标(同一行,名称超长时省略,徽标不被挤走)。
|
|
106
|
+
// 名称本身是主站详情页链接:点它直接跳官网,点行内其它位置仍是本地面板。
|
|
107
|
+
// 阻止冒泡,避免一次点击同时打开本地详情弹窗和新标签页
|
|
105
108
|
h('div', { className: styles.rowMain },
|
|
106
|
-
|
|
109
|
+
repo
|
|
110
|
+
? h('a', {
|
|
111
|
+
className: styles.rowTitle,
|
|
112
|
+
href: pluginSiteUrl(repo),
|
|
113
|
+
target: '_blank',
|
|
114
|
+
rel: 'noopener noreferrer',
|
|
115
|
+
title: t('detail'),
|
|
116
|
+
onClick: (e: MouseEvent<HTMLAnchorElement>) => e.stopPropagation(),
|
|
117
|
+
}, name)
|
|
118
|
+
: h('span', { className: styles.rowTitle }, name),
|
|
107
119
|
item.installedVersion
|
|
108
120
|
? h('span', { className: styles.versionBadge, title: t('installedVersionLabel') }, item.installedVersion)
|
|
109
121
|
: null,
|
|
@@ -114,15 +126,51 @@ function InstalledRow({ item, t, langKey, canReveal, revealLabel, pendingRestart
|
|
|
114
126
|
? h('span', { className: styles.updateBadge, title: t('updatePendingHint') }, t('updatePending', { time: clockTime(item.pendingUntil) }))
|
|
115
127
|
: null,
|
|
116
128
|
),
|
|
117
|
-
//
|
|
118
|
-
//
|
|
129
|
+
// 右上角 Star / Fork:与插件市场列表同一口径,装之前看过的热度在已安装里也能对照。
|
|
130
|
+
// 自定义安装没有目录元数据(plugin === null),没有可展示的统计
|
|
131
|
+
item.plugin
|
|
132
|
+
? h('div', { className: styles.rowStats },
|
|
133
|
+
h('span', { className: styles.rowStar }, '\u2605 ', fmtStars(item.plugin.stats?.stargazers_count)),
|
|
134
|
+
h('span', { className: styles.rowFork }, t('fork'), ' ', fmtStars(item.plugin.stats?.forks_count)),
|
|
135
|
+
)
|
|
136
|
+
: null,
|
|
137
|
+
),
|
|
138
|
+
// 示例项目徽标单独一行(非 dsh 插件):标签较长也能完整显示,不挤压名称行
|
|
139
|
+
!item.dshCapable
|
|
140
|
+
? h('div', { className: styles.exampleRow },
|
|
141
|
+
h('span', { className: styles.exampleBadge, title: t('exampleHint') }, t('exampleLabel')),
|
|
142
|
+
)
|
|
143
|
+
: null,
|
|
144
|
+
// 第二行:仓库 · 分类 · 来源(与名称左对齐缩进,独立成行不再挤压名称)。
|
|
145
|
+
// 来源标签恒定存在,故此行恒渲染:仓库与分类缺失时仍要能看到它是从哪装进来的
|
|
146
|
+
h('div', { className: styles.rowMeta },
|
|
147
|
+
// 仓库名同样指向主站详情页;与名称一样阻止冒泡,不连带打开本地详情弹窗
|
|
148
|
+
item.repo
|
|
149
|
+
? h('a', {
|
|
150
|
+
className: styles.rowRepo,
|
|
151
|
+
href: pluginSiteUrl(item.repo),
|
|
152
|
+
target: '_blank',
|
|
153
|
+
rel: 'noopener noreferrer',
|
|
154
|
+
title: t('detail'),
|
|
155
|
+
onClick: (e: MouseEvent<HTMLAnchorElement>) => e.stopPropagation(),
|
|
156
|
+
}, item.repo)
|
|
157
|
+
: null,
|
|
158
|
+
category ? h('span', { className: styles.rowCategory },
|
|
159
|
+
categoryLabel(CATEGORY_LABELS, category, langKey)) : null,
|
|
160
|
+
// 来源标签:目录插件 →「插件市场」(品牌色),命令行安装 →「手动安装」(琥珀色)
|
|
119
161
|
h('span', {
|
|
120
162
|
className: isCustom
|
|
121
163
|
? `${styles.rowSourceTag} ${styles.rowSourceTagManual}`
|
|
122
164
|
: `${styles.rowSourceTag} ${styles.rowSourceTagHub}`,
|
|
123
165
|
title: isCustom ? t('manualInstallHint') : t('hubInstallHint'),
|
|
124
166
|
}, isCustom ? t('manualInstall') : t('hubInstall')),
|
|
125
|
-
|
|
167
|
+
),
|
|
168
|
+
// 第三行(仅目录插件):简介单独一行展示,超长以省略号收尾
|
|
169
|
+
desc ? h('div', { className: styles.rowDesc, title: desc }, desc) : null,
|
|
170
|
+
// 最后一行:操作按钮单独成行、靠右,名称与版本号那条线不再被按钮挤窄
|
|
171
|
+
h('div', { className: styles.rowActionLine },
|
|
172
|
+
// 行操作:重启(dsh 插件待重启时)/ 在 Finder 中显示 / 安装详情 / 更新(有更新时)/ 卸载
|
|
173
|
+
// —— 按钮点击不触发行打开详情
|
|
126
174
|
h('div', { className: styles.rowActions },
|
|
127
175
|
// 装完未挂载、且在待重启列表里的 dsh 插件:给「重启」入口,点了宿主重启后插件即生效;
|
|
128
176
|
// 已重启但仍加载失败(不在待重启列表)不显示「重启」,改为灰点「未激活」
|
|
@@ -134,8 +182,7 @@ function InstalledRow({ item, t, langKey, canReveal, revealLabel, pendingRestart
|
|
|
134
182
|
onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onRestart() },
|
|
135
183
|
}, t('restart'))
|
|
136
184
|
: null,
|
|
137
|
-
// 支持文件管理器定位的平台(macOS / Linux
|
|
138
|
-
// 行点击本身即打开详情弹窗,故不支持的平台(如 Windows)不显示此按钮
|
|
185
|
+
// 支持文件管理器定位的平台(macOS / Linux)才显示打开安装目录按钮
|
|
139
186
|
canReveal
|
|
140
187
|
? h('button', {
|
|
141
188
|
className: styles.rowDetail,
|
|
@@ -143,6 +190,13 @@ function InstalledRow({ item, t, langKey, canReveal, revealLabel, pendingRestart
|
|
|
143
190
|
onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onReveal(item) },
|
|
144
191
|
}, revealLabel)
|
|
145
192
|
: null,
|
|
193
|
+
// 安装详情:显式入口,打开与点行内空白处同一个本地详情弹窗
|
|
194
|
+
h('button', {
|
|
195
|
+
className: styles.rowDetail,
|
|
196
|
+
type: 'button',
|
|
197
|
+
title: t('detail'),
|
|
198
|
+
onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onOpenDetail(item) },
|
|
199
|
+
}, t('installDetail')),
|
|
146
200
|
item.hasUpdate && item.plugin
|
|
147
201
|
? h('button', {
|
|
148
202
|
className: styles.rowUpdate,
|
|
@@ -158,22 +212,6 @@ function InstalledRow({ item, t, langKey, canReveal, revealLabel, pendingRestart
|
|
|
158
212
|
}, t('uninstall')),
|
|
159
213
|
),
|
|
160
214
|
),
|
|
161
|
-
// 示例项目徽标单独一行(非 dsh 插件):标签较长也能完整显示,不挤压名称行
|
|
162
|
-
!item.dshCapable
|
|
163
|
-
? h('div', { className: styles.exampleRow },
|
|
164
|
-
h('span', { className: styles.exampleBadge, title: t('exampleHint') }, t('exampleLabel')),
|
|
165
|
-
)
|
|
166
|
-
: null,
|
|
167
|
-
// 第二行:仓库 · 分类(与名称左对齐缩进,独立成行不再挤压名称)
|
|
168
|
-
repo || category
|
|
169
|
-
? h('div', { className: styles.rowMeta },
|
|
170
|
-
item.repo ? h('span', { className: styles.rowRepo }, item.repo) : null,
|
|
171
|
-
category ? h('span', { className: styles.rowCategory },
|
|
172
|
-
categoryLabel(CATEGORY_LABELS, category, langKey)) : null,
|
|
173
|
-
)
|
|
174
|
-
: null,
|
|
175
|
-
// 第三行(仅目录插件):简介单独一行展示,超长以省略号收尾
|
|
176
|
-
desc ? h('div', { className: styles.rowDesc, title: desc }, desc) : null,
|
|
177
215
|
)
|
|
178
216
|
}
|
|
179
217
|
|
package/src/client/locales.ts
CHANGED
|
@@ -471,6 +471,9 @@ export const zh = {
|
|
|
471
471
|
installEntryLine: '安装入口:{c}。',
|
|
472
472
|
reportIssue: '去插件仓库提交 Issue',
|
|
473
473
|
detail: '打开详情',
|
|
474
|
+
// 已安装行按钮:打开与点行内空白处相同的本地详情弹窗
|
|
475
|
+
installDetail: '安装详情',
|
|
476
|
+
author: '作者',
|
|
474
477
|
noResult: '没有找到匹配的插件',
|
|
475
478
|
noResultDesc: '换个关键词试试,或前往网站浏览全部插件。',
|
|
476
479
|
today: '今天更新',
|
|
@@ -979,6 +982,9 @@ export const en = {
|
|
|
979
982
|
installEntryLine: 'Install entry: {c}.',
|
|
980
983
|
reportIssue: 'Report an Issue to the plugin repo',
|
|
981
984
|
detail: 'Open details',
|
|
985
|
+
// Installed-row local details button: opens the same dialog as clicking the row body
|
|
986
|
+
installDetail: 'Install details',
|
|
987
|
+
author: 'Author',
|
|
982
988
|
noResult: 'No plugins match your search',
|
|
983
989
|
noResultDesc: 'Try another keyword, or browse all plugins on the website.',
|
|
984
990
|
today: 'updated today',
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
background: var(--hub-text-tertiary);
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
/* 主信息:名称 + 已装版本 +
|
|
224
|
+
/* 主信息:名称 + 已装版本 + 有更新徽标(同一行,名称超长时省略,徽标不被挤走) */
|
|
225
225
|
.rowMain {
|
|
226
226
|
display: flex;
|
|
227
227
|
align-items: baseline;
|
|
@@ -230,25 +230,56 @@
|
|
|
230
230
|
flex: 1 1 auto;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
/* 右上角 Star / Fork:靠右单行,配色与插件市场列表一致(星标琥珀、Fork 次级灰) */
|
|
234
|
+
.rowStats {
|
|
235
|
+
display: flex;
|
|
236
|
+
align-items: center;
|
|
237
|
+
gap: 10px;
|
|
238
|
+
margin-left: auto;
|
|
239
|
+
flex-shrink: 0;
|
|
240
|
+
white-space: nowrap;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.rowStar {
|
|
244
|
+
font-size: 11px;
|
|
245
|
+
line-height: 16px;
|
|
246
|
+
color: var(--hub-warn);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.rowFork {
|
|
250
|
+
font-size: 11px;
|
|
251
|
+
line-height: 16px;
|
|
252
|
+
color: var(--hub-text-tertiary);
|
|
253
|
+
}
|
|
254
|
+
|
|
233
255
|
.rowTitle {
|
|
234
256
|
font-size: 12px;
|
|
235
257
|
line-height: 18px;
|
|
236
258
|
font-weight: 600;
|
|
237
259
|
color: var(--hub-text-primary);
|
|
260
|
+
flex: 0 1 auto;
|
|
238
261
|
min-width: 0;
|
|
239
262
|
white-space: nowrap;
|
|
240
263
|
overflow: hidden;
|
|
241
264
|
text-overflow: ellipsis;
|
|
265
|
+
/* 名称是主站详情页链接:不做成蓝色下划线,悬停才点明可点 */
|
|
266
|
+
text-decoration: none;
|
|
242
267
|
}
|
|
243
268
|
|
|
244
|
-
|
|
269
|
+
a.rowTitle:hover {
|
|
270
|
+
color: var(--hub-brand);
|
|
271
|
+
text-decoration: underline;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* 已装版本:等宽弱化小字。描边透明但保留 1px,与同行的「有更新」「插件市场」等高 */
|
|
245
275
|
.versionBadge {
|
|
246
276
|
flex-shrink: 0;
|
|
247
277
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
248
|
-
font-size:
|
|
249
|
-
line-height:
|
|
278
|
+
font-size: 10px;
|
|
279
|
+
line-height: 14px;
|
|
250
280
|
color: var(--hub-text-tertiary);
|
|
251
281
|
background: var(--hub-bg-hover);
|
|
282
|
+
border: 1px solid transparent;
|
|
252
283
|
border-radius: 4px;
|
|
253
284
|
padding: 0 5px;
|
|
254
285
|
}
|
|
@@ -256,8 +287,8 @@
|
|
|
256
287
|
/* 有更新徽标:品牌色实底小圆标 */
|
|
257
288
|
.updateBadge {
|
|
258
289
|
flex-shrink: 0;
|
|
259
|
-
font-size:
|
|
260
|
-
line-height:
|
|
290
|
+
font-size: 10px;
|
|
291
|
+
line-height: 14px;
|
|
261
292
|
font-weight: 500;
|
|
262
293
|
color: var(--hub-warn);
|
|
263
294
|
background: var(--hub-warn-tint);
|
|
@@ -274,8 +305,8 @@
|
|
|
274
305
|
width: 60px;
|
|
275
306
|
box-sizing: border-box;
|
|
276
307
|
text-align: center;
|
|
277
|
-
font-size:
|
|
278
|
-
line-height:
|
|
308
|
+
font-size: 10px;
|
|
309
|
+
line-height: 14px;
|
|
279
310
|
font-weight: 500;
|
|
280
311
|
border-radius: 4px;
|
|
281
312
|
padding: 0 4px;
|
|
@@ -300,8 +331,8 @@
|
|
|
300
331
|
与「有更新」实底区分,表达「这是示例项目,宿主不加载」 */
|
|
301
332
|
.exampleBadge {
|
|
302
333
|
flex-shrink: 0;
|
|
303
|
-
font-size:
|
|
304
|
-
line-height:
|
|
334
|
+
font-size: 10px;
|
|
335
|
+
line-height: 14px;
|
|
305
336
|
font-weight: 500;
|
|
306
337
|
color: var(--hub-brand);
|
|
307
338
|
background: var(--hub-brand-tint);
|
|
@@ -338,16 +369,34 @@
|
|
|
338
369
|
white-space: nowrap;
|
|
339
370
|
overflow: hidden;
|
|
340
371
|
text-overflow: ellipsis;
|
|
372
|
+
/* 仓库名是主站详情页链接:默认与普通文字无异,悬停才提示可点 */
|
|
373
|
+
text-decoration: none;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
a.rowRepo:hover {
|
|
377
|
+
color: var(--hub-brand);
|
|
378
|
+
text-decoration: underline;
|
|
341
379
|
}
|
|
342
380
|
|
|
343
381
|
.rowCategory {
|
|
344
382
|
flex-shrink: 0;
|
|
345
|
-
font-size:
|
|
346
|
-
line-height:
|
|
383
|
+
font-size: 10px;
|
|
384
|
+
line-height: 14px;
|
|
347
385
|
color: var(--hub-text-tertiary);
|
|
348
386
|
background: var(--hub-bg-hover);
|
|
387
|
+
border: 1px solid transparent;
|
|
349
388
|
border-radius: 4px;
|
|
350
|
-
padding: 0
|
|
389
|
+
padding: 0 5px;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* 来源标签 + 操作按钮行:独立成行靠右成组,名称行只留名称/版本/更新状态 */
|
|
393
|
+
.rowActionLine {
|
|
394
|
+
display: flex;
|
|
395
|
+
align-items: center;
|
|
396
|
+
justify-content: flex-end;
|
|
397
|
+
gap: 8px;
|
|
398
|
+
padding-left: 16px;
|
|
399
|
+
min-width: 0;
|
|
351
400
|
}
|
|
352
401
|
|
|
353
402
|
/* —— 行操作:详情 / 更新 / 卸载 —— */
|
|
@@ -359,14 +408,16 @@
|
|
|
359
408
|
flex-shrink: 0;
|
|
360
409
|
}
|
|
361
410
|
|
|
362
|
-
/*
|
|
411
|
+
/* 详情:默认无边框(低频操作不抢视觉),悬停才出现描边与底色成为按钮形状。
|
|
412
|
+
描边保留 1px 透明而非 none,保证与同行的更新/卸载按钮同高、文字基线对齐 */
|
|
363
413
|
.rowDetail {
|
|
364
414
|
font-family: inherit;
|
|
365
415
|
font-size: 12px;
|
|
366
416
|
line-height: 18px;
|
|
417
|
+
font-weight: 500;
|
|
367
418
|
color: var(--hub-text-secondary);
|
|
368
419
|
background: transparent;
|
|
369
|
-
border: 1px solid
|
|
420
|
+
border: 1px solid transparent;
|
|
370
421
|
border-radius: 6px;
|
|
371
422
|
padding: 2px 10px;
|
|
372
423
|
cursor: pointer;
|
|
@@ -376,7 +427,7 @@
|
|
|
376
427
|
|
|
377
428
|
.rowDetail:hover {
|
|
378
429
|
color: var(--hub-text-primary);
|
|
379
|
-
border-color: var(--hub-border-
|
|
430
|
+
border-color: var(--hub-border-2);
|
|
380
431
|
background: var(--hub-bg-hover);
|
|
381
432
|
}
|
|
382
433
|
|
|
@@ -403,7 +454,8 @@
|
|
|
403
454
|
border-color: var(--hub-warning);
|
|
404
455
|
}
|
|
405
456
|
|
|
406
|
-
/*
|
|
457
|
+
/* 更新:琥珀色实底小按钮(与插件市场「可更新」同色),仅在「有更新」时出现。
|
|
458
|
+
与详情/卸载同度量(1px 描边 + 2px 内距),否则实底按钮会比描边按钮窄一圈 */
|
|
407
459
|
.rowUpdate {
|
|
408
460
|
font-family: inherit;
|
|
409
461
|
font-size: 12px;
|
|
@@ -411,9 +463,9 @@
|
|
|
411
463
|
font-weight: 500;
|
|
412
464
|
color: #fff;
|
|
413
465
|
background: var(--hub-warn);
|
|
414
|
-
border:
|
|
466
|
+
border: 1px solid var(--hub-warn);
|
|
415
467
|
border-radius: 6px;
|
|
416
|
-
padding:
|
|
468
|
+
padding: 2px 10px;
|
|
417
469
|
cursor: pointer;
|
|
418
470
|
user-select: none;
|
|
419
471
|
transition: background 120ms ease;
|
|
@@ -428,6 +480,7 @@
|
|
|
428
480
|
font-family: inherit;
|
|
429
481
|
font-size: 12px;
|
|
430
482
|
line-height: 18px;
|
|
483
|
+
font-weight: 500;
|
|
431
484
|
color: var(--hub-danger);
|
|
432
485
|
background: transparent;
|
|
433
486
|
border: 1px solid var(--hub-danger-border-soft);
|
|
@@ -52,7 +52,8 @@
|
|
|
52
52
|
gap: 4px;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
/* 名称行:名称可收缩到省略号,版本与更新徽标不收缩 —— 长仓库名不会把状态挤没 */
|
|
56
|
+
.cardTitleRow {
|
|
56
57
|
display: flex;
|
|
57
58
|
align-items: center;
|
|
58
59
|
gap: 6px;
|
|
@@ -60,26 +61,55 @@
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
.cardTitle {
|
|
64
|
+
flex: 0 1 auto;
|
|
65
|
+
min-width: 0;
|
|
63
66
|
font-size: 13px;
|
|
64
67
|
line-height: 18px;
|
|
65
68
|
font-weight: 600;
|
|
66
69
|
white-space: nowrap;
|
|
67
70
|
overflow: hidden;
|
|
68
71
|
text-overflow: ellipsis;
|
|
72
|
+
/* 链接形态但不做成蓝色下划线:沿用标题颜色,悬停才点明可点 */
|
|
73
|
+
color: inherit;
|
|
74
|
+
text-decoration: none;
|
|
75
|
+
transition: color 120ms ease;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
a.cardTitle:hover {
|
|
79
|
+
color: var(--hub-brand);
|
|
80
|
+
text-decoration: underline;
|
|
69
81
|
}
|
|
70
82
|
|
|
83
|
+
/* 分类 / 验证徽标行:与名称行分开,长名称与多枚徽标互不抢宽度 */
|
|
84
|
+
.cardBadgeRow {
|
|
85
|
+
display: flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
flex-wrap: wrap;
|
|
88
|
+
gap: 6px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* 徽章统一度量:字号 / 行高 / 内距 / 描边一致,同屏并排时不会一大一小。
|
|
92
|
+
以 14px 行高 + 1px 描边收成 16px 高的轻量标签,不与名称行争视觉重量 */
|
|
71
93
|
.categoryBadge,
|
|
72
94
|
.verified,
|
|
95
|
+
.authorBadge,
|
|
73
96
|
.versionBadge,
|
|
74
97
|
.updateBadge {
|
|
75
98
|
flex-shrink: 0;
|
|
76
99
|
font-size: 10px;
|
|
77
|
-
line-height:
|
|
100
|
+
line-height: 14px;
|
|
78
101
|
border-radius: 4px;
|
|
79
|
-
padding: 0
|
|
102
|
+
padding: 0 5px;
|
|
80
103
|
border: 1px solid transparent;
|
|
81
104
|
}
|
|
82
105
|
|
|
106
|
+
/* 作者:等宽字体 + 中性灰,与分类(品牌蓝)、已验证(绿)区分,避免一行里多个彩色标签抢注意力 */
|
|
107
|
+
.authorBadge {
|
|
108
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
109
|
+
color: var(--hub-text-tertiary);
|
|
110
|
+
border-color: var(--hub-border-ghost);
|
|
111
|
+
}
|
|
112
|
+
|
|
83
113
|
.categoryBadge {
|
|
84
114
|
color: var(--hub-brand);
|
|
85
115
|
border-color: var(--hub-border-ghost);
|