You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
5.5 KiB

import sass from "https://deno.land/x/denosass@1.0.6/mod.ts";
import { Story } from "../wattpad.ts";
import { h, PropsWithChildren } from "../jsx.ts";
import Header from "../components/Header.tsx";
import VR from "../components/VerticalLine.tsx";
interface StoryProps {
story: Story;
currentHref: string;
style?: string;
stylepath?: string;
}
export default (props: PropsWithChildren<StoryProps>) => {
let chaptersInHeader: { name: string; href: string; element?: unknown }[] =
[
{
name: "Homepage",
href: `/`
},
{
name: "",
href: "",
element: <VR />
},
{
name: "Details",
href: `/story?id=${props.story.id}`
},
{
name: "",
href: "",
element: <VR />
}
];
chaptersInHeader = chaptersInHeader.concat(
props.story.storyJSON.parts.map((ch, i) => ({
name: ch.title,
href: `/story?id=${props.story.id}&chapter=${i}`
}))
);
const isChapter = props.currentHref.includes("chapter=");
// FIXME: shouldn't be hardcoded
const currentURL = new URL(
"https://voltpad.ruthenic.com" + props.currentHref
);
const chapterNum = Number(currentURL.searchParams.get("chapter") ?? 0);
return (
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
{/* favicon stuff generated with https://realfavicongenerator.net */}
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<link
rel="mask-icon"
href="/safari-pinned-tab.svg"
color="#5bbad5"
/>
<meta name="apple-mobile-web-app-title" content="Voltpad" />
<meta name="application-name" content="Voltpad" />
<meta name="msapplication-TileColor" content="#2b5797" />
<meta name="theme-color" content="#ffffff" />
<meta property="og:type" content="article" />
<meta
property="article:author"
content={
props.story.storyJSON.user.fullname === ""
? props.story.storyJSON.user.name
: props.story.storyJSON.user.fullname
}
></meta>
<meta property="og:url" content={currentURL.toString()}></meta>
{isChapter ? (
<meta
property="og:title"
content={props.story.chapters[chapterNum].name}
/>
) : (
<meta property="og:title" content={props.story.name} />
)}
{isChapter ? (
props.story.chapters[0].partJSON.photoUrl ? (
<meta
property="og:image"
content={
props.story.chapters[chapterNum].partJSON
.photoUrl
}
/>
) : undefined
) : undefined}
{isChapter ? (
props.story.chapters[0].partJSON.videoId ? (
<meta
property="og:video"
content={`https://www.youtube.com/v/${props.story.chapters[chapterNum].partJSON.videoId}`}
/>
) : undefined
) : undefined}
{isChapter ? undefined : (
<meta
property="og:description"
content={
/* FIXME: should prob expose voltpad's wattpad html parser and run it through that */
props.story.storyJSON.description
.replaceAll('"', "'")
.replaceAll("<br>", "\n")
}
/>
)}
<title>{props.story.name}</title>
{(() => {
if (!props.style) props.style = "";
if (props.stylepath)
props.style += Deno.readTextFileSync(props.stylepath);
else return <div></div>;
return <style>{sass(props.style).to_string()}</style>;
})()}
</head>
<Header
id="storyHeader"
entries={chaptersInHeader}
currentHref={props.currentHref}
></Header>
<div class="main">{props.children}</div>
</html>
);
};