From e57ba6b2f08f93f86c63f3b8b911062b6f9d4ae5 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Tue, 1 Jul 2025 00:05:13 +0900 Subject: [PATCH] #69 --- backend/app/controllers/posts_controller.rb | 3 ++ frontend/src/components/TagSearch.tsx | 2 +- frontend/src/components/TagSidebar.tsx | 35 +++++++++++++++------ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/backend/app/controllers/posts_controller.rb b/backend/app/controllers/posts_controller.rb index 3385616..91cac05 100644 --- a/backend/app/controllers/posts_controller.rb +++ b/backend/app/controllers/posts_controller.rb @@ -11,7 +11,10 @@ class PostsController < ApplicationController def random post = filtered_posts.order('RAND()').first + return head :not_found unless post + viewed = current_user&.viewed?(post) || false + render json: (post .as_json(include: { tags: { only: [:id, :name, :category] } }) .merge(viewed: viewed)) diff --git a/frontend/src/components/TagSearch.tsx b/frontend/src/components/TagSearch.tsx index 9989225..fd5088e 100644 --- a/frontend/src/components/TagSearch.tsx +++ b/frontend/src/components/TagSearch.tsx @@ -61,7 +61,7 @@ const TagSearch: React.FC = () => { setSuggestionsVsbl (false) break } - if (e.key === 'Enter' && search.length && (!(suggestionsVsbl) || activeIndex < 0)) + if (e.key === 'Enter' && (!(suggestionsVsbl) || activeIndex < 0)) { navigate (`/posts?${ (new URLSearchParams ({ tags: search })).toString () }`) setSuggestionsVsbl (false) diff --git a/frontend/src/components/TagSidebar.tsx b/frontend/src/components/TagSidebar.tsx index 81c416b..aaf9aea 100644 --- a/frontend/src/components/TagSidebar.tsx +++ b/frontend/src/components/TagSidebar.tsx @@ -1,7 +1,7 @@ import axios from 'axios' import toCamel from 'camelcase-keys' import React, { useEffect, useState } from 'react' -import { Link, useNavigate, useParams } from 'react-router-dom' +import { Link, useLocation, useNavigate, useParams } from 'react-router-dom' import TagSearch from '@/components/TagSearch' import SectionTitle from '@/components/common/SectionTitle' @@ -20,6 +20,11 @@ export default ({ posts }: Props) => { const [tags, setTags] = useState ({ }) + const location = useLocation () + const query = new URLSearchParams (location.search) + const tagsQuery = query.get ('tags') ?? '' + const anyFlg = query.get ('match') === 'any' + useEffect (() => { const tagsTmp: TagByCategory = { } for (const post of posts) @@ -54,13 +59,25 @@ export default ({ posts }: Props) => { ))} 関聯 - { - ev.preventDefault () - void (axios.get (`${ API_BASE_URL }/posts/random`) - .then (res => navigate (`/posts/${ res.data.id }`))) - }}> - ランダム - + {posts.length && ( + { + ev.preventDefault () + void ((async () => { + try + { + const { data } = await axios.get (`${ API_BASE_URL }/posts/random`, + { params: { tags: tagsQuery.split (' ').filter (e => e !== '').join (','), + match: (anyFlg ? 'any' : 'all') } }) + navigate (`/posts/${ (data as Post).id }`) + } + catch + { + ; + } + }) ()) + }}> + ランダム + )} ) }