Browse Source

#351

feature/351
みてるぞ 3 days ago
parent
commit
7fcfc8b8aa
10 changed files with 55 additions and 23 deletions
  1. +2
    -2
      backend/app/controllers/posts_controller.rb
  2. +7
    -2
      backend/app/models/tag.rb
  3. +8
    -0
      backend/spec/factories/post_tag_sections.rb
  4. +6
    -0
      backend/spec/factories/post_tags.rb
  5. +8
    -0
      backend/spec/factories/posts.rb
  6. +10
    -7
      frontend/src/components/PostEditForm.tsx
  7. +8
    -8
      frontend/src/components/TagDetailSidebar.tsx
  8. +1
    -1
      frontend/src/lib/utils.ts
  9. +1
    -1
      frontend/src/pages/tags/TagDetailPage.tsx
  10. +4
    -2
      frontend/src/test/factories.ts

+ 2
- 2
backend/app/controllers/posts_controller.rb View File

@@ -392,7 +392,7 @@ class PostsController < ApplicationController
tag = tags_by_id[tag_id]
return nil unless tag

sections = PostTagSection.where(post_id: post.id, tag_id: tag.id)
sections = PostTagSection.where(post_id: post.id, tag_id:)
.as_json(only: [:begin_ms, :end_ms])

if path.include?(tag_id)
@@ -419,7 +419,7 @@ class PostsController < ApplicationController

params[:parent_post_ids].to_s.split.map { |token|
id = Integer(token, exception: false)
raise ArgumentError, "親投稿 Id. が不正です: #{ token }" if id.nil? || id <= 0
raise ArgumentError, "親投稿 Id. が不正です: #{ token }" if !(id) || id <= 0

id
}.uniq


+ 7
- 2
backend/app/models/tag.rb View File

@@ -102,7 +102,7 @@ class Tag < ApplicationRecord
tags = tag_names.map do |name|
pf, cat = CATEGORY_PREFIXES.find { |p, _| name.downcase.start_with?(p) } || ['', nil]

name = TagName.canonicalise(name.sub(/\A#{ pf }/i, '')).first
name = name.sub(/\A#{ pf }/i, '')

sections_by_tag = []
while n = name.sub!(/^(\S*?)\[([0-9:.]*?)-([0-9:.]*?)\](\S*?)$/, '\1\4 \2 \3')
@@ -116,9 +116,14 @@ class Tag < ApplicationRecord
sections_by_tag << [begin_ms, end_ms]
end

name = TagName.canonicalise(name).first

find_or_create_by_tag_name!(name, category: (cat || :general)).tap do |tag|
tag.update!(category: cat) if cat && tag.category != cat
sections[tag.id] = sections_by_tag if sections_by_tag.present?
next if sections_by_tag.blank?

sections[tag.id] ||= []
sections[tag.id].concat(sections_by_tag)
end
end



+ 8
- 0
backend/spec/factories/post_tag_sections.rb View File

@@ -0,0 +1,8 @@
FactoryBot.define do
factory :post_tag_section do
association :post
association :tag
begin_ms { 1_000 }
end_ms { 2_000 }
end
end

+ 6
- 0
backend/spec/factories/post_tags.rb View File

@@ -0,0 +1,6 @@
FactoryBot.define do
factory :post_tag do
association :post
association :tag
end
end

+ 8
- 0
backend/spec/factories/posts.rb View File

@@ -0,0 +1,8 @@
FactoryBot.define do
factory :post do
sequence(:url) { |n| "https://example.com/factory-post-#{ n }" }
title { 'factory post' }
thumbnail_base { nil }
uploaded_user { nil }
end
end

+ 10
- 7
frontend/src/components/PostEditForm.tsx View File

@@ -12,21 +12,24 @@ import { msToTime } from '@/lib/utils'

import type { FC, FormEvent } from 'react'

import type { Post, Tag } from '@/types'
import type { Post, TagWithSections } from '@/types'


const tagsToStr = (tags: Tag[]): string => {
const result: Tag[] = []
const tagsToStr = (tags: TagWithSections[]): string => {
const result: Omit<TagWithSections, 'children'>[] = []

const walk = (tag: Tag) => {
const walk = (tag: TagWithSections) => {
const { children, ...rest } = tag
result.push (rest)
children?.forEach (walk)
children.forEach (walk)
}

tags.filter (t => t.category !== 'nico').forEach (walk)

return [...(new Set (result.map (t => `${ t.name }${ t.sections.map (s => `[${ msToTime (s.beginMs) }-${ msToTime (s.endMs) }]`).join ('') }`)))].join (' ')
return [...(new Set (result.map (t =>
`${ t.name }${ t.sections
.map (s => `[${ msToTime (s.beginMs) }-${ msToTime (s.endMs) }]`)
.join ('') }`)))].join (' ')
}


@@ -118,7 +121,7 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
}

useEffect (() => {
setTags(tagsToStr (post.tags))
setTags (tagsToStr (post.tags))
}, [post])

return (


+ 8
- 8
frontend/src/components/TagDetailSidebar.tsx View File

@@ -26,13 +26,13 @@ import { dateString, originalCreatedAtString } from '@/lib/utils'
import type { DragEndEvent } from '@dnd-kit/core'
import type { FC, MutableRefObject, ReactNode } from 'react'

import type { Category, Post, Tag } from '@/types'
import type { Category, Post, TagWithSections } from '@/types'

type TagByCategory = { [key in Category]: Tag[] }
type TagByCategory = { [key in Category]: TagWithSections[] }


const renderTagTree = (
tag: Tag,
tag: TagWithSections,
nestLevel: number,
path: string,
suppressClickRef: MutableRefObject<boolean>,
@@ -63,7 +63,7 @@ const renderTagTree = (


const isDescendant = (
root: Tag,
root: TagWithSections,
targetId: number,
): boolean => {
if (!(root.children))
@@ -84,8 +84,8 @@ const isDescendant = (
const findTag = (
byCat: TagByCategory,
id: number,
): Tag | undefined => {
const walk = (nodes: Tag[]): Tag | undefined => {
): TagWithSections | undefined => {
const walk = (nodes: TagWithSections[]): TagWithSections | undefined => {
for (const t of nodes)
{
if (t.id === id)
@@ -167,7 +167,7 @@ const TagDetailSidebar: FC<Props> = ({ post, sp }) => {
}

for (const cat of Object.keys (tagsTmp) as (keyof typeof tagsTmp)[])
tagsTmp[cat].sort ((tagA: Tag, tagB: Tag) => tagA.name < tagB.name ? -1 : 1)
tagsTmp[cat].sort ((tagA: TagWithSections, tagB: TagWithSections) => tagA.name < tagB.name ? -1 : 1)

return tagsTmp
}, [post])
@@ -378,4 +378,4 @@ const TagDetailSidebar: FC<Props> = ({ post, sp }) => {
</SidebarComponent>)
}

export default TagDetailSidebar
export default TagDetailSidebar

+ 1
- 1
frontend/src/lib/utils.ts View File

@@ -77,7 +77,7 @@ export const msToTime = (ms: number): string => {
const totalS = Math.trunc (ms / 1_000)
const s = String (totalS % 60)
const min = String (Math.trunc (totalS / 60) % 60)
const h = String (Math.trunc (totalS / 3_600))
const h = Math.trunc (totalS / 3_600)

return (h > 0
? `${ h }:${ min.padStart (2, '0') }:${ s.padStart (2, '0') }`


+ 1
- 1
frontend/src/pages/tags/TagDetailPage.tsx View File

@@ -157,4 +157,4 @@ const TagDetailPage: FC = () => {
</MainArea>)
}

export default TagDetailPage
export default TagDetailPage

+ 4
- 2
frontend/src/test/factories.ts View File

@@ -1,6 +1,6 @@
import type { Material, Post, Tag, User, WikiPage } from '@/types'
import type { Material, Post, TagWithSections, User, WikiPage } from '@/types'

export const buildTag = (overrides: Partial<Tag> = {}): Tag => ({
export const buildTag = (overrides: Partial<TagWithSections> = {}): TagWithSections => ({
id: 1,
name: 'テストタグ',
category: 'general',
@@ -13,6 +13,8 @@ export const buildTag = (overrides: Partial<Tag> = {}): Tag => ({
materialId: null,
hasDeerjikists: false,
matchedAlias: null,
sections: [],
children: [],
...overrides,
})



Loading…
Cancel
Save