add language detection
This commit is contained in:
@ -1,9 +1,10 @@
|
||||
import { ReactElement } from "react";
|
||||
import { cache, ReactElement } from "react";
|
||||
import { ActionMenu } from "@/app/components/action-menu";
|
||||
import { Metadata } from "next";
|
||||
import moment from "moment";
|
||||
import { notFound } from "next/navigation";
|
||||
import { CodeBlock } from "@/app/components/codeBlock";
|
||||
import { detectLanguage } from "@/app/common/lang-detection/detection";
|
||||
|
||||
type PasteProps = {
|
||||
params: {
|
||||
@ -21,25 +22,14 @@ type Paste = {
|
||||
* The date the paste was created.
|
||||
*/
|
||||
created: number;
|
||||
|
||||
/**
|
||||
* The detected language of the paste.
|
||||
*/
|
||||
language: string;
|
||||
};
|
||||
|
||||
export async function generateMetadata({
|
||||
params: { id },
|
||||
}: PasteProps): Promise<Metadata> {
|
||||
const data: Paste | undefined = await getData(id);
|
||||
if (data == undefined) {
|
||||
return {
|
||||
description: "Not found",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
title: `Paste - ${id}`,
|
||||
description: `Created: ${moment(data.created)}\n\nClick to view the paste.`,
|
||||
};
|
||||
}
|
||||
|
||||
async function getData(id: string): Promise<Paste | undefined> {
|
||||
const getPaste = cache(async (id: string) => {
|
||||
const response: Response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_API_ENDPOINT}/${id}`,
|
||||
{
|
||||
@ -53,13 +43,33 @@ async function getData(id: string): Promise<Paste | undefined> {
|
||||
if (json.code && json.message) {
|
||||
return undefined;
|
||||
}
|
||||
return json as Paste;
|
||||
return {
|
||||
content: json.content,
|
||||
created: json.created,
|
||||
language: await detectLanguage(json.content),
|
||||
};
|
||||
}) as (id: string) => Promise<Paste | undefined>;
|
||||
|
||||
export async function generateMetadata({
|
||||
params: { id },
|
||||
}: PasteProps): Promise<Metadata> {
|
||||
const data: Paste | undefined = await getPaste(id);
|
||||
if (data == undefined) {
|
||||
return {
|
||||
description: "Not found",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
title: `Paste - ${id}`,
|
||||
description: `Created: ${moment(data.created)}\n\nClick to view the paste.`,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Paste({
|
||||
params: { id },
|
||||
}: PasteProps): Promise<ReactElement> {
|
||||
const data: Paste | undefined = await getData(id);
|
||||
const data: Paste | undefined = await getPaste(id);
|
||||
|
||||
if (data == undefined) {
|
||||
return notFound();
|
||||
@ -67,7 +77,10 @@ export default async function Paste({
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<ActionMenu />
|
||||
<div className="absolute top-0 right-0 flex flex-col items-end mx-3 mt-2">
|
||||
<ActionMenu />
|
||||
<p>{data.language}</p>
|
||||
</div>
|
||||
|
||||
<div className="p-1 hljs !bg-transparent text-sm">
|
||||
<CodeBlock code={data.content} />
|
||||
|
@ -45,9 +45,11 @@ export default function Home(): ReactElement {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ActionMenu>
|
||||
<Button onClick={() => createPaste()}>Save</Button>
|
||||
</ActionMenu>
|
||||
<div className="absolute top-0 right-0 mx-3 mt-2">
|
||||
<ActionMenu>
|
||||
<Button onClick={() => createPaste()}>Save</Button>
|
||||
</ActionMenu>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
25
src/app/common/lang-detection/detection.ts
Normal file
25
src/app/common/lang-detection/detection.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ModelOperations } from "@vscode/vscode-languagedetection";
|
||||
import fs from "node:fs";
|
||||
|
||||
const dir = `${process.cwd()}/src/app/common/lang-detection`;
|
||||
|
||||
const modelOperations = new ModelOperations({
|
||||
modelJsonLoaderFunc: async () => {
|
||||
const response = await fs.promises.readFile(dir + "/model.json");
|
||||
return JSON.parse(response.toString());
|
||||
},
|
||||
weightsLoaderFunc: async () => {
|
||||
const response = await fs.promises.readFile(dir + "/weights.bin");
|
||||
return response.buffer;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Detects the programming language of the given content.
|
||||
*
|
||||
* @param content The content to detect the language of.
|
||||
*/
|
||||
export async function detectLanguage(content: string) {
|
||||
const languages = await modelOperations.runModel(content);
|
||||
return languages.length > 0 ? languages[0].languageId : "Text";
|
||||
}
|
1
src/app/common/lang-detection/model.json
Normal file
1
src/app/common/lang-detection/model.json
Normal file
File diff suppressed because one or more lines are too long
BIN
src/app/common/lang-detection/weights.bin
Normal file
BIN
src/app/common/lang-detection/weights.bin
Normal file
Binary file not shown.
@ -8,7 +8,7 @@ type ActionMenuProps = {
|
||||
|
||||
export function ActionMenu({ children }: ActionMenuProps) {
|
||||
return (
|
||||
<div className="absolute top-0 right-0 flex items-center mx-3 mt-2 bg-secondary rounded-md p-2 gap-2">
|
||||
<div className="flex items-center bg-secondary rounded-md p-2 gap-2">
|
||||
{children}
|
||||
<Link href={"/"}>
|
||||
<Button>New</Button>
|
||||
|
Reference in New Issue
Block a user