diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx
index f1300123..a93bae95 100755
--- a/src/components/Layout.tsx
+++ b/src/components/Layout.tsx
@@ -48,6 +48,7 @@ import Link from 'next/link';
import { useRouter } from 'next/router';
import { useState } from 'react';
import ConfigProvider from './ConfigProvider';
+import VersionBadge from './VersionBadge';
type NavLinks = {
label: string;
@@ -357,23 +358,27 @@ export default function Layout({ children, config }: { children: React.ReactNode
}
})}
-
+
+
-
-
- {config.website.externalLinks.map(({ name, url }, i) => (
- }
- variant='light'
- component={Link}
- href={url}
- target='_blank'
- />
- ))}
-
-
+
+
+
+
+ {config.website.externalLinks.map(({ name, url }, i) => (
+ }
+ variant='light'
+ component={Link}
+ href={url}
+ target='_blank'
+ />
+ ))}
+
+
+
diff --git a/src/components/VersionBadge.tsx b/src/components/VersionBadge.tsx
new file mode 100644
index 00000000..14948e0c
--- /dev/null
+++ b/src/components/VersionBadge.tsx
@@ -0,0 +1,173 @@
+import useVersion from '@/lib/hooks/useVersion';
+import {
+ Anchor,
+ Badge,
+ Button,
+ Flex,
+ Indicator,
+ Modal,
+ Paper,
+ Stack,
+ Text,
+ Title,
+ Tooltip,
+} from '@mantine/core';
+import { useDisclosure } from '@mantine/hooks';
+
+function DataDisplay({ items }: { items: { label: string; value: string; href?: string }[] }) {
+ return (
+
+
+ {items.map((item, index) => (
+
+
+ {item.label}
+
+
+ {item.href ? (
+
+ {item.value}
+
+ ) : (
+ {item.value}
+ )}
+
+ ))}
+
+
+ );
+}
+
+function VersionButton({ text, children, href }: { href: string; text: string; children: React.ReactNode }) {
+ return (
+
+ );
+}
+
+export default function VersionBadge() {
+ const { version, isLoading } = useVersion();
+ const [opened, { open, close }] = useDisclosure(false);
+
+ if (isLoading) return null;
+ if (!version) return null;
+
+ return (
+ <>
+
+ {version.isLatest && Running the latest version of Zipline.}
+ {version.isUpstream && (
+
+ You are running an unstable version of Zipline. Upstream versions are not fully tested and
+ may contain bugs.
+
+ )}
+ {!version.isLatest && !version.isUpstream && version.isRelease && (
+
+ You are running an outdated version of Zipline. It is recommended to update to the{' '}
+ latest version.
+
+ )}
+
+
+
+ Current Version
+
+
+
+
+ {!version.isLatest && version.isUpstream && (
+ <>
+
+ Latest Commit Available
+
+
+ This is only visible when running an upstream version.
+
+
+
+ >
+ )}
+
+ {!version.isLatest && version.isRelease && (
+ <>
+
+ {version.latest?.tag} is available
+
+
+
+ {version.latest?.tag}
+
+
+
+ {version.latest?.tag}
+
+ >
+ )}
+
+
+
+
+ {version.version?.tag}
+
+
+ >
+ );
+}
diff --git a/src/lib/hooks/useVersion.ts b/src/lib/hooks/useVersion.ts
new file mode 100755
index 00000000..4eac3a8d
--- /dev/null
+++ b/src/lib/hooks/useVersion.ts
@@ -0,0 +1,23 @@
+import useSWR from 'swr';
+import { Response } from '../api/response';
+const f = async () => {
+ const res = await fetch('/api/version', {
+ cache: 'force-cache',
+ });
+ if (!res.ok) throw new Error('Failed to fetch version');
+ const r = await res.json();
+ return r;
+};
+
+export default function useVersion() {
+ const { isLoading, data } = useSWR('/api/version', f, {
+ refreshInterval: undefined,
+ revalidateOnFocus: false,
+ revalidateIfStale: false,
+ refreshWhenOffline: false,
+ refreshWhenHidden: false,
+ revalidateOnReconnect: false,
+ });
+
+ return { version: data?.data, isLoading };
+}
diff --git a/src/server/routes/api/version.ts b/src/server/routes/api/version.ts
index 9650d8b5..bdcd5c57 100755
--- a/src/server/routes/api/version.ts
+++ b/src/server/routes/api/version.ts
@@ -3,16 +3,49 @@ import fastifyPlugin from 'fastify-plugin';
import { getVersion } from '@/lib/version';
export type ApiVersionResponse = {
- version: string;
+ details: ReturnType;
+ data: VersionAPI;
};
+interface VersionAPI {
+ isUpstream?: boolean;
+ isRelease?: boolean;
+ isLatest?: boolean;
+ version?: {
+ tag: string;
+ sha: string;
+ url: string;
+ };
+ latest?: {
+ tag: string;
+ url: string;
+ commit?: {
+ sha: string;
+ url: string;
+ pull: boolean;
+ };
+ };
+}
+
export const PATH = '/api/version';
export default fastifyPlugin(
(server, _, done) => {
server.get(PATH, { preHandler: [userMiddleware] }, async (_, res) => {
const details = getVersion();
+ const params = new URLSearchParams([['details', JSON.stringify(details)]]);
- return res.send(details);
+ const resp = await fetch(`https://zipline-version.diced.sh/?${params.toString()}`);
+
+ if (!resp.ok) {
+ return res.internalServerError('failed to fetch version details: ' + await resp.text());
+ }
+
+ const data: VersionAPI = await resp.json();
+
+ return res.send({
+ data,
+ details,
+ });
});
done();