轻提示铺开到全部页面;内核状态悬停变重启;GEO 支持单文件下载
侧栏动作排撤掉重启图标,内核状态(圆点加版本号)本身变成按钮:悬停 换层显示「重启内核」,不在线时只当状态看。行高压成 1 修掉圆点和等宽 字体不居中的问题。 四个页面的一次性反馈(保存、删除、更新订阅、断开连接、测延迟结论) 全部改走 toast,commit() 改返回成败给「失败不关对话框」用;持续状态 (连接页轮询失败、请求页日志流失败)留在页内,会自动消失的提示装不下 需要一直可见的信息。toast 加 info 类别给中性结论用。 GEO 每行的更新改成单独下载那一个文件:内核只有全量更新的口子,单文件 只能服务端自己下(POST /api/geo/sync),代价是只有形状校验(MaxMind 末尾标记、geodata 首字节,shared/geo.ts 带测试)且内核重启后才换用新 文件;「更新全部」文字按钮保留内核的全量口子,有完整校验和热加载。 上传两行的按钮改「选择或拖放文件」,投放区拖入高亮,恢复策略挪到 恢复行下方。
This commit is contained in:
+69
-12
@@ -271,22 +271,23 @@ const current = computed(() => NAV.find((n) => n.key === active.value))
|
||||
>
|
||||
<IconReload />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="side-foot">
|
||||
<!-- 平时是内核状态,悬停变成重启入口。内核不在线时只当状态看 -->
|
||||
<button
|
||||
type="button"
|
||||
class="act"
|
||||
class="kernel-btn"
|
||||
:title="kernel.online ? '重启内核' : '内核未连接'"
|
||||
:disabled="!kernel.online"
|
||||
@click="askRestart = true"
|
||||
>
|
||||
<IconRestart />
|
||||
<span class="k-idle">
|
||||
<span :class="['dot', kernel.online ? 'dot-ok' : 'dot-off']" aria-hidden="true"></span>
|
||||
<span class="kernel-text mono">{{ kernel.online ? kernel.version : 'offline' }}</span>
|
||||
</span>
|
||||
<span class="k-hot" aria-hidden="true"><IconRestart class="k-ico" /> 重启内核</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="side-foot">
|
||||
<div class="kernel" :title="kernel.online ? kernel.version : '内核未连接'">
|
||||
<span :class="['dot', kernel.online ? 'dot-ok' : 'dot-off']" aria-hidden="true"></span>
|
||||
<span class="kernel-text mono">{{ kernel.online ? kernel.version : 'offline' }}</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="densify"
|
||||
@@ -466,13 +467,13 @@ const current = computed(() => NAV.find((n) => n.key === active.value))
|
||||
/* 收拢时淡出的文字。比外层宽度的 0.3s 快,字先消失、再收边,不露半截字 */
|
||||
.brand-name,
|
||||
.nav-label,
|
||||
.kernel {
|
||||
.kernel-btn {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.is-compact .brand-name,
|
||||
.is-compact .nav-label,
|
||||
.is-compact .kernel {
|
||||
.is-compact .kernel-btn {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@@ -579,13 +580,69 @@ const current = computed(() => NAV.find((n) => n.key === active.value))
|
||||
padding: 0 44px 0 var(--s-2);
|
||||
}
|
||||
|
||||
.kernel {
|
||||
/* 内核状态兼重启按钮:两层叠在同一格里,悬停换层 */
|
||||
.kernel-btn {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 26px;
|
||||
padding: 0 var(--s-2);
|
||||
border: none;
|
||||
border-radius: var(--r-sm);
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
}
|
||||
.kernel-btn:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
.kernel-btn:hover:not(:disabled) {
|
||||
background: var(--c-surface-sunken);
|
||||
}
|
||||
|
||||
.k-idle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--s-2);
|
||||
min-width: 0;
|
||||
color: var(--c-text-faint);
|
||||
font-size: var(--t-xs);
|
||||
/* 等宽字体的行框上下不对称,压成 1 让点和文字真正居中 */
|
||||
line-height: 1;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
.k-hot {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--s-2);
|
||||
padding: 0 var(--s-2);
|
||||
color: var(--c-text-soft);
|
||||
font-size: var(--t-xs);
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.kernel-btn:hover:not(:disabled) .k-idle,
|
||||
.kernel-btn:focus-visible:not(:disabled) .k-idle {
|
||||
opacity: 0;
|
||||
}
|
||||
.kernel-btn:hover:not(:disabled) .k-hot,
|
||||
.kernel-btn:focus-visible:not(:disabled) .k-hot {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.k-ico {
|
||||
flex: none;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.dot {
|
||||
|
||||
Reference in New Issue
Block a user