Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions blog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import type {
export { Fragment, h };

const IS_DEV = Deno.args.includes("--dev") && "watchFs" in Deno;
const POSTS = new Map<string, Post>();
let POSTS = new Map<string, Post>();
const HMR_SOCKETS: Set<WebSocket> = new Set();

const HMR_CLIENT = `let socket;
Expand Down Expand Up @@ -199,6 +199,12 @@ async function loadContent(blogDirectory: string, isDev: boolean) {
}
}

POSTS = new Map(
Array.from(POSTS).sort(([, a], [, b]) =>
b.publishDate.getTime() - a.publishDate.getTime()
),
);

if (isDev) {
watchForChanges(postsDirectory).catch(() => {});
}
Expand Down Expand Up @@ -345,6 +351,11 @@ export async function handler(
}

if (pathname === "/") {
let index = 0;
if (searchParams.get("page")?.match(/^[0-9]+$/)) {
index = Number(searchParams.get("page"));
}
const tagPosts = filterPosts(POSTS, searchParams);
return html({
...sharedHtmlOptions,
title: blogState.title ?? "My Blog",
Expand All @@ -364,12 +375,45 @@ export async function handler(
body: (
<Index
state={blogState}
posts={filterPosts(POSTS, searchParams)}
index={index}
postsLength={tagPosts.size}
posts={getPostsByPage(tagPosts, index)}
tag={searchParams}
/>
),
});
}

// if (pathname === "/") {
// const tagPosts = filterPosts(POSTS, searchParams);
// return html({
// ...sharedHtmlOptions,
// title: blogState.title ?? "My Blog",
// meta: {
// "description": blogState.description,
// "og:title": blogState.title,
// "og:description": blogState.description,
// "og:image": ogImage ?? blogState.cover,
// "twitter:title": blogState.title,
// "twitter:description": blogState.description,
// "twitter:image": ogImage ?? blogState.cover,
// "twitter:card": ogImage ? twitterCard : undefined,
// },
// styles: [
// ...(blogState.style ? [blogState.style] : []),
// ],
// body: (
// <Index
// state={blogState}
// postsLength={tagPosts.size}
// posts={getPostsPage(tagPosts, 0)}
// index={0}
// searchParams={searchParams}
// />
// ),
// });
// }

const post = POSTS.get(pathname);
if (post) {
return html({
Expand Down Expand Up @@ -523,6 +567,17 @@ export function redirects(redirectMap: Record<string, string>): BlogMiddleware {
};
}

function getPostsByPage(
posts: Map<string, Post>,
index: number,
) {
const i = Math.round(index);
if (i < 0) return new Map();
return new Map(
Array.from(posts.entries()).slice(i * 10, i * 10 + 10),
);
}

function filterPosts(
posts: Map<string, Post>,
searchParams: URLSearchParams,
Expand Down
87 changes: 86 additions & 1 deletion components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,71 @@ const socialAppIcons = new Map([
["linkedin.com", IconLinkedin],
]);

interface PaginationProps {
index: number;
type: "forward" | "backward" | "both";
tag: string | null;
}
function Pagination({ index, type, tag }: PaginationProps) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the UI is not good, i will add a mockup later

let t;
if (tag) t = "&tag=" + tag;
else t = "";
const page = (
<div class="mt-3 flex gap-2 items-center justify-center">
{(type === "backward" || type === "both")
? (
<a
href={`/?page=${index - 1}${t}`}
class="relative flex items-center justify-center w-8 h-8 rounded-full bg-gray-600/10 dark:bg-gray-400/10 text-gray-700 dark:text-gray-400 hover:bg-gray-600/15 dark:hover:bg-gray-400/15 hover:text-black dark:hover:text-white transition-colors group"
>
<IconPrevious />
</a>
)
: ""}
{(type === "forward" || type === "both")
? (
<a
href={`/?page=${index + 1}${t}`}
class="relative flex items-center justify-center w-8 h-8 rounded-full bg-gray-600/10 dark:bg-gray-400/10 text-gray-700 dark:text-gray-400 hover:bg-gray-600/15 dark:hover:bg-gray-400/15 hover:text-black dark:hover:text-white transition-colors group"
>
<IconNext />
</a>
)
: ""}
</div>
);
return page;
}

interface IndexProps {
state: BlogState;
posts: Map<string, Post>;
index: number;
postsLength: number;
tag: URLSearchParams;
}

export function Index({ state, posts }: IndexProps) {
export function Index(
{ state, posts, index, postsLength, tag }: IndexProps,
) {
const postIndex = [];
for (const [_key, post] of posts.entries()) {
postIndex.push(post);
}
postIndex.sort(
(a, b) => (b.publishDate?.getTime() ?? 0) - (a.publishDate?.getTime() ?? 0),
);
let page;
const t = tag.get("tag");
if ((index + 1) * 10 >= postsLength && index !== 0) {
page = <Pagination tag={t} index={index} type={"backward"} />;
} else if (index === 0 && (index + 1) * 10 >= postsLength) {
page = "";
} else if (index === 0) {
page = <Pagination tag={t} index={index} type={"forward"} />;
} else {
page = <Pagination tag={t} index={index} type={"both"} />;
}

return (
<div class="home">
Expand Down Expand Up @@ -114,6 +166,7 @@ export function Index({ state, posts }: IndexProps) {
/>
))}
</div>
{page}

{state.footer || <Footer author={state.author} />}
</div>
Expand Down Expand Up @@ -356,6 +409,38 @@ function IconExternalLink() {
);
}

function IconPrevious() {
return (
<svg
className="inline-block w-5 h-5"
viewBox="0 0 512 512"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="currentColor"
d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"
/>
</svg>
);
}

function IconNext() {
return (
<svg
className="inline-block w-5 h-5"
viewBox="0 0 512 512"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="currentColor"
d="M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"
/>
</svg>
);
}

function IconGithub() {
return (
<svg
Expand Down