mirror of https://github.com/usbharu/Hideout.git
Merge branch 'develop' into renovate/detekt
This commit is contained in:
commit
4c6c8f5938
|
@ -25,6 +25,7 @@ import org.springframework.data.mongodb.core.MongoTemplate
|
||||||
import org.springframework.data.mongodb.core.mapping.Document
|
import org.springframework.data.mongodb.core.mapping.Document
|
||||||
import org.springframework.data.mongodb.core.query.Criteria
|
import org.springframework.data.mongodb.core.query.Criteria
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
import org.springframework.data.mongodb.core.query.Query
|
||||||
|
import org.springframework.data.mongodb.core.query.isEqualTo
|
||||||
import org.springframework.data.repository.kotlin.CoroutineCrudRepository
|
import org.springframework.data.repository.kotlin.CoroutineCrudRepository
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
@ -84,6 +85,8 @@ class MongoInternalTimelineObjectRepository(
|
||||||
): PaginationList<TimelineObject, PostId> {
|
): PaginationList<TimelineObject, PostId> {
|
||||||
val query = Query()
|
val query = Query()
|
||||||
|
|
||||||
|
query.addCriteria(Criteria.where("timelineId").isEqualTo(timelineId.value))
|
||||||
|
|
||||||
if (page?.minId != null) {
|
if (page?.minId != null) {
|
||||||
query.with(Sort.by(Sort.Direction.ASC, "postCreatedAt"))
|
query.with(Sort.by(Sort.Direction.ASC, "postCreatedAt"))
|
||||||
page.minId?.let { query.addCriteria(Criteria.where("postId").gt(it)) }
|
page.minId?.let { query.addCriteria(Criteria.where("postId").gt(it)) }
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
</noscript>
|
</noscript>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
|
||||||
<a th:href="${nsUrl}">No Script</a>
|
<a th:href="${nsUrl}">No Script</a>
|
||||||
</noscript>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.mastodon.application.accounts
|
package dev.usbharu.hideout.mastodon.application.accounts
|
||||||
|
|
||||||
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
|
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||||
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
|
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
|
||||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Account
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Account
|
||||||
import dev.usbharu.hideout.mastodon.query.AccountQueryService
|
import dev.usbharu.hideout.mastodon.query.AccountQueryService
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
@ -26,11 +26,11 @@ import org.springframework.stereotype.Service
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class GetAccountApplicationService(private val accountQueryService: AccountQueryService, transaction: Transaction) :
|
class GetAccountApplicationService(private val accountQueryService: AccountQueryService, transaction: Transaction) :
|
||||||
LocalUserAbstractApplicationService<GetAccount, Account>(
|
AbstractApplicationService<GetAccount, Account>(
|
||||||
transaction,
|
transaction,
|
||||||
logger
|
logger
|
||||||
) {
|
) {
|
||||||
override suspend fun internalExecute(command: GetAccount, principal: LocalUser): Account {
|
override suspend fun internalExecute(command: GetAccount, principal: Principal): Account {
|
||||||
return accountQueryService.findById(command.accountId.toLong())
|
return accountQueryService.findById(command.accountId.toLong())
|
||||||
?: throw IllegalArgumentException("Account ${command.accountId} not found")
|
?: throw IllegalArgumentException("Account ${command.accountId} not found")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package dev.usbharu.hideout.mastodon.application.timeline
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
||||||
|
|
||||||
|
class MastodonReadTimeline(
|
||||||
|
val timelineId: Long,
|
||||||
|
val mediaOnly: Boolean,
|
||||||
|
val localOnly: Boolean,
|
||||||
|
val remoteOnly: Boolean,
|
||||||
|
val page: Page
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
package dev.usbharu.hideout.mastodon.application.timeline
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||||
|
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.post.Visibility.*
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.acct.Acct
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.page.PaginationList
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
|
||||||
|
import dev.usbharu.hideout.core.external.timeline.ReadTimelineOption
|
||||||
|
import dev.usbharu.hideout.core.external.timeline.TimelineStore
|
||||||
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Account
|
||||||
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.MediaAttachment
|
||||||
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Status
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class MastodonReadTimelineApplicationService(
|
||||||
|
transaction: Transaction,
|
||||||
|
private val timelineRepository: TimelineRepository,
|
||||||
|
private val timelineStore: TimelineStore
|
||||||
|
) :
|
||||||
|
AbstractApplicationService<MastodonReadTimeline, PaginationList<Status, Long>>(transaction, logger) {
|
||||||
|
override suspend fun internalExecute(
|
||||||
|
command: MastodonReadTimeline,
|
||||||
|
principal: Principal
|
||||||
|
): PaginationList<Status, Long> {
|
||||||
|
val timeline = timelineRepository.findById(TimelineId(command.timelineId))
|
||||||
|
?: throw IllegalArgumentException("Timeline ${command.timelineId} not found.")
|
||||||
|
|
||||||
|
val readTimelineOption = ReadTimelineOption(
|
||||||
|
command.mediaOnly,
|
||||||
|
command.localOnly,
|
||||||
|
command.remoteOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
val readTimeline = timelineStore.readTimeline(timeline, readTimelineOption, command.page, principal)
|
||||||
|
|
||||||
|
return PaginationList(readTimeline.map {
|
||||||
|
Status(
|
||||||
|
it.postId.id.toString(),
|
||||||
|
it.post.url.toString(),
|
||||||
|
it.post.createdAt.toString(),
|
||||||
|
account = Account(
|
||||||
|
id = it.postActor.id.id.toString(),
|
||||||
|
username = it.postActor.name.name,
|
||||||
|
acct = Acct(it.postActor.name.name, it.postActor.domain.domain).toString(),
|
||||||
|
url = it.postActor.url.toString(),
|
||||||
|
displayName = it.postActor.screenName.screenName,
|
||||||
|
note = it.postActor.description.description,
|
||||||
|
avatar = it.postActorIconMedia?.url.toString(),
|
||||||
|
avatarStatic = it.postActorIconMedia?.thumbnailUrl.toString(),
|
||||||
|
header = "",
|
||||||
|
headerStatic = "",
|
||||||
|
locked = false,
|
||||||
|
fields = emptyList(),
|
||||||
|
emojis = emptyList(),
|
||||||
|
bot = false,
|
||||||
|
group = false,
|
||||||
|
discoverable = true,
|
||||||
|
createdAt = it.postActor.createdAt.toString(),
|
||||||
|
statusesCount = it.postActor.postsCount.postsCount,
|
||||||
|
noindex = true,
|
||||||
|
moved = it.postActor.moveTo != null,
|
||||||
|
suspended = it.postActor.suspend,
|
||||||
|
limited = false,
|
||||||
|
lastStatusAt = it.postActor.lastPostAt?.toString(),
|
||||||
|
followersCount = it.postActor.followersCount?.relationshipCount,
|
||||||
|
followingCount = it.postActor.followingCount?.relationshipCount,
|
||||||
|
),
|
||||||
|
content = it.post.content.content,
|
||||||
|
visibility = when (it.post.visibility) {
|
||||||
|
PUBLIC -> Status.Visibility.public
|
||||||
|
UNLISTED -> Status.Visibility.unlisted
|
||||||
|
FOLLOWERS -> Status.Visibility.private
|
||||||
|
DIRECT -> Status.Visibility.direct
|
||||||
|
},
|
||||||
|
sensitive = it.post.sensitive,
|
||||||
|
spoilerText = it.post.overview?.overview.orEmpty(),
|
||||||
|
mediaAttachments = it.postMedias.map { MediaAttachment(it.id.id.toString()) },
|
||||||
|
mentions = emptyList(),
|
||||||
|
tags = emptyList(),
|
||||||
|
emojis = emptyList(),
|
||||||
|
reblogsCount = 0,
|
||||||
|
favouritesCount = it.reactionsList.sumOf { it.count },
|
||||||
|
repliesCount = 0,
|
||||||
|
url = it.post.url.toString(),
|
||||||
|
text = it.post.content.text,
|
||||||
|
application = null,
|
||||||
|
inReplyToId = it.replyPost?.id?.toString(),
|
||||||
|
inReplyToAccountId = it.replyPostActor?.id?.toString(),
|
||||||
|
reblog = null,
|
||||||
|
poll = null,
|
||||||
|
card = null,
|
||||||
|
language = null,
|
||||||
|
editedAt = null,
|
||||||
|
favourited = it.favourited,
|
||||||
|
reblogged = false,
|
||||||
|
muted = false,
|
||||||
|
bookmarked = false,
|
||||||
|
pinned = false,
|
||||||
|
filtered = emptyList(),
|
||||||
|
)
|
||||||
|
}, readTimeline.next?.id, readTimeline.prev?.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(MastodonReadTimelineApplicationService::class.java)
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,10 +53,10 @@ class ExposedAccountQueryServiceImpl(private val applicationConfig: ApplicationC
|
||||||
url = resultRow[Actors.url],
|
url = resultRow[Actors.url],
|
||||||
displayName = resultRow[Actors.screenName],
|
displayName = resultRow[Actors.screenName],
|
||||||
note = resultRow[Actors.description],
|
note = resultRow[Actors.description],
|
||||||
avatar = userUrl + "/icon.jpg",
|
avatar = "$userUrl/icon.jpg",
|
||||||
avatarStatic = userUrl + "/icon.jpg",
|
avatarStatic = "$userUrl/icon.jpg",
|
||||||
header = userUrl + "/header.jpg",
|
header = "$userUrl/header.jpg",
|
||||||
headerStatic = userUrl + "/header.jpg",
|
headerStatic = "$userUrl/header.jpg",
|
||||||
locked = resultRow[Actors.locked],
|
locked = resultRow[Actors.locked],
|
||||||
fields = emptyList(),
|
fields = emptyList(),
|
||||||
emojis = emptyList(),
|
emojis = emptyList(),
|
||||||
|
@ -68,6 +68,10 @@ class ExposedAccountQueryServiceImpl(private val applicationConfig: ApplicationC
|
||||||
statusesCount = resultRow[Actors.postsCount],
|
statusesCount = resultRow[Actors.postsCount],
|
||||||
followersCount = resultRow[Actors.followersCount],
|
followersCount = resultRow[Actors.followersCount],
|
||||||
followingCount = resultRow[Actors.followingCount],
|
followingCount = resultRow[Actors.followingCount],
|
||||||
|
noindex = false,
|
||||||
|
moved = false,
|
||||||
|
suspended = resultRow[Actors.suspend],
|
||||||
|
limited = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,16 @@ import dev.usbharu.hideout.core.application.relationship.unfollow.Unfollow
|
||||||
import dev.usbharu.hideout.core.application.relationship.unfollow.UserUnfollowApplicationService
|
import dev.usbharu.hideout.core.application.relationship.unfollow.UserUnfollowApplicationService
|
||||||
import dev.usbharu.hideout.core.application.relationship.unmute.Unmute
|
import dev.usbharu.hideout.core.application.relationship.unmute.Unmute
|
||||||
import dev.usbharu.hideout.core.application.relationship.unmute.UserUnmuteApplicationService
|
import dev.usbharu.hideout.core.application.relationship.unmute.UserUnmuteApplicationService
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
|
||||||
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.SpringSecurityOauth2PrincipalContextHolder
|
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.SpringSecurityOauth2PrincipalContextHolder
|
||||||
import dev.usbharu.hideout.mastodon.application.accounts.GetAccount
|
import dev.usbharu.hideout.mastodon.application.accounts.GetAccount
|
||||||
import dev.usbharu.hideout.mastodon.application.accounts.GetAccountApplicationService
|
import dev.usbharu.hideout.mastodon.application.accounts.GetAccountApplicationService
|
||||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.AccountApi
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.AccountApi
|
||||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.*
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.*
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.asFlow
|
||||||
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.stereotype.Controller
|
import org.springframework.stereotype.Controller
|
||||||
|
|
||||||
|
@ -66,27 +71,30 @@ class SpringAccountApi(
|
||||||
) : AccountApi {
|
) : AccountApi {
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdBlockPost(id: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1AccountsIdBlockPost(id: String): ResponseEntity<Relationship> {
|
||||||
userBlockApplicationService.execute(Block(id.toLong()), principalContextHolder.getPrincipal())
|
val principal = principalContextHolder.getPrincipal()
|
||||||
return fetchRelationship(id)
|
userBlockApplicationService.execute(Block(id.toLong()), principal)
|
||||||
|
return fetchRelationship(id, principal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdFollowPost(
|
override suspend fun apiV1AccountsIdFollowPost(
|
||||||
id: String,
|
id: String,
|
||||||
followRequestBody: FollowRequestBody?,
|
followRequestBody: FollowRequestBody?,
|
||||||
): ResponseEntity<Relationship> {
|
): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userFollowRequestApplicationService.execute(
|
userFollowRequestApplicationService.execute(
|
||||||
FollowRequest(id.toLong()),
|
FollowRequest(id.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(id)
|
return fetchRelationship(id, principal)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun fetchRelationship(
|
private suspend fun fetchRelationship(
|
||||||
id: String,
|
id: String,
|
||||||
|
principal: Principal
|
||||||
): ResponseEntity<Relationship> {
|
): ResponseEntity<Relationship> {
|
||||||
val relationship = getRelationshipApplicationService.execute(
|
val relationship = getRelationshipApplicationService.execute(
|
||||||
GetRelationship(id.toLong()),
|
GetRelationship(id.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return ResponseEntity.ok(
|
return ResponseEntity.ok(
|
||||||
Relationship(
|
Relationship(
|
||||||
|
@ -117,43 +125,56 @@ class SpringAccountApi(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdMutePost(id: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1AccountsIdMutePost(id: String): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userMuteApplicationService.execute(
|
userMuteApplicationService.execute(
|
||||||
Mute(id.toLong()),
|
Mute(id.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(id)
|
return fetchRelationship(id, principal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdRemoveFromFollowersPost(id: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1AccountsIdRemoveFromFollowersPost(id: String): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userRemoveFromFollowersApplicationService.execute(
|
userRemoveFromFollowersApplicationService.execute(
|
||||||
RemoveFromFollowers(id.toLong()),
|
RemoveFromFollowers(id.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(id)
|
return fetchRelationship(id, principal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdUnblockPost(id: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1AccountsIdUnblockPost(id: String): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userUnblockApplicationService.execute(
|
userUnblockApplicationService.execute(
|
||||||
Unblock(id.toLong()),
|
Unblock(id.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(id)
|
return fetchRelationship(id, principal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdUnfollowPost(id: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1AccountsIdUnfollowPost(id: String): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userUnfollowApplicationService.execute(
|
userUnfollowApplicationService.execute(
|
||||||
Unfollow(id.toLong()),
|
Unfollow(id.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(id)
|
return fetchRelationship(id, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun apiV1AccountsRelationshipsGet(
|
||||||
|
id: List<String>?,
|
||||||
|
withSuspended: Boolean
|
||||||
|
): ResponseEntity<Flow<Relationship>> {
|
||||||
|
val principal = runBlocking { principalContextHolder.getPrincipal() }
|
||||||
|
return ResponseEntity.ok(id.orEmpty().asFlow().mapNotNull { fetchRelationship(it, principal).body })
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdUnmutePost(id: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1AccountsIdUnmutePost(id: String): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userUnmuteApplicationService.execute(
|
userUnmuteApplicationService.execute(
|
||||||
Unmute(id.toLong()),
|
Unmute(id.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(id)
|
return fetchRelationship(id, principal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsPost(accountsCreateRequest: AccountsCreateRequest): ResponseEntity<Unit> =
|
override suspend fun apiV1AccountsPost(accountsCreateRequest: AccountsCreateRequest): ResponseEntity<Unit> =
|
||||||
|
@ -220,18 +241,20 @@ class SpringAccountApi(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1FollowRequestsAccountIdAuthorizePost(accountId: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1FollowRequestsAccountIdAuthorizePost(accountId: String): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userAcceptFollowRequestApplicationService.execute(
|
userAcceptFollowRequestApplicationService.execute(
|
||||||
AcceptFollowRequest(accountId.toLong()),
|
AcceptFollowRequest(accountId.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(accountId)
|
return fetchRelationship(accountId, principal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1FollowRequestsAccountIdRejectPost(accountId: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1FollowRequestsAccountIdRejectPost(accountId: String): ResponseEntity<Relationship> {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
userRejectFollowRequestApplicationService.execute(
|
userRejectFollowRequestApplicationService.execute(
|
||||||
RejectFollowRequest(accountId.toLong()),
|
RejectFollowRequest(accountId.toLong()),
|
||||||
principalContextHolder.getPrincipal()
|
principal
|
||||||
)
|
)
|
||||||
return fetchRelationship(accountId)
|
return fetchRelationship(accountId, principal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,59 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.mastodon.interfaces.api
|
package dev.usbharu.hideout.mastodon.interfaces.api
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.exception.InternalServerException
|
||||||
|
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
||||||
|
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.SpringSecurityOauth2PrincipalContextHolder
|
||||||
|
import dev.usbharu.hideout.mastodon.application.timeline.MastodonReadTimeline
|
||||||
|
import dev.usbharu.hideout.mastodon.application.timeline.MastodonReadTimelineApplicationService
|
||||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.TimelineApi
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.TimelineApi
|
||||||
|
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Status
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.asFlow
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.stereotype.Controller
|
import org.springframework.stereotype.Controller
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
class SpringTimelineApi : TimelineApi
|
class SpringTimelineApi(
|
||||||
|
private val mastodonReadTimelineApplicationService: MastodonReadTimelineApplicationService,
|
||||||
|
|
||||||
|
private val principalContextHolder: SpringSecurityOauth2PrincipalContextHolder,
|
||||||
|
private val userDetailRepository: UserDetailRepository,
|
||||||
|
private val transaction: Transaction,
|
||||||
|
) : TimelineApi {
|
||||||
|
override fun apiV1TimelinesHomeGet(
|
||||||
|
maxId: String?,
|
||||||
|
sinceId: String?,
|
||||||
|
minId: String?,
|
||||||
|
limit: Int?
|
||||||
|
): ResponseEntity<Flow<Status>> = runBlocking {
|
||||||
|
val principal = principalContextHolder.getPrincipal()
|
||||||
|
val userDetail = transaction.transaction {
|
||||||
|
userDetailRepository.findByActorId(principal.actorId.id)
|
||||||
|
?: throw InternalServerException("UserDetail not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val homeTimelineId =
|
||||||
|
userDetail.homeTimelineId ?: throw InternalServerException("HomeTimeline ${userDetail.id} is null.")
|
||||||
|
|
||||||
|
ResponseEntity.ok(
|
||||||
|
mastodonReadTimelineApplicationService.execute(
|
||||||
|
MastodonReadTimeline(
|
||||||
|
timelineId = homeTimelineId.value,
|
||||||
|
mediaOnly = false,
|
||||||
|
localOnly = false,
|
||||||
|
remoteOnly = false,
|
||||||
|
page = Page.of(
|
||||||
|
maxId?.toLongOrNull(),
|
||||||
|
sinceId?.toLongOrNull(),
|
||||||
|
minId?.toLongOrNull(),
|
||||||
|
limit
|
||||||
|
)
|
||||||
|
), principal
|
||||||
|
).asFlow()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1597,8 +1597,6 @@ components:
|
||||||
type: integer
|
type: integer
|
||||||
following_count:
|
following_count:
|
||||||
type: integer
|
type: integer
|
||||||
source:
|
|
||||||
$ref: "#/components/schemas/AccountSource"
|
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
|
@ -2020,7 +2018,7 @@ components:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
filter:
|
filter:
|
||||||
$ref: "#/components/schemas/FilterResult"
|
$ref: "#/components/schemas/Filter"
|
||||||
keyword_matches:
|
keyword_matches:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
|
|
Loading…
Reference in New Issue