From ff4b0eecf5599484fdce4b3f7fb7858417455dfe Mon Sep 17 00:00:00 2001 From: miteruzo Date: Tue, 7 Apr 2026 00:45:40 +0900 Subject: [PATCH] #99 --- .../app/controllers/materials_controller.rb | 10 ++-- backend/app/controllers/tags_controller.rb | 10 ++-- backend/app/models/tag.rb | 2 + backend/app/representations/material_repr.rb | 17 +++--- backend/app/representations/tag_repr.rb | 2 +- frontend/src/App.tsx | 2 +- frontend/src/components/TagLink.tsx | 60 ++++++------------- .../src/pages/materials/MaterialBasePage.tsx | 2 +- .../pages/materials/MaterialDetailPage.tsx | 7 +++ frontend/src/pages/posts/PostDetailPage.tsx | 2 +- frontend/src/pages/posts/PostListPage.tsx | 2 +- frontend/src/types.ts | 2 + 12 files changed, 55 insertions(+), 63 deletions(-) diff --git a/backend/app/controllers/materials_controller.rb b/backend/app/controllers/materials_controller.rb index 3452d0a..d61a4b3 100644 --- a/backend/app/controllers/materials_controller.rb +++ b/backend/app/controllers/materials_controller.rb @@ -18,7 +18,7 @@ class MaterialsController < ApplicationController count = q.count materials = q.order(created_at: :desc, id: :desc).limit(limit).offset(offset) - render json: { materials: MaterialRepr.many(materials), count: count } + render json: { materials: MaterialRepr.many(materials, host: request.base_url), count: count } end def show @@ -29,7 +29,9 @@ class MaterialsController < ApplicationController .find_by(id: params[:id]) return head :not_found unless material - render json: MaterialRepr.base(material) + wiki_page_body = material.tag.tag_name.wiki_page&.current_revision&.body + + render json: MaterialRepr.base(material, host: request.base_url).merge(wiki_page_body:) end def create @@ -50,7 +52,7 @@ class MaterialsController < ApplicationController material.file.attach(file) if material.save - render json: MaterialRepr.base(material), status: :created + render json: MaterialRepr.base(material, host: request.base_url), status: :created else render json: { errors: material.errors.full_messages }, status: :unprocessable_entity end @@ -80,7 +82,7 @@ class MaterialsController < ApplicationController end if material.save - render json: MaterialRepr.base(material) + render json: MaterialRepr.base(material, host: request.base_url) else render json: { errors: material.errors.full_messages }, status: :unprocessable_entity end diff --git a/backend/app/controllers/tags_controller.rb b/backend/app/controllers/tags_controller.rb index 3605ef8..5adbce7 100644 --- a/backend/app/controllers/tags_controller.rb +++ b/backend/app/controllers/tags_controller.rb @@ -33,7 +33,7 @@ class TagsController < ApplicationController else Tag.joins(:tag_name) end - .includes(:tag_name, tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page, :materials) q = q.where(posts: { id: post_id }) if post_id.present? q = q.where('tag_names.name LIKE ?', "%#{ name }%") if name @@ -83,7 +83,7 @@ class TagsController < ApplicationController tags = Tag .joins(:tag_name) - .includes(:tag_name, tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page, :materials) .where(category: [:meme, :character, :material]) .where(id: tag_ids) .order('tag_names.name') @@ -128,7 +128,7 @@ class TagsController < ApplicationController end base = Tag.joins(:tag_name) - .includes(:tag_name, tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page, :materials) base = base.where('tags.post_count > 0') if present_only canonical_hit = @@ -153,7 +153,7 @@ class TagsController < ApplicationController def show tag = Tag.joins(:tag_name) - .includes(:tag_name, tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page, :materials) .find_by(id: params[:id]) if tag render json: TagRepr.base(tag) @@ -167,7 +167,7 @@ class TagsController < ApplicationController return head :bad_request if name.blank? tag = Tag.joins(:tag_name) - .includes(:tag_name, tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page, :materials) .find_by(tag_names: { name: }) if tag render json: TagRepr.base(tag) diff --git a/backend/app/models/tag.rb b/backend/app/models/tag.rb index 684d97e..64e0b9b 100644 --- a/backend/app/models/tag.rb +++ b/backend/app/models/tag.rb @@ -73,6 +73,8 @@ class Tag < ApplicationRecord def has_wiki = wiki_page.present? + def material_id = materials.first&.id + def self.tagme @tagme ||= find_or_create_by_tag_name!('タグ希望', category: :meta) end diff --git a/backend/app/representations/material_repr.rb b/backend/app/representations/material_repr.rb index f95cf25..624a0ea 100644 --- a/backend/app/representations/material_repr.rb +++ b/backend/app/representations/material_repr.rb @@ -2,22 +2,23 @@ module MaterialRepr - BASE = { methods: [:content_type], - include: { created_by_user: UserRepr::BASE, + BASE = { only: [:id, :url, :created_at, :updated_at], + methods: [:content_type], + include: { tag: TagRepr::BASE, + created_by_user: UserRepr::BASE, updated_by_user: UserRepr::BASE } }.freeze module_function - def base(material) + def base material, host: material.as_json(BASE).merge( file: if material.file.attached? Rails.application.routes.url_helpers.rails_storage_proxy_url( - material.file, only_path: false) - end, - tag: TagRepr.base(material.tag)) + material.file, host:) + end) end - def many(materials) - materials.map { |m| base(m) } + def many materials, host: + materials.map { |m| base(m, host) } end end diff --git a/backend/app/representations/tag_repr.rb b/backend/app/representations/tag_repr.rb index db8b6eb..df6925b 100644 --- a/backend/app/representations/tag_repr.rb +++ b/backend/app/representations/tag_repr.rb @@ -3,7 +3,7 @@ module TagRepr BASE = { only: [:id, :category, :post_count, :created_at, :updated_at], - methods: [:name, :has_wiki] }.freeze + methods: [:name, :has_wiki, :material_id] }.freeze module_function diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 07f004b..770f46c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -131,7 +131,7 @@ export default (() => { <> -
+
diff --git a/frontend/src/components/TagLink.tsx b/frontend/src/components/TagLink.tsx index 5755ffe..6a41e68 100644 --- a/frontend/src/components/TagLink.tsx +++ b/frontend/src/components/TagLink.tsx @@ -1,8 +1,5 @@ -import { useEffect, useState } from 'react' - import PrefetchLink from '@/components/PrefetchLink' import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts' -import { apiGet } from '@/lib/api' import { cn } from '@/lib/utils' import type { ComponentProps, FC, HTMLAttributes } from 'react' @@ -36,35 +33,6 @@ export default (({ tag, withWiki = true, withCount = true, ...props }: Props) => { - const [havingWiki, setHavingWiki] = useState (true) - - const wikiExists = async (tag: Tag) => { - if ('hasWiki' in tag) - { - setHavingWiki (tag.hasWiki) - return - } - - const tagName = (tag as Tag).name - - try - { - await apiGet (`/wiki/title/${ encodeURIComponent (tagName) }/exists`) - setHavingWiki (true) - } - catch - { - setHavingWiki (false) - } - } - - useEffect (() => { - if (!(linkFlg) || !(withWiki)) - return - - wikiExists (tag) - }, [tag.name, linkFlg, withWiki]) - const spanClass = cn ( `text-${ TAG_COLOUR[tag.category] }-${ LIGHT_COLOUR_SHADE }`, `dark:text-${ TAG_COLOUR[tag.category] }-${ DARK_COLOUR_SHADE }`) @@ -77,17 +45,27 @@ export default (({ tag, <> {(linkFlg && withWiki) && ( - {havingWiki + {(tag.materialId != null || tag.hasWiki) ? ( - - ? - ) + tag.materialId == null + ? ( + + ? + ) + : ( + + ? + )) : ( - + ! )} )} diff --git a/frontend/src/pages/materials/MaterialBasePage.tsx b/frontend/src/pages/materials/MaterialBasePage.tsx index 4c948f1..69d6a33 100644 --- a/frontend/src/pages/materials/MaterialBasePage.tsx +++ b/frontend/src/pages/materials/MaterialBasePage.tsx @@ -6,7 +6,7 @@ import type { FC } from 'react' export default (() => ( -
+
)) satisfies FC diff --git a/frontend/src/pages/materials/MaterialDetailPage.tsx b/frontend/src/pages/materials/MaterialDetailPage.tsx index 04b66d8..99c5d46 100644 --- a/frontend/src/pages/materials/MaterialDetailPage.tsx +++ b/frontend/src/pages/materials/MaterialDetailPage.tsx @@ -3,6 +3,7 @@ import { Helmet } from 'react-helmet-async' import { useParams } from 'react-router-dom' import TagLink from '@/components/TagLink' +import WikiBody from '@/components/WikiBody' import Label from '@/components/common/Label' import PageTitle from '@/components/common/PageTitle' import TabGroup, { Tab } from '@/components/common/TabGroup' @@ -109,6 +110,12 @@ export default (() => {