Add button-driven search filters
This commit is contained in:
@@ -157,13 +157,42 @@ describe('post feed route wiring', () => {
|
||||
await waitFor(() =>
|
||||
expect(usePostFeed).toHaveBeenCalledWith({
|
||||
kind: 'search',
|
||||
query: 'AI lang:ja',
|
||||
query: 'AI lang:ja filter:follows',
|
||||
product: 'Top',
|
||||
following: true,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('compiles button-selected search conditions from the URL', async () => {
|
||||
await renderRoute(
|
||||
'/search?q=TypeScript&from=%40tan_stack&since=2026-08-04&until=2026-08-11&lang=ja&content=images&excludeReplies=true&excludeReposts=true&product=Latest&following=false',
|
||||
)
|
||||
|
||||
await waitFor(() =>
|
||||
expect(usePostFeed).toHaveBeenCalledWith({
|
||||
kind: 'search',
|
||||
query:
|
||||
'TypeScript from:tan_stack since:2026-08-04 until:2026-08-11 lang:ja filter:images -filter:replies -filter:retweets',
|
||||
product: 'Latest',
|
||||
following: false,
|
||||
}),
|
||||
)
|
||||
expect(
|
||||
screen.getByRole('button', { name: '投稿者 @tan_stack を解除' }),
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
it('keeps contradictory date parameters local and idle', async () => {
|
||||
await renderRoute(
|
||||
'/search?q=TypeScript&since=2026-08-11&until=2026-08-10&product=Latest&following=false',
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '期間' }))
|
||||
expect(await screen.findByLabelText('開始日')).toHaveValue('2026-08-11')
|
||||
expect(usePostFeed).toHaveBeenCalledWith(undefined)
|
||||
})
|
||||
|
||||
it('turns a decimal status path into a deliberate thread request', async () => {
|
||||
await renderRoute('/yuta/status/123')
|
||||
|
||||
|
||||
+44
-8
@@ -1,34 +1,70 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
import { AppShell } from '#/components/app-shell'
|
||||
import { PostFeed } from '#/features/posts/components/post-feed'
|
||||
import { SearchForm } from '#/features/posts/components/search-form'
|
||||
import { postSearchRouteSchema } from '#/features/posts/inputs'
|
||||
import {
|
||||
SearchForm,
|
||||
type SearchValues,
|
||||
} from '#/features/posts/components/search-form'
|
||||
import {
|
||||
buildFilteredSearchQuery,
|
||||
postSearchRouteSchema,
|
||||
} from '#/features/posts/inputs'
|
||||
|
||||
export const Route = createFileRoute('/search')({
|
||||
validateSearch: (search) => postSearchRouteSchema.parse(search),
|
||||
component: SearchRoute,
|
||||
})
|
||||
|
||||
function compileQuery(values: SearchValues): string | undefined {
|
||||
if (!values.q && !values.from) return undefined
|
||||
try {
|
||||
return buildFilteredSearchQuery(values, values.following)
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function SearchRoute() {
|
||||
const values = Route.useSearch()
|
||||
const navigate = Route.useNavigate()
|
||||
const formValues = {
|
||||
...values,
|
||||
from: values.from ?? '',
|
||||
since: values.since ?? '',
|
||||
until: values.until ?? '',
|
||||
lang: values.lang ?? 'all',
|
||||
content: values.content ?? 'all',
|
||||
excludeReplies: values.excludeReplies ?? false,
|
||||
excludeReposts: values.excludeReposts ?? false,
|
||||
} satisfies SearchValues
|
||||
const query = compileQuery(formValues)
|
||||
const formKey = [
|
||||
formValues.q,
|
||||
formValues.from,
|
||||
formValues.since,
|
||||
formValues.until,
|
||||
formValues.lang,
|
||||
formValues.content,
|
||||
formValues.excludeReplies,
|
||||
formValues.excludeReposts,
|
||||
formValues.product,
|
||||
formValues.following,
|
||||
].join(':')
|
||||
return (
|
||||
<AppShell active="search">
|
||||
<h1>何を確認しますか?</h1>
|
||||
<p className="intro">入力した条件だけを検索します。</p>
|
||||
<SearchForm
|
||||
initialFollowing={values.following}
|
||||
initialProduct={values.product}
|
||||
initialQuery={values.q}
|
||||
key={`${values.q}:${values.product}:${values.following}`}
|
||||
initialValues={formValues}
|
||||
key={formKey}
|
||||
onSubmit={(search) => navigate({ search })}
|
||||
/>
|
||||
<PostFeed
|
||||
request={
|
||||
values.q
|
||||
query
|
||||
? {
|
||||
kind: 'search',
|
||||
query: values.q,
|
||||
query,
|
||||
product: values.product,
|
||||
following: values.following,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user