Skip to content

feat: enhance translation UI and caching logic#333

Merged
rainxchzed merged 5 commits intomainfrom
feat-translation
Mar 16, 2026
Merged

feat: enhance translation UI and caching logic#333
rainxchzed merged 5 commits intomainfrom
feat-translation

Conversation

@rainxchzed
Copy link
Member

@rainxchzed rainxchzed commented Mar 15, 2026

  • Redesign TranslationControls with a pill-shaped layout, AnimatedContent transitions, and specific visual states for idle, translating, success, and error.
  • Improve LanguagePicker by adding a device language shortcut, search field styling, and better list item visuals.
  • Implement more robust translation caching in TranslationRepositoryImpl with a time-to-live (TTL) of 30 minutes and a more stable cache key logic.
  • Add AnimatedContent to "About" and "What's New" sections for smoother transitions when switching between original and translated text.
  • Update DetailsViewModel to manage translation jobs effectively, ensuring previous requests are cancelled when a new translation or release selection is triggered.
  • Add new string resources for translation error handling and language selection.

Summary by CodeRabbit

  • New Features

    • Device language quick‑select in language picker
    • New UI strings: retry prompt, "translated from" label, and language selection label
  • Improvements

    • Optimized translation caching with 30‑minute expiration for fresher results
    • Smoother animations and refined translation controls, language picker, and content expansion
    • Better translation task handling allowing cancellation and reliable retries
  • Bug Fixes

    • Minor label text capitalization adjusted ("Show original")
  • Documentation

    • Added internal guidance document on coding boundaries
  • Chores

    • Enabled parallel Gradle execution setting

- Redesign `TranslationControls` with a pill-shaped layout, `AnimatedContent` transitions, and specific visual states for idle, translating, success, and error.
- Improve `LanguagePicker` by adding a device language shortcut, search field styling, and better list item visuals.
- Implement more robust translation caching in `TranslationRepositoryImpl` with a time-to-live (TTL) of 30 minutes and a more stable cache key logic.
- Add `AnimatedContent` to "About" and "What's New" sections for smoother transitions when switching between original and translated text.
- Update `DetailsViewModel` to manage translation jobs effectively, ensuring previous requests are cancelled when a new translation or release selection is triggered.
- Add new string resources for translation error handling and language selection.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 77f0291e-116d-4610-b697-19a15acdf3b3

📥 Commits

Reviewing files that changed from the base of the PR and between 21c2707 and 9fa2432.

📒 Files selected for processing (2)
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/About.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt

Walkthrough

Reworks translation handling and UI: adds three new string resources, replaces a string-key cache with a typed CacheKey → CachedTranslation cache with TTL and size limits, adds cancellable translation Jobs in the ViewModel, passes deviceLanguageCode into LanguagePicker, and refactors translation UI to state-driven AnimatedContent.

Changes

Cohort / File(s) Summary
Strings & Resources
core/presentation/src/commonMain/composeResources/values/strings.xml
Added translation_error_retry, translated_from, select_language; changed show_original value capitalization.
Translation Repository / Cache
feature/details/data/src/commonMain/kotlin/.../TranslationRepositoryImpl.kt
Replaced simple string-key cache with CacheKey -> CachedTranslation entries, added CACHE_TTL_MS (30 min) and MAX_CACHE_SIZE, TTL-based eviction on access, removed AutoCloseable/close(), and switched to Kotlin time utilities.
ViewModel: jobs & cancellation
feature/details/presentation/src/commonMain/kotlin/.../DetailsViewModel.kt
Added aboutTranslationJob and whatsNewTranslationJob, translateContent now returns Job and accepts getCurrentState, cancels previous jobs on new requests, propagates CancellationException, resets translation state on selection/category changes.
Language Picker & Root
feature/details/presentation/src/commonMain/kotlin/.../DetailsRoot.kt, feature/details/presentation/src/commonMain/kotlin/.../components/LanguagePicker.kt
DetailsRoot now passes deviceLanguageCode; LanguagePicker signature gains deviceLanguageCode and displays an optional device-language shortcut row when no search is active.
Translation Controls & Sections
feature/details/presentation/src/commonMain/kotlin/.../components/TranslationControls.kt, .../sections/About.kt, .../sections/WhatsNew.kt
Refactored TranslationControls to a state-driven AnimatedContent with private subcomposables and transitions; About and WhatsNew now use AnimatedContent/transitions and extract expandable markdown rendering into a private composable.
Build & Docs
gradle.properties, .claude/memory/feedback_coding_boundaries.md
Enabled org.gradle.parallel=true; added guidance doc .claude/memory/feedback_coding_boundaries.md.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant VM as DetailsViewModel
    participant Repo as TranslationRepositoryImpl
    participant Cache as Cache (CacheKey)
    participant API as Translation API

    User->>VM: Request translation (About / WhatsNew)
    VM->>VM: Cancel existing translation Job (if any)
    VM->>Repo: translate(text, targetLang, sourceLang)

    Repo->>Cache: lookup(CacheKey)
    alt hit and not expired
        Cache-->>Repo: CachedTranslation
        Repo-->>VM: TranslationResult
    else miss or expired
        Repo->>API: fetch translation
        API-->>Repo: response
        Repo->>Cache: store CachedTranslation (with timestamp)
        Repo-->>VM: TranslationResult
    end

    VM->>VM: Update TranslationState -> SHOWING_TRANSLATION
    VM-->>User: UI updates via AnimatedContent (fade)

    alt User changes selection / cancels
        User->>VM: Cancel / select new content
        VM->>VM: aboutTranslationJob?.cancel() / whatsNewTranslationJob?.cancel()
        VM->>VM: Reset TranslationState
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 Hopping through keys with timestamps bright,

Cached translations nap till TTL’s light.
Jobs cancel neatly when the user swaps view,
Device-language shortcut hops into view.
Animated fades — a rabbit’s quiet review.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: enhance translation UI and caching logic' accurately summarizes the main changes: UI improvements to translation controls and language picker, plus caching enhancements in TranslationRepositoryImpl.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-translation
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt (1)

1360-1365: ⚠️ Potential issue | 🟠 Major

Clear the previous translation payload before starting a new request.

Starting from getCurrentState().copy(...) preserves the last translatedText and isShowingTranslation. If the user changes language after one successful translation and the new request fails, the old translation stays on screen and TranslationControls never reaches its error state because translatedText is still non-null.

🐛 Proposed fix
                 updateState(
                     getCurrentState().copy(
                         isTranslating = true,
+                        translatedText = null,
+                        isShowingTranslation = false,
+                        targetLanguageDisplayName = null,
+                        detectedSourceLanguage = null,
                         error = null,
                         targetLanguageCode = targetLanguageCode,
                     ),
                 )

Based on learnings: Use TranslationState model to track the translation UI state including loading, error, and success states.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt`
around lines 1360 - 1365, The current updateState call in DetailsViewModel (via
getCurrentState().copy(...)) preserves previous translatedText and
isShowingTranslation, so a failed new translation can leave old text visible;
modify the copy inside the block that sets isTranslating = true to also clear
the previous translation payload by setting translatedText = null and
isShowingTranslation = false (and keep error = null, targetLanguageCode
unchanged) so the TranslationState reflects a fresh loading state before the new
request.
🧹 Nitpick comments (1)
feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/LanguagePicker.kt (1)

64-75: Hide the shortcut language from the default list.

When searchQuery is blank, filteredLanguages still contains deviceLanguage, so the same option renders twice: once as the shortcut card and once as a regular row. Filtering it out in the blank-query branch keeps the shortcut intentional and avoids double selected states.

♻️ Proposed cleanup
-    val filteredLanguages =
-        remember(searchQuery) {
+    val filteredLanguages =
+        remember(searchQuery, deviceLanguage?.code) {
             val all = SupportedLanguages.all
             if (searchQuery.isBlank()) {
-                all
+                deviceLanguage?.let { shortcut ->
+                    all.filterNot { it.code == shortcut.code }
+                } ?: all
             } else {
                 all.filter {
                     it.displayName.contains(searchQuery, ignoreCase = true) ||
                         it.code.contains(searchQuery, ignoreCase = true)
                 }
             }
         }

Based on learnings: Implement LanguagePicker composable to allow selecting readme translation target language.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/LanguagePicker.kt`
around lines 64 - 75, filteredLanguages includes deviceLanguage when searchQuery
is blank, causing the shortcut card to appear twice; update the blank-query
branch in the LanguagePicker logic to exclude the shortcut by filtering
SupportedLanguages.all to remove deviceLanguage (e.g., use all.filter { it !=
deviceLanguage } or compare by code/identifier) so the shortcut remains only in
the shortcut card and not in the default list.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@feature/details/data/src/commonMain/kotlin/zed/rainxch/details/data/repository/TranslationRepositoryImpl.kt`:
- Around line 84-86: clearCache() currently calls cache.clear() without
synchronization while translate() and the access-ordered LinkedHashMap (cache)
use cacheMutex; with accessOrder=true even reads mutate the map, so wrap the
clear in the same lock. Update clearCache() to acquire cacheMutex (the same
Mutex used by translate()/cache accesses) before calling cache.clear(), or
refactor both paths to use a single non-suspending lock (e.g., a ReentrantLock)
and use that consistently for cache, ensuring all references to cache,
translate(), and clearCache() use the same locking primitive.
- Around line 41-45: The cache key built in buildCacheKey (used under cacheMutex
with cache and isExpired) must uniquely identify the translation request:
include sourceLanguage alongside targetLanguage and either the full text or a
fixed-size hash (e.g., SHA256) of the full text instead of the current
truncation/prefix-suffix/length scheme used elsewhere (lines ~201-204); update
buildCacheKey and any other cache-key construction sites to incorporate
sourceLanguage and replace the truncate/length strategy with a deterministic
hash to avoid aliasing and stale detectedSourceLanguage/translatedText returns.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt`:
- Around line 193-198: The conditional in TranslationControls that sets the chip
text is inverted: swap the branches so the chip shows the action (not the
current state); change the logic using isShowingTranslation so that when
isShowingTranslation is true the text is
stringResource(Res.string.show_original), and when false it is displayName ?:
stringResource(Res.string.translate) (refer to the text assignment in
TranslationControls where displayName, isShowingTranslation, stringResource,
Res.string.translate and Res.string.show_original are used).

---

Outside diff comments:
In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt`:
- Around line 1360-1365: The current updateState call in DetailsViewModel (via
getCurrentState().copy(...)) preserves previous translatedText and
isShowingTranslation, so a failed new translation can leave old text visible;
modify the copy inside the block that sets isTranslating = true to also clear
the previous translation payload by setting translatedText = null and
isShowingTranslation = false (and keep error = null, targetLanguageCode
unchanged) so the TranslationState reflects a fresh loading state before the new
request.

---

Nitpick comments:
In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/LanguagePicker.kt`:
- Around line 64-75: filteredLanguages includes deviceLanguage when searchQuery
is blank, causing the shortcut card to appear twice; update the blank-query
branch in the LanguagePicker logic to exclude the shortcut by filtering
SupportedLanguages.all to remove deviceLanguage (e.g., use all.filter { it !=
deviceLanguage } or compare by code/identifier) so the shortcut remains only in
the shortcut card and not in the default list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fed5bbdf-bcb1-4abe-b4ee-f7dc88fa53bc

📥 Commits

Reviewing files that changed from the base of the PR and between 3d8f6a8 and b4bb08e.

📒 Files selected for processing (9)
  • core/presentation/src/commonMain/composeResources/values/strings.xml
  • feature/details/data/src/commonMain/kotlin/zed/rainxch/details/data/repository/TranslationRepositoryImpl.kt
  • feature/details/domain/src/commonMain/kotlin/zed/rainxch/details/domain/repository/TranslationRepository.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/LanguagePicker.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/About.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt

- Update `TranslationRepositoryImpl` to use a data class for `CacheKey` instead of a manual string builder, incorporating the source language into the key.
- Remove `clearCache` method from the `TranslationRepository` interface and its implementation.
- Refine translation button text logic to correctly toggle between "show original" and the target language display name.
- Reformat `TranslationControls` and `TranslationState` for better code consistency and readability.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
feature/details/data/src/commonMain/kotlin/zed/rainxch/details/data/repository/TranslationRepositoryImpl.kt (1)

22-24: Inject HttpClient from DI for consistency and proper lifecycle management.

TranslationRepositoryImpl is already singleton-scoped, so resource accumulation is not a concern. However, align with the established pattern used by DetailsRepositoryImpl and other repositories by injecting httpClient from the DI container rather than creating it locally. This improves testability and ensures consistent lifecycle management across the codebase.

Proposed direction
 class TranslationRepositoryImpl(
     private val localizationManager: LocalizationManager,
+    private val httpClient: HttpClient,
 ) : TranslationRepository {
-    private val httpClient: HttpClient = createPlatformHttpClient(ProxyConfig.None)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/data/src/commonMain/kotlin/zed/rainxch/details/data/repository/TranslationRepositoryImpl.kt`
around lines 22 - 24, TranslationRepositoryImpl currently constructs its own
HttpClient via createPlatformHttpClient(ProxyConfig.None) instead of receiving
one from DI; change the constructor of TranslationRepositoryImpl to accept an
HttpClient parameter and use that instance instead of calling
createPlatformHttpClient, mirroring the pattern used by DetailsRepositoryImpl;
update any DI module/provider to bind and supply the shared HttpClient to
TranslationRepositoryImpl and remove the local createPlatformHttpClient usage to
ensure consistent lifecycle and testability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt`:
- Around line 111-114: In TranslationControls (the composable in
TranslationControls.kt) the leading decorative Icon calls (e.g.,
Icon(imageVector = Icons.Default.GTranslate, ...) and the other leading icon
around line 237) duplicate the spoken label of adjacent Text, so change their
contentDescription values to null (contentDescription = null) to mark them
decorative; leave accessible labels on the surrounding Text controls unchanged
so screen readers announce the label once.
- Around line 280-287: The error state in TranslationState.controlState
currently requires translatedText == null, but DetailsViewModel only sets error
on failure and leaves translatedText stale, so ERROR never shows; fix by
clearing the previous translation when a translation fails: in the
failure-handling branch inside DetailsViewModel where you set error (the
translation retry/failure handler), also set translatedText = null (and any
related showing flags like isShowingTranslation = false if present) so
TranslationControlState.ERROR becomes reachable; alternatively remove the
translatedText == null check from TranslationState.controlState if you prefer
showing errors regardless of stale text.

---

Nitpick comments:
In
`@feature/details/data/src/commonMain/kotlin/zed/rainxch/details/data/repository/TranslationRepositoryImpl.kt`:
- Around line 22-24: TranslationRepositoryImpl currently constructs its own
HttpClient via createPlatformHttpClient(ProxyConfig.None) instead of receiving
one from DI; change the constructor of TranslationRepositoryImpl to accept an
HttpClient parameter and use that instance instead of calling
createPlatformHttpClient, mirroring the pattern used by DetailsRepositoryImpl;
update any DI module/provider to bind and supply the shared HttpClient to
TranslationRepositoryImpl and remove the local createPlatformHttpClient usage to
ensure consistent lifecycle and testability.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a97b42a2-0ead-480b-808e-61e55308bbe4

📥 Commits

Reviewing files that changed from the base of the PR and between b4bb08e and ef87757.

📒 Files selected for processing (2)
  • feature/details/data/src/commonMain/kotlin/zed/rainxch/details/data/repository/TranslationRepositoryImpl.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt

Comment on lines +111 to +114
Icon(
imageVector = Icons.Default.GTranslate,
contentDescription = stringResource(Res.string.translate),
tint = MaterialTheme.colorScheme.onSurfaceVariant,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n "feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt"

Repository: OpenHub-Store/GitHub-Store

Length of output: 12451


Set contentDescription = null for decorative-leading icons adjacent to Text.

Icons at lines 113 and 237 duplicate the same spoken label already provided by adjacent Text components, causing repetitive TalkBack announcements. For decorative-leading icons in labeled controls, set contentDescription = null.

♿ Suggested fix
         Icon(
             imageVector = Icons.Default.GTranslate,
-            contentDescription = stringResource(Res.string.translate),
+            contentDescription = null,
             tint = MaterialTheme.colorScheme.onSurfaceVariant,
             modifier = Modifier.size(16.dp),
         )
@@
         Icon(
             imageVector = Icons.Default.Refresh,
-            contentDescription = stringResource(Res.string.translation_error_retry),
+            contentDescription = null,
             tint = MaterialTheme.colorScheme.onErrorContainer,
             modifier = Modifier.size(14.dp),
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt`
around lines 111 - 114, In TranslationControls (the composable in
TranslationControls.kt) the leading decorative Icon calls (e.g.,
Icon(imageVector = Icons.Default.GTranslate, ...) and the other leading icon
around line 237) duplicate the spoken label of adjacent Text, so change their
contentDescription values to null (contentDescription = null) to mark them
decorative; leave accessible labels on the surrounding Text controls unchanged
so screen readers announce the label once.

Comment on lines +280 to +287
private val TranslationState.controlState: TranslationControlState
get() =
when {
isTranslating -> TranslationControlState.TRANSLATING
error != null && translatedText == null -> TranslationControlState.ERROR
isShowingTranslation && translatedText != null -> TranslationControlState.SHOWING_TRANSLATION
!isShowingTranslation && translatedText != null -> TranslationControlState.SHOWING_ORIGINAL
else -> TranslationControlState.IDLE
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect how translation state fields are mutated across state model + viewmodel.
fd 'TranslationState.kt|DetailsViewModel.kt' feature/details | while read -r file; do
  echo "===== $file ====="
  rg -n -C3 '\b(isTranslating|isShowingTranslation|translatedText|error)\b' "$file"
done

Repository: OpenHub-Store/GitHub-Store

Length of output: 8488


🏁 Script executed:

cat -n feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt | sed -n '270,300p'

Repository: OpenHub-Store/GitHub-Store

Length of output: 851


🏁 Script executed:

rg -n 'isShowingTranslation|translatedText' feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt -A2 -B2 | head -100

Repository: OpenHub-Store/GitHub-Store

Length of output: 953


🏁 Script executed:

rg -n 'getCurrentState\(\)\.copy' feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt

Repository: OpenHub-Store/GitHub-Store

Length of output: 167


🏁 Script executed:

sed -n '1360,1370p' feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt

Repository: OpenHub-Store/GitHub-Store

Length of output: 452


🏁 Script executed:

sed -n '1394,1402p' feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt

Repository: OpenHub-Store/GitHub-Store

Length of output: 407


Clear stale translation text when error occurs.

The error state condition at line 284 requires translatedText == null to display, but translation failures do not clear the previous translation text (line 1397 in DetailsViewModel only sets error, not translatedText). When a retry fails after a successful translation, the stale text remains, so the ERROR state is unreachable and the error message is hidden behind the prior translation display.

Either:

  • Clear translatedText = null when translation fails (line 1397)
  • Remove the translatedText == null requirement from the error condition (line 284) so errors display regardless of stale data
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/TranslationControls.kt`
around lines 280 - 287, The error state in TranslationState.controlState
currently requires translatedText == null, but DetailsViewModel only sets error
on failure and leaves translatedText stale, so ERROR never shows; fix by
clearing the previous translation when a translation fails: in the
failure-handling branch inside DetailsViewModel where you set error (the
translation retry/failure handler), also set translatedText = null (and any
related showing flags like isShowingTranslation = false if present) so
TranslationControlState.ERROR becomes reachable; alternatively remove the
translatedText == null check from TranslationState.controlState if you prefer
showing errors regardless of stale text.

- Add `org.gradle.parallel=true` to `gradle.properties` to allow Gradle to execute tasks in parallel for decoupled projects.
- Create `.claude/memory/feedback_coding_boundaries.md` to establish guidelines for AI interaction.
- Specify that core implementation tasks—such as architecture, state management, and bug fixes—should be handled by the user.
- Define the AI's role as providing reviews, suggestions, and boilerplate code to ensure the user maintains technical ownership and skill proficiency.
- Add `animateContentSize()` to the `About` section to ensure smooth transitions during content updates
- Refactor `WhatsNew` section by extracting `ExpandableMarkdownContent` into a separate Composable function for better maintainability
- Ensure the `WhatsNew` markdown content properly utilizes `animateContentSize()` and `liquefiable` state
- Improve layout consistency in `WhatsNew` by wrapping the expandable content in a dedicated `item` block within the list view
@rainxchzed rainxchzed merged commit 75a5796 into main Mar 16, 2026
1 check was pending
@rainxchzed rainxchzed deleted the feat-translation branch March 16, 2026 04:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant