Add gateway auto toggle for client mode
This commit is contained in:
@@ -73,20 +73,45 @@ function DurationPart({ name, children }) {
|
||||
);
|
||||
}
|
||||
|
||||
function HarborBrand({ isGateway }) {
|
||||
function HarborBrand({ isGateway, gatewayAvailable, gatewayDirect, busy, onSetGatewayAuto }) {
|
||||
const product = isGateway ? 'Gateway' : 'Connect';
|
||||
const switchable = !isGateway && gatewayAvailable;
|
||||
const label = gatewayDirect
|
||||
? 'Игнорировать Harbor Gateway и использовать локальный VPN'
|
||||
: 'Использовать обнаруженный Harbor Gateway';
|
||||
|
||||
const content = <div className="harbor-brand-content">
|
||||
<svg viewBox="0 0 32 32" aria-hidden="true">
|
||||
<circle cx="16" cy="6" r="3" />
|
||||
<path d="M16 9v15M10 14h12" />
|
||||
<path className="harbor-anchor-left" d="M16 28C11 28 8.4 25.2 6.3 22v-3.3M3.8 21.4l2.5-2.7 2.5 2.7" />
|
||||
<path className="harbor-anchor-right" d="M16 28C21 28 23.6 25.2 25.7 22v-3.3M23.2 21.4l2.5-2.7 2.5 2.7" />
|
||||
</svg>
|
||||
<span className="harbor-brand-name">
|
||||
<strong>Harbor</strong>
|
||||
{switchable ? <span className="harbor-mode-stack" aria-hidden="true">
|
||||
<em className="harbor-mode-connect">Connect</em>
|
||||
<em className="harbor-mode-gateway">Gateway</em>
|
||||
</span> : <em>{product}</em>}
|
||||
</span>
|
||||
{switchable && <svg className="harbor-mode-swap" viewBox="0 0 18 18" aria-hidden="true">
|
||||
<path d="M3 6h10m-3-3 3 3-3 3M15 12H5m3 3-3-3 3-3" />
|
||||
</svg>}
|
||||
</div>;
|
||||
|
||||
return (
|
||||
<div className={`harbor-brand is-${product.toLowerCase()}`} aria-label={`Harbor ${product}`}>
|
||||
<div className="harbor-brand-content">
|
||||
<svg viewBox="0 0 32 32" aria-hidden="true">
|
||||
<circle cx="16" cy="6" r="3" />
|
||||
<path d="M16 9v15M10 14h12" />
|
||||
<path className="harbor-anchor-left" d="M16 28C11 28 8.4 25.2 6.3 22v-3.3M3.8 21.4l2.5-2.7 2.5 2.7" />
|
||||
<path className="harbor-anchor-right" d="M16 28C21 28 23.6 25.2 25.7 22v-3.3M23.2 21.4l2.5-2.7 2.5 2.7" />
|
||||
</svg>
|
||||
<span><strong>Harbor</strong> <em>{product}</em></span>
|
||||
</div>
|
||||
<div className={`harbor-brand is-${product.toLowerCase()}${switchable ? ` is-switchable${gatewayDirect ? ' is-gateway-active' : ''}` : ''}`}>
|
||||
{switchable ? <button
|
||||
className="harbor-brand-control"
|
||||
type="button"
|
||||
aria-label={label}
|
||||
aria-pressed={gatewayDirect}
|
||||
title={label}
|
||||
disabled={busy}
|
||||
onClick={() => onSetGatewayAuto(!gatewayDirect)}
|
||||
>
|
||||
{content}
|
||||
</button> : <div aria-label={`Harbor ${product}`}>{content}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -106,9 +131,11 @@ export function ClientOverviewPage({
|
||||
onApply,
|
||||
onRestart,
|
||||
onStop,
|
||||
onSetGatewayAuto,
|
||||
}) {
|
||||
const isGateway = state?.mode === 'gateway';
|
||||
const gatewayDirect = !isGateway && state?.gatewayAuto?.mode === 'gateway-direct';
|
||||
const gatewayAvailable = !isGateway && Boolean(state?.gatewayAuto?.available);
|
||||
const connected = Boolean(state?.singboxRunning);
|
||||
const hasSubscription = Boolean(state?.hasSubscription);
|
||||
const selectedTag = pendingTag || state?.selectedTag || '';
|
||||
@@ -387,7 +414,13 @@ export function ClientOverviewPage({
|
||||
|
||||
return (
|
||||
<div className={`client-shell${hasSubscription ? '' : ' is-first-run'}${showIntro && !hasSubscription ? ' is-intro' : ''}`}>
|
||||
<HarborBrand isGateway={isGateway} />
|
||||
<HarborBrand
|
||||
isGateway={isGateway}
|
||||
gatewayAvailable={gatewayAvailable}
|
||||
gatewayDirect={gatewayDirect}
|
||||
busy={busy}
|
||||
onSetGatewayAuto={onSetGatewayAuto}
|
||||
/>
|
||||
{hasSubscription && subscriptionContentReady && <button
|
||||
ref={instructionsToggleRef}
|
||||
className={`client-instructions-toggle${instructionsOpen ? ' is-open' : ''}`}
|
||||
|
||||
Reference in New Issue
Block a user