Prevent duplicate server display during profile transitions
Build and Deploy Gateway / build-and-push (push) Successful in 26s
Build and Deploy Gateway / deploy (push) Successful in 6s

This commit is contained in:
2026-08-11 08:02:17 +03:00
parent 9ad0307333
commit 444f26c401
8 changed files with 33 additions and 31 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
export const HARBOR_VERSIONS = Object.freeze({
macClient: '0.23.5',
gatewayClient: '0.24.5',
macClient: '0.23.6',
gatewayClient: '0.24.6',
gatewayBackend: '0.24.0',
});
@@ -728,6 +728,7 @@ export function ClientOverviewPage({
prompt={!profile.desiredServerId}
leaving={pickerState.leaving}
revealVersion={pickerState.revealVersion}
anchorServerId={pickerState.anchorServerId}
onSelect={(serverId) => selectServer(profile, serverId)}
/>}
/>
+8 -6
View File
@@ -167,6 +167,7 @@ interface ServerPickerProps {
prompt: boolean;
leaving: boolean;
revealVersion: number;
anchorServerId?: string;
onSelect: (id: string) => unknown;
}
@@ -179,6 +180,7 @@ export function ServerPicker({
prompt,
leaving,
revealVersion,
anchorServerId = '',
onSelect,
}: ServerPickerProps) {
const favoritesKey = `${FAVORITES_KEY}:${profileId}`;
@@ -207,7 +209,7 @@ export function ServerPicker({
if (view === 'recent') return recent.flatMap((id) => found.find((server) => server.id === id) || []);
return found;
}, [servers, query, view, favorites, recent]);
const results = filtered.filter(({ id }) => id !== selectedServerId);
const results = filtered.filter(({ id }) => id !== selectedServerId && id !== anchorServerId);
const pageCount = Math.max(1, Math.ceil(results.length / SERVER_RESULT_WINDOW));
const visible = results.slice(page * SERVER_RESULT_WINDOW, (page + 1) * SERVER_RESULT_WINDOW);
const grouped = servers.length >= 10;
@@ -282,7 +284,7 @@ export function ServerPicker({
<ServerCheckButton checking={checking} onClick={checkVisible} />
</div>
<div className="client-server-grid">
<ServerRow
{servers[0].id !== anchorServerId && <ServerRow
server={servers[0]}
selected={servers[0].id === selectedServerId}
favorite={false}
@@ -290,7 +292,7 @@ export function ServerPicker({
disabled={disabled}
index={0}
onSelect={onSelect}
/>
/>}
</div>
</section>;
}
@@ -310,8 +312,8 @@ export function ServerPicker({
));
const simpleServers = [
...(selected ? [selected] : []),
...servers.filter(({ id }) => id !== selectedServerId),
...(selected && selected.id !== anchorServerId ? [selected] : []),
...servers.filter(({ id }) => id !== selectedServerId && id !== anchorServerId),
].slice(0, SIMPLE_SERVER_LIMIT);
return <section className={`client-servers is-scalable${servers.length <= SIMPLE_SERVER_LIMIT ? ' is-short' : ''}`} aria-label="Выберите сервер">
@@ -403,7 +405,7 @@ export function ServerPicker({
fallback={autoActive ? undefined : 'Первый стабильный сервер'}
/>
</button>
{selected && <ServerRow
{selected && selected.id !== anchorServerId && <ServerRow
server={selected}
selected
favorite={favorites.includes(selected.id)}
@@ -29,6 +29,7 @@ interface ServerPickerRenderState {
disabled: boolean;
leaving: boolean;
revealVersion: number;
anchorServerId: string;
}
interface SubscriptionFeatureOptions {
@@ -464,9 +465,11 @@ function ProfileGroup({
{localStatus && <div className="client-profile-local-status" role="status">{localStatus}</div>}
{!expanded && !closing && visibleServer && <button
{visibleServer && <button
className="client-profile-selected-server"
type="button"
aria-expanded={expanded}
aria-controls={`client-profile-${profile.id}`}
onClick={() => feature.toggleProfile(profile.id)}
>
<span aria-hidden="true" />
@@ -486,6 +489,7 @@ function ProfileGroup({
disabled: controlsBlocked,
leaving: false,
revealVersion: feature.revealVersions[profile.id] || 0,
anchorServerId: visibleServer?.id || '',
})}
</div>
</div>}
+1 -9
View File
@@ -82,6 +82,7 @@
min-height: 48px;
display: grid;
grid-template-columns: 18px minmax(0, 1fr);
column-gap: 6px;
align-items: center;
padding: 4px 0 4px 8px;
border: 0;
@@ -278,15 +279,6 @@
font: inherit;
text-align: left;
cursor: pointer;
animation: client-profile-selected-in 260ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes client-profile-selected-in {
from {
opacity: 0;
filter: blur(3px);
transform: translateY(-4px);
}
}
.client-profile-selected-server > span {