mirror of
https://github.com/tloncorp/landscape.git
synced 2024-11-24 09:42:26 +03:00
vitals: add new connection check to frontend and improve treaty fetch
This commit is contained in:
parent
ff3c55e6a2
commit
733ce51ea8
2
desk/mar/run-check.hoon
Normal file
2
desk/mar/run-check.hoon
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/= mark /mar/ship
|
||||||
|
mark
|
@ -26,12 +26,11 @@
|
|||||||
:- ['complete' [%s -.p.status.result]]
|
:- ['complete' [%s -.p.status.result]]
|
||||||
?+ -.p.status.result ~
|
?+ -.p.status.result ~
|
||||||
%no-our-planet ['last-contact' (time:enjs last-contact.p.status.result)]~
|
%no-our-planet ['last-contact' (time:enjs last-contact.p.status.result)]~
|
||||||
%no-our-sponsor ['last-contact' (time:enjs last-contact.p.status.result)]~
|
|
||||||
%no-our-galaxy ['last-contact' (time:enjs last-contact.p.status.result)]~
|
%no-our-galaxy ['last-contact' (time:enjs last-contact.p.status.result)]~
|
||||||
%no-sponsor-hit ['ship' (ship:enjs ship.p.status.result)]~
|
%no-sponsor-hit ['ship' (ship:enjs ship.p.status.result)]~
|
||||||
%no-sponsor-miss ['ship' (ship:enjs ship.p.status.result)]~
|
%no-sponsor-miss ['ship' (ship:enjs ship.p.status.result)]~
|
||||||
%no-their-galaxy ['last-contact' (time:enjs last-contact.p.status.result)]~
|
%no-their-galaxy ['last-contact' (time:enjs last-contact.p.status.result)]~
|
||||||
%crash ['crash' (tang:enjs tang.p.status.result)]~
|
%crash ['crash' a+(turn tang.p.status.result tank:enjs)]~
|
||||||
==
|
==
|
||||||
==
|
==
|
||||||
==
|
==
|
||||||
|
4
ui/package-lock.json
generated
4
ui/package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "landscape",
|
"name": "landscape",
|
||||||
"version": "0.0.0",
|
"version": "1.11.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "landscape",
|
"name": "landscape",
|
||||||
"version": "0.0.0",
|
"version": "1.11.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.348.0",
|
"@aws-sdk/client-s3": "^3.348.0",
|
||||||
"@aws-sdk/s3-request-presigner": "^3.348.0",
|
"@aws-sdk/s3-request-presigner": "^3.348.0",
|
||||||
|
79
ui/src/components/ShipConnection.tsx
Normal file
79
ui/src/components/ShipConnection.tsx
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import cn from 'classnames';
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
ConnectionCompleteStatus,
|
||||||
|
ConnectionPendingStatus,
|
||||||
|
ConnectionStatus,
|
||||||
|
} from '@/state/vitals';
|
||||||
|
import Bullet16Icon from './icons/Bullet16Icon';
|
||||||
|
|
||||||
|
interface ShipConnectionProps {
|
||||||
|
ship: string;
|
||||||
|
status?: ConnectionStatus;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompletedText(status: ConnectionCompleteStatus, ship: string) {
|
||||||
|
switch (status.complete) {
|
||||||
|
case 'no-data':
|
||||||
|
return 'No connection data';
|
||||||
|
case 'yes':
|
||||||
|
return 'Connected';
|
||||||
|
case 'no-dns':
|
||||||
|
return 'Unable to connect to DNS';
|
||||||
|
case 'no-our-planet':
|
||||||
|
return 'Unable to reach our planet';
|
||||||
|
case 'no-our-galaxy':
|
||||||
|
return 'Unable to reach our galaxy';
|
||||||
|
case 'no-their-galaxy':
|
||||||
|
return `Unable to reach ${ship}'s galaxy`;
|
||||||
|
case 'no-sponsor-miss':
|
||||||
|
return `${ship}'s sponsor can't reach them`;
|
||||||
|
case 'no-sponsor-hit':
|
||||||
|
return `${ship}'s sponsor can reach them, but we can't`;
|
||||||
|
default:
|
||||||
|
return 'Unable to connect';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPendingText(status: ConnectionPendingStatus, ship: string) {
|
||||||
|
switch (status.pending) {
|
||||||
|
case 'trying-dns':
|
||||||
|
return 'Checking DNS';
|
||||||
|
case 'trying-local':
|
||||||
|
return 'Checking our galaxy';
|
||||||
|
case 'trying-target':
|
||||||
|
return `Checking ${ship}`;
|
||||||
|
case 'trying-sponsor':
|
||||||
|
return `Checking ${ship}'s sponsors (~${(status as any).ship})`;
|
||||||
|
default:
|
||||||
|
return 'Checking connection...';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConnectionColor(status?: ConnectionStatus) {
|
||||||
|
if (!status || 'pending' in status) {
|
||||||
|
return 'text-gray-400';
|
||||||
|
}
|
||||||
|
|
||||||
|
return status.complete === 'yes' ? 'text-green-300' : 'text-red-400';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShipConnection({
|
||||||
|
status,
|
||||||
|
ship,
|
||||||
|
className,
|
||||||
|
}: ShipConnectionProps) {
|
||||||
|
return (
|
||||||
|
<span className={cn('flex text-base font-semibold', className)}>
|
||||||
|
<Bullet16Icon
|
||||||
|
className={cn('-ml-1 h-4 w-4', getConnectionColor(status))}
|
||||||
|
/>{' '}
|
||||||
|
{!status
|
||||||
|
? 'No connection data'
|
||||||
|
: 'pending' in status
|
||||||
|
? getPendingText(status, ship)
|
||||||
|
: getCompletedText(status, ship)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
@ -8,6 +8,8 @@ import { useAppSearchStore } from '../Nav';
|
|||||||
import { AppList } from '../../components/AppList';
|
import { AppList } from '../../components/AppList';
|
||||||
import { addRecentDev } from './Home';
|
import { addRecentDev } from './Home';
|
||||||
import { Spinner } from '../../components/Spinner';
|
import { Spinner } from '../../components/Spinner';
|
||||||
|
import { ShipConnection } from '@/components/ShipConnection';
|
||||||
|
import { pluralize } from '@/logic/utils';
|
||||||
|
|
||||||
type AppsProps = RouteComponentProps<{ ship: string }>;
|
type AppsProps = RouteComponentProps<{ ship: string }>;
|
||||||
|
|
||||||
@ -15,10 +17,12 @@ export const Apps = ({ match }: AppsProps) => {
|
|||||||
const { searchInput, selectedMatch, select } = useAppSearchStore((state) => ({
|
const { searchInput, selectedMatch, select } = useAppSearchStore((state) => ({
|
||||||
searchInput: state.searchInput,
|
searchInput: state.searchInput,
|
||||||
select: state.select,
|
select: state.select,
|
||||||
selectedMatch: state.selectedMatch
|
selectedMatch: state.selectedMatch,
|
||||||
}));
|
}));
|
||||||
const provider = match?.params.ship;
|
const provider = match?.params.ship;
|
||||||
const { treaties, status } = useAllyTreaties(provider);
|
const { treaties, status, connection, awaiting } = useAllyTreaties(provider);
|
||||||
|
console.log(status);
|
||||||
|
const [showConnection, setShowConnection] = React.useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (provider) {
|
if (provider) {
|
||||||
@ -26,6 +30,16 @@ export const Apps = ({ match }: AppsProps) => {
|
|||||||
}
|
}
|
||||||
}, [provider]);
|
}, [provider]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
setShowConnection(true);
|
||||||
|
}, 700);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const results = useMemo(() => {
|
const results = useMemo(() => {
|
||||||
if (!treaties) {
|
if (!treaties) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -47,7 +61,8 @@ export const Apps = ({ match }: AppsProps) => {
|
|||||||
const count = results?.length;
|
const count = results?.length;
|
||||||
|
|
||||||
const getAppPath = useCallback(
|
const getAppPath = useCallback(
|
||||||
(app: Treaty) => `${match?.path.replace(':ship', provider)}/${app.ship}/${app.desk}`,
|
(app: Treaty) =>
|
||||||
|
`${match?.path.replace(':ship', provider)}/${app.ship}/${app.desk}`,
|
||||||
[match]
|
[match]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -66,44 +81,73 @@ export const Apps = ({ match }: AppsProps) => {
|
|||||||
url: getAppPath(r),
|
url: getAppPath(r),
|
||||||
openInNewTab: false,
|
openInNewTab: false,
|
||||||
value: r.desk,
|
value: r.desk,
|
||||||
display: r.title
|
display: r.title,
|
||||||
}))
|
})),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [results]);
|
}, [results]);
|
||||||
|
|
||||||
const showNone =
|
const showLoader =
|
||||||
status === 'error' || ((status === 'success' || status === 'initial') && results?.length === 0);
|
status === 'loading' || status === 'initial' || status === 'awaiting';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dialog-inner-container md:px-6 md:py-8 h4 text-gray-400">
|
<div className="dialog-inner-container h4 text-gray-400 md:px-6 md:py-8">
|
||||||
{status === 'loading' && (
|
{showLoader && (
|
||||||
<span className="mb-3">
|
<div className="mb-3 flex items-start">
|
||||||
<Spinner className="w-7 h-7 mr-3" /> Finding software...
|
<Spinner className="mr-3 h-7 w-7 flex-none" />
|
||||||
</span>
|
<div className="flex flex-1 flex-col">
|
||||||
|
<span>
|
||||||
|
{status === 'awaiting'
|
||||||
|
? `${awaiting} ${pluralize(
|
||||||
|
'app',
|
||||||
|
awaiting
|
||||||
|
)} found, waiting for entries...`
|
||||||
|
: 'Finding software...'}
|
||||||
|
</span>
|
||||||
|
{showConnection && (
|
||||||
|
<ShipConnection ship={provider} status={connection?.status} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
{results && results.length > 0 && (
|
{(status === 'partial' || status === 'finished') &&
|
||||||
<>
|
results &&
|
||||||
|
(results.length > 0 ? (
|
||||||
|
<>
|
||||||
|
<div id="developed-by">
|
||||||
|
<h2 className="mb-3">
|
||||||
|
Software developed by{' '}
|
||||||
|
<ShipName name={provider} className="font-mono" />
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
{count} result{count === 1 ? '' : 's'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<AppList
|
||||||
|
apps={results}
|
||||||
|
labelledBy="developed-by"
|
||||||
|
matchAgainst={selectedMatch}
|
||||||
|
to={getAppPath}
|
||||||
|
/>
|
||||||
|
{status === 'finished' ? (
|
||||||
|
<p>That's it!</p>
|
||||||
|
) : (
|
||||||
|
<p>Awaiting {awaiting} more</p>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
<div id="developed-by">
|
<div id="developed-by">
|
||||||
<h2 className="mb-3">
|
<h2 className="mb-3">
|
||||||
Software developed by <ShipName name={provider} className="font-mono" />
|
Software developed by{' '}
|
||||||
|
<ShipName name={provider} className="font-mono" />
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>No apps found</p>
|
||||||
{count} result{count === 1 ? '' : 's'}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<AppList
|
))}
|
||||||
apps={results}
|
{status === 'error' && (
|
||||||
labelledBy="developed-by"
|
|
||||||
matchAgainst={selectedMatch}
|
|
||||||
to={getAppPath}
|
|
||||||
/>
|
|
||||||
<p>That's it!</p>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{showNone && (
|
|
||||||
<h2>
|
<h2>
|
||||||
Unable to find software developed by <ShipName name={provider} className="font-mono" />
|
Unable to connect to{' '}
|
||||||
|
<ShipName name={provider} className="font-mono" />
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
import api from '@/api';
|
import api from '@/api';
|
||||||
import { normalizeUrbitColor } from '@/logic/utils';
|
import { normalizeUrbitColor } from '@/logic/utils';
|
||||||
import { Status } from '@/logic/useAsyncCall';
|
import { Status } from '@/logic/useAsyncCall';
|
||||||
|
import { ConnectionStatus, useConnectivityCheck } from './vitals';
|
||||||
|
|
||||||
export interface ChargeWithDesk extends Charge {
|
export interface ChargeWithDesk extends Charge {
|
||||||
desk: string;
|
desk: string;
|
||||||
@ -261,42 +262,43 @@ export function useAllies() {
|
|||||||
return useDocketState(selAllies);
|
return useDocketState(selAllies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllyTreatyStatus(
|
||||||
|
treaties: Treaties,
|
||||||
|
fetching: boolean,
|
||||||
|
alliance?: string[],
|
||||||
|
status?: ConnectionStatus
|
||||||
|
): Status | 'awaiting' | 'partial' | 'finished' {
|
||||||
|
const treatyCount = Object.keys(treaties).length;
|
||||||
|
console.log(treatyCount, alliance?.length, fetching, status);
|
||||||
|
if (alliance && alliance.length !== 0 && treatyCount === alliance.length) {
|
||||||
|
return 'finished';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (treatyCount > 0) {
|
||||||
|
return 'partial';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!status || ('complete' in status && status.complete === 'no-data')) {
|
||||||
|
return 'initial';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fetching || 'pending' in status) {
|
||||||
|
return 'loading';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('complete' in status && status.complete === 'yes') {
|
||||||
|
return alliance && alliance.length > 0 ? 'awaiting' : 'finished';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
|
||||||
export function useAllyTreaties(ship: string) {
|
export function useAllyTreaties(ship: string) {
|
||||||
|
const { data } = useConnectivityCheck(ship);
|
||||||
const allies = useAllies();
|
const allies = useAllies();
|
||||||
const isAllied = ship in allies;
|
const isAllied = ship in allies;
|
||||||
const [status, setStatus] = useState<Status>('initial');
|
const [fetching, setFetching] = useState(false);
|
||||||
const [treaties, setTreaties] = useState<Treaties>();
|
const treaties = useDocketState(
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (Object.keys(allies).length > 0 && !isAllied) {
|
|
||||||
setStatus('loading');
|
|
||||||
useDocketState.getState().addAlly(ship);
|
|
||||||
}
|
|
||||||
}, [allies, isAllied, ship]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function fetchTreaties() {
|
|
||||||
if (isAllied) {
|
|
||||||
setStatus('loading');
|
|
||||||
try {
|
|
||||||
const newTreaties = await useDocketState
|
|
||||||
.getState()
|
|
||||||
.fetchAllyTreaties(ship);
|
|
||||||
|
|
||||||
if (Object.keys(newTreaties).length > 0) {
|
|
||||||
setTreaties(newTreaties);
|
|
||||||
setStatus('success');
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
setStatus('error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchTreaties();
|
|
||||||
}, [ship, isAllied]);
|
|
||||||
|
|
||||||
const storeTreaties = useDocketState(
|
|
||||||
useCallback(
|
useCallback(
|
||||||
(s) => {
|
(s) => {
|
||||||
const charter = s.allies[ship];
|
const charter = s.allies[ship];
|
||||||
@ -305,27 +307,42 @@ export function useAllyTreaties(ship: string) {
|
|||||||
[ship]
|
[ship]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
debugger;
|
||||||
|
const status = getAllyTreatyStatus(
|
||||||
|
treaties,
|
||||||
|
fetching,
|
||||||
|
allies[ship],
|
||||||
|
data?.status
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timeout = setTimeout(() => {
|
if (Object.keys(allies).length > 0 && !isAllied) {
|
||||||
setStatus('error');
|
useDocketState.getState().addAlly(ship);
|
||||||
}, 30 * 1000); // wait 30 secs before timing out
|
}
|
||||||
|
}, [allies, isAllied, ship]);
|
||||||
|
|
||||||
if (Object.keys(storeTreaties).length > 0) {
|
useEffect(() => {
|
||||||
setTreaties(storeTreaties);
|
async function fetchTreaties() {
|
||||||
setStatus('success');
|
try {
|
||||||
clearTimeout(timeout);
|
setFetching(true);
|
||||||
|
await useDocketState.getState().fetchAllyTreaties(ship);
|
||||||
|
setFetching(false);
|
||||||
|
} catch {
|
||||||
|
console.log("couldn't fetch initial treaties");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
if (isAllied) {
|
||||||
clearTimeout(timeout);
|
fetchTreaties();
|
||||||
};
|
}
|
||||||
}, [storeTreaties]);
|
}, [ship, isAllied]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isAllied,
|
isAllied,
|
||||||
treaties,
|
treaties,
|
||||||
status,
|
status,
|
||||||
|
connection: data,
|
||||||
|
awaiting: allies[ship]?.length || 0 - Object.keys(treaties).length,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
153
ui/src/state/vitals.ts
Normal file
153
ui/src/state/vitals.ts
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import api from '@/api';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
interface Connected {
|
||||||
|
complete: 'yes';
|
||||||
|
}
|
||||||
|
|
||||||
|
interface YetToCheck {
|
||||||
|
complete: 'no-data';
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoDNS {
|
||||||
|
complete: 'no-dns';
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Crash {
|
||||||
|
complete: 'crash';
|
||||||
|
crash: string[][];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoOurPlanet {
|
||||||
|
complete: 'no-our-planet';
|
||||||
|
'last-contact': number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoOurGalaxy {
|
||||||
|
complete: 'no-our-galaxy';
|
||||||
|
'last-contact': number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoSponsorHit {
|
||||||
|
complete: 'no-sponsor-hit';
|
||||||
|
ship: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoSponsorMiss {
|
||||||
|
complete: 'no-sponsor-miss';
|
||||||
|
ship: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoTheirGalaxy {
|
||||||
|
complete: 'no-their-galaxy';
|
||||||
|
'last-contact': number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ConnectionCompleteStatusKey =
|
||||||
|
| 'yes'
|
||||||
|
| 'crash'
|
||||||
|
| 'no-data'
|
||||||
|
| 'no-dns'
|
||||||
|
| 'no-our-planet'
|
||||||
|
| 'no-our-galaxy'
|
||||||
|
| 'no-sponsor-hit'
|
||||||
|
| 'no-sponsor-miss'
|
||||||
|
| 'no-their-galaxy';
|
||||||
|
|
||||||
|
export interface CompleteStatus {
|
||||||
|
complete: ConnectionCompleteStatusKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ConnectionCompleteStatus =
|
||||||
|
| Connected
|
||||||
|
| YetToCheck
|
||||||
|
| Crash
|
||||||
|
| NoDNS
|
||||||
|
| NoOurPlanet
|
||||||
|
| NoOurGalaxy
|
||||||
|
| NoSponsorHit
|
||||||
|
| NoSponsorMiss
|
||||||
|
| NoTheirGalaxy;
|
||||||
|
|
||||||
|
export type ConnectionPendingStatusKey =
|
||||||
|
| 'setting-up'
|
||||||
|
| 'trying-dns'
|
||||||
|
| 'trying-local'
|
||||||
|
| 'trying-target'
|
||||||
|
| 'trying-sponsor';
|
||||||
|
|
||||||
|
export type ConnectionPendingStatus =
|
||||||
|
| {
|
||||||
|
pending: Omit<ConnectionPendingStatusKey, 'trying-sponsor'>;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
pending: 'trying-sponsor';
|
||||||
|
ship: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConnectionStatus =
|
||||||
|
| ConnectionCompleteStatus
|
||||||
|
| ConnectionPendingStatus;
|
||||||
|
|
||||||
|
export interface ConnectionUpdate {
|
||||||
|
status: ConnectionStatus;
|
||||||
|
timestamp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useConnectivityCheck(ship: string, useStale = false) {
|
||||||
|
const [subbed, setSubbed] = useState(false);
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const query = useQuery(
|
||||||
|
['vitals', ship],
|
||||||
|
async (): Promise<ConnectionUpdate> => {
|
||||||
|
const resp = await api.scry<ConnectionUpdate>({
|
||||||
|
app: 'vitals',
|
||||||
|
path: `/ship/${ship}`,
|
||||||
|
});
|
||||||
|
const now = Date.now();
|
||||||
|
const diff = now - resp.timestamp;
|
||||||
|
|
||||||
|
// if status older than 30 seconds, re-run check
|
||||||
|
if (diff > 30 * 1000 || !useStale) {
|
||||||
|
api.poke({
|
||||||
|
app: 'vitals',
|
||||||
|
mark: 'run-check',
|
||||||
|
json: ship,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: {
|
||||||
|
pending: 'setting-up',
|
||||||
|
},
|
||||||
|
timestamp: now,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: subbed,
|
||||||
|
cacheTime: 0,
|
||||||
|
initialData: {
|
||||||
|
status: {
|
||||||
|
pending: 'setting-up',
|
||||||
|
},
|
||||||
|
timestamp: Date.now(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
api.subscribe({
|
||||||
|
app: 'vitals',
|
||||||
|
path: `/status/${ship}`,
|
||||||
|
event: (data: ConnectionUpdate) => {
|
||||||
|
queryClient.setQueryData(['vitals', ship], data);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setSubbed(true);
|
||||||
|
}, [ship]);
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user