Skip to content

Commit

Permalink
feat(m3): be able to create a new comment.
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardPaligot committed Nov 2, 2023
1 parent 3993f18 commit efe1240
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.openfeedback.android.m3

import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Send
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
import io.openfeedback.android.R

@Composable
fun CommentInput(
value: String,
onValueChange: (String) -> Unit,
onSubmit: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true
) {
TextField(
value = value,
onValueChange = onValueChange,
modifier = modifier,
label = { Text(text = stringResource(id = R.string.openfeedback_comments_title_input)) },
trailingIcon = {
IconButton(onClick = onSubmit) {
Icon(
imageVector = Icons.Outlined.Send,
contentDescription = stringResource(id = R.string.openfeedback_comments_send)
)
}
},
enabled = enabled,
keyboardActions = KeyboardActions(onDone = { onSubmit() }),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
maxLines = 5
)
}

@Preview
@Composable
private fun CommentInputPreview() {
MaterialTheme {
CommentInput(
value = "My comment",
onValueChange = {},
onSubmit = {}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal fun CommentItems(
comments: List<UIComment>,
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(8.dp),
commentInput: @Composable ColumnScope.() -> Unit,
comment: @Composable ColumnScope.(UIComment) -> Unit
) {
Column(
Expand All @@ -29,6 +30,7 @@ internal fun CommentItems(
text = stringResource(id = R.string.openfeedback_comments_title),
style = MaterialTheme.typography.titleMedium
)
commentInput()
comments.forEachIndexed { index, uiComment ->
comment(uiComment)
}
Expand Down Expand Up @@ -60,6 +62,9 @@ private fun VoteItemsPreview() {
votedByUser = true
)
),
commentInput = {
CommentInput(value = "", onValueChange = {}, onSubmit = {})
},
comment = {
Comment(comment = it, onClick = {})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ fun OpenFeedback(
onClick = viewModel::upVote
)
},
commentInput = {
CommentInput(
value = session.commentValue,
onValueChange = viewModel::valueChangedComment,
onSubmit = viewModel::submitComment,
modifier = Modifier.fillMaxWidth()
)
},
content = {
VoteCard(
voteModel = it,
Expand All @@ -83,6 +91,7 @@ fun OpenFeedbackLayout(
horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(8.dp),
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(8.dp),
comment: @Composable ColumnScope.(UIComment) -> Unit,
commentInput: @Composable ColumnScope.() -> Unit,
content: @Composable ColumnScope.(UIVoteItem) -> Unit
) {
Column(
Expand All @@ -100,6 +109,7 @@ fun OpenFeedbackLayout(
CommentItems(
comments = sessionFeedback.comments,
verticalArrangement = verticalArrangement,
commentInput = commentInput,
comment = comment
)
Spacer(modifier = Modifier.height(8.dp))
Expand All @@ -119,6 +129,8 @@ private fun OpenFeedbackLayoutPreview() {
MaterialTheme {
OpenFeedbackLayout(
sessionFeedback = UISessionFeedback(
commentValue = "",
commentVoteItemId = "",
comments = listOf(
UIComment(
id = "",
Expand Down Expand Up @@ -156,6 +168,9 @@ private fun OpenFeedbackLayoutPreview() {
),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
commentInput = {
CommentInput(value = "", onValueChange = {}, onSubmit = {})
},
comment = { Comment(comment = it, onClick = {}) }
) {
VoteCard(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ class OpenFeedbackViewModel(
}
}

fun valueChangedComment(value: String) {
if (_uiState.value !is OpenFeedbackUiState.Success) return
val session = (_uiState.value as OpenFeedbackUiState.Success).session
_uiState.value = OpenFeedbackUiState.Success(session.copy(commentValue = value))
}

fun submitComment() = viewModelScope.launch {
if (_uiState.value !is OpenFeedbackUiState.Success) return@launch
val session = (_uiState.value as OpenFeedbackUiState.Success).session
if (session.commentVoteItemId == null) return@launch
repository.newComment(
projectId = projectId,
talkId = sessionId,
voteItemId = session.commentVoteItemId,
status = VoteStatus.Active,
text = session.commentValue
)
}

fun vote(voteItem: UIVoteItem) = viewModelScope.launch {
repository.setVote(
projectId = projectId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ fun convertToUiSessionFeedback(
): UISessionFeedback {
val formatter = SimpleDateFormat("dd MMMM yyyy, hh:mm", locale)
return UISessionFeedback(
commentValue = "",
commentVoteItemId = project.voteItems.find { it.type == "text" }?.id,
comments = totalVotes.comments.map { commentItem ->
UIComment(
id = commentItem.value.id,
Expand Down Expand Up @@ -48,6 +50,8 @@ fun convertToUiSessionFeedback(
fun UISessionFeedbackWithColors.convertToUiSessionFeedback(
oldSessionFeedback: UISessionFeedback?
): UISessionFeedback = UISessionFeedback(
commentValue = oldSessionFeedback?.commentValue ?: "",
commentVoteItemId = oldSessionFeedback?.commentVoteItemId ?: this.session.commentVoteItemId,
comments = this.session.comments.map { newCommentItem ->
val oldCommentItem = oldSessionFeedback?.comments?.find { it.id == newCommentItem.id }
val newDots = if (oldCommentItem != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import androidx.compose.runtime.Immutable

@Immutable
data class UISessionFeedback(
val commentValue: String,
val commentVoteItemId: String?,
val comments: List<UIComment>,
val voteItem: List<UIVoteItem>
)
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ class OpenFeedbackRepository(
optimisticVoteCaching.votes
)

suspend fun newComment(projectId: String, talkId: String, voteItemId: String, status: VoteStatus, text: String) {
auth.withFirebaseUser {
firestore.newComment(projectId, it.uid, talkId, voteItemId, status, text)
}
}

suspend fun setVote(projectId: String, talkId: String, voteItemId: String, status: VoteStatus) {
auth.withFirebaseUser {
optimisticVoteCaching.updateVotes(voteItemId, status)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class OpenFeedbackFirestore(
?.map {
val voteItemId = it.key
(it.value as HashMap<*, *>).entries
.filter { (it.value as Map<String, *>).isNotEmpty() }
.map { entry ->
entry.key as String to (entry.value as Map<String, *>)
.convertToModel(
Expand All @@ -66,6 +67,50 @@ class OpenFeedbackFirestore(
)
}

suspend fun newComment(
projectId: String,
userId: String,
talkId: String,
voteItemId: String,
status: VoteStatus,
text: String
) {
if (text.trim() == "") return
val collectionReference = firestore.collection("projects/$projectId/userVotes")
val querySnapshot = collectionReference
.whereEqualTo("userId", userId)
.whereEqualTo("talkId", talkId)
.whereEqualTo("voteItemId", voteItemId)
.get()
.await()
if (querySnapshot.isEmpty) {
val documentReference = collectionReference.document()
documentReference.set(
mapOf(
"id" to documentReference.id,
"createdAt" to Date(),
"projectId" to projectId,
"status" to status.value,
"talkId" to talkId,
"updatedAt" to Date(),
"userId" to userId,
"voteItemId" to voteItemId,
"text" to text.trim()
)
)
} else {
collectionReference
.document(querySnapshot.documents[0].id)
.update(
mapOf(
"updatedAt" to Date(),
"status" to status.value,
"text" to text.trim()
)
)
}
}

suspend fun setVote(
projectId: String,
userId: String,
Expand Down
2 changes: 2 additions & 0 deletions openfeedback/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="openfeedback_comments_title">Commentaires</string>
<string name="openfeedback_comments_title_input">Votre commentaire</string>
<string name="openfeedback_comments_send">Soumettre votre commentaire</string>
<string name="openfeedback_comments_upvotes">%d votes</string>
<string name="powered_by">Proposé par</string>
</resources>
2 changes: 2 additions & 0 deletions openfeedback/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="openfeedback_comments_title">Comments</string>
<string name="openfeedback_comments_title_input">Your comment</string>
<string name="openfeedback_comments_send">Submit comment</string>
<string name="openfeedback_comments_upvotes">%d votes</string>
<string name="powered_by">Powered by</string>
</resources>

0 comments on commit efe1240

Please sign in to comment.