diff --git a/src/server/features/subscription/subscriptionService.ts b/src/server/features/subscription/subscriptionService.ts index 2023e19..9bf58f9 100644 --- a/src/server/features/subscription/subscriptionService.ts +++ b/src/server/features/subscription/subscriptionService.ts @@ -199,11 +199,16 @@ export function createSubscriptionService(dependencies: SubscriptionServiceDepen if (!profile.servers.some((server) => server.id === serverId)) { throw new HarborError('SERVER_NOT_FOUND'); } - if (profile.desiredServerId === serverId) return mutationResult(profile); - const selected = { ...profile, desiredServerId: serverId }; + if (profile.desiredServerId === serverId && state.desiredProfileId === profile.id) { + return mutationResult(profile); + } + const selected = profile.desiredServerId === serverId + ? profile + : { ...profile, desiredServerId: serverId }; dependencies.state.update((current) => ({ ...current, profiles: replaceProfile(current, selected), + desiredProfileId: profile.id, })); return mutationResult(selected); }); diff --git a/src/shared/versions.ts b/src/shared/versions.ts index 49f8015..60f6293 100644 --- a/src/shared/versions.ts +++ b/src/shared/versions.ts @@ -1,7 +1,7 @@ export const HARBOR_VERSIONS = Object.freeze({ - macClient: '0.23.11', - gatewayClient: '0.24.11', - gatewayBackend: '0.24.0', + macClient: '0.24.0', + gatewayClient: '0.25.0', + gatewayBackend: '0.25.0', }); export interface ParsedVersion { diff --git a/src/web/App.tsx b/src/web/App.tsx index 89d9b2c..528f19b 100644 --- a/src/web/App.tsx +++ b/src/web/App.tsx @@ -255,13 +255,6 @@ export function App() { `${profileId}:${serverId}`, profileId, )} - onActivateProfile={(profileId: string) => run( - 'profileActivate', - () => api.profiles.activate(profileId, revisionRef.current), - 'connection', - profileId, - profileId, - )} onRefreshProfile={(profileId: string) => run( 'profileRefresh', () => api.profiles.refresh(profileId, revisionRef.current), diff --git a/src/web/components/ClientOverviewPage.tsx b/src/web/components/ClientOverviewPage.tsx index 990ad77..092370e 100644 --- a/src/web/components/ClientOverviewPage.tsx +++ b/src/web/components/ClientOverviewPage.tsx @@ -105,7 +105,6 @@ interface ClientOverviewPageProps { error: UiError | null; onAddProfile: (label: string, url: string) => Promise; onSelectProfileServer: (profileId: string, serverId: string) => Promise; - onActivateProfile: (profileId: string) => Promise; onRefreshProfile: (profileId: string) => Promise; onForgetProfile: (profileId: string, mode: 'delete' | 'stop-and-delete') => Promise; onApply: (profileId: string, serverId: string) => Promise; @@ -411,7 +410,6 @@ export function ClientOverviewPage({ error, onAddProfile, onSelectProfileServer, - onActivateProfile, onRefreshProfile, onForgetProfile, onApply, @@ -494,7 +492,6 @@ export function ClientOverviewPage({ onAdd: onAddProfile, onRefresh: onRefreshProfile, onForget: onForgetProfile, - onActivate: onActivateProfile, onDismissError, }); const routingFeature = useRoutingFeature({ @@ -553,7 +550,7 @@ export function ClientOverviewPage({ }, []); function selectServer(profile: ProfileSnapshot, serverId: string) { - if (connected && !gatewayDirect && state.selection.appliedProfileId === profile.id) { + if (connected && !gatewayDirect) { onApply(profile.id, serverId); return; } @@ -723,9 +720,9 @@ export function ClientOverviewPage({ profileId={profile.id} pingServers={actions.pingServers} servers={profile.servers} - selectedServerId={profile.desiredServerId} + selectedServerId={pickerState.selectedServerId} disabled={serverApplyBlocked || pickerState.disabled} - prompt={!profile.desiredServerId} + prompt={!pickerState.selectedServerId} leaving={pickerState.leaving} revealVersion={pickerState.revealVersion} anchorServerId={pickerState.anchorServerId} diff --git a/src/web/features/subscription/SubscriptionFeature.tsx b/src/web/features/subscription/SubscriptionFeature.tsx index 7aec5fb..ad816ac 100644 --- a/src/web/features/subscription/SubscriptionFeature.tsx +++ b/src/web/features/subscription/SubscriptionFeature.tsx @@ -32,6 +32,7 @@ interface ServerPickerRenderState { leaving: boolean; revealVersion: number; anchorServerId: string; + selectedServerId: string; } interface SubscriptionFeatureOptions { @@ -45,7 +46,6 @@ interface SubscriptionFeatureOptions { onAdd: (label: string, url: string) => Promise; onRefresh: (profileId: string) => Promise; onForget: (profileId: string, mode: 'delete' | 'stop-and-delete') => Promise; - onActivate: (profileId: string) => Promise; onDismissError: () => void; } @@ -64,7 +64,6 @@ export function useSubscriptionFeature({ onAdd, onRefresh, onForget, - onActivate, onDismissError, }: SubscriptionFeatureOptions) { const [open, setOpen] = useState(false); @@ -281,7 +280,6 @@ export function useSubscriptionFeature({ addBlocked: operationBlocked(operations, 'profileAdd'), refreshBlocked: operationBlocked(operations, 'profileRefresh'), deleteBlocked: operationBlocked(operations, 'profileDelete'), - activateBlocked: operationBlocked(operations, 'profileActivate'), toggle: () => setOpen((current) => !current), close: () => setOpen(false), showAdd, @@ -296,7 +294,6 @@ export function useSubscriptionFeature({ cancelDelete: () => setDeleteId(''), confirmDelete, refresh, - onActivate, }; } @@ -394,8 +391,9 @@ function ProfileGroup({ const refreshing = feature.refreshingIds.includes(profile.id) || feature.operations.profileRefresh?.target === profile.id; const controlsBlocked = operationBlocked(feature.operations, 'profileSelect'); - const selectedServer = profileServer(profile, profile.desiredServerId); - const visibleServerId = applied ? feature.selection.appliedServerId : profile.desiredServerId; + const visibleServerId = applied + ? feature.selection.appliedServerId + : desired ? profile.desiredServerId : ''; const visibleServer = profileServer(profile, visibleServerId) || (applied && feature.selection.appliedServerSnapshot?.id === visibleServerId ? feature.selection.appliedServerSnapshot @@ -403,7 +401,6 @@ function ProfileGroup({ const visibleServerLocation = [visibleServer?.city, visibleServer?.country] .filter((value): value is string => typeof value === 'string' && Boolean(value)) .join(' · '); - const canActivate = !applied && feature.selection.desiredProfileId !== profile.id; const localStatus = profileError?.message || (profile.subscription.status === 'stale' ? `Последнее обновление не удалось. Данные от ${profile.subscription.fetchedAt ? new Date(profile.subscription.fetchedAt).toLocaleString('ru-RU', { dateStyle: 'short', timeStyle: 'short' }) @@ -431,12 +428,7 @@ function ProfileGroup({ {profileDetails} - {canActivate ? : } + {(applied || desired) && }