feat: 刷新按钮改为整页重载;滚动信息间距可配

- 前台刷新按钮改成 window.location.reload(),项目扫描 / 内容库 / 设置 / 主题全部重走
- settings.header 新增 gap(px,默认 26 ≈ 两个中文字宽,最大 120)
- 后台「页头 → 滚动信息」增加「条目间距」输入
This commit is contained in:
2026-11-01 20:44:29 +08:00
parent 0375669a6e
commit 036551ee09
5 changed files with 32 additions and 4 deletions
+6
View File
@@ -50,6 +50,8 @@ pub struct HeaderSettings {
pub enabled: bool, pub enabled: bool,
/// 滚动一轮的秒数 /// 滚动一轮的秒数
pub speed: u32, pub speed: u32,
/// 信息条目之间的间距(px),默认 26 ≈ 两个中文字宽
pub gap: u32,
pub items: Vec<HeaderItem>, pub items: Vec<HeaderItem>,
} }
@@ -58,6 +60,7 @@ impl Default for HeaderSettings {
Self { Self {
enabled: true, enabled: true,
speed: 24, speed: 24,
gap: 26,
items: vec![ items: vec![
HeaderItem { HeaderItem {
text: "共 {count} 个本地应用".into(), text: "共 {count} 个本地应用".into(),
@@ -278,6 +281,9 @@ pub fn validate(settings: &Settings) -> Result<(), StashError> {
"滚动速度需在 {MIN_SPEED}–{MAX_SPEED} 秒之间" "滚动速度需在 {MIN_SPEED}–{MAX_SPEED} 秒之间"
))); )));
} }
if settings.header.gap > 120 {
return Err(StashError::InvalidDirectory("信息间距最多 120".into()));
}
for item in &settings.header.items { for item in &settings.header.items {
let text = item.text.trim(); let text = item.text.trim();
if text.is_empty() { if text.is_empty() {
+4 -3
View File
@@ -267,7 +267,7 @@ export default function AppNext() {
}, []) }, [])
const site: SiteSettings = settings?.settings ?? { const site: SiteSettings = settings?.settings ?? {
header: { enabled: true, speed: 24, items: [] }, header: { enabled: true, speed: 24, gap: 26, items: [] },
sidebar: { sidebar: {
show_profile: true, show_profile: true,
show_service: true, show_service: true,
@@ -666,6 +666,7 @@ export default function AppNext() {
headerItems={site.header.items} headerItems={site.header.items}
headerEnabled={site.header.enabled} headerEnabled={site.header.enabled}
headerSpeed={site.header.speed} headerSpeed={site.header.speed}
headerGap={site.header.gap}
site={site.site} site={site.site}
authenticated={session?.authenticated === true} authenticated={session?.authenticated === true}
username={session?.username ?? undefined} username={session?.username ?? undefined}
@@ -673,8 +674,8 @@ export default function AppNext() {
dark={isDark} dark={isDark}
onToggleTheme={() => void toggleTheme()} onToggleTheme={() => void toggleTheme()}
onRefresh={() => { onRefresh={() => {
refresh() // 刷新 = 整页重载:项目扫描、内容库、设置、主题都重新走一遍
load() window.location.reload()
}} }}
onLogin={() => setLoginOpen(true)} onLogin={() => setLoginOpen(true)}
onLogout={() => { onLogout={() => {
@@ -2057,6 +2057,21 @@ function HeaderPanel({
}} }}
/> />
</FormField> </FormField>
<FormField
label="条目间距"
htmlFor="header-gap"
hint="单位 px;默认 26(约两个中文字宽),最大 120"
>
<Input
id="header-gap"
type="number"
value={String(value.gap ?? 26)}
onChange={(event) => {
const gap = Number(event.target.value)
if (Number.isFinite(gap)) onChange({ ...value, gap })
}}
/>
</FormField>
<Text size="sm" strong> <Text size="sm" strong>
可用通配符 可用通配符
@@ -21,6 +21,8 @@ type SiteHeaderProps = {
headerEnabled: boolean headerEnabled: boolean
/** 滚动一轮的秒数 */ /** 滚动一轮的秒数 */
headerSpeed: number headerSpeed: number
/** 信息条目之间的间距(px) */
headerGap?: number
/** 品牌与操作工具配置 */ /** 品牌与操作工具配置 */
site: SiteMetaSettings site: SiteMetaSettings
/** 是否已登录:决定右侧是「登录」还是「退出登录」 */ /** 是否已登录:决定右侧是「登录」还是「退出登录」 */
@@ -51,6 +53,7 @@ export function SiteHeader({
headerItems, headerItems,
headerEnabled, headerEnabled,
headerSpeed, headerSpeed,
headerGap,
site, site,
authenticated, authenticated,
username, username,
@@ -74,7 +77,7 @@ export function SiteHeader({
/> />
{headerEnabled && ( {headerEnabled && (
<Ticker speed={headerSpeed} label="运行状态"> <Ticker speed={headerSpeed} gap={headerGap} label="运行状态">
{headerItems.map((item, index) => ( {headerItems.map((item, index) => (
<span className="header-ticker-item" key={`${index}-${item.text}`}> <span className="header-ticker-item" key={`${index}-${item.text}`}>
{item.tag !== undefined && item.tag !== null && item.tag !== '' && ( {item.tag !== undefined && item.tag !== null && item.tag !== '' && (
+3
View File
@@ -36,6 +36,8 @@ export type SiteSettings = {
enabled: boolean enabled: boolean
/** 滚动一轮的秒数(8–120) */ /** 滚动一轮的秒数(8–120) */
speed: number speed: number
/** 信息条目之间的间距(px),默认 26 ≈ 两个中文字宽 */
gap: number
items: HeaderItem[] items: HeaderItem[]
} }
sidebar: { sidebar: {
@@ -114,6 +116,7 @@ export function defaultSettings(): SiteSettings {
header: { header: {
enabled: true, enabled: true,
speed: 24, speed: 24,
gap: 26,
items: [ items: [
{ text: '共 {count} 个本地应用', tone: 'plain' }, { text: '共 {count} 个本地应用', tone: 'plain' },
{ text: '{project}', tag: '本地', tone: 'primary' }, { text: '{project}', tag: '本地', tone: 'primary' },