This commit is contained in:
@@ -68,13 +68,32 @@ const prefetchWikiPageShow: Prefetcher = async (qc, url) => {
|
|||||||
|
|
||||||
const prefetchPostsIndex: Prefetcher = async (qc, url) => {
|
const prefetchPostsIndex: Prefetcher = async (qc, url) => {
|
||||||
const tags = url.searchParams.get ('tags') ?? ''
|
const tags = url.searchParams.get ('tags') ?? ''
|
||||||
const m = url.searchParams.get ('match') === 'any' ? 'any' : 'all'
|
const qURL = url.searchParams.get ('url')
|
||||||
|
const title = url.searchParams.get ('title')
|
||||||
|
const originalCreatedFrom = url.searchParams.get ('original_created_from')
|
||||||
|
const originalCreatedTo = url.searchParams.get ('original_created_to')
|
||||||
|
const createdFrom = url.searchParams.get ('created_from')
|
||||||
|
const createdTo = url.searchParams.get ('created_to')
|
||||||
|
const updatedFrom = url.searchParams.get ('updated_from')
|
||||||
|
const updatedTo = url.searchParams.get ('updated_to')
|
||||||
|
const m: 'all' | 'any' = url.searchParams.get ('match') === 'any' ? 'any' : 'all'
|
||||||
const page = Number (url.searchParams.get ('page') || 1)
|
const page = Number (url.searchParams.get ('page') || 1)
|
||||||
const limit = Number (url.searchParams.get ('limit') || 20)
|
const limit = Number (url.searchParams.get ('limit') || 20)
|
||||||
|
|
||||||
|
const keys = {
|
||||||
|
tags, match: m, page, limit,
|
||||||
|
...(qURL && { url: qURL }),
|
||||||
|
...(title && { title }),
|
||||||
|
...(originalCreatedFrom && { original_created_from: originalCreatedFrom }),
|
||||||
|
...(originalCreatedTo && { original_created_to: originalCreatedTo }),
|
||||||
|
...(createdFrom && { created_from: createdFrom }),
|
||||||
|
...(createdTo && { created_to: createdTo }),
|
||||||
|
...(updatedFrom && { updated_from: updatedFrom }),
|
||||||
|
...(updatedTo && { updated_to: updatedTo }) }
|
||||||
|
|
||||||
await qc.prefetchQuery ({
|
await qc.prefetchQuery ({
|
||||||
queryKey: postsKeys.index ({ tags, match: m, page, limit }),
|
queryKey: postsKeys.index (keys),
|
||||||
queryFn: () => fetchPosts ({ tags, match: m, page, limit }) })
|
queryFn: () => fetchPosts (keys) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -103,7 +122,8 @@ const prefetchPostChanges: Prefetcher = async (qc, url) => {
|
|||||||
|
|
||||||
|
|
||||||
export const routePrefetchers: { test: (u: URL) => boolean; run: Prefetcher }[] = [
|
export const routePrefetchers: { test: (u: URL) => boolean; run: Prefetcher }[] = [
|
||||||
{ test: u => u.pathname === '/' || u.pathname === '/posts', run: prefetchPostsIndex },
|
{ test: u => ['/', '/posts', '/posts/search'].includes (u.pathname),
|
||||||
|
run: prefetchPostsIndex },
|
||||||
{ test: u => (!(['/posts/new', '/posts/changes', '/posts/search'].includes (u.pathname))
|
{ test: u => (!(['/posts/new', '/posts/changes', '/posts/search'].includes (u.pathname))
|
||||||
&& Boolean (mPost (u.pathname))),
|
&& Boolean (mPost (u.pathname))),
|
||||||
run: prefetchPostShow },
|
run: prefetchPostShow },
|
||||||
@@ -119,5 +139,6 @@ export const prefetchForURL = async (qc: QueryClient, urlLike: string): Promise<
|
|||||||
const r = routePrefetchers.find (x => x.test (u))
|
const r = routePrefetchers.find (x => x.test (u))
|
||||||
if (!(r))
|
if (!(r))
|
||||||
return
|
return
|
||||||
|
|
||||||
await r.run (qc, u)
|
await r.run (qc, u)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
import { Helmet } from 'react-helmet-async'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
import PrefetchLink from '@/components/PrefetchLink'
|
import PrefetchLink from '@/components/PrefetchLink'
|
||||||
import TagLink from '@/components/TagLink'
|
import TagLink from '@/components/TagLink'
|
||||||
@@ -11,42 +12,56 @@ import Pagination from '@/components/common/Pagination'
|
|||||||
import MainArea from '@/components/layout/MainArea'
|
import MainArea from '@/components/layout/MainArea'
|
||||||
import { SITE_TITLE } from '@/config'
|
import { SITE_TITLE } from '@/config'
|
||||||
import { fetchPosts } from '@/lib/posts'
|
import { fetchPosts } from '@/lib/posts'
|
||||||
|
import { postsKeys } from '@/lib/queryKeys'
|
||||||
|
|
||||||
import type { FC, FormEvent } from 'react'
|
import type { FC, FormEvent } from 'react'
|
||||||
|
|
||||||
import type { Post } from '@/types'
|
|
||||||
|
|
||||||
|
|
||||||
export default (() => {
|
export default (() => {
|
||||||
const [createdFrom, setCreatedFrom] = useState<string | undefined> ()
|
const navigate = useNavigate ()
|
||||||
const [createdTo, setCreatedTo] = useState<string | undefined> ()
|
|
||||||
const [matchType, setMatchType] = useState<'all' | 'any'> ('all')
|
|
||||||
const [originalCreatedFrom, setOriginalCreatedFrom] = useState<string | undefined> ()
|
|
||||||
const [originalCreatedTo, setOriginalCreatedTo] = useState<string | undefined> ()
|
|
||||||
const [tagsStr, setTagsStr] = useState ('')
|
|
||||||
const [title, setTitle] = useState ('')
|
|
||||||
const [updatedFrom, setUpdatedFrom] = useState<string | undefined> ()
|
|
||||||
const [updatedTo, setUpdatedTo] = useState<string | undefined> ()
|
|
||||||
const [url, setURL] = useState ('')
|
|
||||||
const [results, setResults] = useState<Post[]> ([])
|
|
||||||
const [totalPages, setTotalPages] = useState (0)
|
|
||||||
|
|
||||||
const location = useLocation ()
|
const location = useLocation ()
|
||||||
const query = new URLSearchParams (location.search)
|
const query = new URLSearchParams (location.search)
|
||||||
const page = Number (query.get ('page') ?? 1)
|
const page = Number (query.get ('page') ?? 1)
|
||||||
const limit = Number (query.get ('limit') ?? 20)
|
const limit = Number (query.get ('limit') ?? 20)
|
||||||
|
|
||||||
|
const [createdFrom, setCreatedFrom] =
|
||||||
|
useState<string | null> (query.get ('created_from'))
|
||||||
|
const [createdTo, setCreatedTo] =
|
||||||
|
useState<string | null> (query.get ('created_to'))
|
||||||
|
const [matchType, setMatchType] =
|
||||||
|
useState<'all' | 'any'> ((query.get ('match') as 'all' | 'any' | null) ?? 'all')
|
||||||
|
const [originalCreatedFrom, setOriginalCreatedFrom] =
|
||||||
|
useState<string | null> (query.get ('original_created_from'))
|
||||||
|
const [originalCreatedTo, setOriginalCreatedTo] =
|
||||||
|
useState<string | null> (query.get ('original_created_to'))
|
||||||
|
const [tagsStr, setTagsStr] = useState (query.get ('tags') ?? '')
|
||||||
|
const [title, setTitle] = useState (query.get ('title') ?? '')
|
||||||
|
const [updatedFrom, setUpdatedFrom] =
|
||||||
|
useState<string | null> (query.get ('updated_from'))
|
||||||
|
const [updatedTo, setUpdatedTo] =
|
||||||
|
useState<string | null> (query.get ('updated_to'))
|
||||||
|
const [url, setURL] = useState (query.get ('url') ?? '')
|
||||||
|
|
||||||
|
const keys = {
|
||||||
|
tags: tagsStr, match: matchType, page, limit,
|
||||||
|
...(url && { url }),
|
||||||
|
...(title && { title }),
|
||||||
|
...(originalCreatedFrom && { original_created_from: originalCreatedFrom }),
|
||||||
|
...(originalCreatedTo && { original_created_to: originalCreatedTo }),
|
||||||
|
...(createdFrom && { created_from: createdFrom }),
|
||||||
|
...(createdTo && { created_to: createdTo }),
|
||||||
|
...(updatedFrom && { updated_from: updatedFrom }),
|
||||||
|
...(updatedTo && { updated_to: updatedTo }) }
|
||||||
|
const { data, /* isLoading: loading */ } = useQuery ({
|
||||||
|
queryKey: postsKeys.index (keys), queryFn: () => fetchPosts (keys) })
|
||||||
|
const results = data?.posts ?? []
|
||||||
|
const totalPages = data ? Math.ceil (data.count / limit) : 0
|
||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
const tags = tagsStr.split (' ').filter (e => e !== '')
|
const qs = new URLSearchParams (location.search)
|
||||||
const data = await fetchPosts ({
|
qs.set ('page', String ('1'))
|
||||||
url, title, tags: tags.join (' '), match: matchType,
|
navigate (`${ location.pathname }?${ qs.toString () }`)
|
||||||
created_from: createdFrom, created_to: createdTo,
|
|
||||||
updated_from: updatedFrom, updated_to: updatedTo,
|
|
||||||
original_created_from: originalCreatedFrom,
|
|
||||||
original_created_to: originalCreatedTo,
|
|
||||||
page, limit })
|
|
||||||
setResults (data.posts)
|
|
||||||
setTotalPages (data ? Math.ceil (data.count / limit) : 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSearch = (e: FormEvent) => {
|
const handleSearch = (e: FormEvent) => {
|
||||||
@@ -118,11 +133,11 @@ export default (() => {
|
|||||||
<Label>オリジナルの投稿日時</Label>
|
<Label>オリジナルの投稿日時</Label>
|
||||||
<DateTimeField
|
<DateTimeField
|
||||||
value={originalCreatedFrom ?? undefined}
|
value={originalCreatedFrom ?? undefined}
|
||||||
onChange={isoUTC => setOriginalCreatedFrom (isoUTC ?? undefined)}/>
|
onChange={setOriginalCreatedFrom}/>
|
||||||
<span className="mx-1">〜</span>
|
<span className="mx-1">〜</span>
|
||||||
<DateTimeField
|
<DateTimeField
|
||||||
value={originalCreatedTo ?? undefined}
|
value={originalCreatedTo ?? undefined}
|
||||||
onChange={isoUTC => setOriginalCreatedTo (isoUTC ?? undefined)}/>
|
onChange={setOriginalCreatedTo}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 投稿日時 */}
|
{/* 投稿日時 */}
|
||||||
@@ -130,11 +145,11 @@ export default (() => {
|
|||||||
<Label>投稿日時</Label>
|
<Label>投稿日時</Label>
|
||||||
<DateTimeField
|
<DateTimeField
|
||||||
value={createdFrom ?? undefined}
|
value={createdFrom ?? undefined}
|
||||||
onChange={isoUTC => setCreatedFrom (isoUTC ?? undefined)}/>
|
onChange={setCreatedFrom}/>
|
||||||
<span className="mx-1">〜</span>
|
<span className="mx-1">〜</span>
|
||||||
<DateTimeField
|
<DateTimeField
|
||||||
value={createdTo ?? undefined}
|
value={createdTo ?? undefined}
|
||||||
onChange={isoUTC => setCreatedTo (isoUTC ?? undefined)}/>
|
onChange={setCreatedTo}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 更新日時 */}
|
{/* 更新日時 */}
|
||||||
@@ -142,11 +157,11 @@ export default (() => {
|
|||||||
<Label>更新日時</Label>
|
<Label>更新日時</Label>
|
||||||
<DateTimeField
|
<DateTimeField
|
||||||
value={updatedFrom ?? undefined}
|
value={updatedFrom ?? undefined}
|
||||||
onChange={isoUTC => setUpdatedFrom (isoUTC ?? undefined)}/>
|
onChange={setUpdatedFrom}/>
|
||||||
<span className="mx-1">〜</span>
|
<span className="mx-1">〜</span>
|
||||||
<DateTimeField
|
<DateTimeField
|
||||||
value={updatedTo ?? undefined}
|
value={updatedTo ?? undefined}
|
||||||
onChange={isoUTC => setUpdatedTo (isoUTC ?? undefined)}/>
|
onChange={setUpdatedTo}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 検索 */}
|
{/* 検索 */}
|
||||||
|
|||||||
Reference in New Issue
Block a user