Skip to content

Commit

Permalink
NT-1955: UI – Comment Card with threads (#1267)
Browse files Browse the repository at this point in the history
  • Loading branch information
sunday-okpoluaefe committed Jun 2, 2021
1 parent 1b95824 commit d99f750
Show file tree
Hide file tree
Showing 16 changed files with 187 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ class CommentsActivity :
override fun onCommentGuideLinesClicked(comment: Comment) {
}

override fun onCommentRepliesClicked(comment: Comment) {
startThreadActivity(comment, false)
}

/**
* Start the Thread activity with
* @param comment the selected comment to reply
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class ThreadActivity : BaseActivity<ThreadViewModel.ViewModel>() {
private fun configureRootCommentView(comment: Comment) {
binding.commentsCardView.setCommentUserName(comment.author().name())
binding.commentsCardView.setCommentBody(comment.body())
binding.commentsCardView.hideReplyViewGroup()
binding.commentsCardView.setCommentPostTime(DateTimeUtils.relative(this, ksString, comment.createdAt()))
binding.commentsCardView.setCommentUserName(comment.author().name())
binding.commentsCardView.setAvatarUrl(comment.author().avatar().medium())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class CommentCardViewHolder(
fun onReplyButtonClicked(comment: Comment)
fun onFlagButtonClicked(comment: Comment)
fun onCommentGuideLinesClicked(comment: Comment)
fun onCommentRepliesClicked(comment: Comment)
}

private val vm: CommentsViewHolderViewModel.ViewModel = CommentsViewHolderViewModel.ViewModel(environment())
Expand All @@ -31,6 +32,11 @@ class CommentCardViewHolder(
.compose(Transformers.observeForUI())
.subscribe { binding.commentsCardView.setCommentUserName(it) }

this.vm.outputs.commentRepliesCount()
.compose(bindToLifecycle())
.compose(Transformers.observeForUI())
.subscribe { binding.commentsCardView.setCommentReplies(it) }

this.vm.outputs.commentAuthorAvatarUrl()
.compose(bindToLifecycle())
.compose(Transformers.observeForUI())
Expand Down Expand Up @@ -71,6 +77,11 @@ class CommentCardViewHolder(
.compose(Transformers.observeForUI())
.subscribe { this.delegate.onRetryViewClicked(it) }

this.vm.outputs.viewCommentReplies()
.compose(bindToLifecycle())
.compose(Transformers.observeForUI())
.subscribe { this.delegate.onCommentRepliesClicked(it) }

this.vm.outputs.flagComment()
.compose(bindToLifecycle())
.compose(Transformers.observeForUI())
Expand All @@ -89,6 +100,10 @@ class CommentCardViewHolder(
vm.inputs.onFlagButtonClicked()
}

override fun onViewRepliesButtonClicked(view: View) {
vm.inputs.onViewRepliesButtonClicked()
}

override fun onCommentGuideLinesClicked(view: View) {
vm.inputs.onCommentGuideLinesClicked()
}
Expand Down
28 changes: 27 additions & 1 deletion app/src/main/java/com/kickstarter/ui/views/CommentCard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class CommentCard @JvmOverloads constructor(
onCommentCardClickedListener?.onFlagButtonClicked(it)
}

binding.replies.setOnClickListener {
onCommentCardClickedListener?.onViewRepliesButtonClicked(it)
}

binding.flaggedMessage.setOnClickListener {
onCommentCardClickedListener?.onCommentGuideLinesClicked(it)
}
Expand Down Expand Up @@ -75,6 +79,10 @@ class CommentCard @JvmOverloads constructor(
setAvatarUrl(it)
}

getInt(R.styleable.CommentCardView_comment_card_replies, 0).also {
setCommentReplies(it)
}

getString(R.styleable.CommentCardView_comment_card_user_name)?.also {
setCommentUserName(it)
}
Expand Down Expand Up @@ -102,7 +110,12 @@ class CommentCard @JvmOverloads constructor(
cardCommentStatus == CommentCardStatus.DELETED_COMMENT

binding.commentBody.isVisible = cardCommentStatus == CommentCardStatus.COMMENT_WITH_REPLIES ||
cardCommentStatus == CommentCardStatus.COMMENT_WITHOUT_REPLIES
cardCommentStatus == CommentCardStatus.COMMENT_WITHOUT_REPLIES ||
cardCommentStatus != CommentCardStatus.DELETED_COMMENT

binding.commentActionGroup.isVisible = cardCommentStatus == CommentCardStatus.COMMENT_WITH_REPLIES ||
cardCommentStatus == CommentCardStatus.COMMENT_WITHOUT_REPLIES ||
cardCommentStatus == CommentCardStatus.FAILED_TO_SEND_COMMENT

binding.retryButton.isVisible =
cardCommentStatus == CommentCardStatus.FAILED_TO_SEND_COMMENT
Expand All @@ -116,10 +129,22 @@ class CommentCard @JvmOverloads constructor(
binding.commentBody.setTextColor(ContextCompat.getColor(context, commentBodyTextColor))
}

/*
* To display replies count
* binding.replies.text = String.format("%s (%d)",resources.getString(R.string.view_replies), replies)
*/
fun setCommentReplies(replies: Int) {
binding.replies.isVisible = replies > 0
}

fun setCommentUserName(username: String) {
binding.commentUserName.text = username
}

fun hideReplyViewGroup() {
binding.commentActionGroup.isVisible = false
}

fun setCommentPostTime(time: String) {
binding.commentPostTime.text = time
}
Expand All @@ -141,6 +166,7 @@ interface OnCommentCardClickedListener {
fun onRetryViewClicked(view: View)
fun onReplyButtonClicked(view: View)
fun onFlagButtonClicked(view: View)
fun onViewRepliesButtonClicked(view: View)
fun onCommentGuideLinesClicked(view: View)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ interface CommentsViewHolderViewModel {
/** Call when the user clicks reply to comment */
fun onReplyButtonClicked()

/** Call when the user clicks view replies to comment */
fun onViewRepliesButtonClicked()

/** Call when the user clicks flag comment */
fun onFlagButtonClicked()

Expand All @@ -38,6 +41,9 @@ interface CommentsViewHolderViewModel {
/** Emits the commentCardStatus */
fun commentCardStatus(): Observable<CommentCardStatus>

/** Emits the comment replies count. */
fun commentRepliesCount(): Observable<Int>

/** Emits the comment Author Name. */
fun commentAuthorName(): Observable<String>

Expand All @@ -64,6 +70,9 @@ interface CommentsViewHolderViewModel {

/** Emits the current [Comment] when flag clicked.. */
fun flagComment(): Observable<Comment>

/** Emits the current [Comment] when view replies clicked.. */
fun viewCommentReplies(): Observable<Comment>
}

class ViewModel(environment: Environment) : ActivityViewModel<CommentCardViewHolder>(environment), Inputs, Outputs {
Expand All @@ -72,17 +81,20 @@ interface CommentsViewHolderViewModel {
private val onRetryViewClicked = PublishSubject.create<Void>()
private val onReplyButtonClicked = PublishSubject.create<Void>()
private val onFlagButtonClicked = PublishSubject.create<Void>()
private val onViewCommentRepliesButtonClicked = PublishSubject.create<Void>()

private val commentCardStatus = BehaviorSubject.create<CommentCardStatus>()
private val isCommentActionGroupVisible = BehaviorSubject.create<Boolean>()
private val commentAuthorName = BehaviorSubject.create<String>()
private val commentAuthorAvatarUrl = BehaviorSubject.create<String>()
private val commentMessageBody = BehaviorSubject.create<String>()
private val commentRepliesCount = BehaviorSubject.create<Int>()
private val commentPostTime = BehaviorSubject.create<DateTime>()
private val openCommentGuideLines = PublishSubject.create<Comment>()
private val retrySendComment = PublishSubject.create<Comment>()
private val replyToComment = PublishSubject.create<Comment>()
private val flagComment = PublishSubject.create<Comment>()
private val viewCommentReplies = PublishSubject.create<Comment>()

val inputs: Inputs = this
val outputs: Outputs = this
Expand All @@ -104,6 +116,11 @@ interface CommentsViewHolderViewModel {
.filter { ObjectUtils.isNotNull(it) }
.map { requireNotNull(it) }

comment
.map { it.repliesCount() }
.compose(bindToLifecycle())
.subscribe(this.commentRepliesCount)

comment
.map { it.author()?.name() }
.filter { ObjectUtils.isNotNull(it) }
Expand All @@ -128,6 +145,11 @@ interface CommentsViewHolderViewModel {
.compose(bindToLifecycle())
.subscribe(this.commentPostTime)

comment
.compose(takeWhen(this.onViewCommentRepliesButtonClicked))
.compose(bindToLifecycle())
.subscribe(this.viewCommentReplies)

comment
.compose(takeWhen(this.onCommentGuideLinesClicked))
.compose(bindToLifecycle())
Expand Down Expand Up @@ -168,10 +190,14 @@ interface CommentsViewHolderViewModel {

override fun onReplyButtonClicked() = this.onReplyButtonClicked.onNext(null)

override fun onViewRepliesButtonClicked() = this.onViewCommentRepliesButtonClicked.onNext(null)

override fun onFlagButtonClicked() = this.onFlagButtonClicked.onNext(null)

override fun commentCardStatus(): Observable<CommentCardStatus> = this.commentCardStatus

override fun commentRepliesCount(): Observable<Int> = this.commentRepliesCount

override fun commentAuthorName(): Observable<String> = this.commentAuthorName

override fun commentAuthorAvatarUrl(): Observable<String> = this.commentAuthorAvatarUrl
Expand All @@ -189,5 +215,7 @@ interface CommentsViewHolderViewModel {
override fun replyToComment(): Observable<Comment> = replyToComment

override fun flagComment(): Observable<Comment> = flagComment

override fun viewCommentReplies(): Observable<Comment> = this.viewCommentReplies
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,9 @@ interface CommentsViewModel {
.compose(Transformers.takeWhen(this.refresh))
.doOnNext {
this.isRefreshing.onNext(true)
}
.compose(CommentEnvelopeTransformer(initialProject))
// reset cursor
lastCommentCursour = null
}.compose(CommentEnvelopeTransformer(initialProject))
.compose(bindToLifecycle())
.subscribe {
bindCommentList(it.first, LoadingType.PULL_REFRESH, it.second)
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/drawable/ic_mask.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<vector android:height="10dp" android:viewportHeight="12"
android:viewportWidth="8" android:width="6dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#696969" android:fillType="evenOdd" android:pathData="M0.4943,0.9161C0.4943,0.6407 0.8225,0.4973 1.0241,0.6851L6.4991,5.7689C6.6335,5.8937 6.6335,6.1061 6.4991,6.2309L1.0241,11.3153C0.8225,11.5025 0.4943,11.3591 0.4943,11.0837V0.9161Z"/>
</vector>
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/rect_trans_rounded_darker.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<padding
android:bottom="@dimen/grid_2"
android:left="@dimen/grid_2"
android:right="@dimen/grid_3"
android:top="@dimen/grid_2" />
<stroke
android:width="1px"
android:color="@color/kds_support_200" />
<corners android:radius="@dimen/grid_0" />
</shape>
20 changes: 20 additions & 0 deletions app/src/main/res/layout/activity_thread_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,25 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/left_guideline"
app:layout_constraintGuide_begin="@dimen/grid_5"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>


<androidx.recyclerview.widget.RecyclerView
android:id="@+id/comment_replies_recycler_view"
app:layout_constraintStart_toEndOf="@id/left_guideline"
android:layout_width="0dp"
android:paddingEnd="@dimen/grid_5"
android:layout_height="wrap_content"
android:background="@color/kds_white"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@id/comments_card_view"
tools:layout_editor_absoluteX="0dp"
tools:listitem="@layout/comment_card" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
37 changes: 31 additions & 6 deletions app/src/main/res/layout/comment_card.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/CommentCard">
Expand Down Expand Up @@ -37,27 +38,44 @@
android:id="@+id/comment_body"
style="@style/CommentCardBody"
android:text="@string/A_successfully_funded_project_will_collect_your_pledge_in_its_native_currency"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@id/avatar" />

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/replies"
app:layout_constraintTop_toBottomOf="@id/comment_body"
android:background="@drawable/rect_trans_rounded_darker"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/avatar"
android:drawableRight="@drawable/ic_mask"
android:layout_marginStart="@dimen/grid_3"
android:layout_marginEnd="@dimen/grid_3"
android:text="@string/view_replies"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>


<androidx.appcompat.widget.AppCompatButton
android:id="@+id/reply_button"
style="@style/CommentsReplayButton"
android:drawableStart="@drawable/ic_arrow_reply"
android:text="@string/reply"
android:layout_marginTop="@dimen/grid_3"
app:layout_goneMarginTop="0dp"
app:layout_constraintBottom_toTopOf="@+id/separtor"
app:layout_constraintStart_toStartOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@id/comment_body" />
app:layout_constraintTop_toBottomOf="@id/replies" />

<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/flag_button"
style="@style/CommentsReplayButton"
android:src="@drawable/ic_flag"
android:layout_marginTop="@dimen/grid_3"
app:layout_goneMarginTop="0dp"
app:layout_constraintBottom_toTopOf="@+id/separtor"
app:layout_constraintEnd_toEndOf="@id/comment_body"
app:layout_constraintTop_toBottomOf="@id/comment_body" />
app:layout_constraintTop_toBottomOf="@id/replies"/>

<androidx.appcompat.widget.AppCompatButton
android:id="@+id/retry_button"
Expand All @@ -67,15 +85,15 @@
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/separtor"
app:layout_constraintStart_toStartOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@id/comment_body" />
app:layout_constraintTop_toBottomOf="@id/replies" />

<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/info_button"
style="@style/CommentsReplayButton"
android:src="@drawable/ic_info"
app:layout_constraintTop_toTopOf="@+id/flagged_message"
app:layout_constraintStart_toStartOf="@id/avatar"
/>
/>

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/flagged_message"
Expand All @@ -101,6 +119,13 @@
android:visibility="gone"
app:constraint_referenced_ids="reply_button,flag_button" />

<androidx.constraintlayout.widget.Group
android:id="@+id/reply_message_group"
android:layout_width="wrap_content"
android:visibility="gone"
android:layout_height="wrap_content"
app:constraint_referenced_ids="flagged_message,info_button" />

<androidx.constraintlayout.widget.Group
android:id="@+id/comment_deleted_message_group"
android:layout_width="wrap_content"
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/layout/item_comment_card.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<attr name="comment_card_user_name" format="string" />
<attr name="comment_card_post_time" format="string" />
<attr name="comment_card_message" format="string" />
<attr name="comment_card_replies" format="integer" />
<attr name="comment_card_avatar_url" format="string" />
<attr name="is_comment_action_group_visible" format="boolean" />
</declare-styleable>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<resources>
<!-- Kickstarter six-point grid keylines-->
<dimen name="grid_0">2dp</dimen>
<dimen name="grid_1_half">3dp</dimen>
<dimen name="grid_1">6dp</dimen>
<dimen name="grid_3_half">9dp</dimen>
Expand Down
Loading

0 comments on commit d99f750

Please sign in to comment.