114 lines
2.8 KiB
TypeScript
114 lines
2.8 KiB
TypeScript
/// <reference path="../types/jsx.d.ts" />
|
|
import { React, Marked } from "../deps.ts";
|
|
import type { IPackage } from "../db.ts";
|
|
import { sortVersions } from "../utils.ts";
|
|
|
|
import Prism from "../vendor/prism.ts";
|
|
|
|
interface IEntryParams {
|
|
name: string;
|
|
size?: number;
|
|
directory?: true;
|
|
}
|
|
|
|
export function Entry({ name, size, directory }: IEntryParams) {
|
|
return (
|
|
<a class="browse-list-item" href={"./" + name + (directory ? "/" : "")}>
|
|
<img src={directory ? "/public/folder.svg" : "/public/file.svg"} />
|
|
<span>{name}</span>
|
|
{size && <span class="browse-list-item-size">{size}</span>}
|
|
</a>
|
|
);
|
|
}
|
|
|
|
interface IEntryListParams {
|
|
files: { name: string; size: number }[];
|
|
directories: { name: string }[];
|
|
}
|
|
|
|
export function EntryList({ directories, files }: IEntryListParams) {
|
|
return (
|
|
<div class="card" style="padding: 1rem;">
|
|
<div>
|
|
{directories.map((e) => (
|
|
<Entry name={e.name} directory />
|
|
))}
|
|
{files.map((e) => (
|
|
<Entry name={e.name} size={e.size} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface IRenderFileInterface {
|
|
content: string;
|
|
ext: string;
|
|
}
|
|
|
|
const languages: { [key: string]: string } = {
|
|
js: "javascript",
|
|
cjs: "javascript",
|
|
mjs: "javascript",
|
|
ts: "typescript",
|
|
c: "clike",
|
|
svelte: "html",
|
|
cs: "csharp",
|
|
hb: "handlebars",
|
|
ps: "powershell",
|
|
sh: "bash",
|
|
bat: "batch",
|
|
yml: "yaml",
|
|
};
|
|
|
|
export function RenderFile({ content, ext }: IRenderFileInterface) {
|
|
if (ext === ".md") {
|
|
content = Marked.parse(content).content;
|
|
return (
|
|
<div
|
|
class="card browse-code-block"
|
|
style="margin-top: 1rem; padding: 1rem;"
|
|
innerHTML={content}
|
|
/>
|
|
);
|
|
} else {
|
|
let lang = languages[ext.replace(".", "")] || ext.replace(".", "");
|
|
|
|
if (Prism.languages[lang]) {
|
|
content = Prism.highlight(content, Prism.languages[lang], lang);
|
|
}
|
|
|
|
return <pre innerHTML={content} />;
|
|
}
|
|
}
|
|
|
|
interface IBrowseHeaderParams {
|
|
pkg: IPackage;
|
|
version?: string;
|
|
path: string;
|
|
}
|
|
|
|
export function BrowseHeader({ pkg, version, path }: IBrowseHeaderParams) {
|
|
return (
|
|
<>
|
|
<div style="display: flex;">
|
|
<div>
|
|
<h2 style="margin-bottom: 0">Browse: {pkg.name}</h2>
|
|
<h4 class="text-muted" style="margin-top: 0; margin-left: .5rem">
|
|
By {pkg.owner}
|
|
</h4>
|
|
</div>
|
|
<div>
|
|
Version:
|
|
<select>
|
|
{pkg.versions.sort(sortVersions).map((v) => (
|
|
<option selected={version === v}>{v}</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="browse-path">{path}</div>
|
|
</>
|
|
);
|
|
}
|