mirror of https://github.com/usbharu/Hideout.git
commit
6c83306f0d
|
@ -5,24 +5,20 @@ import dev.usbharu.hideout.core.application.timeline.AddTimelineRelationship
|
||||||
import dev.usbharu.hideout.core.application.timeline.UserAddTimelineRelationshipApplicationService
|
import dev.usbharu.hideout.core.application.timeline.UserAddTimelineRelationshipApplicationService
|
||||||
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent
|
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent
|
||||||
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventBody
|
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventBody
|
||||||
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.Visible
|
import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
|
||||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||||
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class TimelineRelationshipFollowSubscriber(
|
class TimelineRelationshipFollowSubscriber(
|
||||||
private val userAddTimelineRelationshipApplicationService: UserAddTimelineRelationshipApplicationService,
|
private val userAddTimelineRelationshipApplicationService: UserAddTimelineRelationshipApplicationService,
|
||||||
private val idGenerateService: IdGenerateService,
|
|
||||||
private val userDetailRepository: UserDetailRepository,
|
private val userDetailRepository: UserDetailRepository,
|
||||||
private val domainEventSubscriber: DomainEventSubscriber
|
private val domainEventSubscriber: DomainEventSubscriber
|
||||||
) : Subscriber {
|
) : Subscriber {
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
domainEventSubscriber.subscribe<RelationshipEventBody>(RelationshipEvent.FOLLOW.eventName) {
|
domainEventSubscriber.subscribe<RelationshipEventBody>(RelationshipEvent.ACCEPT_FOLLOW.eventName) {
|
||||||
val relationship = it.body.getRelationship()
|
val relationship = it.body.getRelationship()
|
||||||
val userDetail = userDetailRepository.findByActorId(relationship.actorId.id)
|
val userDetail = userDetailRepository.findByActorId(relationship.actorId.id)
|
||||||
?: throw InternalServerException("Userdetail ${relationship.actorId} not found by actorid.")
|
?: throw InternalServerException("Userdetail ${relationship.actorId} not found by actorid.")
|
||||||
|
@ -34,12 +30,9 @@ class TimelineRelationshipFollowSubscriber(
|
||||||
@Suppress("UnsafeCallOnNullableType")
|
@Suppress("UnsafeCallOnNullableType")
|
||||||
userAddTimelineRelationshipApplicationService.execute(
|
userAddTimelineRelationshipApplicationService.execute(
|
||||||
AddTimelineRelationship(
|
AddTimelineRelationship(
|
||||||
TimelineRelationship(
|
userDetail.homeTimelineId!!,
|
||||||
TimelineRelationshipId(idGenerateService.generateId()),
|
relationship.targetActorId,
|
||||||
userDetail.homeTimelineId!!,
|
Visible.FOLLOWERS
|
||||||
relationship.targetActorId,
|
|
||||||
Visible.FOLLOWERS
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
it.body.principal
|
it.body.principal
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package dev.usbharu.hideout.core.application.domainevent.subscribers
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.timeline.RemoveTimelineRelationship
|
||||||
|
import dev.usbharu.hideout.core.application.timeline.UserRemoveTimelineRelationshipApplicationService
|
||||||
|
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent
|
||||||
|
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventBody
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class TimelineRelationshipUnfollowSubscriber(
|
||||||
|
private val domainEventSubscriber: DomainEventSubscriber,
|
||||||
|
private val userRemoveTimelineRelationshipApplicationService: UserRemoveTimelineRelationshipApplicationService,
|
||||||
|
private val userDetailRepository: UserDetailRepository,
|
||||||
|
private val timelineRelationshipRepository: TimelineRelationshipRepository,
|
||||||
|
) : Subscriber {
|
||||||
|
override fun init() {
|
||||||
|
domainEventSubscriber.subscribe<RelationshipEventBody>(RelationshipEvent.UNFOLLOW.eventName) {
|
||||||
|
val relationship = it.body.getRelationship()
|
||||||
|
val userDetail = userDetailRepository.findByActorId(relationship.actorId.id) ?: throw IllegalStateException(
|
||||||
|
"UserDetail ${relationship.actorId} not found by actorId."
|
||||||
|
)
|
||||||
|
if (userDetail.homeTimelineId == null) {
|
||||||
|
logger.warn("HomeTimeline for ${userDetail.id} not found.")
|
||||||
|
return@subscribe
|
||||||
|
}
|
||||||
|
|
||||||
|
val timelineRelationship = timelineRelationshipRepository.findByTimelineIdAndActorId(
|
||||||
|
userDetail.homeTimelineId!!,
|
||||||
|
relationship.targetActorId
|
||||||
|
)
|
||||||
|
?: throw IllegalStateException("TimelineRelationship ${userDetail.homeTimelineId} to ${relationship.targetActorId} not found by timelineId and ActorId")
|
||||||
|
|
||||||
|
userRemoveTimelineRelationshipApplicationService.execute(
|
||||||
|
RemoveTimelineRelationship(timelineRelationship.id),
|
||||||
|
it.body.principal
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(TimelineRelationshipUnfollowSubscriber::class.java)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package dev.usbharu.hideout.core.application.model
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineVisibility
|
||||||
|
|
||||||
|
data class Timeline(
|
||||||
|
val id: Long,
|
||||||
|
val userDetailId: Long,
|
||||||
|
val name: String,
|
||||||
|
val visibility: TimelineVisibility,
|
||||||
|
val isSystem: Boolean
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun of(timeline: dev.usbharu.hideout.core.domain.model.timeline.Timeline): Timeline {
|
||||||
|
return Timeline(
|
||||||
|
timeline.id.value,
|
||||||
|
timeline.userDetailId.id,
|
||||||
|
timeline.name.value,
|
||||||
|
timeline.visibility,
|
||||||
|
timeline.isSystem
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,11 @@
|
||||||
package dev.usbharu.hideout.core.application.timeline
|
package dev.usbharu.hideout.core.application.timeline
|
||||||
|
|
||||||
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
|
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
|
||||||
|
|
||||||
data class AddTimelineRelationship(
|
data class AddTimelineRelationship(
|
||||||
val timelineRelationship: TimelineRelationship
|
val timelineId: TimelineId,
|
||||||
|
val actorId: ActorId,
|
||||||
|
val visible: Visible
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package dev.usbharu.hideout.core.application.timeline
|
||||||
|
|
||||||
|
data class GetTimelines(val userDetailId: Long)
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dev.usbharu.hideout.core.application.timeline
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipId
|
||||||
|
|
||||||
|
data class RemoveTimelineRelationship(val timelineRelationshipId: TimelineRelationshipId)
|
|
@ -1,15 +1,22 @@
|
||||||
package dev.usbharu.hideout.core.application.timeline
|
package dev.usbharu.hideout.core.application.timeline
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
|
||||||
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
|
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
|
||||||
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.LocalUser
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
|
||||||
|
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.TimelineRelationshipRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class UserAddTimelineRelationshipApplicationService(
|
class UserAddTimelineRelationshipApplicationService(
|
||||||
private val timelineRelationshipRepository: TimelineRelationshipRepository,
|
private val timelineRelationshipRepository: TimelineRelationshipRepository,
|
||||||
|
private val timelineRepository: TimelineRepository,
|
||||||
|
private val idGenerateService: IdGenerateService,
|
||||||
transaction: Transaction
|
transaction: Transaction
|
||||||
) :
|
) :
|
||||||
LocalUserAbstractApplicationService<AddTimelineRelationship, Unit>(
|
LocalUserAbstractApplicationService<AddTimelineRelationship, Unit>(
|
||||||
|
@ -17,7 +24,21 @@ class UserAddTimelineRelationshipApplicationService(
|
||||||
logger
|
logger
|
||||||
) {
|
) {
|
||||||
override suspend fun internalExecute(command: AddTimelineRelationship, principal: LocalUser) {
|
override suspend fun internalExecute(command: AddTimelineRelationship, principal: LocalUser) {
|
||||||
timelineRelationshipRepository.save(command.timelineRelationship)
|
val timeline = timelineRepository.findById(command.timelineId)
|
||||||
|
?: throw IllegalArgumentException("Timeline ${command.timelineId} not found.")
|
||||||
|
|
||||||
|
if (timeline.userDetailId != principal.userDetailId) {
|
||||||
|
throw PermissionDeniedException()
|
||||||
|
}
|
||||||
|
|
||||||
|
timelineRelationshipRepository.save(
|
||||||
|
TimelineRelationship(
|
||||||
|
TimelineRelationshipId(idGenerateService.generateId()),
|
||||||
|
command.timelineId,
|
||||||
|
command.actorId,
|
||||||
|
command.visible
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package dev.usbharu.hideout.core.application.timeline
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.model.Timeline
|
||||||
|
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||||
|
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineVisibility
|
||||||
|
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class UserGetTimelinesApplicationService(transaction: Transaction, private val timelineRepository: TimelineRepository) :
|
||||||
|
AbstractApplicationService<GetTimelines, List<Timeline>>(
|
||||||
|
transaction,
|
||||||
|
logger
|
||||||
|
) {
|
||||||
|
override suspend fun internalExecute(command: GetTimelines, principal: Principal): List<Timeline> {
|
||||||
|
val userDetailId = UserDetailId(command.userDetailId)
|
||||||
|
|
||||||
|
val timelineVisibility = if (userDetailId == principal.userDetailId) {
|
||||||
|
listOf(TimelineVisibility.PUBLIC, TimelineVisibility.UNLISTED, TimelineVisibility.PRIVATE)
|
||||||
|
} else {
|
||||||
|
listOf(TimelineVisibility.PUBLIC)
|
||||||
|
}
|
||||||
|
|
||||||
|
val timelineList =
|
||||||
|
timelineRepository.findAllByUserDetailIdAndVisibilityIn(userDetailId, timelineVisibility)
|
||||||
|
|
||||||
|
return timelineList.map { Timeline.of(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(UserGetTimelinesApplicationService::class.java)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package dev.usbharu.hideout.core.application.timeline
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
|
||||||
|
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
|
||||||
|
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.timeline.TimelineRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class UserRemoveTimelineRelationshipApplicationService(
|
||||||
|
transaction: Transaction,
|
||||||
|
private val timelineRelationshipRepository: TimelineRelationshipRepository,
|
||||||
|
private val timelineRepository: TimelineRepository
|
||||||
|
) :
|
||||||
|
LocalUserAbstractApplicationService<RemoveTimelineRelationship, Unit>(
|
||||||
|
transaction,
|
||||||
|
logger
|
||||||
|
) {
|
||||||
|
|
||||||
|
override suspend fun internalExecute(command: RemoveTimelineRelationship, principal: LocalUser) {
|
||||||
|
val timelineRelationship = (
|
||||||
|
timelineRelationshipRepository.findById(command.timelineRelationshipId)
|
||||||
|
?: throw IllegalArgumentException("TimelineRelationship ${command.timelineRelationshipId} not found.")
|
||||||
|
)
|
||||||
|
|
||||||
|
val timeline = (
|
||||||
|
timelineRepository.findById(timelineRelationship.timelineId)
|
||||||
|
?: throw IllegalArgumentException("Timeline ${timelineRelationship.timelineId} not found.")
|
||||||
|
)
|
||||||
|
|
||||||
|
if (timeline.userDetailId != principal.userDetailId) {
|
||||||
|
throw PermissionDeniedException()
|
||||||
|
}
|
||||||
|
|
||||||
|
timelineRelationshipRepository.delete(timelineRelationship)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(UserRemoveTimelineRelationshipApplicationService::class.java)
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,7 +35,8 @@ class RelationshipEventBody(
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class RelationshipEvent(val eventName: String) {
|
enum class RelationshipEvent(val eventName: String) {
|
||||||
FOLLOW("RelationshipFollow"),
|
ACCEPT_FOLLOW("RelationshipFollow"),
|
||||||
|
REJECT_FOLLOW("RelationshipRejectFollow"),
|
||||||
UNFOLLOW("RelationshipUnfollow"),
|
UNFOLLOW("RelationshipUnfollow"),
|
||||||
BLOCK("RelationshipBlock"),
|
BLOCK("RelationshipBlock"),
|
||||||
UNBLOCK("RelationshipUnblock"),
|
UNBLOCK("RelationshipUnblock"),
|
||||||
|
|
|
@ -44,15 +44,12 @@ class Relationship(
|
||||||
var mutingFollowRequest: Boolean = mutingFollowRequest
|
var mutingFollowRequest: Boolean = mutingFollowRequest
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun follow() {
|
|
||||||
require(blocking.not())
|
|
||||||
following = true
|
|
||||||
addDomainEvent(RelationshipEventFactory(this).createEvent(RelationshipEvent.FOLLOW))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun unfollow() {
|
fun unfollow() {
|
||||||
following = false
|
following = false
|
||||||
addDomainEvent(RelationshipEventFactory(this).createEvent(RelationshipEvent.UNFOLLOW))
|
followRequesting = false
|
||||||
|
val relationshipEventFactory = RelationshipEventFactory(this)
|
||||||
|
addDomainEvent(relationshipEventFactory.createEvent(RelationshipEvent.UNFOLLOW))
|
||||||
|
addDomainEvent(relationshipEventFactory.createEvent(RelationshipEvent.UNFOLLOW_REQUEST))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun block() {
|
fun block() {
|
||||||
|
@ -96,11 +93,15 @@ class Relationship(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun acceptFollowRequest() {
|
fun acceptFollowRequest() {
|
||||||
follow()
|
require(blocking.not())
|
||||||
|
following = true
|
||||||
|
addDomainEvent(RelationshipEventFactory(this).createEvent(RelationshipEvent.ACCEPT_FOLLOW))
|
||||||
followRequesting = false
|
followRequesting = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rejectFollowRequest() {
|
fun rejectFollowRequest() {
|
||||||
|
require(followRequesting)
|
||||||
|
addDomainEvent(RelationshipEventFactory(this).createEvent(RelationshipEvent.REJECT_FOLLOW))
|
||||||
followRequesting = false
|
followRequesting = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package dev.usbharu.hideout.core.domain.model.timeline
|
package dev.usbharu.hideout.core.domain.model.timeline
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||||
|
|
||||||
interface TimelineRepository {
|
interface TimelineRepository {
|
||||||
suspend fun save(timeline: Timeline): Timeline
|
suspend fun save(timeline: Timeline): Timeline
|
||||||
suspend fun delete(timeline: Timeline)
|
suspend fun delete(timeline: Timeline)
|
||||||
|
@ -7,4 +9,8 @@ interface TimelineRepository {
|
||||||
suspend fun findByIds(ids: List<TimelineId>): List<Timeline>
|
suspend fun findByIds(ids: List<TimelineId>): List<Timeline>
|
||||||
|
|
||||||
suspend fun findById(id: TimelineId): Timeline?
|
suspend fun findById(id: TimelineId): Timeline?
|
||||||
|
suspend fun findAllByUserDetailIdAndVisibilityIn(
|
||||||
|
userDetailId: UserDetailId,
|
||||||
|
visibility: List<TimelineVisibility>
|
||||||
|
): List<Timeline>
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,20 @@ class TimelineRelationship(
|
||||||
val timelineId: TimelineId,
|
val timelineId: TimelineId,
|
||||||
val actorId: ActorId,
|
val actorId: ActorId,
|
||||||
val visible: Visible
|
val visible: Visible
|
||||||
)
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as TimelineRelationship
|
||||||
|
|
||||||
|
return id == other.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return id.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class Visible {
|
enum class Visible {
|
||||||
PUBLIC,
|
PUBLIC,
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package dev.usbharu.hideout.core.domain.model.timelinerelationship
|
package dev.usbharu.hideout.core.domain.model.timelinerelationship
|
||||||
|
|
||||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||||
|
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||||
|
|
||||||
interface TimelineRelationshipRepository {
|
interface TimelineRelationshipRepository {
|
||||||
suspend fun save(timelineRelationship: TimelineRelationship): TimelineRelationship
|
suspend fun save(timelineRelationship: TimelineRelationship): TimelineRelationship
|
||||||
suspend fun delete(timelineRelationship: TimelineRelationship)
|
suspend fun delete(timelineRelationship: TimelineRelationship)
|
||||||
|
|
||||||
suspend fun findByActorId(actorId: ActorId): List<TimelineRelationship>
|
suspend fun findByActorId(actorId: ActorId): List<TimelineRelationship>
|
||||||
|
suspend fun findById(timelineRelationshipId: TimelineRelationshipId): TimelineRelationship?
|
||||||
|
suspend fun findByTimelineIdAndActorId(timelineId: TimelineId, actorId: ActorId): TimelineRelationship?
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,22 @@ class ExposedTimelineRelationshipRepository : AbstractRepository(), TimelineRela
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun findById(timelineRelationshipId: TimelineRelationshipId): TimelineRelationship? {
|
||||||
|
return query {
|
||||||
|
TimelineRelationships.selectAll().where {
|
||||||
|
TimelineRelationships.id eq timelineRelationshipId.value
|
||||||
|
}.singleOrNull()?.toTimelineRelationship()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun findByTimelineIdAndActorId(timelineId: TimelineId, actorId: ActorId): TimelineRelationship? {
|
||||||
|
return query {
|
||||||
|
TimelineRelationships.selectAll().where {
|
||||||
|
TimelineRelationships.timelineId eq timelineId.value and (TimelineRelationships.actorId eq actorId.id)
|
||||||
|
}.singleOrNull()?.toTimelineRelationship()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val logger = LoggerFactory.getLogger(ExposedTimelineRelationshipRepository::class.java)
|
private val logger = LoggerFactory.getLogger(ExposedTimelineRelationshipRepository::class.java)
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,17 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun findAllByUserDetailIdAndVisibilityIn(
|
||||||
|
userDetailId: UserDetailId,
|
||||||
|
visibility: List<TimelineVisibility>
|
||||||
|
): List<Timeline> {
|
||||||
|
return query {
|
||||||
|
Timelines.selectAll().where {
|
||||||
|
Timelines.userDetailId eq userDetailId.id and (Timelines.visibility inList visibility.map { it.name })
|
||||||
|
}.map { it.toTimeline() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java.name)
|
private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java.name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,24 @@ package dev.usbharu.hideout.core.interfaces.web.user
|
||||||
import dev.usbharu.hideout.core.application.actor.GetActorDetail
|
import dev.usbharu.hideout.core.application.actor.GetActorDetail
|
||||||
import dev.usbharu.hideout.core.application.actor.GetActorDetailApplicationService
|
import dev.usbharu.hideout.core.application.actor.GetActorDetailApplicationService
|
||||||
import dev.usbharu.hideout.core.application.instance.GetLocalInstanceApplicationService
|
import dev.usbharu.hideout.core.application.instance.GetLocalInstanceApplicationService
|
||||||
|
import dev.usbharu.hideout.core.application.relationship.followrequest.FollowRequest
|
||||||
|
import dev.usbharu.hideout.core.application.relationship.followrequest.UserFollowRequestApplicationService
|
||||||
|
import dev.usbharu.hideout.core.application.relationship.get.GetRelationship
|
||||||
|
import dev.usbharu.hideout.core.application.relationship.get.GetRelationshipApplicationService
|
||||||
|
import dev.usbharu.hideout.core.application.relationship.unfollow.Unfollow
|
||||||
|
import dev.usbharu.hideout.core.application.relationship.unfollow.UserUnfollowApplicationService
|
||||||
import dev.usbharu.hideout.core.application.timeline.GetUserTimeline
|
import dev.usbharu.hideout.core.application.timeline.GetUserTimeline
|
||||||
import dev.usbharu.hideout.core.application.timeline.GetUserTimelineApplicationService
|
import dev.usbharu.hideout.core.application.timeline.GetUserTimelineApplicationService
|
||||||
import dev.usbharu.hideout.core.domain.model.support.acct.Acct
|
import dev.usbharu.hideout.core.domain.model.support.acct.Acct
|
||||||
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
import dev.usbharu.hideout.core.domain.model.support.page.Page
|
||||||
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
|
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
|
||||||
import dev.usbharu.hideout.core.infrastructure.springframework.SpringSecurityFormLoginPrincipalContextHolder
|
import dev.usbharu.hideout.core.infrastructure.springframework.SpringSecurityFormLoginPrincipalContextHolder
|
||||||
import org.springframework.stereotype.Controller
|
import org.springframework.stereotype.Controller
|
||||||
import org.springframework.ui.Model
|
import org.springframework.ui.Model
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
import org.springframework.web.bind.annotation.RequestParam
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
|
@ -20,7 +28,11 @@ class UserController(
|
||||||
private val getLocalInstanceApplicationService: GetLocalInstanceApplicationService,
|
private val getLocalInstanceApplicationService: GetLocalInstanceApplicationService,
|
||||||
private val getUserDetailApplicationService: GetActorDetailApplicationService,
|
private val getUserDetailApplicationService: GetActorDetailApplicationService,
|
||||||
private val springSecurityFormLoginPrincipalContextHolder: SpringSecurityFormLoginPrincipalContextHolder,
|
private val springSecurityFormLoginPrincipalContextHolder: SpringSecurityFormLoginPrincipalContextHolder,
|
||||||
private val getUserTimelineApplicationService: GetUserTimelineApplicationService
|
private val getUserTimelineApplicationService: GetUserTimelineApplicationService,
|
||||||
|
private val userFollowRequestApplicationService: UserFollowRequestApplicationService,
|
||||||
|
private val getActorDetailApplicationService: GetActorDetailApplicationService,
|
||||||
|
private val userUnfollowApplicationService: UserUnfollowApplicationService,
|
||||||
|
private val userGetRelationshipApplicationService: GetRelationshipApplicationService
|
||||||
) {
|
) {
|
||||||
@GetMapping("/users/{name}")
|
@GetMapping("/users/{name}")
|
||||||
suspend fun userById(
|
suspend fun userById(
|
||||||
|
@ -38,6 +50,14 @@ class UserController(
|
||||||
"user",
|
"user",
|
||||||
actorDetail
|
actorDetail
|
||||||
)
|
)
|
||||||
|
val relationship =
|
||||||
|
if (principal is LocalUser) {
|
||||||
|
userGetRelationshipApplicationService.execute(GetRelationship(actorDetail.id), principal)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("relationship", relationship)
|
||||||
model.addAttribute(
|
model.addAttribute(
|
||||||
"userTimeline",
|
"userTimeline",
|
||||||
getUserTimelineApplicationService.execute(
|
getUserTimelineApplicationService.execute(
|
||||||
|
@ -50,4 +70,24 @@ class UserController(
|
||||||
)
|
)
|
||||||
return "userById"
|
return "userById"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/users/{name}/follow")
|
||||||
|
suspend fun follow(@PathVariable name: String): String {
|
||||||
|
val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal()
|
||||||
|
|
||||||
|
val actorDetail = getActorDetailApplicationService.execute(GetActorDetail(Acct.of(name), null), principal)
|
||||||
|
userFollowRequestApplicationService.execute(FollowRequest((actorDetail.id)), principal)
|
||||||
|
|
||||||
|
return "redirect:/users/$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/users/{name}/unfollow")
|
||||||
|
suspend fun unfollow(@PathVariable name: String): String {
|
||||||
|
val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal()
|
||||||
|
|
||||||
|
val actorDetail = getActorDetailApplicationService.execute(GetActorDetail(Acct.of(name), null), principal)
|
||||||
|
userUnfollowApplicationService.execute(Unfollow((actorDetail.id)), principal)
|
||||||
|
|
||||||
|
return "redirect:/users/$name"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,17 @@
|
||||||
<h2 th:text="${user.screenName}"></h2>
|
<h2 th:text="${user.screenName}"></h2>
|
||||||
</th:block>
|
</th:block>
|
||||||
<p th:text="'@'+${user.name} + '@' + ${user.host}"></p>
|
<p th:text="'@'+${user.name} + '@' + ${user.host}"></p>
|
||||||
|
<th:block th:if="${relationship != null}">
|
||||||
|
<form method="post" th:action="@{/users/{name}/unfollow(name=${user.name+'@'+user.host})}"
|
||||||
|
th:if="${relationship.following}">
|
||||||
|
<input type="submit" value="Unfollow">
|
||||||
|
</form>
|
||||||
|
<form method="post" th:action="@{/users/{name}/follow(name=${user.name+'@'+user.host})}"
|
||||||
|
th:unless="${relationship.following}">
|
||||||
|
<input type="submit" value="Follow">
|
||||||
|
</form>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p th:text="${user.description}"></p>
|
<p th:text="${user.description}"></p>
|
||||||
|
|
Loading…
Reference in New Issue