update with 9f3df09 2022/11/16

This commit is contained in:
sevichecc 2022-11-16 14:01:37 +08:00
parent 2402a28938
commit c25250957e
12 changed files with 1701 additions and 1719 deletions

View file

@ -13,6 +13,7 @@ import { parse, join } from 'path'
import { visit } from 'unist-util-visit' import { visit } from 'unist-util-visit'
import { toString } from 'mdast-util-to-string' import { toString } from 'mdast-util-to-string'
import Slugger from 'github-slugger' import Slugger from 'github-slugger'
import remarkFFF from 'remark-fff'
import remarkFootnotes from 'remark-footnotes' import remarkFootnotes from 'remark-footnotes'
// highlighter // highlighter
@ -24,7 +25,7 @@ type VALUE = { [key in string | number]: VALUE } | Array<VALUE> | string | boole
const remarkUraraFm = const remarkUraraFm =
() => () =>
(tree: Node<Data>, { data, filename }: { data: { fm?: Record<string, unknown> }; filename?: string }) => { (tree: Node<Data>, { data, filename }: { data: { fm?: Record<string, unknown> }; filename?: string }) => {
const filepath = (filename as string).split('/src/routes')[1] const filepath = filename ? filename.split('/src/routes')[1] : 'unknown'
const { dir, name } = parse(filepath) const { dir, name } = parse(filepath)
if (!data.fm) data.fm = {} if (!data.fm) data.fm = {}
// Generate slug & path // Generate slug & path
@ -42,12 +43,6 @@ const remarkUraraFm =
}) })
data.fm.toc = toc data.fm.toc = toc
} }
// Auto-read created & updated
if (!data.fm.created || !data.fm.updated) {
const { ctime, mtime } = statSync(new URL(`./urara${filepath}`, import.meta.url))
if (!data.fm.created) data.fm.created = ctime
if (!data.fm.updated) data.fm.updated = mtime
}
} }
// Better type definitions needed // Better type definitions needed
@ -95,9 +90,24 @@ export default defineConfig({
)}\` }` )}\` }`
} }
}, },
remarkPlugins: [remarkUraraFm, remarkUraraSpoiler, [remarkFootnotes, { inlineNotes: true }]], remarkPlugins: [
[
remarkFFF as any,
{
presets: ['hugo'],
target: 'mdsvex',
autofill: {
provider: 'fs',
path: (path: string) => path.replace('/src/routes/', '/urara/')
}
}
],
remarkUraraFm,
remarkUraraSpoiler,
[remarkFootnotes, { inlineNotes: true }]
],
rehypePlugins: [ rehypePlugins: [
rehypeSlug, rehypeSlug as any,
[rehypeAutolinkHeadings, { behavior: 'wrap' }], [rehypeAutolinkHeadings, { behavior: 'wrap' }],
[ [
rehypeExternalLinks, rehypeExternalLinks,

View file

@ -28,59 +28,61 @@
"@iconify-json/heroicons-outline": "^1.1.4", "@iconify-json/heroicons-outline": "^1.1.4",
"@iconify-json/heroicons-solid": "^1.1.5", "@iconify-json/heroicons-solid": "^1.1.5",
"@iconify-json/ic": "^1.1.9", "@iconify-json/ic": "^1.1.9",
"@iconify-json/material-symbols": "1.1.16", "@iconify-json/material-symbols": "1.1.22",
"@iconify-json/mdi": "^1.1.31", "@iconify-json/mdi": "^1.1.34",
"@iconify-json/simple-icons": "1.1.25", "@iconify-json/simple-icons": "1.1.34",
"@iconify-json/uil": "^1.1.2", "@iconify-json/uil": "^1.1.2",
"@sveltejs/adapter-auto": "next", "@sveltejs/adapter-auto": "1.0.0-next.87",
"@sveltejs/adapter-node": "next", "@sveltejs/adapter-node": "1.0.0-next.100",
"@sveltejs/adapter-static": "next", "@sveltejs/adapter-static": "1.0.0-next.48",
"@sveltejs/kit": "1.0.0-next.502", "@sveltejs/kit": "1.0.0-next.544",
"@tailwindcss/typography": "^0.5.7", "@tailwindcss/typography": "^0.5.8",
"@types/node": "^18.7.16", "@types/node": "^18.11.9",
"@types/unist": "^2.0.6", "@types/unist": "^2.0.6",
"@typescript-eslint/eslint-plugin": "^5.36.2", "@types/workbox-build": "^5.0.1",
"@typescript-eslint/parser": "^5.36.2", "@typescript-eslint/eslint-plugin": "^5.42.1",
"autoprefixer": "^10.4.8", "@typescript-eslint/parser": "^5.42.1",
"chalk": "^5.0.1", "@vite-pwa/sveltekit": "^0.0.1",
"autoprefixer": "^10.4.13",
"chalk": "^5.1.2",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cssnano": "^5.1.13", "cssnano": "^5.1.14",
"daisyui": "^2.31.0", "daisyui": "^2.40.1",
"eslint": "^8.23.0", "eslint": "^8.27.0",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0", "eslint-plugin-svelte3": "^4.0.0",
"fenceparser": "2.0.0", "fenceparser": "2.2.0",
"fff-flavored-frontmatter": "~0.2.2", "fff-flavored-frontmatter": "~0.4.0",
"github-slugger": "^1.4.0", "github-slugger": "^2.0.0",
"mdast-util-to-string": "^3.1.0", "mdast-util-to-string": "^3.1.0",
"mdsvex": "^0.10.6", "mdsvex": "^0.10.6",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss": "^8.4.16", "postcss": "^8.4.19",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.7.0", "prettier-plugin-svelte": "^2.8.0",
"rehype-autolink-headings": "^6.1.1", "rehype-autolink-headings": "^6.1.1",
"rehype-external-links": "^1.0.1", "rehype-external-links": "^2.0.1",
"rehype-slug": "^5.0.1", "rehype-slug": "^5.1.0",
"remark": "^14.0.2", "remark": "^14.0.2",
"remark-fff": "^0.3.0", "remark-fff": "~0.4.0",
"remark-footnotes": "~2.0.0", "remark-footnotes": "~2.0.0",
"shiki-twoslash": "^3.1.0", "shiki-twoslash": "^3.1.0",
"svelte": "^3.50.1", "svelte": "^3.53.1",
"svelte-bricks": "^0.1.7", "svelte-bricks": "^0.1.7",
"svelte-check": "^2.9.0", "svelte-check": "^2.9.2",
"svelte-preprocess": "^4.10.7", "svelte-preprocess": "^4.10.7",
"svelte-typeahead": "^4.3.2", "svelte-typeahead": "^4.4.1",
"tailwindcss": "^3.1.8", "tailwindcss": "^3.2.4",
"tslib": "^2.4.0", "tslib": "^2.4.1",
"typescript": "^4.8.3", "typescript": "^4.8.4",
"unist-util-visit": "^4.1.1", "unist-util-visit": "^4.1.1",
"unocss": "^0.45.18", "unocss": "^0.46.5",
"vite": "^3.1.0", "vite": "^3.2.3",
"vite-plugin-pwa": "^0.12.7", "vite-plugin-pwa": "^0.13.3",
"workbox-window": "^6.5.4" "workbox-window": "^6.5.4"
}, },
"dependencies": { "dependencies": {
"netlify-cli": "^12.0.11" "netlify-cli": "^12.1.1"
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -1,39 +1,133 @@
<script lang="ts"> <script lang="ts">
import { dev } from '$app/environment' import { browser, dev } from '$app/environment'
import { head } from '$lib/config/general' import { fly } from 'svelte/transition'
import { site } from '$lib/config/site' import { site } from '$lib/config/site'
import OpenGraph from '$lib/components/head_opengraph.svelte' import { theme } from '$lib/config/general'
export let post: Urara.Post | undefined = undefined import { title as storedTitle } from '$lib/stores/title'
export let page: Urara.Page | undefined = undefined import { header as headerConfig } from '$lib/config/general'
import { hslToHex } from '$lib/utils/color'
import Nav from '$lib/components/header_nav.svelte'
import Search from '$lib/components/header_search.svelte'
export let path: string
let title: string
let currentTheme: string
let currentThemeColor: string
let search: boolean = false
let pin: boolean = true
let percent: number
let [scrollY, lastY] = [0, 0]
storedTitle.subscribe(storedTitle => (title = storedTitle as string))
$: if (browser && currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme)
currentThemeColor = hslToHex(
...(getComputedStyle(document.documentElement)
.getPropertyValue('--b1')
.slice(dev ? 1 : 0)
.replaceAll('%', '')
.split(' ')
.map(Number) as [number, number, number])
)
}
$: if (scrollY) {
pin = lastY - scrollY > 0 || scrollY === 0 ? true : false
lastY = scrollY
if (browser)
percent =
Math.round((scrollY / (document.documentElement.scrollHeight - document.documentElement.clientHeight)) * 10000) / 100
}
if (browser)
currentTheme =
localStorage.getItem('theme') ?? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
</script> </script>
<svelte:head> <svelte:head>
<meta name="author" content={site.author?.name} /> <meta name="theme-color" content={currentThemeColor} />
{#if post}
<link rel="canonical" href={site.protocol + site.domain + post.path} />
{#if post.type === 'article'}
<title>{post.title} | {site.title}</title>
{:else if post.type === 'note'}
<title>{post.summary ?? post.path.slice(1)} | {site.title}</title>
{/if}
{#if post.tags}<meta name="keywords" content={post.tags.join(', ')} />{/if}
{#if post.summary}<meta name="description" content={post.summary} />{/if}
{:else}
<meta name="description" content={site.description} />
<meta name="keywords" content={site.keywords?.join(', ')} />
{#if page}
<title>{page.title ?? page.path.slice(1)} | {site.title}</title>
<link rel="canonical" href={site.protocol + site.domain + page.path} />
{:else}
<title>{site.subtitle ? `${site.title} - ${site.subtitle}` : site.title}</title>
<link rel="canonical" href={site.protocol + site.domain} />
{/if}
{/if}
{#if head.custom}
{#each head.custom({ dev, post, page }) as tag}
{@html tag}
{/each}
{/if}
</svelte:head> </svelte:head>
<OpenGraph {post} {page} /> <svelte:window bind:scrollY />
<header
id="header"
class:-translate-y-32={!pin && scrollY > 0}
class="fixed z-50 w-screen transition-all duration-500 ease-in-out border-b-2 border-transparent max-h-[4.125rem] {scrollY >
32 && 'backdrop-blur border-base-content/10 bg-base-100/30 md:bg-base-200/30'}">
{#if !search}
<div in:fly={{ x: -50, duration: 300, delay: 300 }} out:fly={{ x: -50, duration: 300 }} class="navbar">
<div class="navbar-start">
{#if headerConfig.nav}
<Nav {path} {title} {pin} {scrollY} nav={headerConfig.nav} />
{/if}
<a href="/" sveltekit:prefetch class="btn btn-ghost normal-case text-lg">{site.title}</a>
</div>
<div class="navbar-end">
{#if headerConfig.search}
<button aria-label="search" on:click={() => (search = !search)} tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-search" />
</button>
{/if}
<div id="change-theme" class="dropdown dropdown-end">
<div tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-color-swatch" />
</div>
<ul
tabindex="0"
class="flex flex-nowrap shadow-2xl menu dropdown-content bg-base-100 text-base-content rounded-box w-52 p-2 gap-2 overflow-y-auto max-h-[21.5rem]"
class:hidden={!pin}>
{#each theme as { name, text }}
<button
data-theme={name}
on:click={() => {
currentTheme = name
localStorage.setItem('theme', name)
}}
class:border-2={currentTheme === name}
class:border-primary={currentTheme === name}
class="btn btn-ghost w-full hover:bg-primary group rounded-lg flex bg-base-100 p-2 transition-all">
<p class="flex-1 text-left text-base-content group-hover:text-primary-content transition-color">
{text ?? name}
</p>
<div class="flex-none m-auto flex gap-1">
<div class="bg-primary w-2 h-4 rounded" />
<div class="bg-secondary w-2 h-4 rounded" />
<div class="bg-accent w-2 h-4 rounded" />
<div class="bg-neutral w-2 h-4 rounded" />
</div>
</button>
{/each}
</ul>
</div>
</div>
</div>
{:else}
<div in:fly={{ x: 50, duration: 300, delay: 300 }} out:fly={{ x: 50, duration: 300 }} class="navbar">
<Search />
<button on:click={() => (search = !search)} tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-x" />
</button>
</div>
{/if}
</header>
<button
id="totop"
on:click={() => window.scrollTo(0, 0)}
class:translate-y-24={!pin || scrollY === 0}
aria-label="scroll to top"
class="fixed grid group btn btn-circle btn-lg border-none backdrop-blur bottom-6 right-6 z-50 duration-500 ease-in-out {percent >
95
? 'btn-accent shadow-lg'
: 'btn-ghost bg-base-100/30 md:bg-base-200/30'}"
class:opacity-100={scrollY}>
<div
class="radial-progress text-accent transition-all duration-500 ease-in-out group-hover:text-accent-focus col-start-1 row-start-1"
style={`--size:4rem; --thickness: 0.25rem; --value:${percent};`} />
<div
class:border-transparent={percent > 95}
class="border-4 border-base-content/10 group-hover:border-transparent col-start-1 row-start-1 rounded-full w-full h-full p-4 grid duration-500 ease-in-out">
<span class="i-heroicons-solid-chevron-up !w-6 !h-6" />
</div>
</button>

View file

@ -14,7 +14,7 @@
id="navbar-dropdown" id="navbar-dropdown"
tabindex="0" tabindex="0"
class:hidden={!pin} class:hidden={!pin}
class="menu menu-compact dropdown-content bg-base-100 text-base-content shadow-lg rounded-box max-w-52 p-2"> class="menu menu-compact dropdown-content bg-base-100 text-base-content shadow-lg rounded-box min-w-max max-w-52 p-2">
{#each nav as { text, link, children }} {#each nav as { text, link, children }}
{#if link && !children} {#if link && !children}
<li> <li>
@ -49,11 +49,11 @@
{#each nav as { text, link, children }} {#each nav as { text, link, children }}
{#if link && !children} {#if link && !children}
<li> <li>
<a sveltekit:prefetch class:font-bold={link === path} href={link}>{text}</a> <a sveltekit:prefetch class="!rounded-btn" class:font-bold={link === path} href={link}>{text}</a>
</li> </li>
{:else if children} {:else if children}
<li tabindex="0"> <li tabindex="0">
<span class:font-bold={children.some(({ link }) => link === path)} class="gap-1"> <span class:font-bold={children.some(({ link }) => link === path)} class="!rounded-btn gap-1">
{text} {text}
<span class="i-heroicons-solid-chevron-down -mr-1" /> <span class="i-heroicons-solid-chevron-down -mr-1" />
</span> </span>
@ -68,4 +68,4 @@
{/if} {/if}
{/each} {/each}
</ul> </ul>
</div> </div>

View file

@ -38,7 +38,7 @@
class:group={preview} class:group={preview}
class:image-full={preview && post.type === 'article' && post.image} class:image-full={preview && post.type === 'article' && post.image}
class:before:!rounded-none={preview && post.image} class:before:!rounded-none={preview && post.image}
class="h-entry card bg-base-100 rounded-none md:rounded-box md:shadow-xl z-10"> class="h-entry card bg-base-100 rounded-none md:rounded-box md:shadow-xl overflow-hidden z-10">
{#if !preview && postConfig.bridgy} {#if !preview && postConfig.bridgy}
<div id="bridgy" class="hidden"> <div id="bridgy" class="hidden">
{#each post.flags?.some( flag => flag.startsWith('bridgy') ) ? post.flags.flatMap( flag => (flag.startsWith('bridgy') ? flag.slice(7) : []) ) : [...(postConfig.bridgy.post ?? []), ...(postConfig.bridgy[post.type] ?? [])] as target} {#each post.flags?.some( flag => flag.startsWith('bridgy') ) ? post.flags.flatMap( flag => (flag.startsWith('bridgy') ? flag.slice(7) : []) ) : [...(postConfig.bridgy.post ?? []), ...(postConfig.bridgy[post.type] ?? [])] as target}

View file

@ -10,7 +10,7 @@
href={prev.path} href={prev.path}
class:image-full={prev['image']} class:image-full={prev['image']}
class:md:rounded-r-box={next && !next['image']} class:md:rounded-r-box={next && !next['image']}
class="flex-1 card group rounded-none before:!rounded-none"> class="flex-1 card group rounded-none before:!rounded-none overflow-hidden">
{#if prev['image']} {#if prev['image']}
<figure class="!block"> <figure class="!block">
<Image <Image
@ -37,7 +37,7 @@
href={next.path} href={next.path}
class:image-full={next['image']} class:image-full={next['image']}
class:md:rounded-l-box={prev && !prev['image']} class:md:rounded-l-box={prev && !prev['image']}
class="flex-1 card group rounded-none before:!rounded-none"> class="flex-1 card group rounded-none before:!rounded-none overflow-hidden">
{#if next['image']} {#if next['image']}
<figure class="!block"> <figure class="!block">
<Image <Image
@ -56,4 +56,4 @@
</div> </div>
</div> </div>
{/if} {/if}
</nav> </nav>

View file

@ -18,18 +18,18 @@
{site.author.name} {site.author.name}
</a> </a>
<span class:hidden={preview} class="opacity-50">/</span> <span class:hidden={preview} class="opacity-50">/</span>
<a href={post.path} class="swap hover:swap-active u-url u-uid"> <a href={post.path} class="u-url u-uid swap group/time">
<time <time
class="swap-off font-semibold opacity-75 duration-500 ease-in-out mr-auto dt-published" class="group-hover/time:opacity-0 font-semibold opacity-75 duration-500 ease-in-out mr-auto dt-published"
datetime={jsonPublished} datetime={jsonPublished}
itemprop="datePublished"> itemprop="datePublished">
{stringPublished} {stringPublished}
</time> </time>
<time <time
class="swap-on font-semibold text-primary duration-500 ease-in-out mr-auto dt-updated" class="opacity-0 group-hover/time:opacity-100 font-semibold text-primary duration-500 ease-in-out mr-auto dt-updated"
datetime={jsonUpdated} datetime={jsonUpdated}
itemprop="dateModified"> itemprop="dateModified">
{stringUpdated} {stringUpdated}
</time> </time>
</a> </a>
</div> </div>

View file

@ -20,6 +20,7 @@
!dev && !dev &&
browser && browser &&
registerSW({ registerSW({
immediate: true,
onRegistered: r => r && setInterval(async () => await r.update(), 198964), onRegistered: r => r && setInterval(async () => await r.update(), 198964),
onRegisterError: error => console.error(error) onRegisterError: error => console.error(error)
}) })

View file

@ -8,7 +8,6 @@
import Head from '$lib/components/head.svelte' import Head from '$lib/components/head.svelte'
import Footer from '$lib/components/footer.svelte' import Footer from '$lib/components/footer.svelte'
import Post from '$lib/components/post_card.svelte' import Post from '$lib/components/post_card.svelte'
// import Post from '$lib/components/index_post.svelte'
import Profile from '$lib/components/index_profile.svelte' import Profile from '$lib/components/index_profile.svelte'
let allPosts: Urara.Post[] let allPosts: Urara.Post[]
@ -18,9 +17,7 @@
storedTitle.set('') storedTitle.set('')
$: storedPosts.subscribe( $: storedPosts.subscribe(storedPosts => (allPosts = storedPosts.filter(post => !post.flags?.includes('unlisted'))))
storedPosts => (allPosts = (storedPosts as Urara.Post[]).filter(post => !post.flags?.includes('unlisted')))
)
$: storedTags.subscribe(storedTags => (allTags = storedTags as string[])) $: storedTags.subscribe(storedTags => (allTags = storedTags as string[]))

View file

@ -25,6 +25,9 @@ export default defineConfig({
assets: 'build', assets: 'build',
fallback: undefined fallback: undefined
}), }),
prerender: {
handleMissingId: 'warn'
},
csp: { mode: 'auto' } csp: { mode: 'auto' }
} }
}) })

View file

@ -3,7 +3,7 @@ import { defineConfig } from 'vite'
// vite plugin // vite plugin
import UnoCSS from 'unocss/vite' import UnoCSS from 'unocss/vite'
import { presetTagify, presetIcons, extractorSvelte } from 'unocss' import { presetTagify, presetIcons, extractorSvelte } from 'unocss'
import { VitePWA } from 'vite-plugin-pwa' import { SvelteKitPWA } from '@vite-pwa/sveltekit'
import { sveltekit } from '@sveltejs/kit/vite' import { sveltekit } from '@sveltejs/kit/vite'
// postcss & tailwindcss // postcss & tailwindcss
import TailwindCSS from 'tailwindcss' import TailwindCSS from 'tailwindcss'
@ -16,7 +16,7 @@ export default defineConfig({
css: { css: {
postcss: { postcss: {
plugins: [ plugins: [
TailwindCSS(tailwindConfig as any) as any, TailwindCSS(tailwindConfig),
autoprefixer(), autoprefixer(),
...(process.env.NODE_ENV === 'production' ...(process.env.NODE_ENV === 'production'
? [ ? [
@ -39,13 +39,11 @@ export default defineConfig({
presetIcons({ scale: 1.5 }) presetIcons({ scale: 1.5 })
] ]
}), }),
VitePWA({ sveltekit(),
srcDir: './build', SvelteKitPWA({
outDir: './.svelte-kit/output/client',
registerType: 'autoUpdate', registerType: 'autoUpdate',
scope: '/', manifest: false,
base: '/' scope: '/'
}), })
sveltekit()
] ]
}) })