アイヌ語追加 (#428) (#433)

Reviewed-on: #433
Co-authored-by: miteruzo <miteruzo@naver.com>
このコミットはプルリクエスト #433 でマージされました。
このコミットが含まれているのは:
2026-10-20 20:44:14 +09:00
committed by みてるぞ
コミット 084a090cab
294個のファイルの変更、13978行の追加、3461行の削除
+55 -38
ファイルの表示
@@ -1,10 +1,11 @@
import { useQuery } from '@tanstack/react-query'
import { motion } from 'framer-motion'
import { useEffect, useMemo, useState } from 'react'
import { Helmet } from 'react-helmet-async'
import { useLocation, useNavigate } from 'react-router-dom'
import { useLocation } from 'react-router-dom'
import { useLocale, useLocaleNavigate } from '@/lib/useLocale'
import PrefetchLink from '@/components/PrefetchLink'
import LocalisedText from '@/components/LocalisedText'
import SortHeader from '@/components/SortHeader'
import TagLink from '@/components/TagLink'
import DateTimeField from '@/components/common/DateTimeField'
@@ -13,7 +14,7 @@ import PageTitle from '@/components/common/PageTitle'
import Pagination from '@/components/common/Pagination'
import TagInput from '@/components/common/TagInput'
import MainArea from '@/components/layout/MainArea'
import { SITE_TITLE } from '@/config'
import PageHead from '@/components/common/PageHead'
import { clientAnimationTransition,
clientScrollBehaviour } from '@/lib/clientAnimation'
import { fetchPosts } from '@/lib/posts'
@@ -28,7 +29,9 @@ import {
} from '@/lib/settings'
import { useClientBehaviourSettings } from '@/lib/useClientBehaviourSettings'
import { useKeyboardShortcuts } from '@/lib/useKeyboardShortcuts'
import { dateString, inputClass, originalCreatedAtString } from '@/lib/utils'
import { localisedDateString, inputClass, originalCreatedAtString } from '@/lib/utils'
import { useUITranslation } from '@/lib/useUITranslation'
import { useHydrated } from '@/lib/useHydrated'
import type { FC, FormEvent } from 'react'
@@ -70,6 +73,9 @@ const parseOrder = (value: string | null): FetchPostsOrder | null => {
const PostSearchPage: FC = () => {
const locale = useLocale ()
const hydrated = useHydrated ()
const { message, label } = useUITranslation ('posts')
const behaviourSettings = useClientBehaviourSettings ()
const animationMode = behaviourSettings.animation ?? 'normal'
const thumbnailTransition = clientAnimationTransition (
@@ -79,7 +85,7 @@ const PostSearchPage: FC = () => {
)
const location = useLocation ()
const navigate = useNavigate ()
const navigate = useLocaleNavigate ()
const query = useMemo (() => new URLSearchParams (location.search),
[location.search])
@@ -87,7 +93,7 @@ const PostSearchPage: FC = () => {
const page = Number (query.get ('page') ?? 1)
const limit = (
parseLimit (query.get ('limit'))
?? getClientListLimit ('postSearch')
?? (hydrated ? getClientListLimit ('postSearch') : null)
?? DEFAULT_POST_LIST_LIMIT
)
@@ -103,7 +109,7 @@ const PostSearchPage: FC = () => {
const qUpdatedTo = query.get ('updated_to') ?? ''
const order = (
parseOrder (query.get ('order'))
?? getClientListOrder<FetchPostsOrder> ('postSearch')
?? (hydrated ? getClientListOrder<FetchPostsOrder> ('postSearch') : null)
?? DEFAULT_POST_LIST_ORDER
)
@@ -120,6 +126,7 @@ const PostSearchPage: FC = () => {
const keys: FetchPostsParams = {
tags: qTags, match: qMatch, page, limit,
...(query.get ('tag_refs') && { tagReferences: query.get ('tag_refs')! }),
url: qURL,
title: qTitle,
originalCreatedFrom: qOriginalCreatedFrom,
@@ -130,14 +137,16 @@ const PostSearchPage: FC = () => {
updatedTo: qUpdatedTo,
order }
const { data, isLoading: loading } = useQuery ({
queryKey: postsKeys.index (keys),
queryFn: () => fetchPosts (keys) })
queryKey: postsKeys.index (keys, locale),
queryFn: () => fetchPosts (keys, locale) })
const results = data?.posts ?? []
const totalPages = data ? Math.ceil (data.count / limit) : 0
useEffect (() => {
if (!hydrated)
return
setClientListSettings ('postSearch', { limit, order })
}, [limit, order])
}, [hydrated, limit, order])
useEffect (() => {
setURL (qURL ?? '')
@@ -220,15 +229,13 @@ const PostSearchPage: FC = () => {
return (
<MainArea>
<Helmet>
<title>広場検索 | {SITE_TITLE}</title>
</Helmet>
<PageHead title={message ('search.title')}/>
<div className="max-w-xl">
<div className="flex flex-wrap items-center justify-between gap-3">
<PageTitle>広場検索</PageTitle>
<PageTitle>{label ('search.title')}</PageTitle>
<label className="flex items-center gap-2 text-xs text-muted-foreground">
<span>件数</span>
<span>{label ('common:countLabel')}</span>
<select
className="rounded border border-border bg-background px-2 py-1 text-sm
text-foreground"
@@ -246,7 +253,7 @@ const PostSearchPage: FC = () => {
<form onSubmit={handleSearch} className="space-y-2">
{/* タイトル */}
<FormField label="タイトル">
<FormField label={label ('shared:labels.title')}>
{({ invalid }) => (
<input
type="text"
@@ -257,7 +264,7 @@ const PostSearchPage: FC = () => {
</FormField>
{/* URL */}
<FormField label="URL">
<FormField label={label ('shared:url')}>
{({ invalid }) => (
<input
type="text"
@@ -267,7 +274,7 @@ const PostSearchPage: FC = () => {
</FormField>
{/* タグ */}
<FormField label="タグ">
<FormField label={label ('navigation:tags')}>
{() => (
<TagInput
includeNico={true}
@@ -276,14 +283,14 @@ const PostSearchPage: FC = () => {
</FormField>
<div>
<fieldset className="w-full my-2">
<label>検索区分:</label>
<label>{label ('search.matchType')}</label>
<label className="mx-2">
<input
type="radio"
name="match-type"
checked={matchType === 'all'}
onChange={() => setMatchType ('all')}/>
AND
{label ('search.all')}
</label>
<label className="mx-2">
<input
@@ -291,13 +298,13 @@ const PostSearchPage: FC = () => {
name="match-type"
checked={matchType === 'any'}
onChange={() => setMatchType ('any')}/>
OR
{label ('search.any')}
</label>
</fieldset>
</div>
{/* オリジナルの投稿日時 */}
<FormField label="オリジナルの投稿日時">
<FormField label={label ('history:originalPostedAt')}>
{() => (
<>
<DateTimeField
@@ -311,7 +318,7 @@ const PostSearchPage: FC = () => {
</FormField>
{/* 投稿日時 */}
<FormField label="投稿日時">
<FormField label={label ('search.createdAt')}>
{() => (
<>
<DateTimeField
@@ -325,7 +332,7 @@ const PostSearchPage: FC = () => {
</FormField>
{/* 更新日時 */}
<FormField label="更新日時">
<FormField label={label ('tags:updatedAt')}>
{() => (
<>
<DateTimeField
@@ -343,13 +350,13 @@ const PostSearchPage: FC = () => {
<button
type="submit"
className="bg-blue-500 text-white px-4 py-2 rounded">
検索
{label ('common:search')}
</button>
</div>
</form>
</div>
{loading ? 'Loading...' : (results.length > 0 ? (
{loading ? label ('common:loading') : (results.length > 0 ? (
<div className="mt-4">
<div className="overflow-x-auto">
<table className="w-full min-w-[1200px] table-fixed border-collapse">
@@ -365,40 +372,40 @@ const PostSearchPage: FC = () => {
<thead className="border-b-2 border-black dark:border-white">
<tr>
<th className="p-2 text-left whitespace-nowrap">投稿</th>
<th className="p-2 text-left whitespace-nowrap">{label ('history:post')}</th>
<th className="p-2 text-left whitespace-nowrap">
<SortHeader<FetchPostsOrderField>
by="title"
label="タイトル"
label={label ('shared:labels.title')}
currentOrder={order}
defaultDirection={defaultDirection}/>
</th>
<th className="p-2 text-left whitespace-nowrap">
<SortHeader<FetchPostsOrderField>
by="url"
label="URL"
label={label ('shared:url')}
currentOrder={order}
defaultDirection={defaultDirection}/>
</th>
<th className="p-2 text-left whitespace-nowrap">タグ</th>
<th className="p-2 text-left whitespace-nowrap">{label ('navigation:tags')}</th>
<th className="p-2 text-left whitespace-nowrap">
<SortHeader<FetchPostsOrderField>
by="original_created_at"
label="オリジナルの投稿日時"
label={label ('history:originalPostedAt')}
currentOrder={order}
defaultDirection={defaultDirection}/>
</th>
<th className="p-2 text-left whitespace-nowrap">
<SortHeader<FetchPostsOrderField>
by="created_at"
label="投稿日時"
label={label ('search.createdAt')}
currentOrder={order}
defaultDirection={defaultDirection}/>
</th>
<th className="p-2 text-left whitespace-nowrap">
<SortHeader<FetchPostsOrderField>
by="updated_at"
label="更新日時"
label={label ('tags:updatedAt')}
currentOrder={order}
defaultDirection={defaultDirection}/>
</th>
@@ -443,18 +450,28 @@ const PostSearchPage: FC = () => {
</span>))}
</td>
<td className="p-2">
{originalCreatedAtString (row.originalCreatedFrom,
row.originalCreatedBefore)}
<LocalisedText language={locale}>
{originalCreatedAtString (row.originalCreatedFrom,
row.originalCreatedBefore, locale)}
</LocalisedText>
</td>
<td className="p-2">
<LocalisedText language={locale}>
{localisedDateString (row.createdAt, locale)}
</LocalisedText>
</td>
<td className="p-2">
<LocalisedText language={locale}>
{localisedDateString (row.updatedAt, locale)}
</LocalisedText>
</td>
<td className="p-2">{dateString (row.createdAt)}</td>
<td className="p-2">{dateString (row.updatedAt)}</td>
</tr>))}
</tbody>
</table>
</div>
<Pagination page={page} totalPages={totalPages}/>
</div>) : '結果ないよ(笑)')}
</div>) : label ('tags:empty'))}
</MainArea>)
}