diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/model/Reactions.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/model/Reactions.kt deleted file mode 100644 index 11d95f7e..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/model/Reactions.kt +++ /dev/null @@ -1,28 +0,0 @@ -package dev.usbharu.hideout.core.application.model - -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji -import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import java.net.URI - -data class Reactions( - val postId: Long, - val count: Int, - val name: String, - val domain: String, - val url: URI?, - val actorIds: List, -) { - companion object { - fun of(reactionList: List, customEmoji: CustomEmoji?): Reactions { - val first = reactionList.first() - return Reactions( - first.id.value, - reactionList.size, - customEmoji?.name ?: first.unicodeEmoji.name, - customEmoji?.domain?.domain ?: first.unicodeEmoji.domain.domain, - customEmoji?.url, - reactionList.map { it.actorId.id } - ) - } - } -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt index 278c0afe..7eb38ed3 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt @@ -9,10 +9,8 @@ import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.model.post.PostRepository -import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl -import dev.usbharu.hideout.core.query.reactions.ReactionsQueryService import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -22,9 +20,7 @@ class GetPostDetailApplicationService( private val postRepository: PostRepository, private val actorRepository: ActorRepository, private val mediaRepository: MediaRepository, - private val iPostReadAccessControl: IPostReadAccessControl, - private val reactionsQueryService: ReactionsQueryService, - private val reactionRepository: ReactionRepository, + private val iPostReadAccessControl: IPostReadAccessControl ) : AbstractApplicationService( transaction, logger @@ -42,15 +38,6 @@ class GetPostDetailApplicationService( val mediaList = mediaRepository.findByIds(post.mediaIds) - val reactions = reactionsQueryService.findAllByPostId(post.id) - - val favourited = reactionRepository.existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji( - post.id, - principal.actorId, - null, - "❤" - ) - return PostDetail.of( post = post, actor = actor, @@ -59,8 +46,6 @@ class GetPostDetailApplicationService( reply = post.replyId?.let { fetchChild(it, actor, iconMedia, principal) }, repost = post.repostId?.let { fetchChild(it, actor, iconMedia, principal) }, moveTo = post.moveTo?.let { fetchChild(it, actor, iconMedia, principal) }, - reactionsList = reactions, - favourited ) } @@ -84,12 +69,10 @@ class GetPostDetailApplicationService( val mediaList = mediaRepository.findByIds(post.mediaIds) return PostDetail.of( - post = post, - actor = first, - iconMedia = third, - mediaList = mediaList, - reactionsList = emptyList(), - favourited = false + post, + first, + third, + mediaList ) } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt index 67dd9d96..567848df 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt @@ -1,6 +1,5 @@ package dev.usbharu.hideout.core.application.post -import dev.usbharu.hideout.core.application.model.Reactions import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.post.Post @@ -24,9 +23,7 @@ data class PostDetail( val sensitive: Boolean, val deleted: Boolean, val mediaDetailList: List, - val moveTo: PostDetail?, - val reactionsList: List, - val favourited: Boolean + val moveTo: PostDetail? ) { companion object { @Suppress("LongParameterList") @@ -38,8 +35,6 @@ data class PostDetail( reply: PostDetail? = null, repost: PostDetail? = null, moveTo: PostDetail? = null, - reactionsList: List, - favourited: Boolean ): PostDetail { return PostDetail( id = post.id.id, @@ -57,9 +52,7 @@ data class PostDetail( sensitive = post.sensitive, deleted = false, mediaDetailList = mediaList.map { MediaDetail.of(it) }, - moveTo = moveTo, - reactionsList = reactionsList, - favourited = favourited + moveTo = moveTo ) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/CreateReaction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/CreateReaction.kt deleted file mode 100644 index 7d6f171b..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/CreateReaction.kt +++ /dev/null @@ -1,3 +0,0 @@ -package dev.usbharu.hideout.core.application.reaction - -data class CreateReaction(val postId: Long, val customEmojiId: Long?, val unicodeEmoji: String) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/RemoveReaction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/RemoveReaction.kt deleted file mode 100644 index 6a7dd7ff..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/RemoveReaction.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.usbharu.hideout.core.application.reaction - -data class RemoveReaction( - val postId: Long, - val customEmojiId: Long?, - val unicodeEmoji: String -) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/UserCreateReactionApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/UserCreateReactionApplicationService.kt deleted file mode 100644 index f0a7f2dd..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/UserCreateReactionApplicationService.kt +++ /dev/null @@ -1,65 +0,0 @@ -package dev.usbharu.hideout.core.application.reaction - -import dev.usbharu.hideout.core.application.exception.PermissionDeniedException -import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService -import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository -import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji -import dev.usbharu.hideout.core.domain.model.post.PostId -import dev.usbharu.hideout.core.domain.model.post.PostRepository -import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import dev.usbharu.hideout.core.domain.model.reaction.ReactionId -import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository -import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser -import dev.usbharu.hideout.core.domain.service.emoji.UnicodeEmojiService -import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl -import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Service -import java.time.Instant - -@Service -class UserCreateReactionApplicationService( - transaction: Transaction, - private val idGenerateService: IdGenerateService, - private val reactionRepository: ReactionRepository, - private val postReadAccessControl: IPostReadAccessControl, - private val postRepository: PostRepository, - private val customEmojiRepository: CustomEmojiRepository, - private val unicodeEmojiService: UnicodeEmojiService -) : - LocalUserAbstractApplicationService( - transaction, - logger - ) { - override suspend fun internalExecute(command: CreateReaction, principal: LocalUser) { - val postId = PostId(command.postId) - val post = postRepository.findById(postId) ?: throw IllegalArgumentException("Post $postId not found.") - if (postReadAccessControl.isAllow(post, principal).not()) { - throw PermissionDeniedException() - } - - val customEmoji = command.customEmojiId?.let { customEmojiRepository.findById(it) } - - val unicodeEmoji = if (unicodeEmojiService.isUnicodeEmoji(command.unicodeEmoji)) { - command.unicodeEmoji - } else { - "❤" - } - - val reaction = Reaction.create( - id = ReactionId(idGenerateService.generateId()), - postId = postId, - actorId = principal.actorId, - customEmojiId = customEmoji?.id, - unicodeEmoji = UnicodeEmoji(unicodeEmoji), - createdAt = Instant.now() - ) - - reactionRepository.save(reaction) - } - - companion object { - private val logger = LoggerFactory.getLogger(UserCreateReactionApplicationService::class.java) - } -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/UserRemoveReactionApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/UserRemoveReactionApplicationService.kt deleted file mode 100644 index 4335ee63..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/reaction/UserRemoveReactionApplicationService.kt +++ /dev/null @@ -1,51 +0,0 @@ -package dev.usbharu.hideout.core.application.reaction - -import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService -import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository -import dev.usbharu.hideout.core.domain.model.post.PostId -import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository -import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser -import dev.usbharu.hideout.core.domain.service.emoji.UnicodeEmojiService -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Service - -@Service -class UserRemoveReactionApplicationService( - transaction: Transaction, - private val customEmojiRepository: CustomEmojiRepository, - private val reactionRepository: ReactionRepository, - private val unicodeEmojiService: UnicodeEmojiService -) : - LocalUserAbstractApplicationService( - transaction, - logger - ) { - override suspend fun internalExecute(command: RemoveReaction, principal: LocalUser) { - val postId = PostId(command.postId) - - val customEmoji = command.customEmojiId?.let { customEmojiRepository.findById(it) } - - val unicodeEmoji = if (unicodeEmojiService.isUnicodeEmoji(command.unicodeEmoji)) { - command.unicodeEmoji - } else { - "❤" - } - val reaction = - reactionRepository.findByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji( - postId, - principal.actorId, - customEmoji?.id, - unicodeEmoji - ) - ?: throw IllegalArgumentException("Reaction $postId ${principal.actorId} ${customEmoji?.id} $unicodeEmoji not found.") - - reaction.delete() - - reactionRepository.delete(reaction) - } - - companion object { - private val logger = LoggerFactory.getLogger(UserRemoveReactionApplicationService::class.java) - } -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt index 8b045657..9facf26c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt @@ -47,9 +47,7 @@ class ReadTimelineApplicationService( it.replyPost, it.replyPostActor!!, it.replyPostActorIconMedia, - it.replyPostMedias.orEmpty(), - reactionsList = emptyList(), - favourited = false, + it.replyPostMedias.orEmpty() ) } else { null @@ -58,12 +56,10 @@ class ReadTimelineApplicationService( val repost = if (it.repostPost != null) { @Suppress("UnsafeCallOnNullableType") PostDetail.of( - post = it.repostPost, - actor = it.repostPostActor!!, - iconMedia = it.repostPostActorIconMedia, - mediaList = it.repostPostMedias.orEmpty(), - reactionsList = emptyList(), - favourited = false + it.repostPost, + it.repostPostActor!!, + it.repostPostActorIconMedia, + it.repostPostMedias.orEmpty() ) } else { null @@ -75,9 +71,7 @@ class ReadTimelineApplicationService( iconMedia = it.postActorIconMedia, mediaList = it.postMedias, reply = reply, - repost = repost, - reactionsList = emptyList(), - favourited = it.favourited + repost = repost ) } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/reaction/ReactionEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/reaction/ReactionEvent.kt deleted file mode 100644 index 6da7a58c..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/reaction/ReactionEvent.kt +++ /dev/null @@ -1,22 +0,0 @@ -package dev.usbharu.hideout.core.domain.event.reaction - -import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import dev.usbharu.hideout.core.domain.model.reaction.ReactionId -import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent -import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody - -class ReactionEventFactory(private val reaction: Reaction) { - fun createEvent(reactionEvent: ReactionEvent): DomainEvent = - DomainEvent.create(reactionEvent.eventName, ReactionEventBody(reaction)) -} - -class ReactionEventBody( - reaction: Reaction -) : DomainEventBody(mapOf("reactionId" to reaction.id)) { - fun getReactionId(): ReactionId = toMap()["reactionId"] as ReactionId -} - -enum class ReactionEvent(val eventName: String) { - CREATE("ReactionCreate"), - DELETE("ReactionDelete"), -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt index 8fd41710..3b282c34 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt @@ -18,7 +18,7 @@ package dev.usbharu.hideout.core.domain.model.actor import dev.usbharu.hideout.core.domain.event.actor.ActorDomainEventFactory import dev.usbharu.hideout.core.domain.event.actor.ActorEvent.* -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.instance.InstanceId import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.model.support.domain.Domain @@ -52,7 +52,7 @@ class Actor( var lastUpdateAt: Instant = createdAt, alsoKnownAs: Set = emptySet(), moveTo: ActorId? = null, - emojiIds: Set, + emojiIds: Set, deleted: Boolean, icon: MediaId?, banner: MediaId?, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt index b80d06cf..e0e29b17 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt @@ -36,7 +36,7 @@ sealed class Emoji { } data class CustomEmoji( - val id: CustomEmojiId, + val id: EmojiId, override val name: String, override val domain: Domain, val instanceId: InstanceId, @@ -50,10 +50,6 @@ data class CustomEmoji( data class UnicodeEmoji( override val name: String ) : Emoji() { - override val domain: Domain = Companion.domain + override val domain: Domain = Domain("unicode.org") override fun id(): String = name - - companion object { - val domain = Domain("unicode.org") - } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiId.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/EmojiId.kt similarity index 93% rename from hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiId.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/EmojiId.kt index 6ad2ec03..5cf4284d 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiId.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/EmojiId.kt @@ -17,7 +17,7 @@ package dev.usbharu.hideout.core.domain.model.emoji @JvmInline -value class CustomEmojiId(val emojiId: Long) { +value class EmojiId(val emojiId: Long) { init { require(0 <= emojiId) } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt index db5f2732..b953bd8e 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt @@ -20,7 +20,7 @@ import dev.usbharu.hideout.core.domain.event.post.PostDomainEventFactory import dev.usbharu.hideout.core.domain.event.post.PostEvent import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorId -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.instance.InstanceId import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable @@ -138,7 +138,7 @@ class Post( return content.text } - val emojiIds: List + val emojiIds: List get() { if (hide) { return PostContent.empty.emojiIds @@ -217,7 +217,7 @@ class Post( override fun hashCode(): Int = id.hashCode() - fun reconstructWith(mediaIds: List, emojis: List, visibleActors: Set): Post { + fun reconstructWith(mediaIds: List, emojis: List, visibleActors: Set): Post { return Post( id = id, actorId = actorId, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostContent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostContent.kt index 9f6b2db7..2d787e75 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostContent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostContent.kt @@ -16,9 +16,9 @@ package dev.usbharu.hideout.core.domain.model.post -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId -data class PostContent(val text: String, val content: String, val emojiIds: List) { +data class PostContent(val text: String, val content: String, val emojiIds: List) { companion object { val empty = PostContent("", "", emptyList()) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/Reaction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/Reaction.kt deleted file mode 100644 index c85c061d..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/Reaction.kt +++ /dev/null @@ -1,57 +0,0 @@ -package dev.usbharu.hideout.core.domain.model.reaction - -import dev.usbharu.hideout.core.domain.event.reaction.ReactionEvent -import dev.usbharu.hideout.core.domain.event.reaction.ReactionEventFactory -import dev.usbharu.hideout.core.domain.model.actor.ActorId -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId -import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji -import dev.usbharu.hideout.core.domain.model.post.PostId -import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable -import java.time.Instant - -class Reaction( - val id: ReactionId, - val postId: PostId, - val actorId: ActorId, - val customEmojiId: CustomEmojiId?, - val unicodeEmoji: UnicodeEmoji, - val createdAt: Instant -) : DomainEventStorable() { - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Reaction - - return id == other.id - } - - override fun hashCode(): Int { - return id.hashCode() - } - - fun delete() { - addDomainEvent(ReactionEventFactory(this).createEvent(ReactionEvent.DELETE)) - } - - companion object { - fun create( - id: ReactionId, - postId: PostId, - actorId: ActorId, - customEmojiId: CustomEmojiId?, - unicodeEmoji: UnicodeEmoji, - createdAt: Instant - ): Reaction { - return Reaction( - id, - postId, - actorId, - customEmojiId, - unicodeEmoji, - createdAt - ).apply { addDomainEvent(ReactionEventFactory(this).createEvent(ReactionEvent.CREATE)) } - } - } -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionId.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionId.kt deleted file mode 100644 index 948fb1ea..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionId.kt +++ /dev/null @@ -1,4 +0,0 @@ -package dev.usbharu.hideout.core.domain.model.reaction - -@JvmInline -value class ReactionId(val value: Long) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt deleted file mode 100644 index 01e893a7..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt +++ /dev/null @@ -1,26 +0,0 @@ -package dev.usbharu.hideout.core.domain.model.reaction - -import dev.usbharu.hideout.core.domain.model.actor.ActorId -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId -import dev.usbharu.hideout.core.domain.model.post.PostId - -interface ReactionRepository { - suspend fun save(reaction: Reaction): Reaction - suspend fun findById(reactionId: ReactionId): Reaction? - suspend fun findByPostId(postId: PostId): List - suspend fun existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji( - postId: PostId, - actorId: ActorId, - customEmojiId: CustomEmojiId?, - unicodeEmoji: String - ): Boolean - - suspend fun findByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji( - postId: PostId, - actorId: ActorId, - customEmojiId: CustomEmojiId?, - unicodeEmoji: String - ): Reaction? - - suspend fun delete(reaction: Reaction) -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt index 43b0fa9f..830612dc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt @@ -1,6 +1,5 @@ package dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail -import dev.usbharu.hideout.core.application.model.Reactions import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.post.Post @@ -30,9 +29,7 @@ data class TimelineObjectDetail( val isPureRepost: Boolean, val lastUpdateAt: Instant, val hasMediaInRepost: Boolean, - val warnFilter: List, - val reactionsList: List, - val favourited: Boolean + val warnFilter: List ) { companion object { @Suppress("LongParameterList") @@ -51,9 +48,7 @@ data class TimelineObjectDetail( repostPostMedias: List?, repostPostActor: Actor?, repostPostActorIconMedia: Media?, - warnFilter: List, - reactionsList: List, - favourited: Boolean + warnFilter: List ): TimelineObjectDetail { return TimelineObjectDetail( id = timelineObject.id, @@ -74,9 +69,7 @@ data class TimelineObjectDetail( isPureRepost = timelineObject.isPureRepost, lastUpdateAt = timelineObject.lastUpdatedAt, hasMediaInRepost = timelineObject.hasMediaInRepost, - warnFilter = warnFilter, - reactionsList = reactionsList, - favourited = favourited + warnFilter = warnFilter ) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timelineobject/TimelineObject.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timelineobject/TimelineObject.kt index f7f57f22..bdce1a0d 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timelineobject/TimelineObject.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timelineobject/TimelineObject.kt @@ -1,7 +1,7 @@ package dev.usbharu.hideout.core.domain.model.timelineobject import dev.usbharu.hideout.core.domain.model.actor.ActorId -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.filter.FilterResult import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.model.post.Post @@ -28,12 +28,12 @@ class TimelineObject( visibility: Visibility, isPureRepost: Boolean, mediaIds: List, - emojiIds: List, + emojiIds: List, visibleActors: List, hasMediaInRepost: Boolean, lastUpdatedAt: Instant, var warnFilters: List, - var favourited: Boolean + ) { var isPureRepost = isPureRepost private set @@ -82,8 +82,7 @@ class TimelineObject( timeline: Timeline, post: Post, replyActorId: ActorId?, - filterResults: List, - favourited: Boolean + filterResults: List ): TimelineObject { return TimelineObject( id = timelineObjectId, @@ -103,8 +102,7 @@ class TimelineObject( visibleActors = post.visibleActors.toList(), hasMediaInRepost = false, lastUpdatedAt = Instant.now(), - warnFilters = filterResults.map { TimelineObjectWarnFilter(it.filter.id, it.matchedKeyword) }, - favourited = favourited + warnFilters = filterResults.map { TimelineObjectWarnFilter(it.filter.id, it.matchedKeyword) } ) } @@ -115,8 +113,7 @@ class TimelineObject( post: Post, replyActorId: ActorId?, repost: Post, - filterResults: List, - favourited: Boolean + filterResults: List ): TimelineObject { require(post.repostId == repost.id) @@ -141,8 +138,7 @@ class TimelineObject( visibleActors = post.visibleActors.toList(), hasMediaInRepost = repost.mediaIds.isNotEmpty(), lastUpdatedAt = Instant.now(), - warnFilters = filterResults.map { TimelineObjectWarnFilter(it.filter.id, it.matchedKeyword) }, - favourited = favourited + warnFilters = filterResults.map { TimelineObjectWarnFilter(it.filter.id, it.matchedKeyword) } ) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/emoji/UnicodeEmojiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/emoji/UnicodeEmojiService.kt deleted file mode 100644 index 35a44ca5..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/emoji/UnicodeEmojiService.kt +++ /dev/null @@ -1,5 +0,0 @@ -package dev.usbharu.hideout.core.domain.service.emoji - -interface UnicodeEmojiService { - fun isUnicodeEmoji(emoji: String): Boolean -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/emojikt/EmojiKtUnicodeEmojiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/emojikt/EmojiKtUnicodeEmojiService.kt deleted file mode 100644 index 3e0fdc43..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/emojikt/EmojiKtUnicodeEmojiService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.emojikt - -import Emojis -import dev.usbharu.hideout.core.domain.service.emoji.UnicodeEmojiService -import org.springframework.stereotype.Service - -@Service -class EmojiKtUnicodeEmojiService : UnicodeEmojiService { - override fun isUnicodeEmoji(emoji: String): Boolean { - return Emojis.allEmojis.singleOrNull { it.char == emoji } != null - } -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/ActorResultRowMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/ActorResultRowMapper.kt index c552c541..59cb72fc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/ActorResultRowMapper.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/ActorResultRowMapper.kt @@ -17,7 +17,7 @@ package dev.usbharu.hideout.core.infrastructure.exposed import dev.usbharu.hideout.core.domain.model.actor.* -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.instance.InstanceId import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.model.support.domain.Domain @@ -57,7 +57,7 @@ class ActorResultRowMapper : ResultRowMapper { emojiIds = resultRow[Actors.emojis] .split(",") .filter { it.isNotEmpty() } - .map { CustomEmojiId(it.toLong()) } + .map { EmojiId(it.toLong()) } .toSet(), deleted = resultRow[Actors.deleted], icon = resultRow[Actors.icon]?.let { MediaId(it) }, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt index 139bd86c..653533ed 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt @@ -17,7 +17,7 @@ package dev.usbharu.hideout.core.infrastructure.exposed import dev.usbharu.hideout.core.domain.model.actor.ActorId -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts @@ -55,7 +55,7 @@ class PostQueryMapper(private val postResultRowMapper: ResultRowMapper) : .mapNotNull { resultRow: ResultRow -> resultRow .getOrNull(PostsEmojis.emojiId) - ?.let { emojiId -> CustomEmojiId(emojiId) } + ?.let { emojiId -> EmojiId(emojiId) } }, visibleActors = it.mapNotNull { resultRow: ResultRow -> resultRow diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ExposedReactionsQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ExposedReactionsQueryService.kt deleted file mode 100644 index d22184e7..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ExposedReactionsQueryService.kt +++ /dev/null @@ -1,73 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import dev.usbharu.hideout.core.application.model.Reactions -import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji -import dev.usbharu.hideout.core.domain.model.post.PostId -import dev.usbharu.hideout.core.infrastructure.exposedrepository.AbstractRepository -import dev.usbharu.hideout.core.infrastructure.exposedrepository.CustomEmojis -import dev.usbharu.hideout.core.infrastructure.exposedrepository.toCustomEmojiOrNull -import dev.usbharu.hideout.core.infrastructure.exposedrepository.toReaction -import dev.usbharu.hideout.core.query.reactions.ReactionsQueryService -import org.jetbrains.exposed.sql.* -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Repository -import java.net.URI -import dev.usbharu.hideout.core.infrastructure.exposedrepository.Reactions as ExposedrepositoryReactions - -@Repository -class ExposedReactionsQueryService : ReactionsQueryService, AbstractRepository() { - override suspend fun findAllByPostId(postId: PostId): List { - return query { - ExposedrepositoryReactions.leftJoin(CustomEmojis).selectAll() - .where { ExposedrepositoryReactions.postId eq postId.id } - .groupBy { - it[ExposedrepositoryReactions.customEmojiId]?.toString() - ?: it[ExposedrepositoryReactions.unicodeEmoji] - } - .map { it.value } - .map { - Reactions.of( - it.map { resultRow -> resultRow.toReaction() }, - it.first().toCustomEmojiOrNull() - ) - } - } - } - - override suspend fun findAllByPostIdIn(postIds: List): List { - return query { - val actorIdsQuery = - ExposedrepositoryReactions.actorId.castTo(VarCharColumnType()).groupConcat(",", true) - - ExposedrepositoryReactions.leftJoin(CustomEmojis) - .select( - ExposedrepositoryReactions.postId, - ExposedrepositoryReactions.postId.count(), - ExposedrepositoryReactions.customEmojiId.max(), - ExposedrepositoryReactions.unicodeEmoji.max(), - actorIdsQuery - ) - .where { ExposedrepositoryReactions.postId inList postIds.map { it.id } } - .groupBy(ExposedrepositoryReactions.postId) - .map { - Reactions( - it[ExposedrepositoryReactions.postId], - it[ExposedrepositoryReactions.postId.count()].toInt(), - it.getOrNull(CustomEmojis.name) - ?: it[ExposedrepositoryReactions.unicodeEmoji.max()]!!, - it.getOrNull(CustomEmojis.domain) ?: UnicodeEmoji.domain.domain, - it.getOrNull(CustomEmojis.url)?.let { it1 -> URI.create(it1) }, - it[actorIdsQuery].split(",").mapNotNull { it.toLongOrNull() } - ) - } - } - } - - override val logger: Logger - get() = Companion.logger - - companion object { - private val logger = LoggerFactory.getLogger(ExposedReactionsQueryService::class.java) - } -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ExposedUserTimelineQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ExposedUserTimelineQueryService.kt index db3fb0f2..82be6f96 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ExposedUserTimelineQueryService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ExposedUserTimelineQueryService.kt @@ -61,12 +61,6 @@ class ExposedUserTimelineQueryService : UserTimelineQueryService, AbstractReposi .leftJoin(iconMedia, { Actors.icon }, { iconMedia[Media.id] }) .leftJoin(PostsMedia, { authorizedQuery[Posts.id] }, { PostsMedia.postId }) .leftJoin(Media, { PostsMedia.mediaId }, { Media.id }) - .leftJoin( - Reactions, - { authorizedQuery[Posts.id] }, - { Reactions.postId }, - { Reactions.id isDistinctFrom principal.actorId.id } - ) .selectAll() .where { authorizedQuery[Posts.id] inList idList.map { it.id } } .groupBy { it[authorizedQuery[Posts.id]] } @@ -75,8 +69,7 @@ class ExposedUserTimelineQueryService : UserTimelineQueryService, AbstractReposi toPostDetail(it.first(), authorizedQuery, iconMedia).copy( mediaDetailList = it.mapNotNull { resultRow -> resultRow.toMediaOrNull()?.let { it1 -> MediaDetail.of(it1) } - }, - favourited = it.any { it.getOrNull(Reactions.actorId) != null } + } ) } } @@ -107,9 +100,7 @@ class ExposedUserTimelineQueryService : UserTimelineQueryService, AbstractReposi sensitive = it[authorizedQuery[Posts.sensitive]], deleted = it[authorizedQuery[Posts.deleted]], mediaDetailList = emptyList(), - moveTo = null, - emptyList(), - favourited = false + moveTo = null ) } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt index e3ca9079..c095ae55 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt @@ -17,8 +17,8 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.instance.InstanceId import dev.usbharu.hideout.core.domain.model.support.domain.Domain import org.jetbrains.exposed.sql.* @@ -81,7 +81,7 @@ class CustomEmojiRepositoryImpl : CustomEmojiRepository, } fun ResultRow.toCustomEmoji(): CustomEmoji = CustomEmoji( - id = CustomEmojiId(this[CustomEmojis.id]), + id = EmojiId(this[CustomEmojis.id]), name = this[CustomEmojis.name], domain = Domain(this[CustomEmojis.domain]), instanceId = InstanceId(this[CustomEmojis.instanceId]), @@ -92,7 +92,7 @@ fun ResultRow.toCustomEmoji(): CustomEmoji = CustomEmoji( fun ResultRow.toCustomEmojiOrNull(): CustomEmoji? { return CustomEmoji( - id = CustomEmojiId(this.getOrNull(CustomEmojis.id) ?: return null), + id = EmojiId(this.getOrNull(CustomEmojis.id) ?: return null), name = this.getOrNull(CustomEmojis.name) ?: return null, domain = Domain(this.getOrNull(CustomEmojis.domain) ?: return null), instanceId = InstanceId(this.getOrNull(CustomEmojis.instanceId) ?: return null), diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt index 37a476b1..9408d01a 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt @@ -168,7 +168,7 @@ class ExposedPostRepository( Posts.id eq id.id } .let(postQueryMapper::map) - .firstOrNull() + .first() } override suspend fun findAllById(ids: List): List { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedReactionRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedReactionRepository.kt deleted file mode 100644 index d44bca1f..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedReactionRepository.kt +++ /dev/null @@ -1,128 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedrepository - -import dev.usbharu.hideout.core.domain.model.actor.ActorId -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId -import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji -import dev.usbharu.hideout.core.domain.model.post.PostId -import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import dev.usbharu.hideout.core.domain.model.reaction.ReactionId -import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository -import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher -import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.javatime.timestamp -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Repository - -@Repository -class ExposedReactionRepository(override val domainEventPublisher: DomainEventPublisher) : - ReactionRepository, - AbstractRepository(), - DomainEventPublishableRepository { - - override val logger: Logger - get() = Companion.logger - - override suspend fun save(reaction: Reaction): Reaction { - return query { - Reactions.upsert { - it[Reactions.id] = reaction.id.value - it[Reactions.postId] = reaction.postId.id - it[Reactions.actorId] = reaction.actorId.id - it[Reactions.customEmojiId] = reaction.customEmojiId?.emojiId - it[Reactions.unicodeEmoji] = reaction.unicodeEmoji.name - it[Reactions.createdAt] = reaction.createdAt - } - onComplete { - update(reaction) - } - reaction - } - } - - override suspend fun findById(reactionId: ReactionId): Reaction? { - return query { - Reactions.selectAll().where { - Reactions.id eq reactionId.value - }.singleOrNull()?.toReaction() - } - } - - override suspend fun findByPostId(postId: PostId): List { - return query { - Reactions.selectAll().where { - Reactions.postId eq postId.id - }.map { it.toReaction() } - } - } - - override suspend fun existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji( - postId: PostId, - actorId: ActorId, - customEmojiId: CustomEmojiId?, - unicodeEmoji: String - ): Boolean { - return query { - Reactions.selectAll().where { - Reactions.postId.eq(postId.id).and(Reactions.actorId eq actorId.id) - .and( - (Reactions.customEmojiId eq customEmojiId?.emojiId or (Reactions.unicodeEmoji eq unicodeEmoji)) - ) - }.empty().not() - } - } - - override suspend fun delete(reaction: Reaction) { - return query { - Reactions.deleteWhere { - Reactions.id eq reaction.id.value - } - onComplete { - update(reaction) - } - } - } - - override suspend fun findByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji( - postId: PostId, - actorId: ActorId, - customEmojiId: CustomEmojiId?, - unicodeEmoji: String - ): Reaction? { - return query { - Reactions.selectAll().where { - Reactions.postId.eq(postId.id).and(Reactions.actorId eq actorId.id) - .and( - (Reactions.customEmojiId eq customEmojiId?.emojiId or (Reactions.unicodeEmoji eq unicodeEmoji)) - ) - }.limit(1).singleOrNull()?.toReaction() - } - } - - companion object { - private val logger = LoggerFactory.getLogger(ExposedReactionRepository::class.java) - } -} - -fun ResultRow.toReaction(): Reaction { - return Reaction( - ReactionId(this[Reactions.id]), - PostId(this[Reactions.postId]), - ActorId(this[Reactions.actorId]), - this[Reactions.customEmojiId]?.let { CustomEmojiId(it) }, - UnicodeEmoji(this[Reactions.unicodeEmoji]), - this[Reactions.createdAt] - ) -} - -object Reactions : Table("reactions") { - val id = long("id") - val postId = long("post_id").references(Posts.id) - val actorId = long("actor_id").references(Actors.id) - val customEmojiId = long("custom_emoji_id").references(CustomEmojis.id).nullable() - val unicodeEmoji = varchar("unicode_emoji", 100) - val createdAt = timestamp("created_at") - override val primaryKey: PrimaryKey = PrimaryKey(id) -} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt index 2e66bbbd..1e476d0c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt @@ -1,7 +1,7 @@ package dev.usbharu.hideout.core.infrastructure.mongorepository import dev.usbharu.hideout.core.domain.model.actor.ActorId -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.filter.FilterId import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.model.post.PostId @@ -133,8 +133,7 @@ data class SpringDataMongoTimelineObject( val visibleActors: List, val hasMediaInRepost: Boolean, val lastUpdatedAt: Long, - val warnFilters: List, - val favourited: Boolean + val warnFilters: List ) { fun toTimelineObject(): TimelineObject { @@ -152,12 +151,11 @@ data class SpringDataMongoTimelineObject( visibility = visibility, isPureRepost = isPureRepost, mediaIds = mediaIds.map { MediaId(it) }, - emojiIds = emojiIds.map { CustomEmojiId(it) }, + emojiIds = emojiIds.map { EmojiId(it) }, visibleActors = visibleActors.map { ActorId(it) }, hasMediaInRepost = hasMediaInRepost, lastUpdatedAt = Instant.ofEpochSecond(lastUpdatedAt), - warnFilters = warnFilters.map { it.toTimelineObjectWarnFilter() }, - favourited = favourited + warnFilters = warnFilters.map { it.toTimelineObjectWarnFilter() } ) } @@ -181,8 +179,7 @@ data class SpringDataMongoTimelineObject( visibleActors = timelineObject.visibleActors.map { it.id }, hasMediaInRepost = timelineObject.hasMediaInRepost, lastUpdatedAt = timelineObject.lastUpdatedAt.epochSecond, - warnFilters = timelineObject.warnFilters.map { SpringDataMongoTimelineObjectWarnFilter.of(it) }, - favourited = timelineObject.favourited + warnFilters = timelineObject.warnFilters.map { SpringDataMongoTimelineObjectWarnFilter.of(it) } ) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/SPAInterceptor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/SPAInterceptor.kt index b3d9a394..b3a6eeb0 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/SPAInterceptor.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/SPAInterceptor.kt @@ -29,7 +29,7 @@ class SPAInterceptor : HandlerInterceptor { return } - if (request.getSession(false)?.getAttribute("s") == "f") { + if (request.session.getAttribute("s") == "f") { return } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt index b22d0121..50801dc2 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt @@ -1,6 +1,5 @@ package dev.usbharu.hideout.core.infrastructure.timeline -import dev.usbharu.hideout.core.application.model.Reactions import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.filter.Filter @@ -76,8 +75,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe post = post, replyActorId = replyActorId, repost = repost, - filterResults = applyFilters.filterResults, - favourited = false + filterResults = applyFilters.filterResults ) } @@ -86,8 +84,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe timeline = timeline, post = post, replyActorId = replyActorId, - filterResults = applyFilters.filterResults, - favourited = false + filterResults = applyFilters.filterResults ) } @@ -259,8 +256,6 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe actors.mapNotNull { it.value.icon } ) - val reactions = getReactions(posts.map { it.id }) - return PaginationList( timelineObjectList.mapNotNull { val timelineUserDetail = userDetails[it.userDetailId] ?: return@mapNotNull null @@ -273,7 +268,6 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe val repost = postMap[it.repostId] val repostMedias = repost?.post?.mediaIds?.mapNotNull { mediaId -> mediaMap[mediaId] } val repostActor = actors[it.repostActorId] - val reactionsList = reactions[it.postId].orEmpty() TimelineObjectDetail.of( timelineObject = it, timelineUserDetail = timelineUserDetail, @@ -294,9 +288,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe filterResult.filter.id, filterResult.matchedKeyword ) - }, - reactionsList = reactionsList, - favourited = it.favourited + } ) }, timelineObjectList.lastOrNull()?.postId, @@ -308,7 +300,5 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe protected abstract suspend fun getMedias(mediaIds: List): Map - protected abstract suspend fun getReactions(postIds: List): Map> - protected abstract suspend fun getUserDetails(userDetailIdList: List): Map } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt index 7426d1b6..36faa561 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt @@ -1,6 +1,5 @@ package dev.usbharu.hideout.core.infrastructure.timeline -import dev.usbharu.hideout.core.application.model.Reactions import dev.usbharu.hideout.core.config.DefaultTimelineStoreConfig import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorId @@ -33,7 +32,6 @@ import dev.usbharu.hideout.core.domain.service.filter.FilterDomainService import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService import dev.usbharu.hideout.core.external.timeline.ReadTimelineOption -import dev.usbharu.hideout.core.query.reactions.ReactionsQueryService import org.springframework.stereotype.Component import java.time.Instant @@ -51,8 +49,7 @@ open class DefaultTimelineStore( private val userDetailRepository: UserDetailRepository, private val actorRepository: ActorRepository, private val mediaRepository: MediaRepository, - private val postIPostReadAccessControl: IPostReadAccessControl, - private val reactionsQueryService: ReactionsQueryService, + private val postIPostReadAccessControl: IPostReadAccessControl ) : AbstractTimelineStore(idGenerateService) { override suspend fun getTimelines(actorId: ActorId): List { return timelineRepository.findByIds( @@ -160,10 +157,6 @@ open class DefaultTimelineStore( override suspend fun getMedias(mediaIds: List): Map = mediaRepository.findByIds(mediaIds).associateBy { it.id } - override suspend fun getReactions(postIds: List): Map> { - return reactionsQueryService.findAllByPostIdIn(postIds).groupBy { PostId(it.postId) } - } - override suspend fun getUserDetails(userDetailIdList: List): Map = userDetailRepository.findAllById(userDetailIdList).associateBy { it.id } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/posts/PostsController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/posts/PostsController.kt index f1005327..4dda4759 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/posts/PostsController.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/posts/PostsController.kt @@ -4,25 +4,18 @@ import dev.usbharu.hideout.core.application.exception.PermissionDeniedException import dev.usbharu.hideout.core.application.instance.GetLocalInstanceApplicationService import dev.usbharu.hideout.core.application.post.GetPostDetail import dev.usbharu.hideout.core.application.post.GetPostDetailApplicationService -import dev.usbharu.hideout.core.application.reaction.CreateReaction -import dev.usbharu.hideout.core.application.reaction.RemoveReaction -import dev.usbharu.hideout.core.application.reaction.UserCreateReactionApplicationService -import dev.usbharu.hideout.core.application.reaction.UserRemoveReactionApplicationService import dev.usbharu.hideout.core.infrastructure.springframework.SpringSecurityFormLoginPrincipalContextHolder import org.springframework.security.access.AccessDeniedException import org.springframework.stereotype.Controller import org.springframework.ui.Model import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.PostMapping @Controller class PostsController( private val getPostDetailApplicationService: GetPostDetailApplicationService, private val springSecurityFormLoginPrincipalContextHolder: SpringSecurityFormLoginPrincipalContextHolder, - private val getLocalInstanceApplicationService: GetLocalInstanceApplicationService, - private val userCreateReactionApplicationService: UserCreateReactionApplicationService, - private val userRemoveReactionApplicationService: UserRemoveReactionApplicationService + private val getLocalInstanceApplicationService: GetLocalInstanceApplicationService ) { @GetMapping("/users/{name}/posts/{id}") suspend fun postById(@PathVariable id: Long, model: Model): String { @@ -38,32 +31,4 @@ class PostsController( return "postById" } - - @PostMapping("/users/{name}/posts/{id}/favourite") - suspend fun favourite(@PathVariable id: Long, @PathVariable name: String): String { - val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal() - userCreateReactionApplicationService.execute( - CreateReaction( - id, - null, - "❤" - ), - principal - ) - return "redirect:/users/$name/posts/$id" - } - - @PostMapping("/users/{name}/posts/{id}/unfavourite") - suspend fun unfavourite(@PathVariable id: Long, @PathVariable name: String): String { - val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal() - userRemoveReactionApplicationService.execute( - RemoveReaction( - id, - null, - "❤" - ), - principal - ) - return "redirect:/users/$name/posts/$id" - } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/reactions/ReactionsQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/reactions/ReactionsQueryService.kt deleted file mode 100644 index e410c4ae..00000000 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/reactions/ReactionsQueryService.kt +++ /dev/null @@ -1,9 +0,0 @@ -package dev.usbharu.hideout.core.query.reactions - -import dev.usbharu.hideout.core.application.model.Reactions -import dev.usbharu.hideout.core.domain.model.post.PostId - -interface ReactionsQueryService { - suspend fun findAllByPostId(postId: PostId): List - suspend fun findAllByPostIdIn(postIds: List): List -} diff --git a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql index f4c62702..6ce43568 100644 --- a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql +++ b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql @@ -318,17 +318,4 @@ create table if not exists filter_keywords keyword varchar(1000) not null, mode varchar(100) not null, constraint fk_filter_keywords_filter_id__id foreign key (filter_id) references filters (id) on delete cascade on update cascade -); - -create table if not exists reactions -( - id bigint primary key, - post_id bigint not null, - actor_id bigint not null, - custom_emoji_id bigint null, - unicode_emoji varchar(100) not null, - created_at timestamp not null, - constraint fk_reactions_post_id__id foreign key (post_id) references posts (id) on delete cascade on update cascade, - constraint fk_reactions_actor_id__id foreign key (actor_id) references actors (id) on delete cascade on update cascade, - unique (post_id, actor_id, created_at, unicode_emoji) -); \ No newline at end of file +) \ No newline at end of file diff --git a/hideout-core/src/main/resources/templates/fragments-post.html b/hideout-core/src/main/resources/templates/fragments-post.html index d16f4861..e55f55be 100644 --- a/hideout-core/src/main/resources/templates/fragments-post.html +++ b/hideout-core/src/main/resources/templates/fragments-post.html @@ -44,27 +44,10 @@
- -
- Reply - - - - -
-
- -
- Reply - - - - -
-
- + Reply + + +
diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/TestActorFactory.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/TestActorFactory.kt index 4f81a194..3286ed74 100644 --- a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/TestActorFactory.kt +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/TestActorFactory.kt @@ -1,6 +1,6 @@ package dev.usbharu.hideout.core.domain.model.actor -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.instance.InstanceId import dev.usbharu.hideout.core.domain.model.support.domain.Domain import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService @@ -35,7 +35,7 @@ object TestActorFactory { suspend: Boolean = false, alsoKnownAs: Set = emptySet(), moveTo: Long? = null, - emojiIds: Set = emptySet(), + emojiIds: Set = emptySet(), deleted: Boolean = false, roles: Set = emptySet(), ): Actor { diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiIdTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/emoji/EmojiIdTest.kt similarity index 82% rename from hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiIdTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/emoji/EmojiIdTest.kt index e9383cdb..c304294b 100644 --- a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiIdTest.kt +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/emoji/EmojiIdTest.kt @@ -3,18 +3,18 @@ package dev.usbharu.hideout.core.domain.model.emoji import org.junit.jupiter.api.Assertions.assertDoesNotThrow import org.junit.jupiter.api.Test -class CustomEmojiIdTest { +class EmojiIdTest { @Test fun emojiIdは0以上である必要がある() { org.junit.jupiter.api.assertThrows { - CustomEmojiId(-1) + EmojiId(-1) } } @Test fun emojiIdは0以上なら設定できる() { assertDoesNotThrow { - CustomEmojiId(1) + EmojiId(1) } } } \ No newline at end of file diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/post/PostTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/post/PostTest.kt index a07a0b0d..ae8cc674 100644 --- a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/post/PostTest.kt +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/post/PostTest.kt @@ -4,7 +4,7 @@ import dev.usbharu.hideout.core.domain.event.post.PostEvent import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.actor.ActorPublicKey import dev.usbharu.hideout.core.domain.model.actor.TestActorFactory -import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.emoji.EmojiId import dev.usbharu.hideout.core.domain.model.media.MediaId import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test @@ -447,7 +447,7 @@ class PostTest { @Test fun `emojiIds hideがtrueの時empty`() { val actor = TestActorFactory.create() - val emojiIds = listOf(CustomEmojiId(1), CustomEmojiId(2)) + val emojiIds = listOf(EmojiId(1), EmojiId(2)) val post = Post.create( id = PostId(1), actorId = actor.id, @@ -473,7 +473,7 @@ class PostTest { @Test fun `emojiIds hideがfalseの時中身が返される`() { val actor = TestActorFactory.create() - val emojiIds = listOf(CustomEmojiId(1), CustomEmojiId(2)) + val emojiIds = listOf(EmojiId(1), EmojiId(2)) val post = Post.create( id = PostId(1), actorId = actor.id, @@ -500,7 +500,7 @@ class PostTest { val post = TestPostFactory.create() val mediaIds = listOf(MediaId(1)) val visibleActors = setOf((ActorId(2))) - val emojis = listOf(CustomEmojiId(3)) + val emojis = listOf(EmojiId(3)) val reconstructWith = post.reconstructWith(mediaIds, emojis, visibleActors) assertEquals(mediaIds, reconstructWith.mediaIds) @@ -511,7 +511,7 @@ class PostTest { @Test fun `mediaIds hideがtrueの時emptyが返される`() { val actor = TestActorFactory.create() - val emojiIds = listOf(CustomEmojiId(1), CustomEmojiId(2)) + val emojiIds = listOf(EmojiId(1), EmojiId(2)) val mediaIds = listOf(MediaId(1)) val post = Post.create( id = PostId(1), @@ -538,7 +538,7 @@ class PostTest { @Test fun `mediaIds hideがfalseの時中身が返される`() { val actor = TestActorFactory.create() - val emojiIds = listOf(CustomEmojiId(1), CustomEmojiId(2)) + val emojiIds = listOf(EmojiId(1), EmojiId(2)) val mediaIds = listOf(MediaId(2)) val post = Post.create( id = PostId(1), @@ -603,7 +603,7 @@ class PostTest { fun `restore 指定された引数で再構成されCHECKUPDATEイベントが発生する`() { val post = TestPostFactory.create(deleted = true) - val postContent = PostContent("aiueo", "aiueo", listOf(CustomEmojiId(1))) + val postContent = PostContent("aiueo", "aiueo", listOf(EmojiId(1))) val overview = PostOverview("overview") val mediaIds = listOf(MediaId(1)) post.restore( @@ -622,7 +622,7 @@ class PostTest { fun deletedがfalseの時失敗する() { val post = TestPostFactory.create(deleted = false) - val postContent = PostContent("aiueo", "aiueo", listOf(CustomEmojiId(1))) + val postContent = PostContent("aiueo", "aiueo", listOf(EmojiId(1))) val overview = PostOverview("overview") val mediaIds = listOf(MediaId(1)) assertThrows { diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/emojikt/EmojiKtUnicodeEmojiServiceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/emojikt/EmojiKtUnicodeEmojiServiceTest.kt deleted file mode 100644 index f589be2c..00000000 --- a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/emojikt/EmojiKtUnicodeEmojiServiceTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.emojikt - -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.ValueSource - -class EmojiKtUnicodeEmojiServiceTest { - - @ParameterizedTest - @ValueSource(strings = ["❤", "👱", "☠️", "⁉️"]) - fun 絵文字の判定ができる(s: String) { - assertTrue(EmojiKtUnicodeEmojiService().isUnicodeEmoji(s)) - } - - -} \ No newline at end of file diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt index 10e54af0..5e045a59 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt @@ -18,10 +18,6 @@ package dev.usbharu.hideout.mastodon.interfaces.api import dev.usbharu.hideout.core.application.post.RegisterLocalPost import dev.usbharu.hideout.core.application.post.RegisterLocalPostApplicationService -import dev.usbharu.hideout.core.application.reaction.CreateReaction -import dev.usbharu.hideout.core.application.reaction.RemoveReaction -import dev.usbharu.hideout.core.application.reaction.UserCreateReactionApplicationService -import dev.usbharu.hideout.core.application.reaction.UserRemoveReactionApplicationService import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.SpringSecurityOauth2PrincipalContextHolder import dev.usbharu.hideout.mastodon.application.status.GetStatus @@ -36,9 +32,7 @@ import org.springframework.stereotype.Controller class SpringStatusApi( private val registerLocalPostApplicationService: RegisterLocalPostApplicationService, private val getStatusApplicationService: GetStatusApplicationService, - private val principalContextHolder: SpringSecurityOauth2PrincipalContextHolder, - private val userCreateReactionApplicationService: UserCreateReactionApplicationService, - private val userRemoveReactionApplicationService: UserRemoveReactionApplicationService + private val principalContextHolder: SpringSecurityOauth2PrincipalContextHolder ) : StatusApi { override suspend fun apiV1StatusesIdEmojiReactionsEmojiDelete(id: String, emoji: String): ResponseEntity = super.apiV1StatusesIdEmojiReactionsEmojiDelete(id, emoji) @@ -55,20 +49,6 @@ class SpringStatusApi( ) } - override suspend fun apiV1StatusesIdFavouritePost(id: String): ResponseEntity { - val principal = principalContextHolder.getPrincipal() - - userCreateReactionApplicationService.execute(CreateReaction(postId = id.toLong(), null, "❤"), principal) - return ResponseEntity.ok(getStatusApplicationService.execute(GetStatus(id), principal)) - } - - override suspend fun apiV1StatusesIdUnfavouritePost(id: String): ResponseEntity { - val principal = principalContextHolder.getPrincipal() - - userRemoveReactionApplicationService.execute(RemoveReaction(postId = id.toLong(), null, "❤"), principal) - return ResponseEntity.ok(getStatusApplicationService.execute(GetStatus(id), principal)) - } - override suspend fun apiV1StatusesPost(statusesRequest: StatusesRequest): ResponseEntity { val principal = principalContextHolder.getPrincipal() val execute = registerLocalPostApplicationService.execute( diff --git a/hideout-mastodon/src/main/resources/openapi/mastodon.yaml b/hideout-mastodon/src/main/resources/openapi/mastodon.yaml index 76d8f5aa..bc5195d5 100644 --- a/hideout-mastodon/src/main/resources/openapi/mastodon.yaml +++ b/hideout-mastodon/src/main/resources/openapi/mastodon.yaml @@ -177,48 +177,6 @@ paths: schema: $ref: "#/components/schemas/Status" - /api/v1/statuses/{id}/favourite: - post: - tags: - - status - security: - - OAuth2: - - "write:favourites" - parameters: - - in: path - name: id - required: true - schema: - type: string - responses: - 200: - description: 成功 - content: - application/json: - schema: - $ref: "#/components/schemas/Status" - - /api/v1/statuses/{id}/unfavourite: - post: - tags: - - status - security: - - OAuth2: - - "write:favourites" - parameters: - - in: path - name: id - required: true - schema: - type: string - responses: - 200: - description: 成功 - content: - application/json: - schema: - $ref: "#/components/schemas/Status" - /api/v1/statuses/{id}/emoji_reactions/{emoji}: put: tags: