Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds the ability to view draft posts in dev mode #223

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import remarkToc from "remark-toc";
import remarkCollapse from "remark-collapse";
import sitemap from "@astrojs/sitemap";
import { SITE } from "./src/config";
import draftModeIntergration from "./src/toolbar/draftMode/draftModeIntergration";

// https://astro.build/config
export default defineConfig({
Expand All @@ -15,6 +16,7 @@ export default defineConfig({
}),
react(),
sitemap(),
draftModeIntergration,
],
markdown: {
remarkPlugins: [
Expand Down
12 changes: 9 additions & 3 deletions src/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface Props {
}

export default function Card({ href, frontmatter, secHeading = true }: Props) {
const { title, pubDatetime, modDatetime, description } = frontmatter;
const { title, pubDatetime, modDatetime, description, draft } = frontmatter;

const headerProps = {
style: { viewTransitionName: slugifyStr(title) },
Expand All @@ -23,9 +23,15 @@ export default function Card({ href, frontmatter, secHeading = true }: Props) {
className="inline-block text-lg font-medium text-skin-accent decoration-dashed underline-offset-4 focus-visible:no-underline focus-visible:underline-offset-0"
>
{secHeading ? (
<h2 {...headerProps}>{title}</h2>
<h2 {...headerProps}>
{draft ? "DRAFT: " : ""}
{title}
</h2>
) : (
<h3 {...headerProps}>{title}</h3>
<h3 {...headerProps}>
{draft ? "DRAFT: " : ""}
{title}
</h3>
)}
</a>
<Datetime pubDatetime={pubDatetime} modDatetime={modDatetime} />
Expand Down
5 changes: 4 additions & 1 deletion src/layouts/PostDetails.astro
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const {
pubDatetime,
modDatetime,
tags,
draft,
} = post.data;

const { Content } = await post.render();
Expand Down Expand Up @@ -59,7 +60,9 @@ const layoutProps = {
</button>
</div>
<main id="main-content">
<h1 transition:name={slugifyStr(title)} class="post-title">{title}</h1>
<h1 transition:name={slugifyStr(title)} class="post-title">
{draft ? "DRAFT: " : ""}{title}
</h1>
<Datetime
pubDatetime={pubDatetime}
modDatetime={modDatetime}
Expand Down
4 changes: 3 additions & 1 deletion src/pages/posts/[slug]/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import PostDetails from "@layouts/PostDetails.astro";
import getSortedPosts from "@utils/getSortedPosts";
import getPageNumbers from "@utils/getPageNumbers";
import getPagination from "@utils/getPagination";
import { draftFilter } from "@utils/postFilters";

export interface Props {
post: CollectionEntry<"blog">;
}

export async function getStaticPaths() {
const posts = await getCollection("blog", ({ data }) => !data.draft);
const posts = await getCollection("blog", draftFilter);

const postResult = posts.map(post => ({
params: { slug: post.slug },
Expand Down Expand Up @@ -39,3 +40,4 @@ const pagination = getPagination({
---

{post ? <PostDetails post={post} /> : <Posts {...pagination} />}
@utils/postFilters
satnaing marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 3 additions & 1 deletion src/pages/search.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import Main from "@layouts/Main.astro";
import Header from "@components/Header.astro";
import Footer from "@components/Footer.astro";
import SearchBar from "@components/Search";
import { draftFilter } from "@utils/postFilters";

// Retrieve all articles
const posts = await getCollection("blog", ({ data }) => !data.draft);
const posts = await getCollection("blog", draftFilter);

// List of items to search in
const searchList = posts.map(({ data, slug }) => ({
Expand All @@ -26,3 +27,4 @@ const searchList = posts.map(({ data, slug }) => ({
</Main>
<Footer />
</Layout>
@utils/postFilters
4 changes: 3 additions & 1 deletion src/pages/tags/[tag]/[page].astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import getUniqueTags from "@utils/getUniqueTags";
import getPostsByTag from "@utils/getPostsByTag";
import getPageNumbers from "@utils/getPageNumbers";
import getPagination from "@utils/getPagination";
import { draftFilter } from "@utils/postFilters";

export interface Props {
post: CollectionEntry<"blog">;
Expand All @@ -31,7 +32,7 @@ export async function getStaticPaths() {
const { page } = Astro.params;
const { tag, tagName } = Astro.props;

const posts = await getCollection("blog", ({ data }) => !data.draft);
const posts = await getCollection("blog", draftFilter);

const postsByTag = getPostsByTag(posts, tag);

Expand All @@ -42,3 +43,4 @@ const pagination = getPagination({
---

<TagPosts {...pagination} {tag} {tagName} />
@utils/postFilters
47 changes: 47 additions & 0 deletions src/toolbar/draftMode/draftModeClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export default {
id: "draft-mode",
name: `Toggle Draft Mode ${
localStorage.getItem("DRAFT_MODE") === "true" ? "Off" : "On"
}`,
icon:
localStorage.getItem("DRAFT_MODE") === "true"
? `<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pencil" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" /><path d="M13.5 6.5l4 4" /></svg>`
: `<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pencil-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M10 10l-6 6v4h4l6 -6m1.99 -1.99l2.504 -2.504a2.828 2.828 0 1 0 -4 -4l-2.5 2.5" /><path d="M13.5 6.5l4 4" /><path d="M3 3l18 18" /></svg>`,
init(canvas, eventTarget) {
console.debug("Initrialising: setting block to TRUE");
let block = true;

eventTarget.addEventListener("app-toggled", event => {
if (!block) {
console.debug(
`Draft Mode has been toggled to ${
event.detail.state ? "enabled" : "disabled"
} mode.`
);
localStorage.setItem("DRAFT_MODE", event.detail.state);
location.reload();
} else {
console.debug(
"App-Toggled Event blocked until initialiation is completed."
);
}
});
import.meta.hot?.on("draftMode:sync", data => {
const bool = data === "true";
if (localStorage.getItem("DRAFT_MODE") !== data) {
console.log(
"Mismatch between server mode and client mode, syncing with the Server. The window will reload."
);
localStorage.setItem("DRAFT_MODE", bool);
location.reload();
}
console.debug("draftMode:sync event triggered, setting state to :", bool);
eventTarget.dispatchEvent(
new CustomEvent("toggle-app", { detail: { state: bool } })
);

console.debug("unblocking the state and reload as init has completed");
block = false;
});
},
};
13 changes: 13 additions & 0 deletions src/toolbar/draftMode/draftModeIntergration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { draftModeServer } from "./draftModeServer";

export default {
name: "Draft-Mode",
hooks: {
"astro:config:setup": ({ addDevToolbarApp }) => {
addDevToolbarApp("./src/toolbar/draftMode/draftModeClient.js");
},
"astro:server:setup": ({ server }) => {
draftModeServer(server);
},
satnaing marked this conversation as resolved.
Show resolved Hide resolved
},
};
30 changes: 30 additions & 0 deletions src/toolbar/draftMode/draftModeServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export function draftModeServer(server) {
let block = true;
if (process.env.DRAFT_MODE === undefined) {
console.debug("DRAFT_MODE env not set, defaulting to false");
process.env.DRAFT_MODE = false;
}
server.ws.on("astro-dev-toolbar:draft-mode:toggled", data => {
if (!block) {
console.debug(
`Draft Mode has been toggled to ${data.state ? "enabled" : "disabled"}!`
);
process.env.DRAFT_MODE = data.state;
} else {
console.debug("still initialising, action blocked");
}
});
server.ws.on("astro-dev-toolbar:draft-mode:initialized", () => {
console.debug(
"Draft Mode has been initialised, removing blocks and sending sync"
);
block = false;
server.ws.send("draftMode:sync", process.env.DRAFT_MODE);
});
server.ws.on("connection", () => {
console.debug(
"Client has connected, initialisation will begin, blocking updates until complete."
);
block = true;
});
}
3 changes: 2 additions & 1 deletion src/utils/getSortedPosts.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { CollectionEntry } from "astro:content";
import { draftFilter } from "./postFilters";

const getSortedPosts = (posts: CollectionEntry<"blog">[]) => {
return posts
.filter(({ data }) => !data.draft)
.filter(draftFilter)
.sort(
(a, b) =>
Math.floor(
Expand Down
3 changes: 2 additions & 1 deletion src/utils/getUniqueTags.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { draftFilter } from "./postFilters";
import { slugifyStr } from "./slugify";
import type { CollectionEntry } from "astro:content";

Expand All @@ -7,7 +8,7 @@ interface Tag {
}

const getUniqueTags = (posts: CollectionEntry<"blog">[]) => {
const filteredPosts = posts.filter(({ data }) => !data.draft);
const filteredPosts = posts.filter(draftFilter);
const tags: Tag[] = filteredPosts
.flatMap(post => post.data.tags)
.map(tag => ({ tag: slugifyStr(tag), tagName: tag }))
Expand Down
5 changes: 5 additions & 0 deletions src/utils/postFilters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { CollectionEntry } from "astro:content";

export const draftFilter = ({ data }: CollectionEntry<"blog">) => {
return process.env.DRAFT_MODE === "true" || !data.draft;
};