去掉转换入口,加测延迟,改掉刷新时丢状态的毛病
最要紧的是第三条:之前每次改完都会先切到「读取中」,页面被拆掉重建, 选中的那一路入站随之丢失,改个设置还得重新找回原来的位置。现在只有首次加载显示占位, 之后都是原地更新。切换策略组还做成了乐观更新——那一步不写配置文件, 没必要让点击等一个往返,真失败了随后的刷新会纠正回来。 测延迟按钮让内核并发测整个策略组。测不通是关于线路的结论而不是 Patchbay 出了问题, 所以全部超时用中性提示,不弹红框。
This commit is contained in:
+38
-37
@@ -6,7 +6,7 @@ import type { ProxyInfo } from '../api'
|
||||
import IconOffline from '~icons/ri/cloud-off-line'
|
||||
import IconEdit from '~icons/ri/edit-line'
|
||||
import IconDelete from '~icons/ri/delete-bin-line'
|
||||
import IconConvert from '~icons/ri/swap-line'
|
||||
import IconFlash from '~icons/ri/flashlight-line'
|
||||
|
||||
const props = defineProps<{
|
||||
inbound: Inbound
|
||||
@@ -19,14 +19,16 @@ const props = defineProps<{
|
||||
runtime: Record<string, ProxyInfo>
|
||||
kernelOnline: boolean
|
||||
saving: boolean
|
||||
/** 正在测延迟 */
|
||||
testing: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
pick: [mode: OutboundMode]
|
||||
edit: []
|
||||
remove: []
|
||||
convert: []
|
||||
select: [group: string, member: string]
|
||||
test: [group: string]
|
||||
}>()
|
||||
|
||||
/**
|
||||
@@ -175,7 +177,18 @@ function delayClass(ms: number | null): string {
|
||||
</p>
|
||||
|
||||
<template v-if="switchable">
|
||||
<h4>{{ switchable.group }} 当前选中</h4>
|
||||
<div class="sub-head">
|
||||
<h4>{{ switchable.group }} 当前选中</h4>
|
||||
<button
|
||||
type="button"
|
||||
class="flash"
|
||||
:disabled="testing"
|
||||
:title="`测试 ${switchable.group} 里所有线路的延迟`"
|
||||
@click="emit('test', switchable.group)"
|
||||
>
|
||||
<IconFlash />
|
||||
</button>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<button
|
||||
v-for="m in switchable.members"
|
||||
@@ -198,15 +211,9 @@ function delayClass(ms: number | null): string {
|
||||
<section class="pick">
|
||||
<h3>出站</h3>
|
||||
|
||||
<div v-if="locked" class="convert">
|
||||
<p>
|
||||
由 <code>{{ inbound.legacyKey }}</code> 声明,这种写法没有 proxy 字段,出站固定是
|
||||
<span class="mono">RULE</span>,下面这些都不能选。
|
||||
</p>
|
||||
<button type="button" :disabled="saving" @click="emit('convert')">
|
||||
<IconConvert /> 转成命名入站
|
||||
</button>
|
||||
</div>
|
||||
<p v-if="locked" class="aside-note">
|
||||
由 <code>{{ inbound.legacyKey }}</code> 声明,这种写法没有 proxy 字段,出站固定是 RULE
|
||||
</p>
|
||||
|
||||
<div v-if="!locked" class="grid">
|
||||
<button
|
||||
@@ -373,43 +380,37 @@ function delayClass(ms: number | null): string {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.convert {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: var(--s-3);
|
||||
padding: var(--s-3);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: var(--r-sm);
|
||||
background: var(--c-surface-sunken);
|
||||
margin-bottom: var(--s-4);
|
||||
.is-dim {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.convert p {
|
||||
color: var(--c-text-soft);
|
||||
font-size: var(--t-sm);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.convert button {
|
||||
.sub-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--s-2);
|
||||
padding: var(--s-2) var(--s-3);
|
||||
border: 1px solid var(--c-border-strong);
|
||||
}
|
||||
|
||||
.flash {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--r-sm);
|
||||
background: var(--c-surface);
|
||||
font-size: var(--t-sm);
|
||||
background: none;
|
||||
color: var(--c-text-faint);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.convert button:hover:not(:disabled) {
|
||||
border-color: var(--c-accent);
|
||||
.flash:hover:not(:disabled) {
|
||||
background: var(--c-accent-soft);
|
||||
color: var(--c-accent-text);
|
||||
}
|
||||
|
||||
.is-dim {
|
||||
opacity: 0.6;
|
||||
.flash:disabled {
|
||||
cursor: progress;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.pick {
|
||||
|
||||
Reference in New Issue
Block a user