fix(tailshare): move configAtBuildRef to IpnProvider level
CI / typetest (pull_request) Successful in 1m32s
CI / typecheck (pull_request) Successful in 1m39s
CI / node-tests (pull_request) Successful in 1m41s
CI / browser-tests (pull_request) Successful in 3m4s
CI / lint (pull_request) Successful in 1m34s
CI / format (pull_request) Successful in 1m34s
CI / install (pull_request) Successful in 4m58s

configAtBuildRef was local to TailscaleConfig, so navigating away from
/tailscale and back would remount the component and reset the ref, making
the restart-required banner disappear even if the config had changed.

Moving configAtBuild into IpnPrepareContext keeps it alive for the
lifetime of the provider.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 22:26:58 +00:00
co-authored by Claude
parent b1c9c2eac6
commit 6c0b8ec3b9
2 changed files with 9 additions and 10 deletions
@@ -70,6 +70,7 @@ function parseConfig(raw: string): TailshareConfig {
export const IpnPrepareContext = createContext<{
config: TailshareConfig
configAtBuild: TailshareConfig | null
setConfig: (patch: Partial<TailshareConfig>) => void
willBuild: boolean
build: () => void
@@ -162,9 +163,13 @@ export function IpnProvider({ children }: { children: ReactNode }) {
if (typeof window !== "undefined") Object.assign(window, { ipn })
const configAtBuildRef = useRef<TailshareConfig | null>(null)
if (willBuild && !configAtBuildRef.current) configAtBuildRef.current = config
const configAtBuild = configAtBuildRef.current
const prepare = useMemo<NonNullable<ContextType<typeof IpnPrepareContext>>>(
() => ({ config, setConfig, willBuild, build, workerAvailable, connectionMode }),
[config, setConfig, willBuild, build, workerAvailable, connectionMode],
() => ({ config, configAtBuild, setConfig, willBuild, build, workerAvailable, connectionMode }),
[config, configAtBuild, setConfig, willBuild, build, workerAvailable, connectionMode],
)
return (
+2 -8
View File
@@ -30,7 +30,7 @@ import {
getWaitingFiles,
} from "@webnet/tsconnect-redux"
import { IpnContext, IpnPrepareContext, useIpnSelector } from "../contexts/IpnContext"
import { use, useRef } from "react"
import { use } from "react"
import styles from "./tailscale.scss"
import { CopyIcon, DownloadIcon, TrashIcon } from "@phosphor-icons/react"
import { useDisclosure } from "@mantine/hooks"
@@ -91,13 +91,7 @@ function TailscaleConfig() {
const dispatch = useTailshareDispatch()
const ipn = use(IpnContext)
const prepare = use(IpnPrepareContext)!
const { config, setConfig, workerAvailable, connectionMode } = prepare
const configAtBuildRef = useRef<typeof config | null>(null)
if (prepare.willBuild && !configAtBuildRef.current) {
configAtBuildRef.current = config
}
const built = configAtBuildRef.current
const { config, configAtBuild: built, setConfig, workerAvailable, connectionMode } = prepare
const requireRestart =
built &&
(config.hostname !== built.hostname ||