@@ -32,9 +32,6 @@ export interface ProxyContextValue {
32
32
// The value `proxy` should always be used instead of `userProxy`. `userProxy` is only exposed
33
33
// so the caller can determine if the proxy being used is the user's selected proxy, or if it
34
34
// 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 */ }
38
35
userProxy ?: Region
39
36
40
37
// proxies is the list of proxies returned by coderd. This is fetched async.
@@ -79,27 +76,18 @@ export const ProxyContext = createContext<ProxyContextValue | undefined>(
79
76
* ProxyProvider interacts with local storage to indicate the preferred workspace proxy.
80
77
*/
81
78
export 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" )
91
81
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 ( ) )
98
85
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
+ )
100
90
101
- const dashboard = useDashboard ( )
102
- const experimentEnabled = dashboard ?. experiments . includes ( "moons" )
103
91
const queryKey = [ "get-proxies" ]
104
92
const {
105
93
data : proxiesResp ,
@@ -109,57 +97,39 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
109
97
} = useQuery ( {
110
98
queryKey,
111
99
queryFn : 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
- } ,
119
100
} )
120
101
121
102
// Every time we get a new proxiesResponse, update the latency check
122
103
// to each workspace proxy.
123
104
const proxyLatencies = useProxyLatency ( proxiesResp )
124
105
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 ( ) ,
145
118
proxyLatencies ,
146
- )
147
- // Set the state for the current context.
148
- setProxy ( preferred )
149
- } ,
150
- [ proxiesResp , proxyLatencies ] ,
151
- )
119
+ ) ,
120
+ )
121
+ } , [ userSavedProxy , proxiesResp , proxyLatencies ] )
152
122
153
123
// This useEffect ensures the proxy to be used is updated whenever the state changes.
154
124
// This includes proxies being loaded, latencies being calculated, and the user selecting a proxy.
155
125
useEffect ( ( ) => {
156
- setAndSaveProxy ( savedProxy )
157
- } , [ savedProxy , proxiesResp , proxyLatencies , setAndSaveProxy ] )
126
+ updateProxy ( )
127
+ } , [ proxiesResp , proxyLatencies ] )
158
128
159
129
return (
160
130
< ProxyContext . Provider
161
131
value = { {
162
- userProxy : savedProxy ,
132
+ userProxy : userSavedProxy ,
163
133
proxyLatencies : proxyLatencies ,
164
134
proxy : experimentEnabled
165
135
? proxy
@@ -177,13 +147,13 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
177
147
setProxy : ( proxy : Region ) => {
178
148
// Save to local storage to persist the user's preference across reloads
179
149
saveUserSelectedProxy ( proxy )
180
- // Set the state for the current context.
181
- setUserProxy ( proxy )
150
+ // Update the selected proxy
151
+ updateProxy ( )
182
152
} ,
183
153
clearProxy : ( ) => {
184
154
// Clear the user's selection from local storage.
185
155
clearUserSelectedProxy ( )
186
- setUserProxy ( undefined )
156
+ updateProxy ( )
187
157
} ,
188
158
} }
189
159
>
0 commit comments