fix searching

This commit is contained in:
polv committed 2020-12-18 09:37:43 +07:00
1 parent 25585aa3da
commit 43edfb60d4
10 files changed
+119 -95

No files matched your search

-8
View File
@@ -1,8 +0,0 @@
export function formatDate (s: string | number) {
return new Date(s).toLocaleDateString([], {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'short'
})
}
+27 -29
View File
@@ -1,14 +1,19 @@
import { THEME } from '~/assets/global' import { THEME } from '~/assets/global'
import styles from '~/styles/Layout.module.css'
import Link from 'next/link' import Link from 'next/link'
import { ReactNode } from 'react' import { useRouter } from 'next/router'
import { ReactNode, useState } from 'react'
const Layout = ({ children }: { children: ReactNode | ReactNode[] }) => {
const router = useRouter()
const [q, setQ] = useState(router.query.q as string)
const Layout = ({ children }: { children: ReactNode }) => {
return ( return (
<main> <main>
<header> <header className={styles.Header}>
<h1>{THEME.title}</h1> <h1>{THEME.title}</h1>
<nav> <nav className={styles.Nav}>
<ul> <ul>
<li> <li>
<Link href="/"> <Link href="/">
@@ -34,35 +39,28 @@ const Layout = ({ children }: { children: ReactNode }) => {
)} )}
</ul> </ul>
<form> <form
<input name="q" type="search" placeholder="Search..." /> className={styles.Form}
<div className="icon">🔎</div> onSubmit={(ev) => {
if (router.pathname.startsWith('/post/')) {
ev.preventDefault()
router.push(`/blog?q=${encodeURIComponent(q)}`)
}
}}
>
<input
name="q"
type="search"
placeholder="Search..."
value={q}
onInput={(ev) => setQ((ev.target as HTMLInputElement).value)}
/>
<div className={styles.icon}>🔎</div>
</form> </form>
</nav> </nav>
</header> </header>
{children} {children}
<style jsx>{`
nav ul {
display: inline-block;
}
form {
float: right;
max-width: 300px;
position: relative;
}
form .icon {
position: absolute;
right: 5px;
top: 5px;
}
input {
padding-right: 1.5em;
}
`}</style>
</main> </main>
) )
} }
+6 -3
View File
@@ -36,8 +36,9 @@ const PostQuery = ({
return pathname return pathname
} }
const [posts, setPosts] = useState(defaults.posts) const [posts, setPosts] = useState([] as IPost[])
const [count, setCount] = useState(defaults.count) const [count, setCount] = useState(0)
const [isLoading, setLoading] = useState(true)
useEffect(() => { useEffect(() => {
if (router.query.q) { if (router.query.q) {
@@ -62,13 +63,15 @@ const PostQuery = ({
setPosts(defaults.posts) setPosts(defaults.posts)
setCount(defaults.count) setCount(defaults.count)
} }
setLoading(false)
}, [router.query.q, router.query.page, router.query.tag]) }, [router.query.q, router.query.page, router.query.tag])
const totalPages = Math.ceil(count / 5) const totalPages = Math.ceil(count / 5)
return ( return (
<article> <article>
{posts.length ? ( {isLoading ? null : posts.length ? (
posts.map((p) => <PostTeaser post={p} key={p.path} />) posts.map((p) => <PostTeaser post={p} key={p.path} />)
) : ( ) : (
<p>No posts found.</p> <p>No posts found.</p>
+4 -27
View File
@@ -1,8 +1,8 @@
import { THEME } from '~/assets/global'
import { formatDate } from '~/assets/util'
import { IPost } from '~/server/db' import { IPost } from '~/server/db'
import Link from 'next/link' import Link from 'next/link'
import TitleDescription from './TitleDesciption'
const PostTeaser = ({ post }: { post: IPost }) => { const PostTeaser = ({ post }: { post: IPost }) => {
return ( return (
<section> <section>
@@ -12,31 +12,8 @@ const PostTeaser = ({ post }: { post: IPost }) => {
</Link> </Link>
</h2> </h2>
<small> <TitleDescription date={post.date} />
<span> <article dangerouslySetInnerHTML={{ __html: post.excerptHtml }}></article>
by&nbsp;
{THEME.author.url ? (
<a
href={THEME.author.url}
target="_blank"
rel="noopener noreferrer"
>
{THEME.author.name}
</a>
) : (
<span>{THEME.author.name}</span>
)}
</span>
{post.date ? (
<span style={{ float: 'right' }}>{formatDate(post.date)}</span>
) : null}
</small>
<article
style={{ marginTop: '2rem' }}
dangerouslySetInnerHTML={{ __html: post.excerptHtml }}
></article>
</section> </section>
) )
} }
@@ -0,0 +1,32 @@
import { THEME } from '~/assets/global'
import styles from '~/styles/TitleDescription.module.css'
const TitleDescription = ({ date }: { date?: number }) => {
return (
<small className={styles.Small}>
<span>
by&nbsp;
{THEME.author.url ? (
<a href={THEME.author.url} target="_blank" rel="noopener noreferrer">
{THEME.author.name}
</a>
) : (
<span>{THEME.author.name}</span>
)}
</span>
{date ? (
<span className={styles.date}>
{new Date(date).toLocaleDateString([], {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'short'
})}
</span>
) : null}
</small>
)
}
export default TitleDescription
+13 -24
View File
@@ -1,7 +1,7 @@
import '~/assets/remark42' import '~/assets/remark42'
import { THEME } from '~/assets/global' import { THEME } from '~/assets/global'
import { formatDate } from '~/assets/util' import TitleDescription from '~/components/TitleDesciption'
import { IPost, dbPost, initDatabase } from '~/server/db' import { IPost, dbPost, initDatabase } from '~/server/db'
import styles from '~/styles/PostPage.module.css' import styles from '~/styles/PostPage.module.css'
import { GetStaticPaths, GetStaticProps } from 'next' import { GetStaticPaths, GetStaticProps } from 'next'
@@ -18,12 +18,22 @@ const PostPage = (post: IPost) => {
window.remark42Instance.destroy() window.remark42Instance.destroy()
} }
const initRemark42 = () => {
window.remark42Instance = window.REMARK42.createInstance({ window.remark42Instance = window.REMARK42.createInstance({
node: remark42Ref.current, node: remark42Ref.current,
host: THEME.comment.remark42.host, host: THEME.comment.remark42.host,
site_id: THEME.comment.remark42.siteId site_id: THEME.comment.remark42.siteId
}) })
} }
if (window.REMARK42) {
initRemark42()
} else {
window.addEventListener('REMARK42::ready', () => {
initRemark42()
})
}
}
}, [remark42Ref.current]) }, [remark42Ref.current])
return ( return (
@@ -53,26 +63,7 @@ const PostPage = (post: IPost) => {
<section> <section>
<h2>{post.title}</h2> <h2>{post.title}</h2>
<small> <TitleDescription date={post.date} />
<span>
by{' '}
{THEME.author.url ? (
<a
href={THEME.author.url}
target="_blank"
rel="noopener noreferrer"
>
{THEME.author.name}
</a>
) : (
<span>{THEME.author.name}</span>
)}
</span>
{post.date ? (
<span style={{ float: 'right' }}>{formatDate(post.date)}</span>
) : null}
</small>
</section> </section>
<section dangerouslySetInnerHTML={{ __html: post.contentHtml }} /> <section dangerouslySetInnerHTML={{ __html: post.contentHtml }} />
@@ -105,9 +96,7 @@ export const getStaticPaths: GetStaticPaths = async () => {
await initDatabase() await initDatabase()
return { return {
paths: dbPost paths: dbPost.find().map(({ path }) => ({
.find()
.map(({ path }) => ({
params: { path: path.split(/\//g).map(encodeURIComponent) } params: { path: path.split(/\//g).map(encodeURIComponent) }
})), })),
fallback: false fallback: false
+2 -2
View File
@@ -58,9 +58,9 @@ export let db: Loki
export let dbPost: Collection<IPost> export let dbPost: Collection<IPost>
export let idx: lunr.Index let idx: lunr.Index
export async function initLunr () { export async function getLunr () {
return idx || lunr.Index.load(require('../build/idx.json')) return idx || lunr.Index.load(require('../build/idx.json'))
} }
+2 -2
View File
@@ -1,4 +1,4 @@
import { dbPost, idx, initDatabase, initLunr } from './db' import { dbPost, getLunr, initDatabase } from './db'
export async function doSearch ({ export async function doSearch ({
q, q,
@@ -10,7 +10,7 @@ export async function doSearch ({
page?: number page?: number
}) { }) {
await initDatabase() await initDatabase()
await initLunr() const idx = await getLunr()
const perPage = 5 const perPage = 5
const offset = (page - 1) * perPage const offset = (page - 1) * perPage
+23
View File
@@ -0,0 +1,23 @@
.Header {
margin-bottom: 4rem;
}
.Nav ul {
display: inline-block;
}
.Form {
float: right;
max-width: 300px;
position: relative;
}
.Form input {
padding-right: 1.5em;
}
.Form .icon {
position: absolute;
right: 5px;
top: 5px;
}
@@ -0,0 +1,10 @@
.Small {
display: block;
min-height: 4em;
}
.Small .date {
float: right;
min-width: 15em;
text-align: right;
}