mirror of https://github.com/usbharu/Hideout.git
feat: タイムラインを読めるように
This commit is contained in:
parent
60d71e1eb2
commit
88a61ba97f
|
@ -1,14 +1,12 @@
|
|||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
||||
import dev.usbharu.hideout.core.domain.model.media.Media
|
||||
import java.net.URI
|
||||
|
||||
data class ActorDetail(
|
||||
val actorId: Long,
|
||||
val instanceId: Long,
|
||||
val instanceName: String,
|
||||
val name: String,
|
||||
val domain: String,
|
||||
val screenName: String,
|
||||
|
@ -17,11 +15,10 @@ data class ActorDetail(
|
|||
val icon: URI?,
|
||||
) {
|
||||
companion object {
|
||||
fun of(actor: Actor, instance: Instance, iconMedia: Media?): ActorDetail {
|
||||
fun of(actor: Actor, iconMedia: Media?): ActorDetail {
|
||||
return ActorDetail(
|
||||
actor.id.id,
|
||||
actor.instance.instanceId,
|
||||
instance.name.name,
|
||||
actor.name.name,
|
||||
actor.domain.domain,
|
||||
actor.screenName.screenName,
|
||||
|
|
|
@ -5,8 +5,6 @@ import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
|||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
|
||||
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
|
||||
|
@ -21,7 +19,6 @@ class GetPostDetailApplicationService(
|
|||
transaction: Transaction,
|
||||
private val postRepository: PostRepository,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val instanceRepository: InstanceRepository,
|
||||
private val mediaRepository: MediaRepository,
|
||||
private val iPostReadAccessControl: IPostReadAccessControl
|
||||
) : AbstractApplicationService<GetPostDetail, PostDetail>(
|
||||
|
@ -36,8 +33,6 @@ class GetPostDetailApplicationService(
|
|||
}
|
||||
val actor =
|
||||
actorRepository.findById(post.actorId) ?: throw InternalServerException("Actor ${post.actorId} not found.")
|
||||
val instance = instanceRepository.findById(post.instanceId)
|
||||
?: throw InternalServerException("Instance ${post.instanceId} not found.")
|
||||
|
||||
val iconMedia = actor.icon?.let { mediaRepository.findById(it) }
|
||||
|
||||
|
@ -46,19 +41,17 @@ class GetPostDetailApplicationService(
|
|||
return PostDetail.of(
|
||||
post,
|
||||
actor,
|
||||
instance,
|
||||
iconMedia,
|
||||
mediaList,
|
||||
post.replyId?.let { fetchChild(it, actor, instance, iconMedia, principal) },
|
||||
post.repostId?.let { fetchChild(it, actor, instance, iconMedia, principal) },
|
||||
post.moveTo?.let { fetchChild(it, actor, instance, iconMedia, principal) },
|
||||
post.replyId?.let { fetchChild(it, actor, iconMedia, principal) },
|
||||
post.repostId?.let { fetchChild(it, actor, iconMedia, principal) },
|
||||
post.moveTo?.let { fetchChild(it, actor, iconMedia, principal) },
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun fetchChild(
|
||||
postId: PostId,
|
||||
actor: Actor,
|
||||
instance: Instance,
|
||||
iconMedia: Media?,
|
||||
principal: Principal
|
||||
): PostDetail? {
|
||||
|
@ -68,21 +61,16 @@ class GetPostDetailApplicationService(
|
|||
return null
|
||||
}
|
||||
|
||||
val (first, second: Instance, third) = if (actor.id != post.actorId) {
|
||||
Triple(
|
||||
actorRepository.findById(post.actorId) ?: return null,
|
||||
instanceRepository.findById(actor.instance) ?: return null,
|
||||
actor.icon?.let { mediaRepository.findById(it) }
|
||||
)
|
||||
val (first, third) = if (actor.id != post.actorId) {
|
||||
(actorRepository.findById(post.actorId) ?: return null) to actor.icon?.let { mediaRepository.findById(it) }
|
||||
} else {
|
||||
Triple(actor, instance, iconMedia)
|
||||
actor to iconMedia
|
||||
}
|
||||
|
||||
val mediaList = mediaRepository.findByIds(post.mediaIds)
|
||||
return PostDetail.of(
|
||||
post,
|
||||
first,
|
||||
second,
|
||||
third,
|
||||
mediaList
|
||||
)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
||||
import dev.usbharu.hideout.core.domain.model.media.Media
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||
import dev.usbharu.hideout.core.domain.model.post.Visibility
|
||||
|
@ -30,7 +29,6 @@ data class PostDetail(
|
|||
fun of(
|
||||
post: Post,
|
||||
actor: Actor,
|
||||
instance: Instance,
|
||||
iconMedia: Media?,
|
||||
mediaList: List<Media>,
|
||||
reply: PostDetail? = null,
|
||||
|
@ -39,7 +37,7 @@ data class PostDetail(
|
|||
): PostDetail {
|
||||
return PostDetail(
|
||||
id = post.id.id,
|
||||
actor = ActorDetail.of(actor, instance, iconMedia),
|
||||
actor = ActorDetail.of(actor, iconMedia),
|
||||
overview = post.overview?.overview,
|
||||
text = post.text,
|
||||
content = post.content.content,
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package dev.usbharu.hideout.core.application.timeline
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
||||
|
||||
data class ReadTimeline(
|
||||
val timelineId: Long,
|
||||
val mediaOnly: Boolean,
|
||||
val localOnly: Boolean,
|
||||
val remoteOnly: Boolean,
|
||||
val page: Page
|
||||
)
|
|
@ -0,0 +1,47 @@
|
|||
package dev.usbharu.hideout.core.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.PostId
|
||||
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.support.timelineobjectdetail.TimelineObjectDetail
|
||||
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 org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class ReadTimelineApplicationService(
|
||||
private val timelineStore: TimelineStore,
|
||||
private val timelineRepository: TimelineRepository,
|
||||
transaction: Transaction
|
||||
) :
|
||||
AbstractApplicationService<ReadTimeline, PaginationList<TimelineObjectDetail, PostId>>(transaction, logger) {
|
||||
override suspend fun internalExecute(
|
||||
command: ReadTimeline,
|
||||
principal: Principal
|
||||
): PaginationList<TimelineObjectDetail, PostId> {
|
||||
val findById = timelineRepository.findById(TimelineId(command.timelineId))
|
||||
?: throw IllegalArgumentException("Timeline ${command.timelineId} not found.")
|
||||
|
||||
val readTimelineOption = ReadTimelineOption(
|
||||
command.mediaOnly,
|
||||
command.localOnly,
|
||||
command.remoteOnly
|
||||
)
|
||||
|
||||
return timelineStore.readTimeline(
|
||||
findById,
|
||||
readTimelineOption,
|
||||
command.page,
|
||||
principal,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ReadTimelineApplicationService::class.java)
|
||||
}
|
||||
}
|
|
@ -22,6 +22,18 @@ interface RelationshipRepository {
|
|||
suspend fun save(relationship: Relationship): Relationship
|
||||
suspend fun delete(relationship: Relationship)
|
||||
suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship?
|
||||
suspend fun findByActorIdsAndTargetIdAndBlocking(
|
||||
actorIds: List<ActorId>,
|
||||
targetId: ActorId,
|
||||
blocking: Boolean
|
||||
): List<Relationship>
|
||||
|
||||
suspend fun findByActorIdAndTargetIdsAndFollowing(
|
||||
actorId: ActorId,
|
||||
targetIds: List<ActorId>,
|
||||
following: Boolean
|
||||
): List<Relationship>
|
||||
|
||||
suspend fun findByTargetId(
|
||||
targetId: ActorId,
|
||||
option: FindRelationshipOption? = null,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail
|
||||
|
||||
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
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObject
|
||||
|
@ -14,11 +15,17 @@ data class TimelineObjectDetail(
|
|||
val postId: PostId,
|
||||
val timelineUserDetail: UserDetail,
|
||||
val post: Post,
|
||||
val postMedias: List<Media>,
|
||||
val postActor: Actor,
|
||||
val postActorIconMedia: Media?,
|
||||
val replyPost: Post?,
|
||||
val replyPostMedias: List<Media>?,
|
||||
val replyPostActor: Actor?,
|
||||
val replyPostActorIconMedia: Media?,
|
||||
val repostPost: Post?,
|
||||
val repostPostMedias: List<Media>?,
|
||||
val repostPostActor: Actor?,
|
||||
val repostPostActorIconMedia: Media?,
|
||||
val isPureRepost: Boolean,
|
||||
val lastUpdateAt: Instant,
|
||||
val hasMediaInRepost: Boolean,
|
||||
|
@ -29,27 +36,39 @@ data class TimelineObjectDetail(
|
|||
timelineObject: TimelineObject,
|
||||
timelineUserDetail: UserDetail,
|
||||
post: Post,
|
||||
postMedias: List<Media>,
|
||||
postActor: Actor,
|
||||
postActorIconMedia: Media?,
|
||||
replyPost: Post?,
|
||||
replyPostMedias: List<Media>?,
|
||||
replyPostActor: Actor?,
|
||||
replyPostActorIconMedia: Media?,
|
||||
repostPost: Post?,
|
||||
repostPostMedias: List<Media>?,
|
||||
repostPostActor: Actor?,
|
||||
repostPostActorIconMedia: Media?,
|
||||
warnFilter: List<TimelineObjectWarnFilter>
|
||||
): TimelineObjectDetail {
|
||||
return TimelineObjectDetail(
|
||||
timelineObject.id,
|
||||
post.id,
|
||||
timelineUserDetail,
|
||||
post,
|
||||
postActor,
|
||||
replyPost,
|
||||
replyPostActor,
|
||||
repostPost,
|
||||
repostPostActor,
|
||||
timelineObject.isPureRepost,
|
||||
timelineObject.lastUpdatedAt,
|
||||
timelineObject.hasMediaInRepost,
|
||||
warnFilter
|
||||
id = timelineObject.id,
|
||||
postId = post.id,
|
||||
timelineUserDetail = timelineUserDetail,
|
||||
post = post,
|
||||
postMedias = postMedias,
|
||||
postActor = postActor,
|
||||
postActorIconMedia = postActorIconMedia,
|
||||
replyPost = replyPost,
|
||||
replyPostMedias = replyPostMedias,
|
||||
replyPostActor = replyPostActor,
|
||||
replyPostActorIconMedia = replyPostActorIconMedia,
|
||||
repostPost = repostPost,
|
||||
repostPostMedias = repostPostMedias,
|
||||
repostPostActor = repostPostActor,
|
||||
repostPostActorIconMedia = repostPostActorIconMedia,
|
||||
isPureRepost = timelineObject.isPureRepost,
|
||||
lastUpdateAt = timelineObject.lastUpdatedAt,
|
||||
hasMediaInRepost = timelineObject.hasMediaInRepost,
|
||||
warnFilter = warnFilter
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.springframework.stereotype.Component
|
|||
|
||||
interface IPostReadAccessControl {
|
||||
suspend fun isAllow(post: Post, principal: Principal): Boolean
|
||||
suspend fun areAllows(postList: List<Post>, principal: Principal): List<Post>
|
||||
}
|
||||
|
||||
@Component
|
||||
|
@ -22,9 +23,9 @@ class DefaultPostReadAccessControl(private val relationshipRepository: Relations
|
|||
}
|
||||
|
||||
val relationship = (
|
||||
relationshipRepository.findByActorIdAndTargetId(post.actorId, principal.actorId)
|
||||
?: Relationship.default(post.actorId, principal.actorId)
|
||||
)
|
||||
relationshipRepository.findByActorIdAndTargetId(post.actorId, principal.actorId)
|
||||
?: Relationship.default(post.actorId, principal.actorId)
|
||||
)
|
||||
|
||||
// ブロックされてたら見れない
|
||||
if (relationship.blocking) {
|
||||
|
@ -57,4 +58,47 @@ class DefaultPostReadAccessControl(private val relationshipRepository: Relations
|
|||
// その他の場合は見れない
|
||||
return false
|
||||
}
|
||||
|
||||
override suspend fun areAllows(postList: List<Post>, principal: Principal): List<Post> {
|
||||
val actorIds = postList.map { it.actorId }
|
||||
val relationshipList =
|
||||
relationshipRepository.findByActorIdsAndTargetIdAndBlocking(actorIds, principal.actorId, true)
|
||||
.map { it.actorId }
|
||||
val inverseRelationshipList =
|
||||
relationshipRepository.findByActorIdAndTargetIdsAndFollowing(principal.actorId, actorIds, true)
|
||||
.map { it.actorId }
|
||||
|
||||
fun internalAllow(post: Post): Boolean {
|
||||
// ポスト主は無条件で見れる
|
||||
if (post.actorId == principal.actorId) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (relationshipList.contains(post.actorId)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (post.visibility == Visibility.PUBLIC || post.visibility == Visibility.UNLISTED) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (principal is Anonymous) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (post.visibility == Visibility.DIRECT && post.visibleActors.contains(principal.actorId)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (post.visibility == Visibility.FOLLOWERS && inverseRelationshipList.contains(principal.actorId)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return postList
|
||||
.filter {
|
||||
internalAllow(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import dev.usbharu.hideout.core.domain.model.post.Post
|
|||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
||||
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.support.timelineobjectdetail.TimelineObjectDetail
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.Timeline
|
||||
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
|
||||
|
@ -22,6 +23,7 @@ interface TimelineStore {
|
|||
suspend fun readTimeline(
|
||||
timeline: Timeline,
|
||||
option: ReadTimelineOption? = null,
|
||||
page: Page? = null
|
||||
page: Page? = null,
|
||||
principal: Principal
|
||||
): PaginationList<TimelineObjectDetail, PostId>
|
||||
}
|
||||
|
|
|
@ -67,6 +67,26 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
|
|||
}.singleOrNull()?.toRelationships()
|
||||
}
|
||||
|
||||
override suspend fun findByActorIdsAndTargetIdAndBlocking(
|
||||
actorIds: List<ActorId>,
|
||||
targetId: ActorId,
|
||||
blocking: Boolean
|
||||
): List<Relationship> = query {
|
||||
Relationships.selectAll().where {
|
||||
Relationships.actorId inList actorIds.map { it.id } and (Relationships.targetActorId eq targetId.id)
|
||||
}.map { it.toRelationships() }
|
||||
}
|
||||
|
||||
override suspend fun findByActorIdAndTargetIdsAndFollowing(
|
||||
actorId: ActorId,
|
||||
targetIds: List<ActorId>,
|
||||
following: Boolean
|
||||
): List<Relationship> = query {
|
||||
Relationships.selectAll().where {
|
||||
Relationships.actorId eq actorId.id and (Relationships.targetActorId inList targetIds.map { it.id })
|
||||
}.map { it.toRelationships() }
|
||||
}
|
||||
|
||||
override suspend fun findByTargetId(
|
||||
targetId: ActorId,
|
||||
option: FindRelationshipOption?,
|
||||
|
|
|
@ -4,11 +4,14 @@ 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
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilteredPost
|
||||
import dev.usbharu.hideout.core.domain.model.media.Media
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.post.Visibility
|
||||
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
||||
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.support.timelineobjectdetail.TimelineObjectDetail
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.Timeline
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||
|
@ -105,7 +108,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
|
|||
|
||||
protected abstract suspend fun getPostsByTimelineRelationshipList(timelineRelationshipList: List<TimelineRelationship>): List<Post>
|
||||
|
||||
protected abstract suspend fun getPostsByPostId(postIds: List<PostId>): List<Post>
|
||||
protected abstract suspend fun getPostsByPostId(postIds: List<PostId>, principal: Principal): List<Post>
|
||||
|
||||
protected abstract suspend fun getTimelineObject(
|
||||
timelineId: TimelineId,
|
||||
|
@ -205,7 +208,8 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
|
|||
override suspend fun readTimeline(
|
||||
timeline: Timeline,
|
||||
option: ReadTimelineOption?,
|
||||
page: Page?
|
||||
page: Page?,
|
||||
principal: Principal
|
||||
): PaginationList<TimelineObjectDetail, PostId> {
|
||||
val timelineObjectList = getTimelineObject(timeline.id, option, page)
|
||||
val lastUpdatedAt = timelineObjectList.minBy { it.lastUpdatedAt }.lastUpdatedAt
|
||||
|
@ -216,7 +220,8 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
|
|||
getPostsByPostId(
|
||||
timelineObjectList.map {
|
||||
it.postId
|
||||
} + timelineObjectList.mapNotNull { it.repostId } + timelineObjectList.mapNotNull { it.replyId }
|
||||
} + timelineObjectList.mapNotNull { it.repostId } + timelineObjectList.mapNotNull { it.replyId },
|
||||
principal
|
||||
)
|
||||
|
||||
val userDetails = getUserDetails(timelineObjectList.map { it.userDetailId })
|
||||
|
@ -232,24 +237,35 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
|
|||
post.id to applyFilters(post, newerFilters)
|
||||
}
|
||||
|
||||
val mediaMap = getMedias(posts.flatMap { it.mediaIds } + actors.mapNotNull { it.value.icon })
|
||||
|
||||
return PaginationList(
|
||||
timelineObjectList.mapNotNull<TimelineObject, TimelineObjectDetail> {
|
||||
val timelineUserDetail = userDetails[it.userDetailId] ?: return@mapNotNull null
|
||||
val actor = actors[it.postActorId] ?: return@mapNotNull null
|
||||
val post = postMap[it.postId] ?: return@mapNotNull null
|
||||
val postMedias = post.post.mediaIds.mapNotNull { mediaId -> mediaMap[mediaId] }
|
||||
val reply = postMap[it.replyId]
|
||||
val replyMedias = reply?.post?.mediaIds?.mapNotNull { mediaId -> mediaMap[mediaId] }
|
||||
val replyActor = actors[it.replyActorId]
|
||||
val repost = postMap[it.repostId]
|
||||
val repostMedias = repost?.post?.mediaIds?.mapNotNull { mediaId -> mediaMap[mediaId] }
|
||||
val repostActor = actors[it.repostActorId]
|
||||
TimelineObjectDetail.of(
|
||||
timelineObject = it,
|
||||
timelineUserDetail = timelineUserDetail,
|
||||
post = post.post,
|
||||
postMedias = postMedias,
|
||||
postActor = actor,
|
||||
postActorIconMedia = mediaMap[actor.icon],
|
||||
replyPost = reply?.post,
|
||||
replyPostMedias = replyMedias,
|
||||
replyPostActor = replyActor,
|
||||
replyPostActorIconMedia = mediaMap[replyActor?.icon],
|
||||
repostPost = repost?.post,
|
||||
repostPostMedias = repostMedias,
|
||||
repostPostActor = repostActor,
|
||||
repostPostActorIconMedia = mediaMap[repostActor?.icon],
|
||||
warnFilter = it.warnFilters + post.filterResults.map {
|
||||
TimelineObjectWarnFilter(
|
||||
it.filter.id,
|
||||
|
@ -265,5 +281,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
|
|||
|
||||
protected abstract suspend fun getActors(actorIds: List<ActorId>): Map<ActorId, Actor>
|
||||
|
||||
protected abstract suspend fun getMedias(mediaIds: List<MediaId>): Map<MediaId, Media>
|
||||
|
||||
protected abstract suspend fun getUserDetails(userDetailIdList: List<UserDetailId>): Map<UserDetailId, UserDetail>
|
||||
}
|
||||
|
|
|
@ -8,12 +8,16 @@ import dev.usbharu.hideout.core.domain.model.filter.Filter
|
|||
import dev.usbharu.hideout.core.domain.model.filter.FilterContext
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilteredPost
|
||||
import dev.usbharu.hideout.core.domain.model.media.Media
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||
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.post.Visibility
|
||||
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
||||
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.Timeline
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
|
||||
|
@ -24,6 +28,7 @@ import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
|
|||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
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 org.springframework.stereotype.Component
|
||||
|
@ -40,7 +45,9 @@ open class DefaultTimelineStore(
|
|||
private val defaultTimelineStoreConfig: DefaultTimelineStoreConfig,
|
||||
private val internalTimelineObjectRepository: InternalTimelineObjectRepository,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
private val actorRepository: ActorRepository
|
||||
private val actorRepository: ActorRepository,
|
||||
private val mediaRepository: MediaRepository,
|
||||
private val postIPostReadAccessControl: IPostReadAccessControl
|
||||
) : AbstractTimelineStore(idGenerateService) {
|
||||
override suspend fun getTimelines(actorId: ActorId): List<Timeline> {
|
||||
return timelineRepository.findByIds(
|
||||
|
@ -99,8 +106,9 @@ open class DefaultTimelineStore(
|
|||
return timelineRelationshipList.flatMap { getActorPost(it.actorId, visibilities(it)) }
|
||||
}
|
||||
|
||||
override suspend fun getPostsByPostId(postIds: List<PostId>): List<Post> {
|
||||
return postRepository.findAllById(postIds)
|
||||
override suspend fun getPostsByPostId(postIds: List<PostId>, principal: Principal): List<Post> {
|
||||
val findAllById = postRepository.findAllById(postIds)
|
||||
return postIPostReadAccessControl.areAllows(findAllById, principal)
|
||||
}
|
||||
|
||||
override suspend fun getTimelineObject(
|
||||
|
@ -131,6 +139,10 @@ open class DefaultTimelineStore(
|
|||
return actorRepository.findAllById(actorIds).associateBy { it.id }
|
||||
}
|
||||
|
||||
override suspend fun getMedias(mediaIds: List<MediaId>): Map<MediaId, Media> {
|
||||
return mediaRepository.findByIds(mediaIds).associateBy { it.id }
|
||||
}
|
||||
|
||||
override suspend fun getUserDetails(userDetailIdList: List<UserDetailId>): Map<UserDetailId, UserDetail> {
|
||||
return userDetailRepository.findAllById(userDetailIdList).associateBy { it.id }
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package dev.usbharu.hideout.core.infrastructure.timeline
|
|||
import dev.usbharu.hideout.core.config.DefaultTimelineStoreConfig
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.filter.*
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||
import dev.usbharu.hideout.core.domain.model.post.TestPostFactory
|
||||
import dev.usbharu.hideout.core.domain.model.post.Visibility
|
||||
|
@ -16,6 +17,7 @@ import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
|
|||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import dev.usbharu.hideout.core.domain.service.filter.FilterDomainService
|
||||
import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl
|
||||
import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
|
@ -56,6 +58,12 @@ class DefaultTimelineStoreTest {
|
|||
@Mock
|
||||
lateinit var actorRepository: ActorRepository
|
||||
|
||||
@Mock
|
||||
lateinit var mediaRepository: MediaRepository
|
||||
|
||||
@Mock
|
||||
lateinit var iPostReadAccessControl: IPostReadAccessControl
|
||||
|
||||
@Spy
|
||||
val defaultTimelineStoreConfig = DefaultTimelineStoreConfig(500)
|
||||
|
||||
|
|
Loading…
Reference in New Issue