mirror of
https://github.com/MbinOrg/mbin-website.git
synced 2025-07-04 00:58:56 +00:00
Add warning for outdated servers and for "No API" servers
This commit is contained in:
parent
a44e087eae
commit
966ba99fad
5 changed files with 136 additions and 5 deletions
|
@ -4,10 +4,17 @@ import { Dynamic } from 'solid-js/web';
|
||||||
const Chip: ParentComponent<{
|
const Chip: ParentComponent<{
|
||||||
icon?: (props: ComponentProps<'svg'>) => JSX.Element;
|
icon?: (props: ComponentProps<'svg'>) => JSX.Element;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
class?: string;
|
||||||
|
classList?: {
|
||||||
|
[k: string]: boolean | undefined;
|
||||||
|
};
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
return (
|
return (
|
||||||
<span
|
<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}
|
title={props.title}
|
||||||
>
|
>
|
||||||
<Show when={props.icon}>
|
<Show when={props.icon}>
|
||||||
|
|
34
src/components/ui/tooltip.tsx
Normal file
34
src/components/ui/tooltip.tsx
Normal 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 }
|
|
@ -3,6 +3,28 @@ import fs from 'node:fs/promises';
|
||||||
await fs.rm('./.output/data', { recursive: true, force: true });
|
await fs.rm('./.output/data', { recursive: true, force: true });
|
||||||
await fs.mkdir('./.output/data', { recursive: 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>}
|
* @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} */
|
/** @type {import('./routes/servers').Server} */
|
||||||
const output = {
|
const output = {
|
||||||
domain: domain,
|
domain: domain,
|
||||||
version: jsonNodeInfo.software.version,
|
version: version,
|
||||||
|
versionOutdated: versionOutdated,
|
||||||
name: jsonNodeInfo.metadata.nodeName,
|
name: jsonNodeInfo.metadata.nodeName,
|
||||||
description: jsonNodeInfo.metadata.nodeDescription,
|
description: jsonNodeInfo.metadata.nodeDescription,
|
||||||
openRegistrations: jsonNodeInfo.openRegistrations,
|
openRegistrations: jsonNodeInfo.openRegistrations,
|
||||||
|
|
6
src/routes/releases.tsx
Normal file
6
src/routes/releases.tsx
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export interface Release {
|
||||||
|
version: string;
|
||||||
|
publishedAt: string;
|
||||||
|
githubUrl: string;
|
||||||
|
body: string;
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import MaterialSymbolsPerson from '~icons/material-symbols/person';
|
||||||
import MaterialSymbolsPersonCheck from '~icons/material-symbols/person-check';
|
import MaterialSymbolsPersonCheck from '~icons/material-symbols/person-check';
|
||||||
import MaterialSymbolsNews from '~icons/material-symbols/news';
|
import MaterialSymbolsNews from '~icons/material-symbols/news';
|
||||||
import MaterialSymbolsComment from '~icons/material-symbols/comment';
|
import MaterialSymbolsComment from '~icons/material-symbols/comment';
|
||||||
|
import MaterialSymbolsWarning from '~icons/material-symbols/warning';
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
|
@ -32,12 +33,18 @@ import {
|
||||||
} from '~/components/ui/select';
|
} from '~/components/ui/select';
|
||||||
import { Checkbox } from '~/components/ui/checkbox';
|
import { Checkbox } from '~/components/ui/checkbox';
|
||||||
import { Label } from '~/components/ui/label';
|
import { Label } from '~/components/ui/label';
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from '~/components/ui/tooltip';
|
||||||
|
|
||||||
const servers = serversJson as Server[];
|
const servers = serversJson as Server[];
|
||||||
|
|
||||||
export interface Server {
|
export interface Server {
|
||||||
domain: string;
|
domain: string;
|
||||||
version: string;
|
version: string;
|
||||||
|
versionOutdated: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
openRegistrations: boolean;
|
openRegistrations: boolean;
|
||||||
|
@ -179,7 +186,39 @@ export default function ServersPage() {
|
||||||
{(server) => {
|
{(server) => {
|
||||||
const StatChips = () => (
|
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}>
|
<Show when={server.api}>
|
||||||
<Chip title="Language" icon={MaterialSymbolsLanguage}>
|
<Chip title="Language" icon={MaterialSymbolsLanguage}>
|
||||||
{languageNames.of(server.api!.defaultLang)}
|
{languageNames.of(server.api!.defaultLang)}
|
||||||
|
@ -262,8 +301,7 @@ export default function ServersPage() {
|
||||||
when={server.api}
|
when={server.api}
|
||||||
fallback={
|
fallback={
|
||||||
<div>
|
<div>
|
||||||
No information available. This server's api is
|
No information available due to inaccessible api.
|
||||||
inaccessible and it's not recommended to use.
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
Loading…
Add table
Reference in a new issue