feat: タイムラインを読み込めるように

This commit is contained in:
usbharu 2024-07-20 16:11:35 +09:00
parent efbf2b0af7
commit d0ff47525f
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
15 changed files with 322 additions and 21 deletions

View File

@ -21,4 +21,5 @@ interface ActorRepository {
suspend fun delete(actor: Actor)
suspend fun findById(id: ActorId): Actor?
suspend fun findByNameAndDomain(name: String, domain: String): Actor?
suspend fun findAllById(actorIds: List<ActorId>): List<Actor>
}

View File

@ -24,6 +24,12 @@ interface PostRepository {
suspend fun save(post: Post): Post
suspend fun saveAll(posts: List<Post>): List<Post>
suspend fun findById(id: PostId): Post?
suspend fun findAllById(ids: List<PostId>): List<Post>
suspend fun findByActorId(id: ActorId, page: Page? = null): PaginationList<Post, PostId>
suspend fun delete(post: Post)
suspend fun findByActorIdAndVisibilityInList(
actorId: ActorId,
visibilityList: List<Visibility>,
of: Page? = null
): PaginationList<Post, PostId>
}

View File

@ -0,0 +1,53 @@
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.post.Post
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObject
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObjectId
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObjectWarnFilter
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
import java.time.Instant
data class TimelineObjectDetail(
val id: TimelineObjectId,
val timelineUserDetail: UserDetail,
val post: Post,
val postActor: Actor,
val replyPost: Post?,
val replyPostActor: Actor?,
val repostPost: Post?,
val repostPostActor: Actor?,
val isPureRepost: Boolean,
val lastUpdateAt: Instant,
val hasMediaInRepost: Boolean,
val warnFilter: List<TimelineObjectWarnFilter>
) {
companion object {
fun of(
timelineObject: TimelineObject,
timelineUserDetail: UserDetail,
post: Post,
postActor: Actor,
replyPost: Post?,
replyPostActor: Actor?,
repostPost: Post?,
repostPostActor: Actor?,
warnFilter: List<TimelineObjectWarnFilter>
): TimelineObjectDetail {
return TimelineObjectDetail(
timelineObject.id,
timelineUserDetail,
post,
postActor,
replyPost,
replyPostActor,
repostPost,
repostPostActor,
timelineObject.isPureRepost,
timelineObject.lastUpdatedAt,
timelineObject.hasMediaInRepost,
warnFilter
)
}
}
}

View File

@ -21,7 +21,9 @@ class TimelineObject(
val postActorId: ActorId,
val postCreatedAt: Instant,
val replyId: PostId?,
val replyActorId: ActorId?,
val repostId: PostId?,
val repostActorId: ActorId?,
visibility: Visibility,
isPureRepost: Boolean,
mediaIds: List<MediaId>,
@ -75,6 +77,7 @@ class TimelineObject(
timelineObjectId: TimelineObjectId,
timeline: Timeline,
post: Post,
replyActorId: ActorId?,
filterResults: List<FilterResult>
): TimelineObject {
return TimelineObject(
@ -85,7 +88,9 @@ class TimelineObject(
postActorId = post.actorId,
postCreatedAt = post.createdAt,
replyId = post.replyId,
replyActorId = replyActorId,
repostId = null,
repostActorId = null,
visibility = post.visibility,
isPureRepost = true,
mediaIds = post.mediaIds,
@ -101,6 +106,7 @@ class TimelineObject(
timelineObjectId: TimelineObjectId,
timeline: Timeline,
post: Post,
replyActorId: ActorId?,
repost: Post,
filterResults: List<FilterResult>
): TimelineObject {
@ -115,7 +121,9 @@ class TimelineObject(
postActorId = post.actorId,
postCreatedAt = post.createdAt,
replyId = post.replyId,
replyActorId = replyActorId,
repostId = repost.id,
repostActorId = repost.actorId,
visibility = post.visibility,
isPureRepost = repost.mediaIds.isEmpty() &&
repost.overview == null &&

View File

@ -6,5 +6,13 @@ import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
class TimelineRelationship(
val id: TimelineRelationshipId,
val timelineId: TimelineId,
val actorId: ActorId
val actorId: ActorId,
val visible: Visible
)
enum class Visible {
PUBLIC,
UNLISTED,
FOLLOWERS,
DIRECT
}

View File

@ -21,4 +21,5 @@ interface UserDetailRepository {
suspend fun delete(userDetail: UserDetail)
suspend fun findByActorId(actorId: Long): UserDetail?
suspend fun findById(id: Long): UserDetail?
suspend fun findAllById(idList: List<UserDetailId>): List<UserDetail>
}

View File

@ -1,6 +1,7 @@
package dev.usbharu.hideout.core.external.timeline
import dev.usbharu.hideout.core.domain.model.post.Post
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
@ -10,6 +11,10 @@ interface TimelineStore {
suspend fun removePost(post: Post)
suspend fun addTimelineRelationship(timelineRelationship: TimelineRelationship)
suspend fun removeTimelineRelationship(timelineRelationship: TimelineRelationship)
suspend fun updateTimelineRelationship(timelineRelationship: TimelineRelationship)
suspend fun addTimeline(timeline: Timeline, timelineRelationshipList: List<TimelineRelationship>)
suspend fun removeTimeline(timeline: Timeline)
suspend fun readTimeline(timeline: Timeline): List<TimelineObjectDetail>
}

View File

@ -98,6 +98,18 @@ class ExposedActorRepository(
}
}
override suspend fun findAllById(actorIds: List<ActorId>): List<Actor> {
return query {
Actors
.leftJoin(ActorsAlsoKnownAs, onColumn = { id }, otherColumn = { actorId })
.selectAll()
.where {
Actors.id inList actorIds.map { it.id }
}
.let(actorQueryMapper::map)
}
}
companion object {
private val logger = LoggerFactory.getLogger(ExposedActorRepository::class.java)
}

View File

@ -162,6 +162,18 @@ class ExposedPostRepository(
.first()
}
override suspend fun findAllById(ids: List<PostId>): List<Post> {
return query {
Posts
.selectAll()
.where {
Posts.id inList ids.map { it.id }
}
.let(postQueryMapper::map)
}
}
override suspend fun findByActorId(id: ActorId, page: Page?): PaginationList<Post, PostId> = PaginationList(query {
Posts
.selectAll()
@ -180,6 +192,21 @@ class ExposedPostRepository(
update(post)
}
override suspend fun findByActorIdAndVisibilityInList(
actorId: ActorId,
visibilityList: List<Visibility>,
of: Page?
): PaginationList<Post, PostId> {
return PaginationList(query {
Posts
.selectAll()
.where {
Posts.actorId eq actorId.id and (visibility inList visibilityList.map { it.name })
}
.let(postQueryMapper::map)
}, null, null)
}
companion object {
private val logger = LoggerFactory.getLogger(ExposedPostRepository::class.java)
}

View File

@ -5,6 +5,7 @@ import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipId
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository
import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.slf4j.Logger
@ -22,6 +23,7 @@ class ExposedTimelineRelationshipRepository : AbstractRepository(), TimelineRela
it[id] = timelineRelationship.id.value
it[timelineId] = timelineRelationship.timelineId.value
it[actorId] = timelineRelationship.actorId.id
it[visible] = timelineRelationship.visible.name
}
}
return timelineRelationship
@ -53,6 +55,7 @@ fun ResultRow.toTimelineRelationship(): TimelineRelationship {
TimelineRelationshipId(this[TimelineRelationships.id]),
TimelineId(this[TimelineRelationships.timelineId]),
ActorId(this[TimelineRelationships.actorId]),
Visible.valueOf(this[TimelineRelationships.visible])
)
}
@ -60,5 +63,6 @@ object TimelineRelationships : Table("timeline_relationships") {
val id = long("id")
val timelineId = long("timeline_id").references(Timelines.id)
val actorId = long("actor_id").references(Actors.id)
val visible = varchar("visible", 100)
override val primaryKey: PrimaryKey = PrimaryKey(id)
}

View File

@ -89,6 +89,23 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
}
}
override suspend fun findAllById(idList: List<UserDetailId>): List<UserDetail> {
return query {
UserDetails
.selectAll()
.where { UserDetails.id inList idList.map { it.id } }
.map {
UserDetail.create(
UserDetailId(it[UserDetails.id]),
ActorId(it[UserDetails.actorId]),
UserDetailHashedPassword(it[UserDetails.password]),
it[UserDetails.autoAcceptFolloweeFollowRequest],
it[UserDetails.lastMigration]
)
}
}
}
companion object {
private val logger = LoggerFactory.getLogger(UserDetailRepositoryImpl::class.java)
}

View File

@ -51,6 +51,11 @@ class MongoInternalTimelineObjectRepository(private val springDataMongoTimelineO
springDataMongoTimelineObjectRepository.deleteByTimelineId(timelineId.value)
}
override suspend fun findByTimelineId(timelineId: TimelineId): List<TimelineObject> {
return springDataMongoTimelineObjectRepository.findByTimelineId(timelineId).map { it.toTimelineObject() }
.toList()
}
}
@ -63,7 +68,9 @@ data class SpringDataMongoTimelineObject(
val postActorId: Long,
val postCreatedAt: Long,
val replyId: Long?,
val replyActorId: Long?,
val repostId: Long?,
val repostActorId: Long?,
val visibility: Visibility,
val isPureRepost: Boolean,
val mediaIds: List<Long>,
@ -83,7 +90,9 @@ data class SpringDataMongoTimelineObject(
ActorId(postActorId),
Instant.ofEpochSecond(postCreatedAt),
replyId?.let { PostId(it) },
replyActorId?.let { ActorId(it) },
repostId?.let { PostId(it) },
repostActorId?.let { ActorId(it) },
visibility,
isPureRepost,
mediaIds.map { MediaId(it) },
@ -105,7 +114,9 @@ data class SpringDataMongoTimelineObject(
timelineObject.postActorId.id,
timelineObject.postCreatedAt.epochSecond,
timelineObject.replyId?.id,
timelineObject.replyActorId?.id,
timelineObject.repostId?.id,
timelineObject.repostActorId?.id,
timelineObject.visibility,
timelineObject.isPureRepost,
timelineObject.mediaIds.map { it.id },
@ -149,4 +160,6 @@ interface SpringDataMongoTimelineObjectRepository : CoroutineCrudRepository<Spri
suspend fun deleteByTimelineIdAndPostActorId(timelineId: Long, postActorId: Long)
suspend fun deleteByTimelineId(timelineId: Long)
suspend fun findByTimelineId(timelineId: TimelineId): Flow<SpringDataMongoTimelineObject>
}

View File

@ -1,27 +1,36 @@
package dev.usbharu.hideout.core.infrastructure.timeline
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.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.timelineobjectdetail.TimelineObjectDetail
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.TimelineVisibility
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObject
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObjectId
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObjectWarnFilter
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
import dev.usbharu.hideout.core.external.timeline.TimelineStore
import java.time.Instant
abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateService) : TimelineStore {
override suspend fun addPost(post: Post) {
val timelineList = getTimelines(post.actorId)
val repost = post.repostId?.let { getPost(it) }
val replyActorId = post.replyId?.let { getPost(it)?.actorId }
val timelineObjectList = timelineList.map {
createTimelineObject(post, repost, it)
val timelineObjectList = timelineList.mapNotNull {
createTimelineObject(post, replyActorId, repost, it)
}
insertTimelineObject(timelineObjectList)
@ -31,24 +40,46 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
protected abstract suspend fun getTimeline(timelineId: TimelineId): Timeline?
protected suspend fun createTimelineObject(post: Post, repost: Post?, timeline: Timeline): TimelineObject {
protected suspend fun createTimelineObject(
post: Post,
replyActorId: ActorId?,
repost: Post?,
timeline: Timeline
): TimelineObject? {
if (post.visibility == Visibility.DIRECT) {
return null
}
if (timeline.visibility == TimelineVisibility.PUBLIC && post.visibility != Visibility.PUBLIC) {
return null
}
if (timeline.visibility == TimelineVisibility.UNLISTED && (post.visibility != Visibility.PUBLIC || post.visibility != Visibility.UNLISTED)) {
return null
}
val filters = getFilters(timeline.userDetailId)
val applyFilters = applyFilters(post, filters)
if (repost != null) {
return TimelineObject.create(
TimelineObjectId(idGenerateService.generateId()), timeline, post, repost, applyFilters.filterResults
TimelineObjectId(idGenerateService.generateId()),
timeline,
post,
replyActorId,
repost,
applyFilters.filterResults
)
}
return TimelineObject.create(
TimelineObjectId(idGenerateService.generateId()), timeline, post, applyFilters.filterResults
TimelineObjectId(idGenerateService.generateId()), timeline, post, replyActorId, applyFilters.filterResults
)
}
protected abstract suspend fun getFilters(userDetailId: UserDetailId): List<Filter>
protected abstract suspend fun getNewerFilters(userDetailId: UserDetailId, lastUpdateAt: Instant): List<Filter>
protected abstract suspend fun applyFilters(post: Post, filters: List<Filter>): FilteredPost
protected abstract suspend fun getPost(postId: PostId): Post?
@ -65,7 +96,11 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
protected abstract suspend fun removeTimelineObject(timelineId: TimelineId)
protected abstract suspend fun getPosts(timelineRelationshipList: List<TimelineRelationship>): List<Post>
protected abstract suspend fun getPostsByTimelineRelationshipList(timelineRelationshipList: List<TimelineRelationship>): List<Post>
protected abstract suspend fun getPostsByPostId(postIds: List<PostId>): List<Post>
protected abstract suspend fun getTimelineObject(timelineId: TimelineId): List<TimelineObject>
override suspend fun updatePost(post: Post) {
val timelineObjectByPostId = getTimelineObjectByPostId(post.id)
@ -91,33 +126,62 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
updateTimelineObject(timelineObjectList)
}
protected abstract suspend fun getActorPost(actorId: ActorId): List<Post>
protected abstract suspend fun getActorPost(actorId: ActorId, visibilityList: List<Visibility>): List<Post>
override suspend fun removePost(post: Post) {
removeTimelineObject(post.id)
}
override suspend fun addTimelineRelationship(timelineRelationship: TimelineRelationship) {
val postList = getActorPost(timelineRelationship.actorId)
val visibilityList = visibilities(timelineRelationship)
val postList = getActorPost(timelineRelationship.actorId, visibilityList)
val timeline = getTimeline(timelineRelationship.timelineId) ?: return
val timelineObjects = postList.map { post ->
val timelineObjects = postList.mapNotNull { post ->
val repost = post.repostId?.let { getPost(it) }
createTimelineObject(post, repost, timeline)
val replyActorId = post.replyId?.let { getPost(it)?.actorId }
createTimelineObject(post, replyActorId, repost, timeline)
}
insertTimelineObject(timelineObjects)
}
protected fun visibilities(timelineRelationship: TimelineRelationship): List<Visibility> {
val visibilityList = when (timelineRelationship.visible) {
Visible.PUBLIC -> {
listOf(Visibility.PUBLIC)
}
Visible.UNLISTED -> {
listOf(Visibility.PUBLIC, Visibility.UNLISTED)
}
Visible.FOLLOWERS -> {
listOf(Visibility.PUBLIC, Visibility.UNLISTED, Visibility.FOLLOWERS)
}
Visible.DIRECT -> {
listOf(Visibility.PUBLIC, Visibility.UNLISTED, Visibility.FOLLOWERS, Visibility.DIRECT)
}
}
return visibilityList
}
override suspend fun removeTimelineRelationship(timelineRelationship: TimelineRelationship) {
removeTimelineObject(timelineRelationship.timelineId, timelineRelationship.actorId)
}
override suspend fun addTimeline(timeline: Timeline, timelineRelationshipList: List<TimelineRelationship>) {
val postList = getPosts(timelineRelationshipList)
override suspend fun updateTimelineRelationship(timelineRelationship: TimelineRelationship) {
removeTimelineRelationship(timelineRelationship)
addTimelineRelationship(timelineRelationship)
}
val timelineObjectList = postList.map { post ->
override suspend fun addTimeline(timeline: Timeline, timelineRelationshipList: List<TimelineRelationship>) {
val postList = getPostsByTimelineRelationshipList(timelineRelationshipList)
val timelineObjectList = postList.mapNotNull { post ->
val repost = post.repostId?.let { getPost(it) }
createTimelineObject(post, repost, timeline)
val replyActorId = post.replyId?.let { getPost(it)?.actorId }
createTimelineObject(post, replyActorId, repost, timeline)
}
insertTimelineObject(timelineObjectList)
@ -126,4 +190,53 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
override suspend fun removeTimeline(timeline: Timeline) {
removeTimelineObject(timeline.id)
}
override suspend fun readTimeline(timeline: Timeline): List<TimelineObjectDetail> {
val timelineObjectList = getTimelineObject(timeline.id)
val lastUpdatedAt = timelineObjectList.minBy { it.lastUpdatedAt }.lastUpdatedAt
val newerFilters = getNewerFilters(timeline.userDetailId, lastUpdatedAt)
val posts =
getPostsByPostId(timelineObjectList.map { it.postId } + timelineObjectList.mapNotNull { it.repostId } + timelineObjectList.mapNotNull { it.replyId })
val userDetails = getUserDetails(timelineObjectList.map { it.userDetailId })
val actors =
getActors(timelineObjectList.map { it.postActorId } + timelineObjectList.mapNotNull { it.repostActorId } + timelineObjectList.mapNotNull { it.replyActorId })
val postMap = posts.associate { post ->
post.id to applyFilters(post, newerFilters)
}
return 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 reply = postMap[it.replyId]
val replyActor = actors[it.replyActorId]
val repost = postMap[it.repostId]
val repostActor = actors[it.repostActorId]
TimelineObjectDetail.of(
timelineObject = it,
timelineUserDetail = timelineUserDetail,
post = post.post,
postActor = actor,
replyPost = reply?.post,
replyPostActor = replyActor,
repostPost = repost?.post,
repostPostActor = repostActor,
warnFilter = it.warnFilters + post.filterResults.map {
TimelineObjectWarnFilter(
it.filter.id,
it.matchedKeyword
)
}
)
}
}
abstract suspend fun getActors(actorIds: List<ActorId>): Map<ActorId, Actor>
abstract suspend fun getUserDetails(userDetailIdList: List<UserDetailId>): Map<UserDetailId, UserDetail>
}

View File

@ -1,7 +1,9 @@
package dev.usbharu.hideout.core.infrastructure.timeline
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
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
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
@ -9,6 +11,7 @@ import dev.usbharu.hideout.core.domain.model.filter.FilteredPost
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.timeline.Timeline
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
@ -16,10 +19,13 @@ import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObject
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository
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.shared.id.IdGenerateService
import org.springframework.stereotype.Component
import java.time.Instant
@Component
open class DefaultTimelineStore(
@ -30,7 +36,9 @@ open class DefaultTimelineStore(
private val filterDomainService: FilterDomainService,
idGenerateService: IdGenerateService,
private val defaultTimelineStoreConfig: DefaultTimelineStoreConfig,
private val internalTimelineObjectRepository: InternalTimelineObjectRepository
private val internalTimelineObjectRepository: InternalTimelineObjectRepository,
private val userDetailRepository: UserDetailRepository,
private val actorRepository: ActorRepository
) : AbstractTimelineStore(idGenerateService) {
override suspend fun getTimelines(actorId: ActorId): List<Timeline> {
return timelineRepository.findByIds(
@ -49,6 +57,10 @@ open class DefaultTimelineStore(
return filterRepository.findByUserDetailId(userDetailId)
}
override suspend fun getNewerFilters(userDetailId: UserDetailId, lastUpdateAt: Instant): List<Filter> {
TODO("Not yet implemented")
}
override suspend fun applyFilters(post: Post, filters: List<Filter>): FilteredPost {
return filterDomainService.apply(post, FilterContext.HOME, filters)
}
@ -81,11 +93,31 @@ open class DefaultTimelineStore(
internalTimelineObjectRepository.deleteByTimelineId(timelineId)
}
override suspend fun getPosts(timelineRelationshipList: List<TimelineRelationship>): List<Post> {
return timelineRelationshipList.map { it.actorId }.flatMap { getActorPost(it) }
override suspend fun getPostsByTimelineRelationshipList(timelineRelationshipList: List<TimelineRelationship>): List<Post> {
return timelineRelationshipList.flatMap { getActorPost(it.actorId, visibilities(it)) }
}
override suspend fun getActorPost(actorId: ActorId): List<Post> {
return postRepository.findByActorId(actorId, Page.of(limit = defaultTimelineStoreConfig.actorPostsCount))
override suspend fun getPostsByPostId(postIds: List<PostId>): List<Post> {
return postRepository.findAllById(postIds)
}
override suspend fun getTimelineObject(timelineId: TimelineId): List<TimelineObject> {
return internalTimelineObjectRepository.findByTimelineId(timelineId)
}
override suspend fun getActorPost(actorId: ActorId, visibilityList: List<Visibility>): List<Post> {
return postRepository.findByActorIdAndVisibilityInList(
actorId,
visibilityList,
Page.of(limit = defaultTimelineStoreConfig.actorPostsCount)
)
}
override suspend fun getActors(actorIds: List<ActorId>): Map<ActorId, Actor> {
return actorRepository.findAllById(actorIds).associateBy { it.id }
}
override suspend fun getUserDetails(userDetailIdList: List<UserDetailId>): Map<UserDetailId, UserDetail> {
return userDetailRepository.findAllById(userDetailIdList).associateBy { it.id }
}
}

View File

@ -17,4 +17,5 @@ interface InternalTimelineObjectRepository {
suspend fun deleteByTimelineIdAndActorId(timelineId: TimelineId, actorId: ActorId)
suspend fun deleteByTimelineId(timelineId: TimelineId)
suspend fun findByTimelineId(timelineId: TimelineId): List<TimelineObject>
}