Revert "fix(client): 将模型发布标记改为蓝色纯文字" (#6936)

This commit is contained in:
imccyu authored and GitHub committed 2026-10-22 13:21:40 +08:00
1 parent 2e0ce8d448
commit 9fb3a064ea
13 files changed
+24 -112

No files matched your search

+1 -2
View File
@@ -57,8 +57,7 @@ describe.skipIf(webSnapshotMode() === 'record')('web e2e: context details placem
})
await page.evaluate(async () => {
await Promise.all(document.getAnimations()
.filter(animation => animation.timeline === document.timeline
&& animation.effect?.getComputedTiming().iterations !== Infinity)
.filter(animation => animation.effect?.getComputedTiming().iterations !== Infinity)
.map(animation => animation.finished.catch(() => undefined)))
})
await expect.poll(async () => {
@@ -69,44 +69,6 @@ describe.skipIf(MODE === 'record')('web e2e: temporary DeepSeek release badge',
}
})
it('fades out the inline release with the model name and restores it after widening', async () => {
const trigger = page.getByRole('button', { name: /^选择模型/ })
const readLayout = () => trigger.getByText('1017', { exact: true }).evaluate((release) => {
const label = release.parentElement!
const box = label.closest('[data-provider-id]')!.parentElement!
const style = getComputedStyle(release)
const labelStyle = getComputedStyle(label)
const boxStyle = getComputedStyle(box)
return {
clipped: box.scrollWidth > box.clientWidth,
textOverflow: boxStyle.textOverflow,
fade: boxStyle.maskImage,
inline: labelStyle.display === 'inline' && style.display === 'inline',
sameFontSize: style.fontSize === labelStyle.fontSize,
background: style.backgroundColor,
padding: style.padding,
}
})
try {
await page.setViewportSize({ width: 500, height: 900 })
await expect.poll(async () => (await readLayout()).clipped).toBe(true)
const narrowed = await readLayout()
expect(narrowed).toEqual({
clipped: true, textOverflow: 'clip',
fade: 'linear-gradient(90deg, rgb(0, 0, 0) calc(100% - 24px), rgba(0, 0, 0, 0))',
inline: true, sameFontSize: true, background: 'rgba(0, 0, 0, 0)', padding: '0px',
})
await page.setViewportSize({ width: 1440, height: 900 })
await expect.poll(async () => (await readLayout()).clipped).toBe(false)
await compareOrRefreshGolden(
fileURLToPath(new URL('./expected/deepseek-model-label-1017/layout.expected.md', import.meta.url)),
JSON.stringify({ narrowed, widened: await readLayout() }, null, 2), MODE,
)
} finally {
await page.setViewportSize({ width: 1440, height: 900 })
}
})
it('keeps the release badge inside a 390px model menu and uses both theme palettes', async () => {
try {
await page.setViewportSize({ width: 390, height: 844 })
@@ -134,10 +96,7 @@ describe.skipIf(MODE === 'record')('web e2e: temporary DeepSeek release badge',
}
})
expect(colors[0]).not.toEqual(colors[1])
for (const color of colors) {
expect(color.background).toBe('rgba(0, 0, 0, 0)')
expect(color.color).not.toBe(color.background)
}
for (const color of colors) expect(color.color).not.toBe(color.background)
} finally {
await page.keyboard.press('Escape')
await page.keyboard.press('Escape')
@@ -1,20 +0,0 @@
{
"narrowed": {
"clipped": true,
"textOverflow": "clip",
"fade": "linear-gradient(90deg, rgb(0, 0, 0) calc(100% - 24px), rgba(0, 0, 0, 0))",
"inline": true,
"sameFontSize": true,
"background": "rgba(0, 0, 0, 0)",
"padding": "0px"
},
"widened": {
"clipped": false,
"textOverflow": "clip",
"fade": "none",
"inline": true,
"sameFontSize": true,
"background": "rgba(0, 0, 0, 0)",
"padding": "0px"
}
}
+3 -5
View File
@@ -169,15 +169,13 @@ function firstRecallPulse(page: Page): Promise<boolean> {
}
/**
* Wait until no time-based animation under the page is running, so a probe measures
* the settled layout instead of a frame of a column slide. Scroll-driven animations
* never finish and are ignored.
* Wait until nothing under the page is animating, so a probe measures the settled
* layout instead of a frame of a column slide.
* @param page - the page under test.
*/
async function settled(page: Page): Promise<void> {
await expect.poll(() => page.evaluate(() => document.getAnimations()
.every(animation => animation.timeline !== document.timeline
|| animation.playState === 'finished' || animation.playState === 'idle')),
.every(animation => animation.playState === 'finished' || animation.playState === 'idle')),
{ timeout: 20_000 }).toBe(true)
}
@@ -15,11 +15,11 @@
en: d152484eb41ac6b4
zh: 09388d293f9be9cb
/deepseek-ai-dsh-client-ui-deepseek-model-label-1017/use-this-package:
en: c241d810553094d8
zh: 9102b83b2aa5e032
en: a6d5fcecfa93935b
zh: 8ae2809a06910c52
/deepseek-ai-dsh-client-ui-deepseek-model-label-1017/understand-the-implementation:
en: 368aae60ad92d90e
zh: 67ac74f0351f1b5e
en: ca1d0c5db1b819a0
zh: 960e8db56fa5987e
/deepseek-ai-dsh-client-ui-deepseek-model-label-1017/further-exploration:
en: 2885099078047d38
zh: d7de1db3f1ba0a50
@@ -27,7 +27,7 @@ This package shows `1017` beside `DeepSeek-V4.1-Flash` in the composer model sel
The Web bundle includes this plugin, including when Desktop uses that bundle. It has no configuration fields.
The badge appears only when the provider is `deepseek-official` or `deepseek-account`, the model ID is `deepseek-flash`, and the catalog name is exactly `DeepSeek-V4.1-Flash`. Other names and providers keep their catalog text. The input button, current-model menu row, and model options share the blue plain-text release marker. It uses the model name’s font size and baseline, with no capsule; when space is limited, the selector fades out the end of the combined text, so the marker may be hidden.
The badge appears only when the provider is `deepseek-official` or `deepseek-account`, the model ID is `deepseek-flash`, and the catalog name is exactly `DeepSeek-V4.1-Flash`. Other names and providers keep their catalog text. The input button, current-model menu row, and model options share the badge.
Disable the following row through a profile patch to restore the catalog name:
@@ -44,7 +44,7 @@ Disable the following row through a profile patch to restore the catalog name:
<details>
<summary>Implementation internals — click to expand</summary>
The browser entry contributes to the existing `conversation.input.model.label` slot through `ctx.slots.inject()`. Its component derives the label from owner props and renders the release marker as an inline span; it owns no cache, subscription, network request, or model-selection state. Registration and dictionaries leave with the plugin. The Host entry only makes the browser package available to the Loader.
The browser entry contributes to the existing `conversation.input.model.label` slot through `ctx.slots.inject()`. Its component derives the label from owner props and uses the shared `Tag` primitive; it owns no cache, subscription, network request, or model-selection state. Registration and dictionaries leave with the plugin. The Host entry only makes the browser package available to the Loader.
</details>
@@ -27,7 +27,7 @@ kind: "package-reference"
Web bundle 包含本插件,桌面端使用该 bundle 时也会加载。本包没有配置字段。
只有提供方为 `deepseek-official` 或 `deepseek-account`、模型 ID 为 `deepseek-flash`,且目录名称恰好为 `DeepSeek-V4.1-Flash` 时才显示角标。其他名称和提供方保留目录文字。输入框按钮、当前模型菜单行和模型选项共用蓝色纯文字版本标记。标记与模型名称字号相同、基线对齐,不使用胶囊;空间不足时由选择器将整段文字末尾渐隐,版本标记可能被隐藏。
只有提供方为 `deepseek-official` 或 `deepseek-account`、模型 ID 为 `deepseek-flash`,且目录名称恰好为 `DeepSeek-V4.1-Flash` 时才显示角标。其他名称和提供方保留目录文字。输入框按钮、当前模型菜单行和模型选项共用这个角标。
通过 profile patch 停用以下条目即可恢复目录名称:
@@ -44,7 +44,7 @@ Web bundle 包含本插件,桌面端使用该 bundle 时也会加载。本包
<details>
<summary>内部实现 — 点击展开</summary>
浏览器入口通过 `ctx.slots.inject()` 向已有的 `conversation.input.model.label` slot 注册组件。组件根据 owner props 派生标签,以行内 span 显示版本标记,不拥有缓存、订阅、网络请求或模型选择状态。注册和字典随插件卸载。Host 入口仅让 Loader 能加载浏览器包。
浏览器入口通过 `ctx.slots.inject()` 向已有的 `conversation.input.model.label` slot 注册组件。组件根据 owner props 派生标签,使用共享 `Tag` 基元,不拥有缓存、订阅、网络请求或模型选择状态。注册和字典随插件卸载。Host 入口仅让 Loader 能加载浏览器包。
</details>
@@ -1,7 +1,7 @@
.label {
display: inline-flex;
align-items: center;
gap: 4px;
vertical-align: baseline;
white-space: nowrap;
}
.release {
color: var(--dsw-alias-state-business-primary);
}
@@ -1,6 +1,7 @@
/** Display-only release marking; the catalog and selected route remain unchanged. */
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
import type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'
import { Tag } from '@deepseek-ai/dsh-client-ui-primitives'
import css from './DeepSeekModelLabel.module.css'
const MODEL_NAME = 'DeepSeek-V4.1-Flash'
@@ -8,7 +9,7 @@ const MODEL_NAME = 'DeepSeek-V4.1-Flash'
/**
* Render the fixed 1017 release label for recognized official Flash entries.
* @param props - Provider and model identity plus the badge dictionary.
* @returns The base name with a blue release marker, or the untouched catalog name.
* @returns The base name with a badge, or the untouched catalog name.
*/
export function DeepSeekModelLabel({ provider, model, t }:
PropsRuntime<'conversation.input.model.label'> & PropsLocale<'deepseek-model-label-1017'>,
@@ -16,6 +17,6 @@ export function DeepSeekModelLabel({ provider, model, t }:
const official = provider.id === 'deepseek-account' || provider.id === 'deepseek-official'
if (!official || model.id !== 'deepseek-flash' || model.name !== MODEL_NAME) return model.name
return <span className={css.label}>
{model.name}{' '}<span className={css.release}>{t('badge.label')}</span>
<span>{model.name}</span>{' '}<Tag tone="info">{t('badge.label')}</Tag>
</span>
}
@@ -18,8 +18,8 @@
en: ef50e68e7493d0a9
zh: 3b1faea17b606173
/deepseek-ai-dsh-client-ui-model-selection/use-this-package/model-and-effort:
en: aa78900b8856b7eb
zh: b140e3e1218a7c7b
en: 48f8157ffdfe6e69
zh: 64ec9a533e2aa8f4
/deepseek-ai-dsh-client-ui-model-selection/use-this-package/model-label-extensions:
en: bc47871cf8b61451
zh: 17d21da46604f071
+1 -1
View File
@@ -43,7 +43,7 @@ Model and reasoning-effort names use weight 400 (regular) in the composer menu,
Both entries group models by provider, with DeepSeek Account first and DeepSeek second; third-party providers retain their catalog order. Both use the shared, asynchronously observed sticky headings from [ui-primitives](../ui-primitives/README.md#understand-the-implementation): transparent at rest, with the theme's 94%-opaque fill only while pinned, and `md` corners outside macOS Desktop. The composer menu shows model and effort names only. Navigation chevrons use `--dsw-alias-menu-icon`. The `/model` popup shows provider names as group headings and model names as rows, without repeating the provider on each row or showing catalog descriptions. Its search placeholder, no-match text, and empty-catalog text use the same localized labels as the composer model menu. The popup applies the selected model's default effort; the composer can then choose any advertised effort. An adapter without reasoning metadata leaves the Effort row absent; there is no arbitrary effort input.
The composer replaces the model and effort text with the Models icon when the expanded controls cannot share one line, and restores the text when space permits. The full selection remains available in the trigger's accessible name, tooltip, and menu. Model and effort text that does not fit its space, in the trigger, the root menu values, and the option rows, is clipped and fades out over its last 24px instead of ending in an ellipsis; browsers without scroll-driven animations keep the ellipsis.
The composer replaces the model and effort text with the Models icon when the expanded controls cannot share one line, and restores the text when space permits. The full selection remains available in the trigger's accessible name, tooltip, and menu.
### Model label extensions
@@ -43,7 +43,7 @@ composer 菜单中的模型名称和推理等级均使用 400(regular)字重
两个入口均按提供方分组,DeepSeek 账号排第一,DeepSeek 排第二,第三方提供方保持目录原有顺序。两者采用 [ui-primitives](../ui-primitives/README.zh.md#understand-the-implementation) 异步观察的共享吸顶标题:原位透明,仅吸顶时使用主题的 94% 不透明填充,macOS 桌面端以外使用 `md` 圆角。composer 菜单只显示模型与推理强度名称。导航箭头使用 `--dsw-alias-menu-icon` 文本色。`/model` 弹窗以提供方名称作为分组标题、模型名称作为选项行,不在每行重复提供方,也不显示目录说明。搜索占位文字、无匹配提示和空目录提示与 composer 模型菜单共用同一组本地化文案。弹窗应用所选模型的默认推理强度;composer 随后可以选择任一已公布的推理强度。适配器没有推理元数据时不显示 Effort 行;不存在任意推理强度输入。
展开的控件无法排在同一行时,composer 将模型与推理强度文字替换为模型图标;空间足够后恢复文字。触发器的无障碍名称、提示和菜单仍提供完整选择。触发按钮、根菜单当前值和选项行中放不下的模型与推理强度文字会被裁切,并在末尾 24px 内渐隐,不显示省略号;不支持滚动驱动动画的浏览器仍显示省略号。
展开的控件无法排在同一行时,composer 将模型与推理强度文字替换为模型图标;空间足够后恢复文字。触发器的无障碍名称、提示和菜单仍提供完整选择。
### 模型名称扩展
@@ -70,31 +70,6 @@
flex: 0 0 auto;
}
/* Clipped selector text fades over its last 24px instead of ending in an
ellipsis. A self scroll timeline is active only while the box overflows,
so the mask never touches text that fits; browsers without scroll-driven
animations keep the ellipsis. A mask rather than a painted gradient, so
the fade matches the trigger's bare and hover fills and every menu row. */
@supports (animation-timeline: scroll()) {
.triggerLabel,
.triggerEffort,
.modelName,
.cellValue {
text-overflow: clip;
/* Longhands only: the build folds a full set into the `animation`
shorthand, which cannot carry a timeline. */
animation-name: clipped-fade;
animation-fill-mode: both;
animation-timeline: scroll(self inline);
}
}
@keyframes clipped-fade {
from, to {
mask-image: linear-gradient(to right, black calc(100% - 24px), transparent);
}
}
/* The composer measures expanded row demand and owns these display variables.
Outside a composer, the trigger retains its text. */
.triggerLabel,