Refactor server picker and limit ping requests
This commit is contained in:
@@ -16,6 +16,7 @@ import { formatBytes } from '../utils/format.js';
|
||||
import { instructionBlocks } from '../instructions.js';
|
||||
import { operationBlocked } from '../state/operations.js';
|
||||
import { ConfirmationPopup } from './ConfirmationPopup.jsx';
|
||||
import { ServerPicker } from './ServerPicker.jsx';
|
||||
import { canAppendRouteRule } from '../../shared/routingRules.js';
|
||||
import {
|
||||
HARBOR_VERSIONS,
|
||||
@@ -623,7 +624,6 @@ export function ClientOverviewPage({
|
||||
const [editingSubscription, setEditingSubscription] = useState(!state?.hasSubscription);
|
||||
const [showIntro, setShowIntro] = useState(!hasSubscription);
|
||||
const [subscriptionContentReady, setSubscriptionContentReady] = useState(hasSubscription);
|
||||
const [pings, setPings] = useState({});
|
||||
const [accessTab, setAccessTab] = useState('gateway');
|
||||
const [copyFeedback, setCopyFeedback] = useState(null);
|
||||
const [refreshingInfo, setRefreshingInfo] = useState(false);
|
||||
@@ -648,7 +648,6 @@ export function ClientOverviewPage({
|
||||
const localRulesCloseRef = useRef(null);
|
||||
const localRulesBaselineRef = useRef('[]');
|
||||
const previousHasSubscriptionRef = useRef(hasSubscription);
|
||||
const serverKey = servers.map((server) => server.id).join('|');
|
||||
const gatewayAddress = isGateway ? window.location.hostname : '127.0.0.1';
|
||||
const proxyUrls = localProxyUrls(state?.proxyPort, gatewayAddress);
|
||||
const usage = subscriptionUsage(state?.userInfo);
|
||||
@@ -695,31 +694,6 @@ export function ClientOverviewPage({
|
||||
return () => clearInterval(timer);
|
||||
}, [connected, state?.singboxStartedAt]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!servers.length) {
|
||||
setPings({});
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
setPings(Object.fromEntries(servers.map((server) => [server.id, { checking: true }])));
|
||||
api.servers.pingAll()
|
||||
.then((data) => {
|
||||
if (cancelled) return;
|
||||
setPings(Object.fromEntries((data.results || []).map((ping) => [
|
||||
ping.id || ping.tag,
|
||||
ping,
|
||||
])));
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
setPings(Object.fromEntries(servers.map((server) => [server.id, { ok: false }])));
|
||||
}
|
||||
});
|
||||
|
||||
return () => { cancelled = true; };
|
||||
}, [serverKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (editingSubscription) subscriptionInputRef.current?.focus();
|
||||
}, [editingSubscription]);
|
||||
@@ -916,7 +890,7 @@ export function ClientOverviewPage({
|
||||
requestAnimationFrame(() => setUsageUpdated(true));
|
||||
setTimeout(() => setUsageUpdated(false), 900);
|
||||
setServersLeaving(true);
|
||||
await new Promise((resolve) => setTimeout(resolve, 420 + Math.max(0, servers.length - 1) * 90));
|
||||
await new Promise((resolve) => setTimeout(resolve, 420 + Math.min(7, Math.max(0, servers.length - 1)) * 90));
|
||||
setServerRevealVersion((version) => version + 1);
|
||||
setServersLeaving(false);
|
||||
} finally {
|
||||
@@ -1376,40 +1350,15 @@ export function ClientOverviewPage({
|
||||
)}
|
||||
|
||||
{hasSubscription && subscriptionContentReady && (
|
||||
<section className="client-servers" aria-label="Выберите сервер">
|
||||
{!showPower && <span className="client-server-prompt">Выберите сервер</span>}
|
||||
<div
|
||||
className={`client-server-grid${serversLeaving ? ' is-leaving' : ''}`}
|
||||
key={`${serverKey}:${serverRevealVersion}`}
|
||||
>
|
||||
{servers.map((server, index) => {
|
||||
const ping = pings[server.id];
|
||||
const selected = server.id === selectedServerId;
|
||||
const pingText = ping?.checking
|
||||
? 'Проверка…'
|
||||
: ping?.ok ? `${ping.latency} ms` : 'Недоступен';
|
||||
const pingClass = ping?.ok
|
||||
? ping.latency < 100 ? 'good' : ping.latency < 250 ? 'medium' : 'slow'
|
||||
: '';
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`client-server ${selected ? 'is-selected' : ''}`}
|
||||
type="button"
|
||||
key={server.id}
|
||||
disabled={serverApplyBlocked}
|
||||
aria-pressed={selected}
|
||||
aria-label={`${server.label}, ${server.host}:${server.port}, ${pingText}`}
|
||||
style={{ '--server-index': index }}
|
||||
onClick={() => selectServer(server.id)}
|
||||
>
|
||||
<strong>{server.label}</strong>
|
||||
<small className={pingClass}>{pingText}</small>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
<ServerPicker
|
||||
servers={servers}
|
||||
selectedServerId={selectedServerId}
|
||||
disabled={serverApplyBlocked}
|
||||
prompt={!showPower}
|
||||
leaving={serversLeaving}
|
||||
revealVersion={serverRevealVersion}
|
||||
onSelect={selectServer}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user