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

This commit is contained in:
usbharu 2024-08-15 18:22:56 +09:00
parent 88a61ba97f
commit 711084e366
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
7 changed files with 138 additions and 10 deletions

View File

@ -0,0 +1,10 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
class RegisterLocalUserSetHomeTimelineSubscriber(private val domainEventSubscriber: DomainEventSubscriber) :
Subscriber {
init {
domainEventSubscriber.subscribe<>()
}
}
//todo userdetailにdomain event付けて createのイベントで反応させる タイムラインを新しく一つ作って userdetailのhometimelineに紐づけて自分自身をtimleine relationshipに入れる

View File

@ -2,17 +2,18 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.domain.event.post.PostEvent
import dev.usbharu.hideout.core.domain.event.post.PostEventBody
import dev.usbharu.hideout.core.external.timeline.TimelineStore
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Component
class TimelinePostCreateSubscriber(domainEventSubscriber: DomainEventSubscriber) : Subscriber {
class TimelinePostCreateSubscriber(
private val timelineStore: TimelineStore,
domainEventSubscriber: DomainEventSubscriber
) : Subscriber {
init {
domainEventSubscriber.subscribe<PostEventBody>(PostEvent.CREATE.eventName) {
val post = it.body.getPost()
val actor = it.body.getActor()
logger.info("New Post! : {}", post)
timelineStore.addPost(it.body.getPost())
}
}

View File

@ -1,11 +1,11 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.application.post.PostDetail
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
@ -19,11 +19,11 @@ class ReadTimelineApplicationService(
private val timelineRepository: TimelineRepository,
transaction: Transaction
) :
AbstractApplicationService<ReadTimeline, PaginationList<TimelineObjectDetail, PostId>>(transaction, logger) {
AbstractApplicationService<ReadTimeline, PaginationList<PostDetail, PostId>>(transaction, logger) {
override suspend fun internalExecute(
command: ReadTimeline,
principal: Principal
): PaginationList<TimelineObjectDetail, PostId> {
): PaginationList<PostDetail, PostId> {
val findById = timelineRepository.findById(TimelineId(command.timelineId))
?: throw IllegalArgumentException("Timeline ${command.timelineId} not found.")
@ -33,12 +33,48 @@ class ReadTimelineApplicationService(
command.remoteOnly
)
return timelineStore.readTimeline(
val timeline = timelineStore.readTimeline(
findById,
readTimelineOption,
command.page,
principal,
)
val postDetailList = timeline.map {
val reply = if (it.replyPost != null) {
PostDetail.of(
it.replyPost,
it.replyPostActor!!,
it.replyPostActorIconMedia,
it.replyPostMedias.orEmpty()
)
} else {
null
}
val repost = if (it.repostPost != null) {
PostDetail.of(
it.repostPost,
it.repostPostActor!!,
it.repostPostActorIconMedia,
it.repostPostMedias.orEmpty()
)
} else {
null
}
PostDetail.of(
it.post,
it.postActor,
it.postActorIconMedia,
it.postMedias,
reply,
repost
)
}
return PaginationList(postDetailList, timeline.next, timeline.prev)
}
companion object {

View File

@ -52,7 +52,7 @@ import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint
@Configuration
@EnableWebSecurity(debug = true)
@EnableWebSecurity(debug = false)
class SecurityConfig {
@Bean
fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder()

View File

@ -0,0 +1,48 @@
package dev.usbharu.hideout.core.interfaces.web.timeline
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.timeline.ReadTimeline
import dev.usbharu.hideout.core.application.timeline.ReadTimelineApplicationService
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.SpringSecurityFormLoginPrincipalContextHolder
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
@Controller
class TimelineController(
private val readTimelineApplicationService: ReadTimelineApplicationService,
private val userDetailRepository: UserDetailRepository,
private val springSecurityFormLoginPrincipalContextHolder: SpringSecurityFormLoginPrincipalContextHolder,
private val transaction: Transaction
) {
@GetMapping("/home")
suspend fun homeTimeline(model: Model, @RequestParam sinceId: String?, @RequestParam maxId: String?): String {
val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal()
val userDetail = transaction.transaction {
userDetailRepository.findByActorId(principal.actorId.id)
?: throw InternalServerException("UserDetail not found.")
}
val homeTimelineId = userDetail.homeTimelineId!!
val execute = readTimelineApplicationService.execute(
ReadTimeline(
timelineId = homeTimelineId.value,
mediaOnly = false,
localOnly = false,
remoteOnly = false,
page = Page.of(
maxId = maxId?.toLongOrNull(),
sinceId = sinceId?.toLongOrNull()
)
), principal
)
model.addAttribute("timeline", execute)
return "homeTimeline"
}
}

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<th:block th:fragment="simple-timline(timelineObject,href)">
<!--/*@thymesVar id="timelineObject" type="dev.usbharu.hideout.core.domain.model.support.page.PaginationList<dev.usbharu.hideout.core.application.post.PostDetail,dev.usbharu.hideout.core.domain.model.post.PostId>"*/-->
<div th:if="${timelineObject.prev == null}">
<a th:href="${href + '/?maxId=' + timelineObject.prev}"></a>
</div>
<div th:each="postDetail : ${timelineObject}">
<th:block th:replace="fragments-post :: single-simple-post(${postDetail})"></th:block>
</div>
<div th:if="${timelineObject.next == null}">
<a th:href="${href + '/?sinceId=' + timelineObject.next}"></a>
</div>
</th:block>
</body>
</html>

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<noscript>
<div th:replace="fragments-timeline :: simple-timline(${timeline},'/home')"></div>
</noscript>
</body>
</html>