1 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.space.vcs.review.details
4 import circlet.client.api.ProjectKey
5 import circlet.client.api.TD_MemberProfile
6 import circlet.client.api.identifier
7 import circlet.code.api.*
8 import circlet.code.codeReview
9 import circlet.platform.api.Ref
10 import circlet.platform.client.KCircletClient
11 import circlet.platform.client.property
12 import circlet.platform.client.resolve
13 import circlet.workspaces.Workspace
14 import libraries.coroutines.extra.Lifetime
15 import runtime.reactive.Property
16 import runtime.reactive.cellProperty
17 import runtime.reactive.live
18 import runtime.reactive.property.combineLatest
20 internal class SpaceReviewParticipantsVmImpl(
21 override val lifetime: Lifetime,
22 private val projectKey: ProjectKey,
23 val review: Ref<CodeReviewRecord>,
24 participantsRef: Ref<CodeReviewParticipants>,
25 private val pendingCounterRef: Ref<CodeReviewPendingMessageCounter>,
26 private val reviewIdentifier: ReviewIdentifier,
27 private val workspace: Workspace
28 ) : SpaceReviewParticipantsVm {
29 private val client: KCircletClient = workspace.client
31 private val participants = participantsRef.property()
32 override val codeReviewRecord: CodeReviewRecord = review.resolve()
34 override val authors: Property<List<CodeReviewParticipant>> = cellProperty {
35 participants.live.participants?.filter { it.role == CodeReviewParticipantRole.Author } ?: emptyList()
38 override val reviewers: Property<List<CodeReviewParticipant>> = cellProperty {
39 participants.live.participants?.filter { it.role == CodeReviewParticipantRole.Reviewer } ?: emptyList()
41 override val me: TD_MemberProfile
42 get() = workspace.me.value
44 override val controlVm: Property<ParticipantStateControlVM> = combineLatest(
48 { reviewRecord, reviewers, authors ->
49 if (reviewRecord.state != CodeReviewState.Opened) return@combineLatest ParticipantStateControlVM.WithoutControls
51 createControlVm(reviewers, authors, reviewRecord)
54 private fun createControlVm(reviewers: List<CodeReviewParticipant>,
55 authors: List<CodeReviewParticipant>,
56 reviewRecord: CodeReviewRecord): ParticipantStateControlVM {
57 val meReviewer = reviewers.me()
58 val meAuthor = authors.me()
59 val isTurnBased = reviewRecord.turnBased == true
62 meReviewer != null -> return when {
63 meReviewer.theirTurn == true && isTurnBased -> {
64 ParticipantStateControlVM.ReviewerDropdown(turnBased = true, pendingCounterRef)
66 (meReviewer.theirTurn == null || !isTurnBased) && meReviewer.reviewerState == null -> {
67 ParticipantStateControlVM.ReviewerDropdown(turnBased = false, pendingCounterRef)
69 meReviewer.theirTurn == false && isTurnBased -> {
70 ParticipantStateControlVM.ReviewerResumeReviewButton(meReviewer.state)
72 (meReviewer.theirTurn == null || !isTurnBased) && meReviewer.reviewerState != null -> {
73 ParticipantStateControlVM.ReviewerResumeReviewButton(meReviewer.state)
75 else -> ParticipantStateControlVM.WithoutControls
78 meAuthor != null -> return when {
79 !isTurnBased -> ParticipantStateControlVM.WithoutControls
80 meAuthor.theirTurn == true -> {
81 ParticipantStateControlVM.AuthorEndTurnButton(
82 canPassTurn = !reviewers.all { it.reviewerState == ReviewerState.Accepted },
83 canFinishReview = reviewers.any { it.reviewerState == ReviewerState.Accepted } &&
84 reviewers.none { it.reviewerState == null && it.theirTurn == false }
87 meAuthor.theirTurn == false && reviewers.isNotEmpty() -> {
88 ParticipantStateControlVM.AuthorResumeReviewButton
90 else -> ParticipantStateControlVM.WithoutControls
92 else -> return ParticipantStateControlVM.WithoutControls
96 private fun List<CodeReviewParticipant>.me() = singleOrNull { it.user.id == me.id }
98 override suspend fun addReviewer(profile: TD_MemberProfile) {
99 client.codeReview.addReviewParticipant(
100 projectKey.identifier,
103 CodeReviewParticipantRole.Reviewer
107 override suspend fun removeReviewer(profile: TD_MemberProfile) {
108 client.codeReview.removeReviewParticipant(
109 projectKey.identifier,
112 CodeReviewParticipantRole.Reviewer