feat: add spinner to latencies when refetching (#8278)

* feat: add spinner to latencies when refetching
This commit is contained in:
Steven Masley
2023-07-05 13:06:09 -04:00
committed by GitHub
parent 9a7705c656
commit 0f5a1ad480
7 changed files with 58 additions and 14 deletions

View File

@ -29,8 +29,8 @@ const Template: Story<AppLinkProps> = (args) => (
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>

View File

@ -188,6 +188,7 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
}) => {
const buttonRef = useRef<HTMLButtonElement>(null)
const [isOpen, setIsOpen] = useState(false)
const [refetchDate, setRefetchDate] = useState<Date>()
const selectedProxy = proxyContextValue.proxy.proxy
const refreshLatencies = proxyContextValue.refetchProxyLatencies
const closeMenu = () => setIsOpen(false)
@ -196,6 +197,26 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
const isLoadingLatencies = Object.keys(latencies).length === 0
const isLoading = proxyContextValue.isLoading || isLoadingLatencies
const permissions = usePermissions()
const proxyLatencyLoading = (proxy: TypesGen.Region): boolean => {
if (!refetchDate) {
// Only show loading if the user manually requested a refetch
return false
}
const latency = latencies?.[proxy.id]
// Only show a loading spinner if:
// - A latency exists. This means the latency was fetched at some point, so the
// loader *should* be resolved.
// - The proxy is healthy. If it is not, the loader might never resolve.
// - The latency reported is older than the refetch date. This means the latency
// is stale and we should show a loading spinner until the new latency is
// fetched.
if (proxy.healthy && latency && latency.at < refetchDate) {
return true
}
return false
}
if (isLoading) {
return (
@ -234,6 +255,7 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
{selectedProxy.display_name}
<ProxyStatusLatency
latency={latencies?.[selectedProxy.id]?.latencyMS}
isLoading={proxyLatencyLoading(selectedProxy)}
/>
</Box>
) : (
@ -277,7 +299,10 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
/>
</Box>
{proxy.display_name}
<ProxyStatusLatency latency={latencies?.[proxy.id]?.latencyMS} />
<ProxyStatusLatency
latency={latencies?.[proxy.id]?.latencyMS}
isLoading={proxyLatencyLoading(proxy)}
/>
</Box>
</MenuItem>
))}
@ -298,7 +323,8 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
// Stop the menu from closing
e.stopPropagation()
// Refresh the latencies.
refreshLatencies()
const refetchDate = refreshLatencies()
setRefetchDate(refetchDate)
}}
>
Refresh Latencies

View File

@ -4,11 +4,29 @@ import Box from "@mui/material/Box"
import Tooltip from "@mui/material/Tooltip"
import { FC } from "react"
import { getLatencyColor } from "utils/latency"
import CircularProgress from "@mui/material/CircularProgress"
export const ProxyStatusLatency: FC<{ latency?: number }> = ({ latency }) => {
export const ProxyStatusLatency: FC<{
latency?: number
isLoading?: boolean
}> = ({ latency, isLoading }) => {
const theme = useTheme()
const color = getLatencyColor(theme, latency)
if (isLoading) {
return (
<Tooltip title="Loading latency...">
<CircularProgress
size="14px"
sx={{
// Always use the no latency color for loading.
color: getLatencyColor(theme, undefined),
}}
/>
</Tooltip>
)
}
if (!latency) {
return (
<Tooltip title="Latency not available">

View File

@ -68,8 +68,8 @@ const TemplateFC = (
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>

View File

@ -33,8 +33,8 @@ Example.args = {
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>
@ -106,8 +106,8 @@ BunchOfMetadata.args = {
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>

View File

@ -42,8 +42,8 @@ const meta: Meta<typeof Workspace> = {
setProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>

View File

@ -53,7 +53,7 @@ export interface ProxyContextValue {
proxyLatencies: Record<string, ProxyLatencyReport>
// refetchProxyLatencies will trigger refreshing of the proxy latencies. By default the latencies
// are loaded once.
refetchProxyLatencies: () => void
refetchProxyLatencies: () => Date
// setProxy is a function that sets the user's selected proxy. This function should
// only be called if the user is manually selecting a proxy. This value is stored in local
// storage and will persist across reloads and tabs.