Skip to content

Conversation

@adalpari
Copy link
Contributor

@adalpari adalpari commented Oct 23, 2025

Description

This PR main purpose is to make the whole new Support UI look more AndroidMaterial3 looking.
In addition, some side improvements have been made around the code and the logic. And markdown messages are now supported.

Testing instructions

  • Smoke test the whole new support screens and check that everything looks consistent.
Screen_recording_20251027_114907.mp4

Copy link
Contributor

@jkmassel jkmassel left a comment

Choose a reason for hiding this comment

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

This is generally looking better – a couple of notes:

  1. The "New Ticket" selector has too many colours – we should probably just have the outline and then the inner highlight should be the same colour with 1/2 to 1/3rd of the saturation.
  2. Both conversation types should parse and display markdown as rich text. No need to support composing rich text yet.

Base automatically changed from feat/CMM-872-support-HE-conversations-and-tickets-logic to trunk October 27, 2025 08:04
…-flow-and-style

# Conflicts:
#	WordPress/src/main/java/org/wordpress/android/support/aibot/ui/AIBotConversationsListScreen.kt
#	WordPress/src/main/java/org/wordpress/android/support/common/ui/EmptyConversationsView.kt
#	WordPress/src/main/java/org/wordpress/android/support/he/ui/HEConversationsListScreen.kt
#	WordPress/src/main/java/org/wordpress/android/support/he/ui/HENewTicketScreen.kt
#	WordPress/src/main/java/org/wordpress/android/support/he/ui/TicketMainContentView.kt
#	WordPress/src/main/res/values/strings.xml
@adalpari
Copy link
Contributor Author

@claude

@claude
Copy link

claude bot commented Oct 27, 2025

Claude finished @adalpari's task —— View job


Code Review for PR #22310

I've completed a comprehensive review of this PR. Here are my findings across multiple dimensions:


Overview

This PR implements a significant UI overhaul for the support flow, introducing Compose-based screens and markdown rendering capabilities. The changes span 11 files with 808 additions and 427 deletions.

Key Findings

1. Code Quality & Architecture

Strengths

  • Well-structured Compose code: The composables follow good practices with proper state management and separation of concerns
  • Consistent styling: Material3 design system is used consistently across all screens
  • Good composable breakdown: Complex screens are properly decomposed into smaller, reusable components
  • Preview coverage: Excellent preview coverage with light/dark themes and WordPress/Jetpack variants
  • Proper state management: Good use of StateFlow with collectAsState() for reactive UI updates

⚠️ Issues to Address

Critical: Markdown Parser Security & Edge Cases

Location: WordPress/src/main/java/org/wordpress/android/ui/compose/utils/MarkdownUtils.kt:20

  1. Missing documentation: The function lacks KDoc explaining supported syntax, limitations, and security considerations
  2. Nested markdown not handled: Doesn't support nested formatting (e.g., **bold *and italic***)
  3. Escaped characters not handled: Can't escape markdown characters (e.g., \*not italic\*)
  4. Edge cases: Consider scenarios like mixed delimiters (**bold__), very long strings, Unicode characters
  5. Performance: Character-by-character scanning may be slow for long messages (>1000 chars)

Color Scheme Issue - Reviewer Feedback Not Addressed

Location: WordPress/src/main/java/org/wordpress/android/support/he/ui/HENewTicketScreen.kt:344-350

Per @jkmassel's feedback: "The 'New Ticket' selector has too many colours – we should probably just have the outline and then the inner highlight should be the same colour with 1/2 to 1/3rd of the saturation."

Current implementation uses bold primary color for both border and icon when selected. This needs to be toned down with reduced saturation.

Minor Issues

  • EmptyConversationsView.kt:38 - Hardcoded emoji "💬" may not render consistently across Android versions
  • EmptyConversationsView.kt:23 - Duplicate import of androidx.compose.ui.unit.dp

2. Test Coverage Issues

Critical Concern: 0% Coverage on New Code

According to Codecov, this PR has 345 lines with missing coverage:

  • HENewTicketScreen.kt: 128 missing lines
  • SupportScreen.kt: 62 missing lines
  • TicketMainContentView.kt: 49 missing lines
  • HEConversationsListScreen.kt: 33 missing lines
  • AIBotConversationsListScreen.kt: 27 missing lines
  • EmptyConversationsView.kt: 24 missing lines
  • LogsListScreen.kt: 21 missing lines

Paradox: MarkdownUtils.kt has comprehensive unit tests (229 lines in MarkdownUtilsTest.kt), yet Codecov reports 0% coverage. This suggests:

  • Tests may not be running in CI
  • Test source set configuration issue
  • Coverage reporting configuration problem

Recommendation:

  1. Verify tests are actually executing in CI pipeline
  2. Add screenshot/integration tests for critical UI flows
  3. At minimum, ensure the existing MarkdownUtils tests show in coverage reports

3. Performance Considerations

Good Performance Practices

  • Proper use of key = { it.id } in LazyColumn items for efficient recomposition
  • LaunchedEffect used appropriately for side effects
  • State hoisting follows best practices

⚠️ Minor Performance Considerations

  • Markdown parser scans character-by-character; may be slow for very long messages
  • Consider caching parsed markdown results if messages are re-rendered frequently

4. Security Review

Low Security Risk

  • No SQL injection vectors
  • No file system operations
  • No network operations in UI layer
  • User input properly handled through Compose state
  • Markdown parser is text-only (no HTML injection risk)

⚠️ Considerations

  1. Ensure includeAppLogs feature filters sensitive information from logs
  2. Document that markdown parser should only be used with trusted content or add sanitization

5. Documentation

Missing Critical Documentation

  1. PR Description is empty: No description of what the PR does or how to test it
  2. No testing instructions: Reviewers don't know what to test
  3. MarkdownUtils.kt: Missing KDoc for the main function
  4. Complex composables: Components like HENewTicketScreen lack parameter documentation

6. Reviewer Feedback Status

Per @jkmassel's review from 2025-10-26:

  1. Markdown parsing implemented: Both conversation types now parse and display markdown as rich text

    • HEConversationDetailScreen.kt:294 uses markdownToAnnotatedString()
    • AIBotConversationDetailScreen.kt:278 uses markdownToAnnotatedString()
  2. Color scheme NOT addressed: The "New Ticket" selector still has too many bold colors (see inline comment for specific fix)

Inline Comments Added

I've added inline comments on:

  • MarkdownUtils.kt:20 - Documentation and edge case handling
  • HENewTicketScreen.kt:344 - Color scheme fix per reviewer feedback
  • EmptyConversationsView.kt:23 - Duplicate import

Summary & Recommendation

Overall Assessment: This is a solid Compose implementation with good architectural practices, but several issues need attention before merge:

Must Fix (Blocking)

  1. Address reviewer feedback: Fix the color scheme in ticket selector per @jkmassel's comments
  2. Test coverage: Investigate why MarkdownUtils tests show 0% coverage and ensure they run in CI
  3. PR documentation: Add description and testing instructions

Should Fix (High Priority)

  1. ⚠️ Markdown parser: Add KDoc, edge case handling, and performance considerations
  2. ⚠️ UI test coverage: Add at least basic UI tests or screenshot tests for critical flows

Nice to Have (Low Priority)

  1. ⚠️ Replace hardcoded emoji with drawable
  2. ⚠️ Remove duplicate import

Recommendation: Request changes - The code quality is good, but the unaddressed reviewer feedback and test coverage issues should be resolved before merging.


* Convert markdown text to Compose AnnotatedString.
* Supports basic markdown formatting: bold, italic, bold+italic, and inline code.
*/
fun markdownToAnnotatedString(markdownText: String): AnnotatedString = buildAnnotatedString {
Copy link

Choose a reason for hiding this comment

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

Missing Documentation: This function needs KDoc explaining:

  • Supported markdown syntax (bold, italic, bold+italic, inline code)
  • Known limitations (no nesting, no character escaping, no block-level elements)
  • Security considerations (should only be used with trusted content)
  • Example usage

Also consider:

  • Adding a max length parameter to prevent performance issues with very long strings
  • Handling escaped characters (e.g., \*not italic\*)
  • Adding input validation/sanitization if this will be used with user-generated content

colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surface
),
border = BorderStroke(
Copy link

Choose a reason for hiding this comment

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

Per reviewer feedback from @jkmassel: The "New Ticket" selector has too many colors. The border and icon colors should use a more subtle color scheme.

Suggestion: When selected, use the primary color with reduced saturation (e.g., primary.copy(alpha = 0.3f)) for the inner highlight to maintain visual hierarchy without overwhelming the user with multiple bold colors.

Suggested change
border = BorderStroke(
border = BorderStroke(
width = if (isSelected) 2.dp else 1.dp,
color = if (isSelected) {
MaterialTheme.colorScheme.primary.copy(alpha = 0.3f)
} else {
MaterialTheme.colorScheme.outline.copy(alpha = 0.5f)
}
),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did achieve it, but finally didn't use alpha. I opted to use "selected/unselected" status. So it looks very clear) and imo clean) from the user perspective.

@adalpari
Copy link
Contributor Author

Must Fix (Blocking)

  1. Address reviewer feedback: Fix the color scheme in ticket selector per @jkmassel's comments
  2. Test coverage: Investigate why MarkdownUtils tests show 0% coverage and ensure they run in CI
  3. PR documentation: Add description and testing instructions
  1. I've addressed it. No alpha used, though. I just outlined the card (removing the extra color) and made icons having two tints: selected or unselected. Which I think looks good.
  2. MarkdownUtils HAS a test class: MarkdownUtilsTest
  3. PR documentation is comming

@adalpari
Copy link
Contributor Author

Critical: Markdown Parser Security & Edge Cases

Location: WordPress/src/main/java/org/wordpress/android/ui/compose/utils/MarkdownUtils.kt:20

  1. Missing documentation: The function lacks KDoc explaining supported syntax, limitations, and security considerations
  2. Nested markdown not handled: Doesn't support nested formatting (e.g., **bold *and italic***)
  3. Escaped characters not handled: Can't escape markdown characters (e.g., \*not italic\*)
  4. Edge cases: Consider scenarios like mixed delimiters (**bold__), very long strings, Unicode characters
  5. Performance: Character-by-character scanning may be slow for long messages (>1000 chars)

Critical 😅 ?

  1. Done
  2. Done
  3. Done
  4. Performance concerns???? This is literally O(n). I'm moving the call to the VM, inside a coroutine, though.

@adalpari adalpari marked this pull request as ready for review October 27, 2025 11:31
@adalpari
Copy link
Contributor Author

@jkmassel I think the PR is now ready to review it :)

@adalpari adalpari requested a review from a team as a code owner October 28, 2025 17:23
@adalpari
Copy link
Contributor Author

I refined the markdown parsing (finally used a well-known library), and this is how it looks:

Screenshot 2025-10-28 at 18 01 16

@sonarqubecloud
Copy link

@wpmobilebot
Copy link
Contributor

Project dependencies changes

list
+ New Dependencies
org.commonmark:commonmark:0.24.0
tree
+\--- org.commonmark:commonmark:0.24.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants