mirror of https://github.com/usbharu/Hideout.git
feat: 絵文字リアクションAPIを追加
This commit is contained in:
parent
a015566e52
commit
a5618e3307
|
@ -6,4 +6,5 @@ import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji
|
|||
interface EmojiService {
|
||||
suspend fun fetchEmoji(url: String): Pair<Emoji, CustomEmoji>
|
||||
suspend fun fetchEmoji(emoji: Emoji): Pair<Emoji, CustomEmoji>
|
||||
suspend fun findByEmojiName(emojiName: String): CustomEmoji?
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package dev.usbharu.hideout.activitypub.service.objects.emoji
|
|||
import dev.usbharu.hideout.activitypub.domain.model.Emoji
|
||||
import dev.usbharu.hideout.activitypub.service.common.APResourceResolveServiceImpl
|
||||
import dev.usbharu.hideout.activitypub.service.common.resolve
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
|
||||
import dev.usbharu.hideout.core.service.instance.InstanceService
|
||||
|
@ -17,7 +18,8 @@ class EmojiServiceImpl(
|
|||
private val customEmojiRepository: CustomEmojiRepository,
|
||||
private val instanceService: InstanceService,
|
||||
private val mediaService: MediaService,
|
||||
private val apResourceResolveServiceImpl: APResourceResolveServiceImpl
|
||||
private val apResourceResolveServiceImpl: APResourceResolveServiceImpl,
|
||||
private val applicationConfig: ApplicationConfig
|
||||
) : EmojiService {
|
||||
override suspend fun fetchEmoji(url: String): Pair<Emoji, CustomEmoji> {
|
||||
val emoji = apResourceResolveServiceImpl.resolve<Emoji>(url, null as Long?)
|
||||
|
@ -60,4 +62,20 @@ class EmojiServiceImpl(
|
|||
|
||||
return customEmojiRepository.save(customEmoji1)
|
||||
}
|
||||
|
||||
override suspend fun findByEmojiName(emojiName: String): CustomEmoji? {
|
||||
val split = emojiName.trim(':').split("@")
|
||||
|
||||
return when (split.size) {
|
||||
1 -> {
|
||||
customEmojiRepository.findByNameAndDomain(split.first(), applicationConfig.url.host)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
customEmojiRepository.findByNameAndDomain(split.first(), split[1])
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException("Unknown Emoji Format. $emojiName")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,10 @@ class StatusQueryServiceImpl : StatusQueryService {
|
|||
return resolveReplyAndRepost(pairs)
|
||||
}
|
||||
|
||||
override suspend fun findByPostId(id: Long): Status {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun resolveReplyAndRepost(pairs: List<Pair<Status, Long?>>): List<Status> {
|
||||
val statuses = pairs.map { it.first }
|
||||
return pairs
|
||||
|
|
|
@ -24,4 +24,16 @@ class MastodonStatusesApiContoller(private val statusesApiService: StatusesApiSe
|
|||
HttpStatus.OK
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun apiV1StatusesIdEmojiReactionsEmojiDelete(id: String, emoji: String): ResponseEntity<Status> {
|
||||
return super.apiV1StatusesIdEmojiReactionsEmojiDelete(id, emoji)
|
||||
}
|
||||
|
||||
override suspend fun apiV1StatusesIdEmojiReactionsEmojiPut(id: String, emoji: String): ResponseEntity<Status> {
|
||||
return super.apiV1StatusesIdEmojiReactionsEmojiPut(id, emoji)
|
||||
}
|
||||
|
||||
override suspend fun apiV1StatusesIdGet(id: String): ResponseEntity<Status> {
|
||||
return super.apiV1StatusesIdGet(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,6 @@ interface StatusQueryService {
|
|||
tagged: String? = null,
|
||||
includeFollowers: Boolean = false
|
||||
): List<Status>
|
||||
|
||||
suspend fun findByPostId(id: Long): Status
|
||||
}
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
package dev.usbharu.hideout.mastodon.service.status
|
||||
|
||||
import dev.usbharu.hideout.activitypub.service.objects.emoji.EmojiService
|
||||
import dev.usbharu.hideout.application.external.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
|
||||
import dev.usbharu.hideout.core.domain.model.media.toMediaAttachments
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
||||
import dev.usbharu.hideout.core.service.post.PostCreateDto
|
||||
import dev.usbharu.hideout.core.service.post.PostService
|
||||
import dev.usbharu.hideout.core.service.reaction.ReactionService
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Status.Visibility.*
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.status.StatusesRequest
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.status.toPostVisibility
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.status.toStatusVisibility
|
||||
import dev.usbharu.hideout.mastodon.query.StatusQueryService
|
||||
import dev.usbharu.hideout.mastodon.service.account.AccountService
|
||||
import dev.usbharu.hideout.util.EmojiUtil
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
import java.time.Instant
|
||||
|
@ -22,6 +29,23 @@ interface StatusesApiService {
|
|||
statusesRequest: StatusesRequest,
|
||||
userId: Long
|
||||
): Status
|
||||
|
||||
suspend fun findById(
|
||||
id: Long,
|
||||
userId: Long?
|
||||
): Status?
|
||||
|
||||
suspend fun emojiReactions(
|
||||
postId: Long,
|
||||
userId: Long,
|
||||
emojiName: String
|
||||
): Status?
|
||||
|
||||
suspend fun removeEmojiReactions(
|
||||
postId: Long,
|
||||
userId: Long,
|
||||
emojiName: String
|
||||
): Status?
|
||||
}
|
||||
|
||||
@Service
|
||||
|
@ -31,7 +55,11 @@ class StatsesApiServiceImpl(
|
|||
private val mediaRepository: MediaRepository,
|
||||
private val transaction: Transaction,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val postRepository: PostRepository
|
||||
private val postRepository: PostRepository,
|
||||
private val statusQueryService: StatusQueryService,
|
||||
private val relationshipRepository: RelationshipRepository,
|
||||
private val reactionService: ReactionService,
|
||||
private val emojiService: EmojiService
|
||||
) :
|
||||
StatusesApiService {
|
||||
override suspend fun postStatus(
|
||||
|
@ -95,6 +123,63 @@ class StatsesApiServiceImpl(
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun findById(id: Long, userId: Long?): Status? {
|
||||
val status = statusQueryService.findByPostId(id)
|
||||
|
||||
return status(status, userId)
|
||||
}
|
||||
|
||||
private suspend fun status(
|
||||
status: Status,
|
||||
userId: Long?
|
||||
): Status? {
|
||||
return when (status.visibility) {
|
||||
public -> status
|
||||
unlisted -> status
|
||||
private -> {
|
||||
if (userId == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val relationship =
|
||||
relationshipRepository.findByUserIdAndTargetUserId(userId, status.account.id.toLong())
|
||||
?: return null
|
||||
if (relationship.following) {
|
||||
return status
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
direct -> null
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun emojiReactions(postId: Long, userId: Long, emojiName: String): Status? {
|
||||
|
||||
status(statusQueryService.findByPostId(postId), userId) ?: return null
|
||||
|
||||
val emoji = try {
|
||||
if (EmojiUtil.isEmoji(emojiName)) {
|
||||
UnicodeEmoji(emojiName)
|
||||
} else {
|
||||
emojiService.findByEmojiName(emojiName)!!
|
||||
}
|
||||
} catch (e: IllegalStateException) {
|
||||
UnicodeEmoji("❤")
|
||||
} catch (e: NullPointerException) {
|
||||
UnicodeEmoji("❤")
|
||||
}
|
||||
reactionService.sendReaction(emoji, userId, postId)
|
||||
return statusQueryService.findByPostId(postId)
|
||||
}
|
||||
|
||||
override suspend fun removeEmojiReactions(postId: Long, userId: Long, emojiName: String): Status? {
|
||||
|
||||
reactionService.removeReaction(userId, postId)
|
||||
|
||||
return status(statusQueryService.findByPostId(postId), userId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(StatusesApiService::class.java)
|
||||
}
|
||||
|
|
|
@ -152,6 +152,79 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Status"
|
||||
|
||||
/api/v1/statuses/{id}:
|
||||
get:
|
||||
tags:
|
||||
- status
|
||||
security:
|
||||
- OAuth2:
|
||||
- "write:statuses"
|
||||
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:
|
||||
- status
|
||||
security:
|
||||
- OAuth2:
|
||||
- "write:statuses"
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: emoji
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Status"
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- status
|
||||
security:
|
||||
- OAuth2:
|
||||
- "write:statuses"
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: emoji
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Status"
|
||||
|
||||
|
||||
/api/v1/apps:
|
||||
post:
|
||||
tags:
|
||||
|
|
Loading…
Reference in New Issue