@@ -32,9 +32,6 @@ export interface ProxyContextValue {
3232// The value `proxy` should always be used instead of `userProxy`. `userProxy` is only exposed
3333// so the caller can determine if the proxy being used is the user's selected proxy, or if it
3434// was auto selected based on some other criteria.
35- //
36- // if(proxy.selectedProxy.id === userProxy.id) { /* user selected proxy */ }
37- // else { /* proxy was auto selected */ }
3835userProxy ?:Region
3936
4037// proxies is the list of proxies returned by coderd. This is fetched async.
@@ -79,27 +76,18 @@ export const ProxyContext = createContext<ProxyContextValue | undefined>(
7976 * ProxyProvider interacts with local storage to indicate the preferred workspace proxy.
8077 */
8178export const ProxyProvider :FC < PropsWithChildren > = ( { children} ) => {
82- // Try to load the preferred proxy from local storage.
83- const [ savedProxy , setUserProxy ] = useState < Region | undefined > (
84- loadUserSelectedProxy ( ) ,
85- )
86-
87- // As the proxies are being loaded, default to using the saved proxy.
88- // If the saved proxy is not valid when the async fetch happens, the
89- // proxy will be updated accordingly.
90- let defaultPreferredProxy = computeUsableURLS ( savedProxy )
79+ const dashboard = useDashboard ( )
80+ const experimentEnabled = dashboard ?. experiments . includes ( "moons" )
9181
92- if ( ! savedProxy ) {
93- // If no preferred proxy is saved, then default to using relative paths
94- // and no subdomain support until the proxies are properly loaded.
95- // This is the same as a user not selecting any proxy.
96- defaultPreferredProxy = getPreferredProxy ( [ ] )
97- }
82+ // Using a useState so the caller always has the latest user saved
83+ // proxy.
84+ const [ userSavedProxy , setUserSavedProxy ] = useState ( loadUserSelectedProxy ( ) )
9885
99- const [ proxy , setProxy ] = useState < PreferredProxy > ( defaultPreferredProxy )
86+ // Load the initial state from local storage.
87+ const [ proxy , setProxy ] = useState < PreferredProxy > (
88+ computeUsableURLS ( userSavedProxy ) ,
89+ )
10090
101- const dashboard = useDashboard ( )
102- const experimentEnabled = dashboard ?. experiments . includes ( "moons" )
10391const queryKey = [ "get-proxies" ]
10492const {
10593data :proxiesResp ,
@@ -109,57 +97,39 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
10997} = useQuery ( {
11098 queryKey,
11199queryFn :getWorkspaceProxies ,
112- // This onSuccess ensures the local storage is synchronized with the
113- // proxies returned by coderd. If the selected proxy is not in the list,
114- // then the user selection is ignored.
115- onSuccess :( resp ) => {
116- // Always pass in the user's choice.
117- setAndSaveProxy ( savedProxy , resp . regions )
118- } ,
119100} )
120101
121102// Every time we get a new proxiesResponse, update the latency check
122103// to each workspace proxy.
123104const proxyLatencies = useProxyLatency ( proxiesResp )
124105
125- // If the proxies change or latencies change, we need to update the
126- // callback function.
127- const setAndSaveProxy = useCallback (
128- (
129- selectedProxy ?:Region ,
130- // By default the proxies come from the api call above.
131- // Allow the caller to override this if they have a more up
132- // to date list of proxies.
133- proxies :Region [ ] = proxiesResp ?. regions || [ ] ,
134- ) => {
135- if ( ! proxies ) {
136- throw new Error (
137- "proxies are not yet loaded, so selecting a proxy makes no sense. How did you get here?" ,
138- )
139- }
140-
141- // The preferred proxy attempts to use the user's selection if it is valid.
142- const preferred = getPreferredProxy (
143- proxies ,
144- selectedProxy ,
106+ // updateProxy is a helper function that when called will
107+ // update the proxy being used.
108+ const updateProxy = useCallback ( ( ) => {
109+ // Update the saved user proxy for the caller.
110+ setUserSavedProxy ( loadUserSelectedProxy ( ) )
111+ setProxy (
112+ getPreferredProxy (
113+ proxiesResp ?. regions ?? [ ] ,
114+ // For some reason if I use 'userSavedProxy' here,
115+ // the tests fail. It does not load "undefined" after a
116+ // clear, but takes the previous value.
117+ loadUserSelectedProxy ( ) ,
145118proxyLatencies ,
146- )
147- // Set the state for the current context.
148- setProxy ( preferred )
149- } ,
150- [ proxiesResp , proxyLatencies ] ,
151- )
119+ ) ,
120+ )
121+ } , [ userSavedProxy , proxiesResp , proxyLatencies ] )
152122
153123// This useEffect ensures the proxy to be used is updated whenever the state changes.
154124// This includes proxies being loaded, latencies being calculated, and the user selecting a proxy.
155125useEffect ( ( ) => {
156- setAndSaveProxy ( savedProxy )
157- } , [ savedProxy , proxiesResp , proxyLatencies , setAndSaveProxy ] )
126+ updateProxy ( )
127+ } , [ proxiesResp , proxyLatencies ] )
158128
159129return (
160130< ProxyContext . Provider
161131value = { {
162- userProxy :savedProxy ,
132+ userProxy :userSavedProxy ,
163133proxyLatencies :proxyLatencies ,
164134proxy :experimentEnabled
165135 ?proxy
@@ -177,13 +147,13 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
177147setProxy :( proxy :Region ) => {
178148// Save to local storage to persist the user's preference across reloads
179149saveUserSelectedProxy ( proxy )
180- //Set thestate for the current context.
181- setUserProxy ( proxy )
150+ //Update theselected proxy
151+ updateProxy ( )
182152} ,
183153clearProxy :( ) => {
184154// Clear the user's selection from local storage.
185155clearUserSelectedProxy ( )
186- setUserProxy ( undefined )
156+ updateProxy ( )
187157} ,
188158} }
189159>