Add warning for outdated servers and for "No API" servers

This commit is contained in:
John Wesley 2024-07-16 13:28:46 -04:00
parent a44e087eae
commit 966ba99fad
5 changed files with 136 additions and 5 deletions

View file

@ -4,10 +4,17 @@ import { Dynamic } from 'solid-js/web';
const Chip: ParentComponent<{
icon?: (props: ComponentProps<'svg'>) => JSX.Element;
title?: string;
class?: string;
classList?: {
[k: string]: boolean | undefined;
};
}> = (props) => {
return (
<span
class="px-2 py-1 border rounded-lg inline-flex items-center"
class={
'px-2 py-1 border rounded-lg inline-flex items-center ' + props.class
}
classList={props.classList}
title={props.title}
>
<Show when={props.icon}>

View file

@ -0,0 +1,34 @@
import { splitProps, ValidComponent, type Component } from "solid-js"
import { PolymorphicProps } from "@kobalte/core/polymorphic"
import * as TooltipPrimitive from "@kobalte/core/tooltip"
import { cn } from "~/lib/utils"
const TooltipTrigger = TooltipPrimitive.Trigger
const Tooltip: Component<TooltipPrimitive.TooltipRootProps> = (props) => {
return <TooltipPrimitive.Root gutter={4} {...props} />
}
type TooltipContentProps<T extends ValidComponent = "div"> =
TooltipPrimitive.TooltipContentProps<T> & { class?: string | undefined }
const TooltipContent = <T extends ValidComponent = "div">(
props: PolymorphicProps<T, TooltipContentProps<T>>
) => {
const [local, others] = splitProps(props as TooltipContentProps, ["class"])
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
class={cn(
"z-50 origin-[var(--kb-popover-content-transform-origin)] overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
local.class
)}
{...others}
/>
</TooltipPrimitive.Portal>
)
}
export { Tooltip, TooltipTrigger, TooltipContent }

View file

@ -3,6 +3,28 @@ import fs from 'node:fs/promises';
await fs.rm('./.output/data', { recursive: true, force: true });
await fs.mkdir('./.output/data', { recursive: true });
/** @returns {Promise<Array<import('./routes/releases').Release>>} */
const fetchReleases = async () => {
const releasesJson = await (
await fetch(
'https://api.github.com/repos/mbinOrg/mbin/releases?per_page=100',
)
).json();
/** @type {Array<import('./routes/releases').Release>} */
const output = releasesJson.map((v) => ({
version: v.tag_name.substring(1),
publishedAt: v.published_at,
githubUrl: v.html_url,
body: v.body,
}));
return output.sort((a, b) => a.publishedAt - b.publishedAt);
};
const releases = await fetchReleases();
fs.writeFile('./.output/data/releases.json', JSON.stringify(releases), 'utf8');
/**
* @returns {Promise<string>}
*/
@ -119,10 +141,34 @@ const fetchServerInfo = async (domain) => {
);
}
const version = jsonNodeInfo.software.version;
// A server is considered outdated if a newer version has been available for more than 30 days.
const releaseIndex = releases.findIndex((v) => v.version === version);
console.log(
releaseIndex,
version,
releases[releaseIndex].version,
releases[releaseIndex].publishedAt,
);
if (releaseIndex > 0) {
console.log(
Date.now() - Date.parse(releases[releaseIndex - 1].publishedAt),
releases[releaseIndex - 1].publishedAt,
Date.now() - Date.parse(releases[releaseIndex - 1].publishedAt) >
1000 * 60 * 60 * 24 * 30,
);
}
const versionOutdated =
releaseIndex > 0 &&
Date.now() - Date.parse(releases[releaseIndex - 1].publishedAt) >
1000 * 60 * 60 * 24 * 30;
/** @type {import('./routes/servers').Server} */
const output = {
domain: domain,
version: jsonNodeInfo.software.version,
version: version,
versionOutdated: versionOutdated,
name: jsonNodeInfo.metadata.nodeName,
description: jsonNodeInfo.metadata.nodeDescription,
openRegistrations: jsonNodeInfo.openRegistrations,

6
src/routes/releases.tsx Normal file
View file

@ -0,0 +1,6 @@
export interface Release {
version: string;
publishedAt: string;
githubUrl: string;
body: string;
}

View file

@ -23,6 +23,7 @@ import MaterialSymbolsPerson from '~icons/material-symbols/person';
import MaterialSymbolsPersonCheck from '~icons/material-symbols/person-check';
import MaterialSymbolsNews from '~icons/material-symbols/news';
import MaterialSymbolsComment from '~icons/material-symbols/comment';
import MaterialSymbolsWarning from '~icons/material-symbols/warning';
import {
Select,
SelectContent,
@ -32,12 +33,18 @@ import {
} from '~/components/ui/select';
import { Checkbox } from '~/components/ui/checkbox';
import { Label } from '~/components/ui/label';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '~/components/ui/tooltip';
const servers = serversJson as Server[];
export interface Server {
domain: string;
version: string;
versionOutdated: boolean;
name: string;
description: string;
openRegistrations: boolean;
@ -179,7 +186,39 @@ export default function ServersPage() {
{(server) => {
const StatChips = () => (
<>
<Chip title="Mbin Version">Mbin {server.version}</Chip>
<Chip
classList={{
'bg-red-900 bg-opacity-40': server.versionOutdated,
}}
>
Mbin {server.version}
<Show when={server.versionOutdated}>
<Tooltip>
<TooltipTrigger>
<MaterialSymbolsWarning class="ml-1 text-red-500" />
</TooltipTrigger>
<TooltipContent>
This server is using an outdated version. Please ask the
server admin to upgrade or use a different server.
</TooltipContent>
</Tooltip>
</Show>
</Chip>
<Show when={!server.api}>
<Tooltip>
<TooltipTrigger>
<Chip class="bg-red-900 bg-opacity-40">
No API
<MaterialSymbolsWarning class="ml-1 text-red-500" />
</Chip>
</TooltipTrigger>
<TooltipContent>
This server's api is inaccessible and will not work with
apps. Please ask the server admin to fix the issue or use
a different server.
</TooltipContent>
</Tooltip>
</Show>
<Show when={server.api}>
<Chip title="Language" icon={MaterialSymbolsLanguage}>
{languageNames.of(server.api!.defaultLang)}
@ -262,8 +301,7 @@ export default function ServersPage() {
when={server.api}
fallback={
<div>
No information available. This server's api is
inaccessible and it's not recommended to use.
No information available due to inaccessible api.
</div>
}
>