Skip to content

Commit

Permalink
refactor codeblock theme handling
Browse files Browse the repository at this point in the history
Signed-off-by: Vu Van Dung <me@joulev.dev>
  • Loading branch information
joulev committed Dec 13, 2023
1 parent 579eb57 commit 2a192e1
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ next-env.d.ts
.next-types
src/lib/gql
.fonts
.theme
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
"version": "0.1.0",
"private": true,
"scripts": {
"build": "pnpm download-fonts && pnpm codegen && next build",
"build": "pnpm download-fonts && pnpm download-theme && pnpm codegen && next build",
"codegen": "graphql-codegen --config codegen.ts",
"db:push": "drizzle-kit push:pg",
"deploy-worker": "wrangler deploy misc/multi-tenancy-worker.ts --name multi-tenant-on-website --compatibility-date 2023-12-05",
"dev": "pnpm download-fonts && concurrently \"pnpm codegen --watch\" \"next dev\"",
"download-fonts": "./scripts/download-fonts.sh",
"download-theme": "./scripts/download-theme.sh",
"format": "prettier --write .",
"lint": "next lint",
"start": "next start"
Expand Down
9 changes: 9 additions & 0 deletions scripts/download-theme.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

mkdir -p ./.theme
cd ./.theme

echo -n "Downloading theme file..."
curl -L "https://l.joulev.dev/theme" -o "theme.json" -s
echo " done"
cd ..
5 changes: 2 additions & 3 deletions src/app/(public)/apps/snippets/create-snippet-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { redirect } from "next/navigation";
import { getHighlighter, toShikiTheme } from "shikiji";
import * as v from "valibot";

import { env } from "~/env.mjs";
import themeJson from "~/../.theme/theme.json";
import { db } from "~/lib/db";
import { codeSnippets } from "~/lib/db/schema";

Expand All @@ -21,8 +21,7 @@ function processCode(code: string) {
}

async function highlightCode(code: string, language: string) {
const themeJson: unknown = await fetch(env.EDITOR_THEME_URL).then(r => r.json());
const theme = toShikiTheme(themeJson as Parameters<typeof toShikiTheme>[0]);
const theme = toShikiTheme(themeJson as unknown as Parameters<typeof toShikiTheme>[0]);
const highlighter = await getHighlighter({ themes: [theme], langs: [language] });
return highlighter.codeToHtml(code, { theme: theme.name, lang: language });
}
Expand Down
1 change: 0 additions & 1 deletion src/app/(public)/apps/snippets/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export function Editor() {
<input type="hidden" name="language" value={language} />
<ShikiEditor
name="code"
theme="/editor-theme"
language={language}
tabSize={tabSize}
value={code}
Expand Down
8 changes: 0 additions & 8 deletions src/app/editor-theme/route.ts

This file was deleted.

26 changes: 7 additions & 19 deletions src/components/shiki-editor.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { type Highlighter, type ThemeRegistration, getHighlighter, toShikiTheme } from "shikiji";

import themeJson from "~/../.theme/theme.json";

interface ShikiEditorProps {
name: string;
/**
* URL to the theme JSON
*/
theme: string;
language: string;
tabSize?: number;
value: string;
Expand All @@ -20,25 +18,13 @@ interface Shiki {

const preloadedLanguages = ["tsx", "css", "html", "json"];

async function getShikiTheme(theme: string) {
const themeJson: unknown = await fetch(theme).then(r => r.json());
return toShikiTheme(themeJson as Parameters<typeof toShikiTheme>[0]);
}

async function delay(ms: number): Promise<void> {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}

export function ShikiEditor({
name,
theme,
language,
tabSize = 2,
value,
onChange,
}: ShikiEditorProps) {
export function ShikiEditor({ name, language, tabSize = 2, value, onChange }: ShikiEditorProps) {
const [shiki, setShiki] = useState<Shiki | Error | null>(null);
const [loadedLanguages, setLoadedLanguages] = useState<string[]>(preloadedLanguages);
const [displayedLanguage, setDisplayedLanguage] = useState(language);
Expand Down Expand Up @@ -87,14 +73,16 @@ export function ShikiEditor({
// Load Shiki
useEffect(() => {
(async () => {
const resolvedTheme = await getShikiTheme(theme);
const resolvedTheme = toShikiTheme(
themeJson as unknown as Parameters<typeof toShikiTheme>[0],
);
const highlighter = await getHighlighter({
themes: [resolvedTheme],
langs: preloadedLanguages,
});
setShiki({ highlighter, theme: resolvedTheme });
})().catch(() => setShiki(new Error()));
}, [theme]);
}, []);

// Load languages that are not preloaded
useEffect(() => {
Expand Down
1 change: 0 additions & 1 deletion src/env.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export const env = createEnv({
GITHUB_TOKEN: z.string().startsWith("ghp_"),
RECENT_FAVOURITE_PLAYLIST_ID: z.string().length(YOUTUBE_PLAYLIST_ID_LENGTH),
DATABASE_URL: z.string().startsWith("postgres://"),
EDITOR_THEME_URL: z.string().url(),

// irasuto
R2_ACCOUNT_ID: z.string().min(1),
Expand Down

0 comments on commit 2a192e1

Please sign in to comment.