Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.wordpress.android.support.he.model

object ConversationStatus {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These status values are more for the support person than for the user – we probably shouldn't expose them directly.

On iOS we have "waiting for support","waiting for user", "solved" and "closed" – we can probably mirror that here?

Copy link
Contributor Author

@adalpari adalpari Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point!
I've made some changes here (and refactor)

Screenshot 2025-11-07 at 18 59 42 Screenshot 2025-11-07 at 19 00 07

const val NEW = "new"
const val OPEN = "open"
const val PENDING = "pending"
const val ON_HOLD = "hold"
const val SOLVED = "solved"
const val CLOSED = "closed"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ data class SupportConversation(
val title: String,
val description: String,
val lastMessageSentAt: Date,
val status: String,
val messages: List<SupportMessage>
): Conversation {
override fun getConversationId(): Long = id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class HESupportRepository @Inject constructor(
title = it.title,
description = it.description,
lastMessageSentAt = it.updatedAt,
status = it.status,
messages = emptyList()
)
}
Expand All @@ -191,6 +192,7 @@ class HESupportRepository @Inject constructor(
title = title,
description = description,
lastMessageSentAt = updatedAt,
status = status,
messages = messages.map { it.toSupportMessage() }
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import androidx.compose.ui.unit.dp
import coil.request.ImageRequest
import org.wordpress.android.R
import org.wordpress.android.support.aibot.util.formatRelativeTime
import org.wordpress.android.support.he.model.ConversationStatus
import org.wordpress.android.support.he.model.SupportAttachment
import org.wordpress.android.support.he.model.SupportConversation
import org.wordpress.android.support.he.model.SupportMessage
Expand Down Expand Up @@ -111,12 +112,17 @@ fun HEConversationDetailScreen(
)
},
bottomBar = {
ReplyButton(
enabled = !isLoading,
onClick = {
showBottomSheet = true
}
)
val isClosed = conversation.status.equals(ConversationStatus.CLOSED, ignoreCase = true)
if (isClosed) {
ClosedConversationBanner()
} else {
ReplyButton(
enabled = !isLoading,
onClick = {
showBottomSheet = true
}
)
}
}
) { contentPadding ->
Box(
Expand Down Expand Up @@ -285,6 +291,36 @@ private fun ConversationTitleCard(title: String) {
}
}

@Composable
private fun ClosedConversationBanner() {
Box(
modifier = Modifier
.fillMaxWidth()
.background(
color = MaterialTheme.colorScheme.errorContainer,
shape = RoundedCornerShape(8.dp)
)
.padding(16.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Icon(
painter = painterResource(R.drawable.ic_info_outline_white_24dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.onErrorContainer,
modifier = Modifier.size(24.dp)
)
Text(
text = stringResource(R.string.he_support_conversation_closed_message),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onErrorContainer
)
}
}
}

@Composable
private fun MessageItem(
message: SupportMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package org.wordpress.android.support.he.ui

import android.content.res.Configuration.UI_MODE_NIGHT_YES
import android.content.res.Resources
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
Expand All @@ -28,6 +30,7 @@ import org.wordpress.android.R
import org.wordpress.android.support.aibot.util.formatRelativeTime
import org.wordpress.android.support.common.ui.ConversationsListScreen
import org.wordpress.android.support.common.ui.ConversationsSupportViewModel
import org.wordpress.android.support.he.model.ConversationStatus
import org.wordpress.android.support.he.model.SupportConversation
import org.wordpress.android.support.he.util.generateSampleHESupportConversations
import org.wordpress.android.ui.compose.theme.AppThemeM3
Expand Down Expand Up @@ -79,6 +82,9 @@ private fun HEConversationListItem(
Column(
modifier = Modifier.weight(1f)
) {
// Status badge
ConversationStatusBadge(status = conversation.status)

Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
Expand All @@ -95,7 +101,10 @@ private fun HEConversationListItem(
)

Text(
text = formatRelativeTime(conversation.lastMessageSentAt, resources),
text = formatRelativeTime(
conversation.lastMessageSentAt,
resources
),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(start = 8.dp)
Expand All @@ -121,6 +130,60 @@ private fun HEConversationListItem(
}
}

@Composable
private fun ConversationStatusBadge(status: String) {
val (statusText, backgroundColor, textColor) = when (status.lowercase()) {
ConversationStatus.NEW -> Triple(
stringResource(R.string.he_support_status_new),
MaterialTheme.colorScheme.primaryContainer,
MaterialTheme.colorScheme.onPrimaryContainer
)
ConversationStatus.OPEN -> Triple(
stringResource(R.string.he_support_status_open),
MaterialTheme.colorScheme.primaryContainer,
MaterialTheme.colorScheme.onPrimaryContainer
)
ConversationStatus.PENDING -> Triple(
stringResource(R.string.he_support_status_pending),
MaterialTheme.colorScheme.secondaryContainer,
MaterialTheme.colorScheme.onSecondaryContainer
)
ConversationStatus.ON_HOLD -> Triple(
stringResource(R.string.he_support_status_on_hold),
MaterialTheme.colorScheme.surfaceVariant,
MaterialTheme.colorScheme.onSurfaceVariant
)
ConversationStatus.SOLVED -> Triple(
stringResource(R.string.he_support_status_solved),
MaterialTheme.colorScheme.primary,
MaterialTheme.colorScheme.onPrimary
)
ConversationStatus.CLOSED -> Triple(
stringResource(R.string.he_support_status_closed),
MaterialTheme.colorScheme.tertiaryContainer,
MaterialTheme.colorScheme.onTertiaryContainer
)
else -> Triple(
status,
MaterialTheme.colorScheme.surfaceVariant,
MaterialTheme.colorScheme.onSurfaceVariant
)
}

Text(
text = statusText,
style = MaterialTheme.typography.labelSmall,
color = textColor,
modifier = Modifier
.padding(bottom = 4.dp)
.background(
color = backgroundColor,
shape = RoundedCornerShape(4.dp)
)
.padding(horizontal = 6.dp, vertical = 2.dp)
)
}

@Preview(showBackground = true, name = "HE Support Conversations List")
@Composable
private fun ConversationsScreenPreview() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ fun generateSampleHESupportConversations(): List<SupportConversation> {
description = "I'm having trouble logging into my account. The two-factor authentication code " +
"doesn't seem to be working properly when I try to access my site from the mobile app.",
lastMessageSentAt = oneHourAgo,
status = "Open",
messages = listOf(
SupportMessage(
id = 1,
Expand Down Expand Up @@ -73,6 +74,7 @@ fun generateSampleHESupportConversations(): List<SupportConversation> {
"store, I've noticed significant slowdowns and occasional timeout errors affecting customer " +
"experience.",
lastMessageSentAt = twoDaysAgo,
status = "closed",
messages = listOf(
SupportMessage(
id = 4,
Expand Down Expand Up @@ -101,6 +103,7 @@ fun generateSampleHESupportConversations(): List<SupportConversation> {
"configuration, SSL certificate setup, and setting up professional email forwarding for my " +
"business site.",
lastMessageSentAt = oneWeekAgo,
status = "solved",
messages = listOf(
SupportMessage(
id = 6,
Expand Down
7 changes: 7 additions & 0 deletions WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5180,6 +5180,13 @@ translators: %s: Select control option value e.g: "Auto, 25%". -->
<string name="he_support_include_logs_description">Including logs can help our team investigate issues. Logs may contain recent app activity.</string>
<string name="he_support_download_attachment">Download attachment</string>
<string name="he_support_select_attachments">Select attachments</string>
<string name="he_support_status_new">Waiting for Support</string>
<string name="he_support_status_open">Open</string>
<string name="he_support_status_pending">Pending</string>
<string name="he_support_status_on_hold">On-hold</string>
<string name="he_support_status_solved">Solved</string>
<string name="he_support_status_closed">Closed</string>
<string name="he_support_conversation_closed_message">This conversation is closed. You can no longer reply to it.</string>

<!-- HE Support - New Ticket Screen -->
<string name="he_support_contact_support_title">Contact Support</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ class HESupportRepositoryTest : BaseUnitTest() {
title = title,
description = description,
lastMessageSentAt = updatedAt,
status = status,
messages = emptyList()
)

Expand All @@ -359,6 +360,7 @@ class HESupportRepositoryTest : BaseUnitTest() {
title = this.title,
description = this.description,
lastMessageSentAt = this.updatedAt,
status = this.status,
messages = this.messages.map { it.toSupportMessage() }
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -672,13 +672,15 @@ class HESupportViewModelTest : BaseUnitTest() {
private fun createTestConversation(
id: Long,
title: String = "Test Conversation",
description: String = "Test Description"
description: String = "Test Description",
status: String = "open"
): SupportConversation {
return SupportConversation(
id = id,
title = title,
description = description,
lastMessageSentAt = Date(),
status = status,
messages = emptyList()
)
}
Expand Down