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