feat(settings): replicate the WorkBuddy about and help panels without external jumps (TODO 19)
Recover the shared WorkBuddy 5.8.3 HelpFeedbackPanel stylesheet through REA (18 module rules plus scoped light/dark tokens) and rebuild the 关于 and 获取帮助 pages: 638x620 panels, 638x108 two-row cards, 82x32/102x32 actions, the 638x226 follow card with three 120x120 QR frames and the 638x44 footer. Keep the user's no-jump requirement explicit: every external entry (检查更新, 前往官网, 填写反馈, 查看文档, 隐私政策, 服务协议) keeps the original wording and geometry but is aria-disabled with a 暂未接入/尚未配置 tooltip and performs no navigation; the WorkBuddy account QR codes become same-size 尚未配置 placeholders. The version line reads the real appInfo version. Also fix a CSS bundling regression found while wiring this page: the shared general-settings stylesheet was inlined three times and overrode the personalization long-card padding, collapsing the 598x160 previews to 614 wide. Remove the duplicate import and raise the personalization padding specificity. Verify with scripts/verify-about-help-settings.cjs (15 assertions: both pages, geometry, real version, disabled jumpless actions, no anchors, dark surfaces) and keep all existing settings regressions green.
This commit is contained in:
1 parent
0dc088f1f7
commit
b3be45715e
20 files changed
+683
-7
No files matched your search
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* 设置 → 关于 / 获取帮助:WorkBuddy 5.8.3 两页布局的 1:1 复刻(TODO 19)。
|
||||
*
|
||||
* REA 依据(设置窗口 900×680):
|
||||
* - ev_7e063ae669e788666080ec25be3247d2c75504d89d076f9963a737cf69ccf25c(关于·浅色 DOM/layout/computed style + 模块 CSS)
|
||||
* - ev_4d3e8c9e277578ef06a16aa4aad5b4766c6a55744c65beb3e8a14033648476c9(获取帮助·浅色)
|
||||
* - ev_ed6dce11ff79cf06e3e01c6c1b5ae3e3cc11eac10b37327ce12c06d5c3447053(关于·深色)
|
||||
* - ev_ea353952860b6b59699c26fc72d40740b9a3770fe9a3a6e76515686f4363abe6(获取帮助·深色)
|
||||
* - ev_17cc173b4e9da27258d5378924a16fb0a5e0c7b5fd845bec319361fbdff56e30(最终浅色关于页顶部)
|
||||
*
|
||||
* 几何:两页右侧 panel 均为 [232,40,638,620];顶部卡片 638×108(两行 606×32,行距 20、padding 12×16);
|
||||
* 关注卡片 638×226(标题居中 + 三列 120×120 二维码框,内图 102×102);
|
||||
* 页脚 [232,616,638,44],隐私政策 · 服务协议为 12px 禁用文字按钮。
|
||||
*
|
||||
* 用户限定(TODO 19):只复刻布局,不复刻原版跳转链接。YCode 没有官网/反馈/文档/隐私/协议入口,
|
||||
* 所有链接类按钮保持原版几何与文案,但禁用并标注「尚未配置」;「检查更新」没有更新通道,标注「暂未接入」。
|
||||
* 原版三张二维码指向 WorkBuddy 官方账号,替换为同尺寸「尚未配置」占位块,不臆造二维码内容。
|
||||
*/
|
||||
import { useEffect, useState } from 'react'
|
||||
import './source-about-help-panels.css'
|
||||
|
||||
export type AboutHelpSection = 'helpFeedback' | 'getHelp'
|
||||
|
||||
const QR_ITEMS: ReadonlyArray<{ key: string; label: string }> = [
|
||||
{ key: 'official-account', label: '公众号' },
|
||||
{ key: 'channels', label: '视频号' },
|
||||
{ key: 'tencent-channel', label: '腾讯频道' }
|
||||
]
|
||||
|
||||
function ExternalArrow(): React.JSX.Element {
|
||||
return (
|
||||
<svg className="wb-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M5.25 3.75h7v7M12 4 4.25 11.75" />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
function UnavailableAction({ label, title, arrow = false }: { label: string; title: string; arrow?: boolean }): React.JSX.Element {
|
||||
return (
|
||||
<span className="help-feedback-panel__action-wrapper">
|
||||
<button type="button" className="wb-button wb-button--secondary wb-button--medium help-feedback-panel__action-button"
|
||||
aria-disabled="true" title={title}
|
||||
onClick={(event) => { event.preventDefault(); event.stopPropagation() }}>
|
||||
<span className="wb-button__content">{label}</span>
|
||||
{arrow ? <span className="wb-button__icon"><ExternalArrow /></span> : null}
|
||||
</button>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export default function AboutHelpSettingsPanel({ section }: { section: AboutHelpSection }): React.JSX.Element {
|
||||
const [version, setVersion] = useState('—')
|
||||
useEffect(() => {
|
||||
let active = true
|
||||
void window.ycode.app.info()
|
||||
.then((info) => { if (active) setVersion(info.version) })
|
||||
.catch(() => { if (active) setVersion('—') })
|
||||
return () => { active = false }
|
||||
}, [])
|
||||
|
||||
const about = section === 'helpFeedback'
|
||||
return (
|
||||
<div className="general-settings-panel help-feedback-panel" data-about-help-panel={section}>
|
||||
<div className="help-feedback-panel__card">
|
||||
{about ? (
|
||||
<>
|
||||
<div className="help-feedback-panel__card-row">
|
||||
<div className="help-feedback-panel__card-label">当前版本<span className="help-feedback-panel__card-value">v{version}</span></div>
|
||||
<UnavailableAction label="检查更新" title="暂未接入" />
|
||||
</div>
|
||||
<div className="help-feedback-panel__card-row">
|
||||
<div className="help-feedback-panel__card-label">关于 YCode</div>
|
||||
<UnavailableAction label="前往官网" title="尚未配置" arrow />
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="help-feedback-panel__card-row">
|
||||
<div className="help-feedback-panel__card-label">意见反馈</div>
|
||||
<UnavailableAction label="填写反馈" title="尚未配置" />
|
||||
</div>
|
||||
<div className="help-feedback-panel__card-row">
|
||||
<div className="help-feedback-panel__card-label">帮助文档</div>
|
||||
<UnavailableAction label="查看文档" title="尚未配置" arrow />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{about ? (
|
||||
<>
|
||||
<div className="help-feedback-panel__follow-card">
|
||||
<div className="help-feedback-panel__follow-title">关注我们,获取实用技巧与产品最新动态</div>
|
||||
<div className="help-feedback-panel__qr-list">
|
||||
{QR_ITEMS.map((item) => (
|
||||
<div className="help-feedback-panel__qr-item" key={item.key}>
|
||||
<div className="help-feedback-panel__qr-label">{item.label}</div>
|
||||
<div className="help-feedback-panel__qr-container" aria-disabled="true" title="尚未配置">
|
||||
<div className="help-feedback-panel__qr help-feedback-panel__qr--placeholder">尚未配置</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="help-feedback-panel__footer">
|
||||
<button type="button" className="wb-button help-feedback-panel__footer-link" aria-disabled="true" disabled title="尚未配置">隐私政策</button>
|
||||
<span className="help-feedback-panel__footer-separator" aria-hidden="true">|</span>
|
||||
<button type="button" className="wb-button help-feedback-panel__footer-link" aria-disabled="true" disabled title="尚未配置">服务协议</button>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import GeneralSettingsPanel from './GeneralSettingsPanel'
|
||||
import AppearanceSettingsPanel from './AppearanceSettingsPanel'
|
||||
import ShortcutsSettingsPanel from './ShortcutsSettingsPanel'
|
||||
import PersonalizationSettingsPanel from './PersonalizationSettingsPanel'
|
||||
import AboutHelpSettingsPanel from './AboutHelpSettingsPanel'
|
||||
import SourceSettingsNavigation from './SourceSettingsNavigation'
|
||||
import { useSharedTheme } from '../useSharedTheme'
|
||||
import { SOURCE_WINDOWS_SETTINGS_TABS } from './SourceSettingsNavigation'
|
||||
@@ -55,7 +56,7 @@ export default function SettingsDialog({ theme, onThemeChange, onClose, nativeWi
|
||||
return () => window.removeEventListener('keydown', escape)
|
||||
}, [onClose])
|
||||
const modal = <section className={`settings-modal${nativeWindow ? ' settings-modal--window' : ''}`} role="dialog" aria-label="设置" aria-modal={!nativeWindow}>
|
||||
<div className="settings-modal__nav"><SourceSettingsNavigation activeTab={section} supportedTabs={['settings', 'models', 'appearance', 'keyboardShortcuts', 'personalization']} visibleTabs={VISIBLE_SETTINGS_TABS}
|
||||
<div className="settings-modal__nav"><SourceSettingsNavigation activeTab={section} supportedTabs={['settings', 'models', 'appearance', 'keyboardShortcuts', 'personalization', 'helpFeedback', 'getHelp']} visibleTabs={VISIBLE_SETTINGS_TABS}
|
||||
onTabChange={(id) => { setError(''); setSection(id === 'models' ? 'model' : id) }} onUnavailable={() => setError('该设置尚未接入')} /></div>
|
||||
<div className="settings-modal__content"><div className="settings-modal__panel">
|
||||
{error && <p role="alert">{error}</p>}
|
||||
@@ -65,6 +66,7 @@ export default function SettingsDialog({ theme, onThemeChange, onClose, nativeWi
|
||||
{section === 'appearance' && <AppearanceSettingsPanel theme={theme} onThemeChange={onThemeChange} />}
|
||||
{section === 'keyboardShortcuts' && <ShortcutsSettingsPanel />}
|
||||
{section === 'personalization' && <PersonalizationSettingsPanel />}
|
||||
{(section === 'helpFeedback' || section === 'getHelp') && <AboutHelpSettingsPanel section={section} />}
|
||||
{section === 'about' && <div className="settings-window-panel"><h2>YCode</h2><p>{settings.appInfo?.version}</p></div>}
|
||||
</div></div>
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/* REA aboutLight=ev_7e063ae669e788666080ec25be3247d2c75504d89d076f9963a737cf69ccf25c; helpLight=ev_4d3e8c9e277578ef06a16aa4aad5b4766c6a55744c65beb3e8a14033648476c9; aboutDark=ev_ed6dce11ff79cf06e3e01c6c1b5ae3e3cc11eac10b37327ce12c06d5c3447053; helpDark=ev_ea353952860b6b59699c26fc72d40740b9a3770fe9a3a6e76515686f4363abe6; HelpFeedbackPanel-CQNpj-cs.css light-sha256=fc5a287a1f5a4a76ede74ba971ff12f340ae2193e1dbef9c8898a9b7c3d894e7 dark-sha256=19ec85a3c3fc11a581bbcdf8182e4d78a32dcf5d71307d3da1bbaf92177af765; tokens sha256=13f2bf82c96e5167a7d7098e36950c6c22c475b3337dbb8bb29ad2fe79cde696. */
|
||||
.help-feedback-panel{flex-direction:column;gap:16px;min-height:100%;display:flex}.help-feedback-panel__card,.help-feedback-panel__follow-card{background:var(--wb-bg-primary,#fff);border-radius:12px}.help-feedback-panel__card{flex-direction:column;gap:20px;padding:12px 16px;display:flex}.help-feedback-panel__card-row{justify-content:space-between;align-items:center;gap:20px;min-height:32px;display:flex}.help-feedback-panel__card-label{min-width:0;color:var(--wb-color-text-primary,#000000e6);align-items:center;gap:4px;font-size:14px;font-weight:400;line-height:22px;display:inline-flex}.help-feedback-panel__card-value{color:var(--wb-color-text-tertiary,#00000080);font-size:12px;line-height:20px}.help-feedback-panel__action-button{flex-shrink:0}.help-feedback-panel__action-wrapper{flex-shrink:0;display:inline-flex}.help-feedback-panel__follow-card{flex-direction:column;align-items:center;gap:16px;padding:20px 16px;display:flex}.help-feedback-panel__follow-title{color:var(--wb-color-text-primary,#000000e6);text-align:center;font-size:14px;font-weight:400;line-height:22px}.help-feedback-panel__qr-list{justify-content:center;gap:24px;display:flex}.help-feedback-panel__qr-item{flex-direction:column;align-items:center;gap:8px;display:flex}.help-feedback-panel__qr-label{color:var(--wb-color-text-tertiary,#00000080);font-size:12px;line-height:20px}.help-feedback-panel__qr-container{box-sizing:border-box;background:var(--wb-color-bg-secondary-default,#fff);border:.5px solid var(--wb-color-border-secondary,#ebebeb);border-radius:16px;width:120px;height:120px;padding:8px}.help-feedback-panel__qr{object-fit:contain;background:var(--wb-palette-white-100,#fff);width:100%;height:100%;display:block}.help-feedback-panel__footer{justify-content:center;align-items:center;gap:var(--wb-spacing-4);padding-top:var(--wb-spacing-7);margin-top:auto;display:flex}.help-feedback-panel__footer-link.wb-button{min-width:0;height:auto;color:var(--wb-color-text-disabled,#0000004d);box-shadow:none;padding:0;font-size:12px;line-height:20px}.help-feedback-panel__footer-link.wb-button:hover:not(:disabled){color:var(--wb-color-text-tertiary,#00000080);background:0 0}
|
||||
.help-feedback-panel{--wb-bg-primary:var(--wb-palette-white-100);--wb-color-text-primary:var(--wb-palette-black-100);--wb-color-text-tertiary:var(--wb-palette-black-50);--wb-color-bg-secondary-default:var(--wb-palette-white-100);--wb-color-border-secondary:var(--wb-palette-gray-4);--wb-palette-white-100:#fff;--wb-spacing-4:12px;--wb-spacing-7:24px;--wb-color-text-disabled:var(--wb-palette-black-30);--wb-palette-gray-3:#f2f2f2;--wb-palette-black-100:#000;--wb-palette-black-50:#00000080;--wb-palette-gray-2:#f7f7f7;--wb-palette-gray-4:#ebebeb;--wb-palette-gray-5:#e6e6e6;--wb-palette-black-30:#0000004d}
|
||||
[data-theme=dark] .help-feedback-panel{--wb-bg-primary:var(--wb-palette-gray-3);--wb-color-text-primary:#fff;--wb-color-text-tertiary:#ffffff80;--wb-color-bg-secondary-default:var(--wb-palette-gray-2);--wb-color-border-secondary:var(--wb-palette-gray-5);--wb-palette-white-100:#fff;--wb-spacing-4:12px;--wb-spacing-7:24px;--wb-color-text-disabled:#ffffff59;--wb-palette-gray-3:#1f1f1f;--wb-palette-black-100:#000;--wb-palette-black-50:#00000080;--wb-palette-gray-2:#292929;--wb-palette-gray-4:#242424;--wb-palette-gray-5:#3a3a3a;--wb-palette-black-30:#0000004d}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 设置 → 关于 / 获取帮助(TODO 19)。
|
||||
* - source-about-help-panels-recovered.css:REA 回收的 HelpFeedbackPanel-CQNpj-cs.css 投影。
|
||||
* - 按钮所需的 .wb-button UI kit 由 GeneralSettingsPanel 已加载的 source-general-settings.css 提供;
|
||||
* 这里不再重复 @import,避免同一份通用样式表被打包多次、排到本页规则之后改变层叠。
|
||||
* 以下是二维码占位与深色正文的本地适配(原版二维码指向 WorkBuddy 官方账号,按用户要求不复刻)。
|
||||
*/
|
||||
@import './source-about-help-panels-recovered.css';
|
||||
|
||||
/*
|
||||
* REA ev_ed6dce11…(关于·深色):正文 color 为 rgb(242,243,245)。
|
||||
* 原版设置窗口把 --wb-color-text-primary 覆盖为 #f2f3f5(比全局 tokens 的 #fff 更具体),这里同优先级还原。
|
||||
*/
|
||||
:root[data-theme=dark] .general-settings-panel.help-feedback-panel {
|
||||
--wb-color-text-primary: #f2f3f5;
|
||||
}
|
||||
|
||||
/* 原版二维码图片为白底;YCode 无对应账号,用同尺寸占位块并明确标注。 */
|
||||
.help-feedback-panel .help-feedback-panel__qr--placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--wb-color-text-tertiary);
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
border: 1px dashed var(--wb-color-border-secondary);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.help-feedback-panel .help-feedback-panel__footer-separator {
|
||||
color: var(--wb-color-text-disabled);
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
@@ -165,3 +165,12 @@
|
||||
/* 未接入行为保持原版形态,但禁用交互(与通用页约定一致)。 */
|
||||
.personalization-panel [data-settings-unavailable=true] { cursor: default }
|
||||
.personalization-panel [data-settings-unavailable=true] .wb-switch { cursor: default }
|
||||
|
||||
/*
|
||||
* 原版长卡左右各 8px 内边距(预览 598 = 614 − 16)。通用页样式表会被多个面板 @import,
|
||||
* 打包顺序可能排到本页规则之后;这里提高特异性,保证 598×160 的几何不被通用 section 覆盖。
|
||||
*/
|
||||
.general-settings-panel.personalization-panel .local-memory-long .general-settings-panel__section--plain {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
Reference in new issue
Block a user