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 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() {
|
||||||
|
|||||||
@@ -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 !== '' && (
|
||||||
|
|||||||
@@ -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' },
|
||||||
|
|||||||
Reference in New Issue
Block a user