设置页重做:配置文件下载上传、内核参数、资源、免责声明
配置每次落盘都打顶层 patchbay: 标记(盐加版本的哈希)。内核忽略未知 顶层键(yaml.Unmarshal 没开严格模式,config/config.go:612)。刻意不对 内容做哈希:本项目只接管部分段落,手改其余段落是正常用法,内容哈希 会把合法手改判成无效。上传配置时靠标记分流:有标记的确认后替换, 没有的用更重的措辞确认导入;两者都走 config-store 完整保护链路 (新端点 POST /api/config/import)。自动备份列表从界面撤下,改成 下载当前配置 + 拖放上传。 内核参数一组编辑五个老式顶层端口和 keep-alive-interval(config.go:444, 整数秒),走带基准指纹的保存链路。资源一组接 POST /configs/geo (同步接口,透传给了 300 秒超时)。测速地址成为本地偏好,延迟测试 读它;prefs 模块顶层的浏览器全局加了存在性守卫——api.ts 开始引用 prefs,而 bun test 环境没有 localStorage。 退出登录挪到侧栏底部;密度设置从设置页撤下(侧栏按钮还在); 免责声明和关于做成子页(左上角返回),登录页输入框下加同一份 免责声明的弹层入口。
This commit is contained in:
+106
-1
@@ -1,8 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import { DISCLAIMER, DISCLAIMER_TITLE } from '../legal'
|
||||
import IconClose from '~icons/ri/close-line'
|
||||
|
||||
const emit = defineEmits<{ submit: [token: string] }>()
|
||||
const value = ref('')
|
||||
|
||||
const legalOpen = ref(false)
|
||||
const legalDialog = ref<HTMLDialogElement | null>(null)
|
||||
|
||||
watch(legalOpen, (open) => {
|
||||
if (open) legalDialog.value?.showModal()
|
||||
else legalDialog.value?.close()
|
||||
})
|
||||
|
||||
/** 点在遮罩上就关闭。内容区的点击 target 是里面的元素,到不了 dialog 本身。 */
|
||||
function onBackdrop(event: MouseEvent) {
|
||||
if (event.target === legalDialog.value) legalOpen.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -23,7 +38,26 @@ const value = ref('')
|
||||
<p class="where">
|
||||
令牌位于服务端配置文件的同级目录 <code>.patchbay-token</code>,启动时也会输出到控制台。
|
||||
</p>
|
||||
<button type="button" class="legal" @click="legalOpen = true">
|
||||
使用 Patchbay 即视为同意《免责声明》
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<dialog
|
||||
ref="legalDialog"
|
||||
class="dlg"
|
||||
@click="onBackdrop"
|
||||
@close="legalOpen = false"
|
||||
@cancel.prevent="legalOpen = false"
|
||||
>
|
||||
<div class="dlg-body">
|
||||
<header class="dlg-head">
|
||||
<h2>{{ DISCLAIMER_TITLE }}</h2>
|
||||
<button type="button" class="x" @click="legalOpen = false"><IconClose /></button>
|
||||
</header>
|
||||
<p v-for="(para, i) in DISCLAIMER" :key="i" class="para">{{ para }}</p>
|
||||
</div>
|
||||
</dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -85,4 +119,75 @@ h1 {
|
||||
line-height: 1.6;
|
||||
margin-top: var(--s-2);
|
||||
}
|
||||
|
||||
.legal {
|
||||
align-self: flex-start;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--c-text-faint);
|
||||
font-size: var(--t-xs);
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
.legal:hover {
|
||||
color: var(--c-text-soft);
|
||||
}
|
||||
|
||||
.dlg {
|
||||
width: min(480px, calc(100vw - 2 * var(--s-5)));
|
||||
padding: 0;
|
||||
border: 1px solid var(--c-border-strong);
|
||||
border-radius: var(--r-lg);
|
||||
background: var(--c-surface);
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
.dlg::backdrop {
|
||||
background: rgb(0 0 0 / 0.45);
|
||||
}
|
||||
|
||||
.dlg-body {
|
||||
padding: var(--s-5);
|
||||
}
|
||||
|
||||
.dlg-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: var(--s-3);
|
||||
}
|
||||
|
||||
.dlg-head h2 {
|
||||
font-size: var(--t-lg);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.x {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--r-sm);
|
||||
background: none;
|
||||
color: var(--c-text-faint);
|
||||
cursor: pointer;
|
||||
}
|
||||
.x:hover {
|
||||
background: var(--c-surface-sunken);
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
.para {
|
||||
color: var(--c-text-soft);
|
||||
font-size: var(--t-sm);
|
||||
line-height: var(--line);
|
||||
}
|
||||
|
||||
.para + .para {
|
||||
margin-top: var(--s-3);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user