このコミットが含まれているのは:
@@ -33,6 +33,10 @@ npm run lint
|
||||
|
||||
If either command cannot be run or fails, report the exact command and failure.
|
||||
|
||||
Do not create, modify, or run tests unless the user explicitly asks for test
|
||||
work. When the user asks for tests, keep working and rerun them until they
|
||||
pass or the remaining failure is clearly blocked.
|
||||
|
||||
## TypeScript
|
||||
|
||||
- TypeScript is strict. `tsconfig.app.json` enables `strict`,
|
||||
|
||||
+15
-2
@@ -40,7 +40,7 @@ import WikiHistoryPage from '@/pages/wiki/WikiHistoryPage'
|
||||
import WikiNewPage from '@/pages/wiki/WikiNewPage'
|
||||
import WikiSearchPage from '@/pages/wiki/WikiSearchPage'
|
||||
|
||||
import type { Dispatch, FC, SetStateAction } from 'react'
|
||||
import type { Dispatch, FC, ReactNode, SetStateAction } from 'react'
|
||||
|
||||
import type { User } from '@/types'
|
||||
|
||||
@@ -81,7 +81,10 @@ const RouteTransitionWrapper = ({ user, setUser }: {
|
||||
<Route path="/users/settings" element={<SettingPage user={user} setUser={setUser}/>}/>
|
||||
<Route path="/settings" element={<Navigate to="/users/settings" replace/>}/>
|
||||
<Route path="/tos" element={<TOSPage/>}/>
|
||||
<Route path="/gekanator" element={<GekanatorPage/>}/>
|
||||
<Route path="/gekanator" element={
|
||||
<AdminOnly user={user}>
|
||||
<GekanatorPage/>
|
||||
</AdminOnly>}/>
|
||||
<Route path="/more" element={<MorePage/>}/>
|
||||
<Route path="*" element={<NotFound/>}/>
|
||||
</Routes>
|
||||
@@ -89,6 +92,16 @@ const RouteTransitionWrapper = ({ user, setUser }: {
|
||||
}
|
||||
|
||||
|
||||
const AdminOnly = ({ user, children }: {
|
||||
user: User | null
|
||||
children: ReactNode }) => {
|
||||
if (user?.role !== 'admin')
|
||||
return <NotFound/>
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
|
||||
const PostDetailRoute = ({ user }: { user: User | null }) => {
|
||||
const location = useLocation ()
|
||||
const key = location.pathname
|
||||
|
||||
@@ -66,7 +66,6 @@ export const menuOutline = ({ tag, wikiId, user, pathName }: {
|
||||
{ name: '履歴', to: `/wiki/changes?id=${ wikiId }`, visible: wikiPageFlg },
|
||||
{ name: '編輯', to: `/wiki/${ wikiId || wikiTitle }/edit`, visible: wikiPageFlg }] },
|
||||
{ name: 'おたのしみ', visible: false, subMenu: [
|
||||
{ name: 'グカネータ', to: '/gekanator' },
|
||||
{ name: '上映会 (β)', to: '/theatres/1' }] },
|
||||
{ name: 'ユーザ', to: '/users/settings', visible: false, subMenu: [
|
||||
{ name: '一覧', to: '/users', visible: false },
|
||||
|
||||
@@ -208,7 +208,6 @@ export const saveGekanatorGame = async ({
|
||||
await apiPost ('/gekanator/games', {
|
||||
guessed_post_id: guessedPostId,
|
||||
correct_post_id: correctPostId,
|
||||
question_count: answers.length,
|
||||
answers: answers.map (answer => ({
|
||||
question_id: answer.questionId,
|
||||
question_text: answer.questionText,
|
||||
|
||||
@@ -335,6 +335,8 @@ const chooseQuestion = ({
|
||||
candidates: { post: Post; score: number }[],
|
||||
) => {
|
||||
const redundant = redundantSignatures (candidates)
|
||||
const nonTagCount =
|
||||
questions.filter (question => askedIds.has (question.id) && question.kind !== 'tag').length
|
||||
|
||||
return questionsToRank
|
||||
.map (question => {
|
||||
@@ -348,7 +350,7 @@ const chooseQuestion = ({
|
||||
return null
|
||||
|
||||
const splitScore = Math.abs (candidates.length / 2 - yes)
|
||||
const tagPenalty = question.kind === 'tag' ? 0 : 20
|
||||
const tagPenalty = question.kind === 'tag' && nonTagCount < 4 ? 12 : 0
|
||||
const minSide = candidates.length < 10 ? 1 : Math.max (3, candidates.length * .08)
|
||||
const narrowPenalty = yes < minSide || no < minSide ? candidates.length : 0
|
||||
|
||||
|
||||
新しい課題から参照
ユーザをブロックする