From 56429b4cb69427344f0ef4d4d367fa456faae4c6 Mon Sep 17 00:00:00 2001 From: rainxchzed Date: Sat, 28 Feb 2026 10:45:26 +0500 Subject: [PATCH 1/4] feat(details): Implement expandable sections and improved Markdown preprocessing This commit introduces expandable "About" and "What's New" sections in the repository details view to handle long READMEs and release notes. It also significantly enhances the Markdown preprocessing logic to better handle HTML-in-Markdown and GitHub-specific formatting. - **feat(details)**: Introduced `ExpandableMarkdownContent` component to provide "Read More" and "Show Less" functionality for long text blocks. - **feat(details)**: Added `isAboutExpanded` and `isWhatsNewExpanded` states to `DetailsState` along with corresponding toggle actions in `DetailsViewModel`. - **refactor(data)**: Extensively updated `preprocessMarkdown.kt` to handle various HTML tags (e.g., ``, `""", + setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL) + ) + ) { match -> + val src = match.groupValues[2] + "[Video]($src)" + } + + // 6. Convert HTML headings

→ markdown headings + for (level in 1..6) { + val hashes = "#".repeat(level) + processed = processed.replace( + Regex( + """]*>(.*?)""", + setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL) + ) + ) { match -> + val content = match.groupValues[1].trim() + "\n$hashes $content\n" } + } - if (isSvgUrl(finalUrl)) { - svgSkipped++ - if (alt.isNotEmpty()) { - "**$alt**" - } else { - "" - } + // 7. Convert
and
tags + processed = processed.replace( + Regex("""""", RegexOption.IGNORE_CASE), + "\n" + ) + processed = processed.replace( + Regex("""""", RegexOption.IGNORE_CASE), + "\n---\n" + ) + + // 8. Convert inline formatting tags + // / → **text** + processed = processed.replace( + Regex( + """<(b|strong)>(.*?)""", + setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL) + ) + ) { match -> + "**${match.groupValues[2]}**" + } + // / → *text* + processed = processed.replace( + Regex( + """<(i|em)>(.*?)""", + setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL) + ) + ) { match -> + "*${match.groupValues[2]}*" + } + // → `text` (single-line only, not
)
+    processed = processed.replace(
+        Regex(
+            """([^<]*?)""",
+            RegexOption.IGNORE_CASE
+        )
+    ) { match ->
+        "`${match.groupValues[1]}`"
+    }
+    //  /  /  → ~~text~~
+    processed = processed.replace(
+        Regex(
+            """<(s|del|strike)>(.*?)""",
+            setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)
+        )
+    ) { match ->
+        "~~${match.groupValues[2]}~~"
+    }
+
+    // 9. Convert text → [text](url) (non-image links)
+    processed = processed.replace(
+        Regex(
+            """]*?href=(["'])([^"']+)\1[^>]*>(.*?)""",
+            setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)
+        )
+    ) { match ->
+        val url = match.groupValues[2]
+        val text = match.groupValues[3].trim()
+        if (text.isEmpty()) {
+            "[$url]($url)"
         } else {
-            imageCount++
-            "![$alt]($finalUrl)"
+            "[$text]($url)"
         }
     }
 
+    // 10.  → `text`
+    processed = processed.replace(
+        Regex(
+            """(.*?)""",
+            setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)
+        )
+    ) { match ->
+        "`${match.groupValues[1]}`"
+    }
+
+    // 11. Strip remaining wrapper tags (keep content)
+    // 
and
processed = processed.replace( Regex("""]*?align=["']center["'][^>]*?>\s*""", RegexOption.IGNORE_CASE), "\n\n" @@ -94,21 +219,60 @@ fun preprocessMarkdown(markdown: String, baseUrl: String): String { Regex("""\s*""", RegexOption.IGNORE_CASE), "\n\n" ) + //

/

+ processed = processed.replace( + Regex("""]*?>""", RegexOption.IGNORE_CASE), + "\n" + ) + processed = processed.replace( + Regex("""

""", RegexOption.IGNORE_CASE), + "\n" + ) + //
/ + processed = processed.replace( + Regex("""]*?>""", RegexOption.IGNORE_CASE), + "\n" + ) + processed = processed.replace( + Regex("""
""", RegexOption.IGNORE_CASE), + "\n" + ) + processed = processed.replace( + Regex("""]*?>(.*?)""", setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)) + ) { match -> + "**${match.groupValues[1].trim()}**\n" + } + // , , — strip tags, keep content + processed = processed.replace( + Regex("""]*?>""", RegexOption.IGNORE_CASE), + "" + ) + // 12. Decode common HTML entities + processed = processed + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace(""", "\"") + .replace("'", "'") + .replace("'", "'") + .replace(" ", " ") + + // 13. Clean up empty

tags and excess newlines processed = processed.replace( Regex("""]*?>\s*

""", RegexOption.IGNORE_CASE), "" ) - processed = processed.replace( Regex("""\n{3,}"""), "\n\n" ) + // 14. Clean up orphaned markdown link fragments processed = processed.replace( Regex("""^\]\([^)]+\)""", RegexOption.MULTILINE), "" ) return processed -} \ No newline at end of file +} diff --git a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsAction.kt b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsAction.kt index cb8e2409..c7080867 100644 --- a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsAction.kt +++ b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsAction.kt @@ -38,4 +38,6 @@ sealed interface DetailsAction { data class SelectReleaseCategory(val category: ReleaseCategory) : DetailsAction data class SelectRelease(val release: GithubRelease) : DetailsAction data object ToggleVersionPicker : DetailsAction + data object ToggleAboutExpanded : DetailsAction + data object ToggleWhatsNewExpanded : DetailsAction } \ No newline at end of file diff --git a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt index 14b66097..a2d8a92c 100644 --- a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt +++ b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt @@ -240,12 +240,18 @@ fun DetailsScreen( state.readmeMarkdown?.let { about( readmeMarkdown = state.readmeMarkdown, - readmeLanguage = state.readmeLanguage + readmeLanguage = state.readmeLanguage, + isExpanded = state.isAboutExpanded, + onToggleExpanded = { onAction(DetailsAction.ToggleAboutExpanded) } ) } state.selectedRelease?.let { release -> - whatsNew(release) + whatsNew( + release = release, + isExpanded = state.isWhatsNewExpanded, + onToggleExpanded = { onAction(DetailsAction.ToggleWhatsNewExpanded) } + ) } state.userProfile?.let { userProfile -> diff --git a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsState.kt b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsState.kt index 91e2d166..4f90f517 100644 --- a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsState.kt +++ b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsState.kt @@ -54,6 +54,9 @@ data class DetailsState( val isFavourite: Boolean = false, val isStarred: Boolean = false, val isTrackingApp: Boolean = false, + + val isAboutExpanded: Boolean = false, + val isWhatsNewExpanded: Boolean = false, ) { /** * True when the app is detected as installed on the system (via assets matching) diff --git a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt index 5bdbb91f..755cf175 100644 --- a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt +++ b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt @@ -776,6 +776,18 @@ class DetailsViewModel( } } + DetailsAction.ToggleAboutExpanded -> { + _state.update { + it.copy(isAboutExpanded = !it.isAboutExpanded) + } + } + + DetailsAction.ToggleWhatsNewExpanded -> { + _state.update { + it.copy(isWhatsNewExpanded = !it.isWhatsNewExpanded) + } + } + DetailsAction.TrackExistingApp -> { val snapshot = _state.value if (snapshot.isTrackingApp || !snapshot.isTrackable) return diff --git a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/About.kt b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/About.kt index 4006b68b..882811c5 100644 --- a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/About.kt +++ b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/About.kt @@ -1,23 +1,39 @@ package zed.rainxch.details.presentation.components.sections +import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.mikepenz.markdown.compose.Markdown +import com.mikepenz.markdown.model.ImageTransformer import zed.rainxch.githubstore.core.presentation.res.* import io.github.fletchmckee.liquid.liquefiable import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor @@ -30,6 +46,8 @@ import zed.rainxch.details.presentation.utils.rememberMarkdownTypography fun LazyListScope.about( readmeMarkdown: String, readmeLanguage: String?, + isExpanded: Boolean, + onToggleExpanded: () -> Unit, ) { item { val liquidState = LocalTopbarLiquidState.current @@ -68,24 +86,97 @@ fun LazyListScope.about( item { val liquidState = LocalTopbarLiquidState.current - Surface( - color = Color.Transparent, - contentColor = MaterialTheme.colorScheme.onBackground + ExpandableMarkdownContent( + content = readmeMarkdown, + isExpanded = isExpanded, + onToggleExpanded = onToggleExpanded, + imageTransformer = MarkdownImageTransformer, + modifier = Modifier + .fillMaxWidth() + .liquefiable(liquidState), + ) + } +} + +@Composable +fun ExpandableMarkdownContent( + content: String, + isExpanded: Boolean, + onToggleExpanded: () -> Unit, + imageTransformer: ImageTransformer, + modifier: Modifier = Modifier, +) { + val density = LocalDensity.current + val colors = rememberMarkdownColors() + val typography = rememberMarkdownTypography() + val flavour = remember { GFMFlavourDescriptor() } + val surfaceColor = MaterialTheme.colorScheme.background + + BoxWithConstraints(modifier = modifier) { + val collapsedHeightDp = maxHeight * 0.7f + val collapsedHeightPx = with(density) { collapsedHeightDp.toPx() } + var contentHeightPx by remember { mutableStateOf(0f) } + val needsExpansion = contentHeightPx > collapsedHeightPx && collapsedHeightPx > 0f + + Column( + modifier = Modifier.animateContentSize() ) { - val colors = rememberMarkdownColors() - val typography = rememberMarkdownTypography() - val flavour = remember { GFMFlavourDescriptor() } + Box { + Surface( + color = Color.Transparent, + contentColor = MaterialTheme.colorScheme.onBackground, + modifier = if (!isExpanded && needsExpansion) { + Modifier.heightIn(max = collapsedHeightDp).clipToBounds() + } else { + Modifier + } + ) { + Markdown( + content = content, + colors = colors, + typography = typography, + flavour = flavour, + imageTransformer = imageTransformer, + modifier = Modifier + .fillMaxWidth() + .onGloballyPositioned { coordinates -> + contentHeightPx = coordinates.size.height.toFloat() + }, + ) + } - Markdown( - content = readmeMarkdown, - colors = colors, - typography = typography, - flavour = flavour, - imageTransformer = MarkdownImageTransformer, - modifier = Modifier - .fillMaxWidth() - .liquefiable(liquidState), - ) + if (!isExpanded && needsExpansion) { + Box( + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .height(80.dp) + .background( + Brush.verticalGradient( + 0f to surfaceColor.copy(alpha = 0f), + 1f to surfaceColor + ) + ) + ) + } + } + + if (needsExpansion) { + TextButton( + onClick = onToggleExpanded, + modifier = Modifier.align(Alignment.CenterHorizontally) + ) { + Text( + text = if (isExpanded) { + stringResource(Res.string.show_less) + } else { + stringResource(Res.string.read_more) + }, + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.primary + ) + } + } } } -} \ No newline at end of file +} diff --git a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt index 59b83af1..2c7c59e7 100644 --- a/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt +++ b/feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt @@ -1,11 +1,16 @@ package zed.rainxch.details.presentation.components.sections +import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.material3.Card @@ -13,9 +18,17 @@ import androidx.compose.material3.CardDefaults import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.mikepenz.markdown.coil3.Coil3ImageTransformerImpl @@ -29,7 +42,11 @@ import zed.rainxch.details.presentation.utils.LocalTopbarLiquidState import zed.rainxch.details.presentation.utils.rememberMarkdownColors import zed.rainxch.details.presentation.utils.rememberMarkdownTypography -fun LazyListScope.whatsNew(release: GithubRelease) { +fun LazyListScope.whatsNew( + release: GithubRelease, + isExpanded: Boolean, + onToggleExpanded: () -> Unit, +) { item { val liquidState = LocalTopbarLiquidState.current @@ -82,22 +99,82 @@ fun LazyListScope.whatsNew(release: GithubRelease) { Spacer(Modifier.height(12.dp)) + val density = LocalDensity.current val colors = rememberMarkdownColors() val typography = rememberMarkdownTypography() val flavour = remember { GFMFlavourDescriptor() } + val cardColor = MaterialTheme.colorScheme.surfaceContainerLow - Markdown( - content = release.description ?: stringResource(Res.string.no_release_notes), - colors = colors, - typography = typography, - flavour = flavour, - imageTransformer = Coil3ImageTransformerImpl, - modifier = Modifier - .fillMaxWidth() - .liquefiable(liquidState), - ) + BoxWithConstraints( + modifier = Modifier.fillMaxWidth() + ) { + val collapsedHeightDp = maxHeight * 0.7f + val collapsedHeightPx = with(density) { collapsedHeightDp.toPx() } + var contentHeightPx by remember { mutableStateOf(0f) } + val needsExpansion = contentHeightPx > collapsedHeightPx && collapsedHeightPx > 0f + + Column( + modifier = Modifier.animateContentSize() + ) { + Box { + Box( + modifier = if (!isExpanded && needsExpansion) { + Modifier.heightIn(max = collapsedHeightDp).clipToBounds() + } else { + Modifier + } + ) { + Markdown( + content = release.description + ?: stringResource(Res.string.no_release_notes), + colors = colors, + typography = typography, + flavour = flavour, + imageTransformer = Coil3ImageTransformerImpl, + modifier = Modifier + .fillMaxWidth() + .liquefiable(liquidState) + .onGloballyPositioned { coordinates -> + contentHeightPx = coordinates.size.height.toFloat() + }, + ) + } + + if (!isExpanded && needsExpansion) { + Box( + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .height(80.dp) + .background( + Brush.verticalGradient( + 0f to cardColor.copy(alpha = 0f), + 1f to cardColor + ) + ) + ) + } + } + + if (needsExpansion) { + TextButton( + onClick = onToggleExpanded, + modifier = Modifier.align(Alignment.CenterHorizontally) + ) { + Text( + text = if (isExpanded) { + stringResource(Res.string.show_less) + } else { + stringResource(Res.string.read_more) + }, + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.primary + ) + } + } + } + } } } } } - From fe0e7f777d0f393e86db10626ad941a1cf261e5b Mon Sep 17 00:00:00 2001 From: rainxchzed Date: Sat, 28 Feb 2026 10:45:38 +0500 Subject: [PATCH 2/4] i18n: Add "Read More" and "Show Less" strings in multiple languages This commit adds localized string resources for the "Read More" and "Show Less" labels across several languages to support UI components with expandable text. - **i18n**: Added `read_more` and `show_less` string resources to Turkish (tr), Spanish (es), Chinese (zh-rCN), French (fr), Hindi (hi), Italian (it), Japanese (ja), Korean (kr), Polish (pl), Bengali (bn), and Russian (ru) locales. --- .../src/commonMain/composeResources/values-bn/strings-bn.xml | 4 ++++ .../src/commonMain/composeResources/values-es/strings-es.xml | 4 ++++ .../src/commonMain/composeResources/values-fr/strings-fr.xml | 4 ++++ .../src/commonMain/composeResources/values-hi/strings-hi.xml | 4 ++++ .../src/commonMain/composeResources/values-it/strings-it.xml | 4 ++++ .../src/commonMain/composeResources/values-ja/strings-ja.xml | 4 ++++ .../src/commonMain/composeResources/values-kr/strings-kr.xml | 4 ++++ .../src/commonMain/composeResources/values-pl/strings-pl.xml | 4 ++++ .../src/commonMain/composeResources/values-ru/strings-ru.xml | 4 ++++ .../src/commonMain/composeResources/values-tr/strings-tr.xml | 4 ++++ .../composeResources/values-zh-rCN/strings-zh-rCN.xml | 4 ++++ 11 files changed, 44 insertions(+) diff --git a/core/presentation/src/commonMain/composeResources/values-bn/strings-bn.xml b/core/presentation/src/commonMain/composeResources/values-bn/strings-bn.xml index 671e6bc6..0c723b23 100644 --- a/core/presentation/src/commonMain/composeResources/values-bn/strings-bn.xml +++ b/core/presentation/src/commonMain/composeResources/values-bn/strings-bn.xml @@ -420,4 +420,8 @@ অনুগ্রহ করে আপনার ইন্টারনেট সংযোগ পরীক্ষা করুন এবং আবার চেষ্টা করুন। আপনি অনুমোদনের অনুরোধ প্রত্যাখ্যান করেছেন। এটি অনিচ্ছাকৃত হলে আবার চেষ্টা করুন। + + আরও পড়ুন + কম দেখান + diff --git a/core/presentation/src/commonMain/composeResources/values-es/strings-es.xml b/core/presentation/src/commonMain/composeResources/values-es/strings-es.xml index 29367d9b..a13f3f07 100644 --- a/core/presentation/src/commonMain/composeResources/values-es/strings-es.xml +++ b/core/presentation/src/commonMain/composeResources/values-es/strings-es.xml @@ -385,4 +385,8 @@ Revisa tu conexión a internet e intenta de nuevo. Rechazaste la solicitud de autorización. Intenta de nuevo si fue involuntario. + + Leer más + Mostrar menos + \ No newline at end of file diff --git a/core/presentation/src/commonMain/composeResources/values-fr/strings-fr.xml b/core/presentation/src/commonMain/composeResources/values-fr/strings-fr.xml index 61422b74..65b1d36f 100644 --- a/core/presentation/src/commonMain/composeResources/values-fr/strings-fr.xml +++ b/core/presentation/src/commonMain/composeResources/values-fr/strings-fr.xml @@ -385,4 +385,8 @@ Vérifiez votre connexion internet et réessayez. Vous avez refusé la demande d\'autorisation. Réessayez si c\'était involontaire. + + Lire la suite + Afficher moins + \ No newline at end of file diff --git a/core/presentation/src/commonMain/composeResources/values-hi/strings-hi.xml b/core/presentation/src/commonMain/composeResources/values-hi/strings-hi.xml index e42699d6..2816abff 100644 --- a/core/presentation/src/commonMain/composeResources/values-hi/strings-hi.xml +++ b/core/presentation/src/commonMain/composeResources/values-hi/strings-hi.xml @@ -420,4 +420,8 @@ कृपया अपना इंटरनेट कनेक्शन जाँचें और पुनः प्रयास करें। आपने प्राधिकरण अनुरोध अस्वीकार कर दिया। यदि यह अनजाने में हुआ तो पुनः प्रयास करें। + + और पढ़ें + कम दिखाएं + diff --git a/core/presentation/src/commonMain/composeResources/values-it/strings-it.xml b/core/presentation/src/commonMain/composeResources/values-it/strings-it.xml index 8c0c1c23..5f497459 100644 --- a/core/presentation/src/commonMain/composeResources/values-it/strings-it.xml +++ b/core/presentation/src/commonMain/composeResources/values-it/strings-it.xml @@ -421,4 +421,8 @@ Controlla la tua connessione internet e riprova. Hai rifiutato la richiesta di autorizzazione. Riprova se è stato involontario. + + Leggi di più + Mostra meno + \ No newline at end of file diff --git a/core/presentation/src/commonMain/composeResources/values-ja/strings-ja.xml b/core/presentation/src/commonMain/composeResources/values-ja/strings-ja.xml index 2f77ab29..19c11992 100644 --- a/core/presentation/src/commonMain/composeResources/values-ja/strings-ja.xml +++ b/core/presentation/src/commonMain/composeResources/values-ja/strings-ja.xml @@ -384,4 +384,8 @@ 新しいコードを取得するために再度サインインしてください。 インターネット接続を確認して再試行してください。 認証リクエストを拒否しました。意図しない場合は再試行してください。 + + もっと読む + 折りたたむ + \ No newline at end of file diff --git a/core/presentation/src/commonMain/composeResources/values-kr/strings-kr.xml b/core/presentation/src/commonMain/composeResources/values-kr/strings-kr.xml index ea518a21..7c87267f 100644 --- a/core/presentation/src/commonMain/composeResources/values-kr/strings-kr.xml +++ b/core/presentation/src/commonMain/composeResources/values-kr/strings-kr.xml @@ -417,4 +417,8 @@ 새 코드를 받으려면 다시 로그인해 주세요. 인터넷 연결을 확인하고 다시 시도하세요. 인증 요청을 거부했습니다. 의도하지 않은 경우 다시 시도하세요. + + 더 보기 + 간략히 + \ No newline at end of file diff --git a/core/presentation/src/commonMain/composeResources/values-pl/strings-pl.xml b/core/presentation/src/commonMain/composeResources/values-pl/strings-pl.xml index 894f0dd0..30b15c95 100644 --- a/core/presentation/src/commonMain/composeResources/values-pl/strings-pl.xml +++ b/core/presentation/src/commonMain/composeResources/values-pl/strings-pl.xml @@ -383,4 +383,8 @@ Sprawdź połączenie internetowe i spróbuj ponownie. Odrzuciłeś żądanie autoryzacji. Spróbuj ponownie, jeśli było to niezamierzone. + + Czytaj więcej + Pokaż mniej + \ No newline at end of file diff --git a/core/presentation/src/commonMain/composeResources/values-ru/strings-ru.xml b/core/presentation/src/commonMain/composeResources/values-ru/strings-ru.xml index 045bbff8..156aa7db 100644 --- a/core/presentation/src/commonMain/composeResources/values-ru/strings-ru.xml +++ b/core/presentation/src/commonMain/composeResources/values-ru/strings-ru.xml @@ -385,4 +385,8 @@ Проверьте подключение к интернету и попробуйте снова. Вы отклонили запрос авторизации. Попробуйте снова, если это было непреднамеренно. + + Читать далее + Свернуть + \ No newline at end of file diff --git a/core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml b/core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml index 8f4fa07b..1675f4d8 100644 --- a/core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml +++ b/core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml @@ -417,4 +417,8 @@ Lütfen internet bağlantınızı kontrol edin ve tekrar deneyin. Yetkilendirme isteğini reddettiniz. İstemeden yaptıysanız tekrar deneyin. + + Devamını oku + Daha az göster + diff --git a/core/presentation/src/commonMain/composeResources/values-zh-rCN/strings-zh-rCN.xml b/core/presentation/src/commonMain/composeResources/values-zh-rCN/strings-zh-rCN.xml index 918ea9cb..55361385 100644 --- a/core/presentation/src/commonMain/composeResources/values-zh-rCN/strings-zh-rCN.xml +++ b/core/presentation/src/commonMain/composeResources/values-zh-rCN/strings-zh-rCN.xml @@ -385,4 +385,8 @@ 请重新登录以获取新的验证码。 请检查您的网络连接并重试。 您拒绝了授权请求。如果是误操作,请重试。 + + 阅读更多 + 收起 + \ No newline at end of file From 40a4e8ac6fd746ebfb9250c041aabbbef06a6711 Mon Sep 17 00:00:00 2001 From: rainxchzed Date: Sat, 28 Feb 2026 16:07:57 +0500 Subject: [PATCH 3/4] feat(details): enhance Markdown processing and UI expansion logic This commit significantly improves the Markdown preprocessing for repository descriptions and READMEs. It introduces more robust URL resolution, better handling of HTML-to-Markdown conversions, and filters out SVGs/badges to keep the UI clean. Additionally, it refines the "Read More" expansion logic in the UI by centralizing height constraints. - **feat(data)**: Overhauled `preprocessMarkdown` with support for reference-style links/images, better HTML tag stripping (e.g., ``, `