update: Separate internal to it's own route file

This commit is contained in:
mbaharip
2025-01-24 17:46:24 +07:00
parent 128f3c494d
commit 33c50765e7
5 changed files with 132 additions and 73 deletions
+6 -73
View File
@@ -2,8 +2,7 @@ import { type Metadata, type ResolvedMetadata } from "next";
import { notFound } from "next/navigation";
import { FileActions, FileBreadcrumb, FileExplorerLayout, FileReadme } from "~/components/explorer";
import { Status } from "~/components/global";
import { Password } from "~/components/layout";
import { ErrorComponent, Password } from "~/components/layout";
import { PreviewLayout } from "~/components/preview";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
@@ -15,44 +14,17 @@ import { CheckPagePassword } from "~/actions/password";
import { ValidatePaths } from "~/actions/paths";
import { CreateFileToken } from "~/actions/token";
import ErrorComponent from "../error";
import ConfiguratorPage from "./ConfiguratorPage";
import DeployPage from "./DeployPage";
import EmbedPage from "./EmbedPage";
export const revalidate = 60;
export const dynamic = "force-dynamic";
export const dynamicParams = false;
type Props = {
params: Promise<{
rest: string[];
}>;
};
const internal = (paths: string[]) => {
const joinedPaths = (paths.join("/").startsWith("/") ? paths.join("/") : `/${paths.join("/")}`).replace(/\/+/g, "/");
return {
isInternalRoot: joinedPaths === "/_",
isGuidePage: joinedPaths === "/_/deploy",
isConfiguratorPage: joinedPaths === "/_/configurator",
isEmbedRootPage: joinedPaths === "/_/embed",
isEmbedPage: joinedPaths.startsWith("/_/embed/"),
};
};
export async function generateMetadata({ params }: Props, parent: ResolvedMetadata): Promise<Metadata> {
const p = await params;
let rest = p.rest;
const { isInternalRoot, isGuidePage, isConfiguratorPage, isEmbedPage, isEmbedRootPage } = internal(p.rest);
if (isInternalRoot)
return { title: "Reserved Internal Path", description: "This path is reserved for internal pages" };
if (isGuidePage) return { title: "Guide", description: "Read on how to deploy your own index" };
if (isConfiguratorPage) return { title: "Configurator", description: "Configure your index" };
if (isEmbedRootPage) return { title: "Not Found" };
if (isEmbedPage) {
rest = rest.slice(2);
}
const { rest } = await params;
const paths = await ValidatePaths(rest);
if (!paths.success) return { title: "Not Found" };
@@ -61,14 +33,10 @@ export async function generateMetadata({ params }: Props, parent: ResolvedMetada
if (!currentPath?.id) return { title: "Not Found" };
const banner = await GetBanner(currentPath.id);
if (isEmbedPage && !currentPath.mimeType.includes("video") && !currentPath.mimeType.includes("audio"))
return { title: "Not Found" };
return {
title: isEmbedPage ? `${decodeURIComponent(currentPath.path)} (embed)` : decodeURIComponent(currentPath.path),
description: isEmbedPage
? `Embed ${currentPath.path}`
: currentPath.mimeType.includes("folder")
title: decodeURIComponent(currentPath.path),
description: currentPath.mimeType.includes("folder")
? `Browse ${currentPath.path} files`
: `View ${currentPath.path}`,
openGraph: {
@@ -85,29 +53,12 @@ export async function generateMetadata({ params }: Props, parent: ResolvedMetada
};
}
export default async function RestPage({ params }: Props) {
const p = await params;
let rest = p.rest;
const { isInternalRoot, isConfiguratorPage, isEmbedPage, isEmbedRootPage, isGuidePage } = internal(p.rest);
if (isInternalRoot)
return (
<div className='grid grow place-items-center'>
<Status
icon='Lock'
message="This path is preserved for all internal pages, make sure you don't use this path on your google drive"
/>
</div>
);
if (isGuidePage) return <DeployPage />;
if (isConfiguratorPage) return <ConfiguratorPage />;
if (isEmbedRootPage) return notFound();
if (isEmbedPage) rest = rest.slice(2);
const { rest } = await params;
const paths = await ValidatePaths(rest);
if (!paths.success) notFound();
const unlocked = await CheckPagePassword(paths.data);
if (!unlocked.success && isEmbedPage)
return <ErrorComponent error={new Error("Protected file cannot be embedded")} />;
if (!unlocked.success) {
return (
<Password
@@ -118,7 +69,7 @@ export default async function RestPage({ params }: Props) {
);
}
const currentPath = paths.data[paths.data.length - 1];
const currentPath = paths.data.pop();
if (!currentPath) return <ErrorComponent error={new Error("Failed to get current path")} />;
const Layout: React.FC<{
@@ -137,7 +88,6 @@ export default async function RestPage({ params }: Props) {
);
if (currentPath.mimeType.includes("folder")) {
if (isEmbedPage) return <ErrorComponent error={new Error("Folder cannot be embedded")} />;
const [data, readme] = await Promise.all([ListFiles({ id: currentPath.id }), GetReadme(currentPath.id)]);
if (!data.success) return <ErrorComponent error={new Error(data.error)} />;
if (!readme.success) return <ErrorComponent error={new Error(readme.error)} />;
@@ -181,23 +131,6 @@ export default async function RestPage({ params }: Props) {
const token = await CreateFileToken(file.data);
if (!token.success) return <ErrorComponent error={new Error(token.error)} />;
if (isEmbedPage) {
if (!currentPath.mimeType.includes("video") && !currentPath.mimeType.includes("audio"))
return (
<div className='max-w-screen fixed left-0 top-0 grid h-full max-h-screen w-full place-items-center bg-transparent p-2'>
<ErrorComponent error={new Error("Only video and audio file can be embedded")} />
</div>
);
return (
<div className='max-w-screen fixed left-0 top-0 grid h-full max-h-screen w-full place-items-center bg-transparent p-2'>
<EmbedPage
file={file.data}
type={currentPath.mimeType.includes("video") ? "video" : "audio"}
/>
</div>
);
}
return (
<Layout>
<PreviewLayout
@@ -0,0 +1,14 @@
import { type Metadata } from "next";
import { ConfiguratorPage } from "~/components/internal";
export const dynamic = "force-static";
export const metadata: Metadata = {
title: "Configurator",
description: "Generate configuration file for your index",
};
export default function InternalConfiguratorPage() {
return <ConfiguratorPage />;
}
+14
View File
@@ -0,0 +1,14 @@
import { type Metadata } from "next";
import { DeployPage } from "~/components/internal";
export const dynamic = "force-static";
export const metadata: Metadata = {
title: "Deploying Guide",
description: "Read on how to deploy your own index instance",
};
export default function InternalDeployPage() {
return <DeployPage />;
}
@@ -0,0 +1,77 @@
import { type Metadata, type ResolvedMetadata } from "next";
import { notFound } from "next/navigation";
import { EmbedPage } from "~/components/internal";
import { ErrorComponent } from "~/components/layout";
import { GetFile } from "~/actions/files";
import { CheckPagePassword } from "~/actions/password";
import { ValidatePaths } from "~/actions/paths";
import { CreateFileToken } from "~/actions/token";
export const revalidate = 60;
export const dynamic = "force-dynamic";
type Props = {
params: Promise<{
rest: string[];
}>;
};
export async function generateMetadata({ params }: Props, parent: ResolvedMetadata): Promise<Metadata> {
const { rest } = await params;
const paths = await ValidatePaths(rest);
if (!paths.success) return { title: "Not Found" };
const currentPath = paths.data.pop();
if (!currentPath?.id) return { title: "Not Found" };
if (!currentPath.mimeType.includes("video") && !currentPath.mimeType.includes("audio")) return { title: "Not Found" };
return {
title: `${decodeURIComponent(currentPath.path)} (embed)`,
description: `Embed view of ${currentPath.path}`,
openGraph: {
images: parent.openGraph?.images,
},
};
}
export default async function InternalEmbedPage({ params }: Props) {
const { rest } = await params;
const paths = await ValidatePaths(rest);
if (!paths.success) notFound();
const unlocked = await CheckPagePassword(paths.data);
if (!unlocked.success) return <ErrorComponent error={new Error("Protected file cannot be embedded")} />;
const currentPath = paths.data.pop();
if (!currentPath) return <ErrorComponent error={new Error("Failed to get current path")} />;
if (!currentPath.mimeType.includes("video") && !currentPath.mimeType.includes("audio"))
return (
<div className='max-w-screen fixed left-0 top-0 grid h-full max-h-screen w-full place-items-center bg-transparent p-2'>
<ErrorComponent error={new Error("Only video and audio files can be embedded")} />
</div>
);
const file = await GetFile(currentPath.id);
if (!file.success) {
if (file.error === "NotFound") notFound();
return <ErrorComponent error={new Error(file.error)} />;
}
if (!file.data) return <ErrorComponent error={new Error("Failed to get file data")} />;
const token = await CreateFileToken(file.data);
if (!token.success) return <ErrorComponent error={new Error(token.error)} />;
return (
<div className='max-w-screen fixed left-0 top-0 grid h-full max-h-screen w-full place-items-center bg-transparent p-2'>
<EmbedPage
file={file.data}
type={currentPath.mimeType.includes("video") ? "video" : "audio"}
/>
</div>
);
}
+21
View File
@@ -0,0 +1,21 @@
import { type Metadata } from "next";
import { Status } from "~/components/global";
export const dynamic = "force-static";
export const metadata: Metadata = {
title: "Reserved Internal Path",
description: "This path is preserved for all internal pages, make sure you don't use this path on your google drive",
};
export default async function InternalRootPage() {
return (
<div className='grid grow place-items-center'>
<Status
icon='Lock'
message="This path is preserved for all internal pages, make sure you don't use this path on your google drive"
/>
</div>
);
}