Skip to content

Commit ac7304b

Browse files
authored
CMM-933: Don't allow to reply support closed tickets (#22342)
* Adding the field * Showing closed status in the UI * Extracting string * Detekt * Adding all other statuses * Some PR suggestions and fix * Using "waiting for support" string in "New" tickets * Hiding support status and using a more user-friendly ones * Some refactor
1 parent 69ed046 commit ac7304b

File tree

10 files changed

+167
-32
lines changed

10 files changed

+167
-32
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.wordpress.android.support.he.model
2+
3+
enum class ConversationStatus {
4+
WAITING_FOR_SUPPORT,
5+
WAITING_FOR_USER,
6+
CLOSED,
7+
SOLVED,
8+
UNKNOWN;
9+
10+
companion object {
11+
fun fromStatus(status: String): ConversationStatus {
12+
return when (status.lowercase()) {
13+
"open", "new", "hold" -> WAITING_FOR_SUPPORT
14+
"closed" -> CLOSED
15+
"pending" -> WAITING_FOR_USER
16+
"solved" -> SOLVED
17+
else -> UNKNOWN
18+
}
19+
}
20+
}
21+
}

WordPress/src/main/java/org/wordpress/android/support/he/model/SupportConversation.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ data class SupportConversation(
88
val title: String,
99
val description: String,
1010
val lastMessageSentAt: Date,
11+
val status: String,
1112
val messages: List<SupportMessage>
1213
): Conversation {
1314
override fun getConversationId(): Long = id

WordPress/src/main/java/org/wordpress/android/support/he/repository/HESupportRepository.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class HESupportRepository @Inject constructor(
181181
title = it.title,
182182
description = it.description,
183183
lastMessageSentAt = it.updatedAt,
184+
status = it.status,
184185
messages = emptyList()
185186
)
186187
}
@@ -191,6 +192,7 @@ class HESupportRepository @Inject constructor(
191192
title = title,
192193
description = description,
193194
lastMessageSentAt = updatedAt,
195+
status = status,
194196
messages = messages.map { it.toSupportMessage() }
195197
)
196198

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.wordpress.android.support.he.ui
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.padding
5+
import androidx.compose.foundation.shape.RoundedCornerShape
6+
import androidx.compose.material3.MaterialTheme
7+
import androidx.compose.material3.Text
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.res.stringResource
11+
import androidx.compose.ui.unit.dp
12+
import org.wordpress.android.R
13+
import org.wordpress.android.support.he.model.ConversationStatus
14+
15+
@Composable
16+
fun ConversationStatusBadge(
17+
status: String,
18+
modifier: Modifier = Modifier
19+
) {
20+
val conversationStatus = ConversationStatus.fromStatus(status)
21+
val (statusText, backgroundColor, textColor) = when (conversationStatus) {
22+
ConversationStatus.WAITING_FOR_SUPPORT -> Triple(
23+
stringResource(R.string.he_support_status_waiting_for_support),
24+
MaterialTheme.colorScheme.primaryContainer,
25+
MaterialTheme.colorScheme.onPrimaryContainer
26+
)
27+
ConversationStatus.WAITING_FOR_USER -> Triple(
28+
stringResource(R.string.he_support_status_waiting_for_user),
29+
MaterialTheme.colorScheme.secondaryContainer,
30+
MaterialTheme.colorScheme.onSecondaryContainer
31+
)
32+
ConversationStatus.SOLVED -> Triple(
33+
stringResource(R.string.he_support_status_solved),
34+
MaterialTheme.colorScheme.primary,
35+
MaterialTheme.colorScheme.onPrimary
36+
)
37+
ConversationStatus.CLOSED -> Triple(
38+
stringResource(R.string.he_support_status_closed),
39+
MaterialTheme.colorScheme.tertiaryContainer,
40+
MaterialTheme.colorScheme.onTertiaryContainer
41+
)
42+
ConversationStatus.UNKNOWN -> Triple(
43+
stringResource(R.string.he_support_status_unknown),
44+
MaterialTheme.colorScheme.surfaceVariant,
45+
MaterialTheme.colorScheme.onSurfaceVariant
46+
)
47+
}
48+
49+
Text(
50+
text = statusText,
51+
style = MaterialTheme.typography.labelSmall,
52+
color = textColor,
53+
modifier = modifier
54+
.background(
55+
color = backgroundColor,
56+
shape = RoundedCornerShape(4.dp)
57+
)
58+
.padding(horizontal = 6.dp, vertical = 2.dp)
59+
)
60+
}

WordPress/src/main/java/org/wordpress/android/support/he/ui/HEConversationDetailScreen.kt

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import coil.request.videoFrameMillis
6161
import org.wordpress.android.R
6262
import org.wordpress.android.support.aibot.util.formatRelativeTime
6363
import org.wordpress.android.support.he.model.AttachmentState
64+
import org.wordpress.android.support.he.model.ConversationStatus
6465
import org.wordpress.android.support.he.model.MessageSendResult
6566
import org.wordpress.android.support.he.model.AttachmentType
6667
import org.wordpress.android.support.he.model.SupportAttachment
@@ -118,12 +119,18 @@ fun HEConversationDetailScreen(
118119
)
119120
},
120121
bottomBar = {
121-
ReplyButton(
122-
enabled = !isLoading,
123-
onClick = {
124-
showBottomSheet = true
125-
}
126-
)
122+
val status = ConversationStatus.fromStatus(conversation.status)
123+
val isClosed = status == ConversationStatus.CLOSED
124+
if (isClosed) {
125+
ClosedConversationBanner()
126+
} else {
127+
ReplyButton(
128+
enabled = !isLoading,
129+
onClick = {
130+
showBottomSheet = true
131+
}
132+
)
133+
}
127134
}
128135
) { contentPadding ->
129136
Box(
@@ -140,7 +147,7 @@ fun HEConversationDetailScreen(
140147
) {
141148
item {
142149
ConversationHeader(
143-
messageCount = conversation.messages.size,
150+
status = conversation.status,
144151
lastUpdated = formatRelativeTime(conversation.lastMessageSentAt, resources),
145152
isLoading = isLoading
146153
)
@@ -256,13 +263,24 @@ fun HEConversationDetailScreen(
256263

257264
@Composable
258265
private fun ConversationHeader(
259-
messageCount: Int,
266+
status: String,
260267
lastUpdated: String,
261268
isLoading: Boolean = false
262269
) {
270+
val statusText = when (ConversationStatus.fromStatus(status)) {
271+
ConversationStatus.WAITING_FOR_SUPPORT ->
272+
stringResource(R.string.he_support_status_waiting_for_support)
273+
ConversationStatus.WAITING_FOR_USER ->
274+
stringResource(R.string.he_support_status_waiting_for_user)
275+
ConversationStatus.SOLVED ->
276+
stringResource(R.string.he_support_status_solved)
277+
ConversationStatus.CLOSED ->
278+
stringResource(R.string.he_support_status_closed)
279+
ConversationStatus.UNKNOWN ->
280+
stringResource(R.string.he_support_status_unknown)
281+
}
263282
val headerDescription = if (!isLoading) {
264-
"${stringResource(R.string.he_support_message_count, messageCount)}. " +
265-
stringResource(R.string.he_support_last_updated, lastUpdated)
283+
"$statusText. ${stringResource(R.string.he_support_last_updated, lastUpdated)}"
266284
} else {
267285
stringResource(R.string.he_support_last_updated, lastUpdated)
268286
}
@@ -277,26 +295,7 @@ private fun ConversationHeader(
277295
horizontalArrangement = Arrangement.SpaceBetween,
278296
verticalAlignment = Alignment.CenterVertically
279297
) {
280-
if (!isLoading) {
281-
Row(
282-
horizontalArrangement = Arrangement.spacedBy(8.dp),
283-
verticalAlignment = Alignment.CenterVertically
284-
) {
285-
Icon(
286-
painter = painterResource(R.drawable.ic_comment_white_24dp),
287-
contentDescription = null,
288-
tint = MaterialTheme.colorScheme.onSurfaceVariant,
289-
modifier = Modifier.size(20.dp)
290-
)
291-
Text(
292-
text = stringResource(R.string.he_support_message_count, messageCount),
293-
style = MaterialTheme.typography.bodyMedium,
294-
color = MaterialTheme.colorScheme.onSurfaceVariant
295-
)
296-
}
297-
} else {
298-
Spacer(modifier = Modifier.size(0.dp))
299-
}
298+
ConversationStatusBadge(status = status)
300299

301300
Text(
302301
text = stringResource(R.string.he_support_last_updated, lastUpdated),
@@ -323,6 +322,36 @@ private fun ConversationTitleCard(title: String) {
323322
}
324323
}
325324

325+
@Composable
326+
private fun ClosedConversationBanner() {
327+
Box(
328+
modifier = Modifier
329+
.fillMaxWidth()
330+
.background(
331+
color = MaterialTheme.colorScheme.errorContainer,
332+
shape = RoundedCornerShape(8.dp)
333+
)
334+
.padding(16.dp)
335+
) {
336+
Row(
337+
verticalAlignment = Alignment.CenterVertically,
338+
horizontalArrangement = Arrangement.spacedBy(12.dp)
339+
) {
340+
Icon(
341+
painter = painterResource(R.drawable.ic_info_outline_white_24dp),
342+
contentDescription = null,
343+
tint = MaterialTheme.colorScheme.onErrorContainer,
344+
modifier = Modifier.size(24.dp)
345+
)
346+
Text(
347+
text = stringResource(R.string.he_support_conversation_closed_message),
348+
style = MaterialTheme.typography.bodyMedium,
349+
color = MaterialTheme.colorScheme.onErrorContainer
350+
)
351+
}
352+
}
353+
}
354+
326355
@Composable
327356
private fun MessageItem(
328357
message: SupportMessage,

WordPress/src/main/java/org/wordpress/android/support/he/ui/HEConversationsListScreen.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ private fun HEConversationListItem(
7979
Column(
8080
modifier = Modifier.weight(1f)
8181
) {
82+
// Status badge
83+
ConversationStatusBadge(
84+
status = conversation.status,
85+
modifier = Modifier.padding(bottom = 4.dp)
86+
)
87+
8288
Row(
8389
modifier = Modifier.fillMaxWidth(),
8490
horizontalArrangement = Arrangement.SpaceBetween,
@@ -95,7 +101,10 @@ private fun HEConversationListItem(
95101
)
96102

97103
Text(
98-
text = formatRelativeTime(conversation.lastMessageSentAt, resources),
104+
text = formatRelativeTime(
105+
conversation.lastMessageSentAt,
106+
resources
107+
),
99108
style = MaterialTheme.typography.bodyMedium,
100109
color = MaterialTheme.colorScheme.onSurfaceVariant,
101110
modifier = Modifier.padding(start = 8.dp)

WordPress/src/main/java/org/wordpress/android/support/he/util/HEConversationUtils.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ fun generateSampleHESupportConversations(): List<SupportConversation> {
2121
description = "I'm having trouble logging into my account. The two-factor authentication code " +
2222
"doesn't seem to be working properly when I try to access my site from the mobile app.",
2323
lastMessageSentAt = oneHourAgo,
24+
status = "Open",
2425
messages = listOf(
2526
SupportMessage(
2627
id = 1,
@@ -73,6 +74,7 @@ fun generateSampleHESupportConversations(): List<SupportConversation> {
7374
"store, I've noticed significant slowdowns and occasional timeout errors affecting customer " +
7475
"experience.",
7576
lastMessageSentAt = twoDaysAgo,
77+
status = "closed",
7678
messages = listOf(
7779
SupportMessage(
7880
id = 4,
@@ -101,6 +103,7 @@ fun generateSampleHESupportConversations(): List<SupportConversation> {
101103
"configuration, SSL certificate setup, and setting up professional email forwarding for my " +
102104
"business site.",
103105
lastMessageSentAt = oneWeekAgo,
106+
status = "solved",
104107
messages = listOf(
105108
SupportMessage(
106109
id = 6,

WordPress/src/main/res/values/strings.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5182,6 +5182,12 @@ translators: %s: Select control option value e.g: "Auto, 25%". -->
51825182
<string name="he_support_include_logs_description">Including logs can help our team investigate issues. Logs may contain recent app activity.</string>
51835183
<string name="he_support_download_attachment">Download attachment</string>
51845184
<string name="he_support_select_attachments">Select attachments</string>
5185+
<string name="he_support_status_waiting_for_support">Waiting for Support</string>
5186+
<string name="he_support_status_waiting_for_user">Waiting for User</string>
5187+
<string name="he_support_status_solved">Solved</string>
5188+
<string name="he_support_status_closed">Closed</string>
5189+
<string name="he_support_status_unknown">Unknown</string>
5190+
<string name="he_support_conversation_closed_message">This conversation is closed. You can no longer reply to it.</string>
51855191
<string name="he_support_video_playback_error_title">Unable to play video</string>
51865192
<string name="he_support_video_playback_error_message">This video cannot be played inline. Please download it to view.</string>
51875193
<string name="he_support_download_video_button">Download Video</string>

WordPress/src/test/java/org/wordpress/android/support/he/repository/HESupportRepositoryTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ class HESupportRepositoryTest : BaseUnitTest() {
350350
title = title,
351351
description = description,
352352
lastMessageSentAt = updatedAt,
353+
status = status,
353354
messages = emptyList()
354355
)
355356

@@ -359,6 +360,7 @@ class HESupportRepositoryTest : BaseUnitTest() {
359360
title = this.title,
360361
description = this.description,
361362
lastMessageSentAt = this.updatedAt,
363+
status = this.status,
362364
messages = this.messages.map { it.toSupportMessage() }
363365
)
364366

WordPress/src/test/java/org/wordpress/android/support/he/ui/HESupportViewModelTest.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,13 +962,15 @@ class HESupportViewModelTest : BaseUnitTest() {
962962
private fun createTestConversation(
963963
id: Long,
964964
title: String = "Test Conversation",
965-
description: String = "Test Description"
965+
description: String = "Test Description",
966+
status: String = "open"
966967
): SupportConversation {
967968
return SupportConversation(
968969
id = id,
969970
title = title,
970971
description = description,
971972
lastMessageSentAt = Date(),
973+
status = status,
972974
messages = emptyList()
973975
)
974976
}

0 commit comments

Comments
 (0)