From 11bcbcf1241c9f032858e49b6502a092e7fffa64 Mon Sep 17 00:00:00 2001 From: Marko Kocic Date: Thu, 12 Dec 2024 14:41:36 +0100 Subject: [PATCH 1/2] Implement hide/show highlights context option on ArticleDetailsScreen --- .../articles/feed/ui/ArticleDropdownMenu.kt | 22 ++++ .../core/compose/icons/__PrimalIcons.kt | 8 ++ .../ContextHideHighlightsOutlined.kt | 85 ++++++++++++++ .../ContextShowHighlightsOutlined.kt | 108 ++++++++++++++++++ .../compose/icons/primaliconpack/Highlight.kt | 60 ++++++++++ .../icons/primaliconpack/RemoveHighlight.kt | 71 ++++++++++++ .../details/ArticleDetailsContract.kt | 3 + .../articles/details/ArticleDetailsScreen.kt | 7 ++ .../details/ArticleDetailsViewModel.kt | 1 + .../details/ui/ArticleDetailsHeader.kt | 1 + .../details/ui/rendering/MarkdownRenderer.kt | 3 +- app/src/main/res/values/strings.xml | 2 + 12 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextHideHighlightsOutlined.kt create mode 100644 app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextShowHighlightsOutlined.kt create mode 100644 app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/Highlight.kt create mode 100644 app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/RemoveHighlight.kt diff --git a/app/src/main/kotlin/net/primal/android/articles/feed/ui/ArticleDropdownMenu.kt b/app/src/main/kotlin/net/primal/android/articles/feed/ui/ArticleDropdownMenu.kt index ea1ec0840..1614684f6 100644 --- a/app/src/main/kotlin/net/primal/android/articles/feed/ui/ArticleDropdownMenu.kt +++ b/app/src/main/kotlin/net/primal/android/articles/feed/ui/ArticleDropdownMenu.kt @@ -25,10 +25,12 @@ import net.primal.android.core.compose.icons.primaliconpack.ContextCopyNoteLink import net.primal.android.core.compose.icons.primaliconpack.ContextCopyNoteText import net.primal.android.core.compose.icons.primaliconpack.ContextCopyPublicKey import net.primal.android.core.compose.icons.primaliconpack.ContextCopyRawData +import net.primal.android.core.compose.icons.primaliconpack.ContextHideHighlightsOutlined import net.primal.android.core.compose.icons.primaliconpack.ContextMuteUser import net.primal.android.core.compose.icons.primaliconpack.ContextRemoveBookmark import net.primal.android.core.compose.icons.primaliconpack.ContextReportUser import net.primal.android.core.compose.icons.primaliconpack.ContextShare +import net.primal.android.core.compose.icons.primaliconpack.ContextShowHighlightsOutlined import net.primal.android.core.utils.copyText import net.primal.android.core.utils.resolvePrimalArticleLink import net.primal.android.core.utils.systemShareText @@ -50,6 +52,8 @@ fun ArticleDropdownMenuIcon( authorId: String, isBookmarked: Boolean, enabled: Boolean = true, + showHighlights: Boolean? = null, + onToggleHighlightsClick: (() -> Unit)? = null, onBookmarkClick: (() -> Unit)? = null, onMuteUserClick: (() -> Unit)? = null, onReportContentClick: ((reportType: ReportType) -> Unit)? = null, @@ -103,6 +107,24 @@ fun ArticleDropdownMenuIcon( menuVisible = false }, ) + if (showHighlights != null) { + DropdownPrimalMenuItem( + trailingIconVector = if (showHighlights) { + PrimalIcons.ContextHideHighlightsOutlined + } else { + PrimalIcons.ContextShowHighlightsOutlined + }, + text = if (showHighlights) { + stringResource(id = R.string.article_feed_context_hide_highglights) + } else { + stringResource(id = R.string.article_feed_context_show_highglights) + }, + onClick = { + onToggleHighlightsClick?.invoke() + menuVisible = false + }, + ) + } DropdownPrimalMenuItem( trailingIconVector = PrimalIcons.ContextCopyNoteLink, text = stringResource(id = R.string.article_feed_context_copy_article_link), diff --git a/app/src/main/kotlin/net/primal/android/core/compose/icons/__PrimalIcons.kt b/app/src/main/kotlin/net/primal/android/core/compose/icons/__PrimalIcons.kt index 9ad69116e..a4ed259b3 100644 --- a/app/src/main/kotlin/net/primal/android/core/compose/icons/__PrimalIcons.kt +++ b/app/src/main/kotlin/net/primal/android/core/compose/icons/__PrimalIcons.kt @@ -19,11 +19,13 @@ import net.primal.android.core.compose.icons.primaliconpack.ContextCopyNoteLink import net.primal.android.core.compose.icons.primaliconpack.ContextCopyNoteText import net.primal.android.core.compose.icons.primaliconpack.ContextCopyPublicKey import net.primal.android.core.compose.icons.primaliconpack.ContextCopyRawData +import net.primal.android.core.compose.icons.primaliconpack.ContextHideHighlightsOutlined import net.primal.android.core.compose.icons.primaliconpack.ContextMuteConversation import net.primal.android.core.compose.icons.primaliconpack.ContextMuteUser import net.primal.android.core.compose.icons.primaliconpack.ContextRemoveBookmark import net.primal.android.core.compose.icons.primaliconpack.ContextReportUser import net.primal.android.core.compose.icons.primaliconpack.ContextShare +import net.primal.android.core.compose.icons.primaliconpack.ContextShowHighlightsOutlined import net.primal.android.core.compose.icons.primaliconpack.Copy import net.primal.android.core.compose.icons.primaliconpack.CopyAlt import net.primal.android.core.compose.icons.primaliconpack.DarkMode @@ -64,6 +66,7 @@ import net.primal.android.core.compose.icons.primaliconpack.FeedZapsFilled import net.primal.android.core.compose.icons.primaliconpack.FontSize import net.primal.android.core.compose.icons.primaliconpack.GenericLinkIcon import net.primal.android.core.compose.icons.primaliconpack.Help +import net.primal.android.core.compose.icons.primaliconpack.Highlight import net.primal.android.core.compose.icons.primaliconpack.Home import net.primal.android.core.compose.icons.primaliconpack.HomeFilled import net.primal.android.core.compose.icons.primaliconpack.ImportPhotoFromCamera @@ -111,6 +114,7 @@ import net.primal.android.core.compose.icons.primaliconpack.PrimalPremium import net.primal.android.core.compose.icons.primaliconpack.QrCode import net.primal.android.core.compose.icons.primaliconpack.Quote import net.primal.android.core.compose.icons.primaliconpack.Read +import net.primal.android.core.compose.icons.primaliconpack.RemoveHighlight import net.primal.android.core.compose.icons.primaliconpack.Report import net.primal.android.core.compose.icons.primaliconpack.Repost import net.primal.android.core.compose.icons.primaliconpack.Search @@ -198,8 +202,12 @@ val PrimalIcons.PrimalIcons: ____KtList Zap, Repost, Quote, + Highlight, + RemoveHighlight, ContextCopyNoteLink, ContextCopyNoteId, + ContextShowHighlightsOutlined, + ContextHideHighlightsOutlined, ContextCopyPublicKey, ContextReportUser, ContextCopyRawData, diff --git a/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextHideHighlightsOutlined.kt b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextHideHighlightsOutlined.kt new file mode 100644 index 000000000..456c3f65f --- /dev/null +++ b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextHideHighlightsOutlined.kt @@ -0,0 +1,85 @@ +package net.primal.android.core.compose.icons.primaliconpack + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathFillType +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.unit.dp +import net.primal.android.core.compose.icons.PrimalIcons +import kotlin.Suppress + +val PrimalIcons.ContextHideHighlightsOutlined: ImageVector + get() { + if (_ContextHideHighlightsOutlined != null) { + return _ContextHideHighlightsOutlined!! + } + _ContextHideHighlightsOutlined = ImageVector.Builder( + name = "ContextHideHighlightsOutlined", + defaultWidth = 20.dp, + defaultHeight = 20.dp, + viewportWidth = 20f, + viewportHeight = 20f + ).apply { + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(0.251f, 1.443f) + curveTo(-0.084f, 1.113f, -0.084f, 0.578f, 0.251f, 0.248f) + curveTo(0.586f, -0.083f, 1.128f, -0.083f, 1.463f, 0.248f) + lineTo(19.749f, 18.276f) + curveTo(20.084f, 18.606f, 20.084f, 19.141f, 19.749f, 19.471f) + curveTo(19.414f, 19.801f, 18.872f, 19.801f, 18.537f, 19.471f) + lineTo(0.251f, 1.443f) + close() + } + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(4.643f, 7.81f) + lineTo(3.387f, 8.671f) + curveTo(1.915f, 9.681f, 1.516f, 11.573f, 2.307f, 13.039f) + curveTo(2.465f, 13.332f, 2.67f, 13.608f, 2.923f, 13.856f) + lineTo(6.884f, 17.738f) + curveTo(7.137f, 17.987f, 7.419f, 18.188f, 7.717f, 18.343f) + curveTo(9.213f, 19.118f, 11.143f, 18.727f, 12.174f, 17.284f) + lineTo(13.033f, 16.081f) + lineTo(11.951f, 15.015f) + lineTo(10.953f, 16.413f) + curveTo(10.256f, 17.389f, 8.804f, 17.52f, 7.934f, 16.667f) + lineTo(3.973f, 12.785f) + curveTo(3.129f, 11.957f, 3.243f, 10.589f, 4.235f, 9.908f) + lineTo(5.731f, 8.882f) + lineTo(4.643f, 7.81f) + close() + } + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(9.26f, 6.461f) + lineTo(8.172f, 5.388f) + lineTo(13.5f, 1.732f) + curveTo(15.142f, 0.605f, 17.373f, 0.797f, 18.79f, 2.186f) + curveTo(20.207f, 3.575f, 20.403f, 5.761f, 19.253f, 7.371f) + lineTo(15.506f, 12.618f) + lineTo(14.424f, 11.552f) + lineTo(18.033f, 6.499f) + curveTo(18.75f, 5.494f, 18.632f, 4.132f, 17.74f, 3.257f) + curveTo(16.837f, 2.372f, 15.403f, 2.246f, 14.349f, 2.969f) + lineTo(9.26f, 6.461f) + close() + } + path( + fill = SolidColor(Color(0xFFFFFFFF)), + pathFillType = PathFillType.EvenOdd + ) { + moveTo(5.242f, 18.668f) + lineTo(5.72f, 18.199f) + lineTo(2.453f, 14.997f) + lineTo(0.341f, 17.067f) + curveTo(-0.387f, 17.78f, 0.128f, 19f, 1.158f, 19f) + lineTo(4.425f, 19f) + curveTo(4.731f, 19f, 5.025f, 18.881f, 5.242f, 18.668f) + close() + } + }.build() + + return _ContextHideHighlightsOutlined!! + } + +@Suppress("ObjectPropertyName") +private var _ContextHideHighlightsOutlined: ImageVector? = null diff --git a/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextShowHighlightsOutlined.kt b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextShowHighlightsOutlined.kt new file mode 100644 index 000000000..57bdf5a15 --- /dev/null +++ b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/ContextShowHighlightsOutlined.kt @@ -0,0 +1,108 @@ +package net.primal.android.core.compose.icons.primaliconpack + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathFillType +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.unit.dp +import net.primal.android.core.compose.icons.PrimalIcons +import kotlin.Suppress + +val PrimalIcons.ContextShowHighlightsOutlined: ImageVector + get() { + if (_ContextShowHighlightsOutlined != null) { + return _ContextShowHighlightsOutlined!! + } + _ContextShowHighlightsOutlined = ImageVector.Builder( + name = "ContextShowHighlightsOutlined", + defaultWidth = 20.dp, + defaultHeight = 20.dp, + viewportWidth = 20f, + viewportHeight = 20f + ).apply { + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(4.643f, 7.81f) + lineTo(3.387f, 8.671f) + curveTo(1.915f, 9.681f, 1.516f, 11.573f, 2.307f, 13.039f) + curveTo(2.465f, 13.332f, 2.67f, 13.608f, 2.923f, 13.856f) + lineTo(6.884f, 17.738f) + curveTo(7.137f, 17.987f, 7.419f, 18.188f, 7.717f, 18.343f) + curveTo(9.213f, 19.118f, 11.143f, 18.727f, 12.174f, 17.284f) + lineTo(13.033f, 16.081f) + lineTo(11.951f, 15.015f) + lineTo(10.953f, 16.413f) + curveTo(10.256f, 17.389f, 8.804f, 17.52f, 7.934f, 16.667f) + lineTo(3.973f, 12.785f) + curveTo(3.129f, 11.957f, 3.243f, 10.589f, 4.235f, 9.908f) + lineTo(5.731f, 8.882f) + lineTo(4.643f, 7.81f) + close() + } + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(9.26f, 6.461f) + lineTo(8.172f, 5.388f) + lineTo(13.5f, 1.732f) + curveTo(15.142f, 0.605f, 17.373f, 0.797f, 18.79f, 2.186f) + curveTo(20.207f, 3.575f, 20.403f, 5.761f, 19.253f, 7.371f) + lineTo(15.506f, 12.618f) + lineTo(14.424f, 11.552f) + lineTo(18.033f, 6.499f) + curveTo(18.75f, 5.494f, 18.632f, 4.132f, 17.74f, 3.257f) + curveTo(16.837f, 2.372f, 15.403f, 2.246f, 14.349f, 2.969f) + lineTo(9.26f, 6.461f) + close() + } + path( + fill = SolidColor(Color(0xFFFFFFFF)), + pathFillType = PathFillType.EvenOdd + ) { + moveTo(5.242f, 18.668f) + lineTo(5.72f, 18.199f) + lineTo(2.453f, 14.997f) + lineTo(0.341f, 17.067f) + curveTo(-0.387f, 17.78f, 0.128f, 19f, 1.158f, 19f) + lineTo(4.425f, 19f) + curveTo(4.731f, 19f, 5.025f, 18.881f, 5.242f, 18.668f) + close() + } + path( + fill = SolidColor(Color(0xFFFFFFFF)), + pathFillType = PathFillType.EvenOdd + ) { + moveTo(5.72f, 18.199f) + lineTo(5.242f, 18.668f) + curveTo(5.025f, 18.881f, 4.731f, 19f, 4.425f, 19f) + lineTo(1.158f, 19f) + curveTo(0.128f, 19f, -0.387f, 17.78f, 0.341f, 17.067f) + lineTo(2.453f, 14.997f) + lineTo(5.72f, 18.199f) + close() + moveTo(7.717f, 18.343f) + curveTo(9.213f, 19.118f, 11.143f, 18.727f, 12.174f, 17.284f) + lineTo(19.253f, 7.371f) + curveTo(20.403f, 5.761f, 20.207f, 3.575f, 18.79f, 2.186f) + curveTo(17.373f, 0.797f, 15.142f, 0.605f, 13.5f, 1.732f) + lineTo(3.387f, 8.671f) + curveTo(1.915f, 9.681f, 1.516f, 11.573f, 2.307f, 13.039f) + curveTo(2.465f, 13.332f, 2.67f, 13.608f, 2.923f, 13.856f) + lineTo(6.884f, 17.738f) + curveTo(7.137f, 17.987f, 7.419f, 18.188f, 7.717f, 18.343f) + close() + moveTo(17.74f, 3.257f) + curveTo(16.837f, 2.372f, 15.403f, 2.246f, 14.349f, 2.969f) + lineTo(4.235f, 9.908f) + curveTo(3.243f, 10.589f, 3.129f, 11.957f, 3.973f, 12.785f) + lineTo(7.934f, 16.667f) + curveTo(8.804f, 17.52f, 10.256f, 17.389f, 10.953f, 16.413f) + lineTo(18.033f, 6.499f) + curveTo(18.75f, 5.494f, 18.632f, 4.132f, 17.74f, 3.257f) + close() + } + }.build() + + return _ContextShowHighlightsOutlined!! + } + +@Suppress("ObjectPropertyName") +private var _ContextShowHighlightsOutlined: ImageVector? = null diff --git a/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/Highlight.kt b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/Highlight.kt new file mode 100644 index 000000000..4b929bb03 --- /dev/null +++ b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/Highlight.kt @@ -0,0 +1,60 @@ +package net.primal.android.core.compose.icons.primaliconpack + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathFillType +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.unit.dp +import net.primal.android.core.compose.icons.PrimalIcons +import kotlin.Suppress + +val PrimalIcons.Highlight: ImageVector + get() { + if (_Highlight != null) { + return _Highlight!! + } + _Highlight = ImageVector.Builder( + name = "Highlight", + defaultWidth = 20.dp, + defaultHeight = 20.dp, + viewportWidth = 20f, + viewportHeight = 20f + ).apply { + path( + fill = SolidColor(Color(0xFFFFFFFF)), + pathFillType = PathFillType.EvenOdd + ) { + moveTo(13.5f, 1.732f) + curveTo(15.142f, 0.605f, 17.373f, 0.797f, 18.79f, 2.186f) + curveTo(20.207f, 3.575f, 20.403f, 5.761f, 19.253f, 7.371f) + lineTo(12.174f, 17.284f) + curveTo(10.938f, 19.015f, 8.408f, 19.232f, 6.884f, 17.738f) + lineTo(2.923f, 13.856f) + curveTo(1.4f, 12.363f, 1.621f, 9.883f, 3.387f, 8.671f) + lineTo(13.5f, 1.732f) + close() + moveTo(11.438f, 13.395f) + curveTo(10.311f, 14.501f, 8.482f, 14.501f, 7.354f, 13.395f) + curveTo(6.226f, 12.29f, 6.226f, 10.497f, 7.354f, 9.392f) + curveTo(8.482f, 8.286f, 10.311f, 8.286f, 11.438f, 9.392f) + curveTo(12.566f, 10.497f, 12.566f, 12.29f, 11.438f, 13.395f) + close() + } + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(5.72f, 18.199f) + lineTo(2.453f, 14.997f) + lineTo(0.341f, 17.067f) + curveTo(-0.387f, 17.78f, 0.128f, 19f, 1.158f, 19f) + lineTo(4.425f, 19f) + curveTo(4.731f, 19f, 5.025f, 18.881f, 5.242f, 18.668f) + lineTo(5.72f, 18.199f) + close() + } + }.build() + + return _Highlight!! + } + +@Suppress("ObjectPropertyName") +private var _Highlight: ImageVector? = null diff --git a/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/RemoveHighlight.kt b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/RemoveHighlight.kt new file mode 100644 index 000000000..beb23d90d --- /dev/null +++ b/app/src/main/kotlin/net/primal/android/core/compose/icons/primaliconpack/RemoveHighlight.kt @@ -0,0 +1,71 @@ +package net.primal.android.core.compose.icons.primaliconpack + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.unit.dp +import net.primal.android.core.compose.icons.PrimalIcons +import kotlin.Suppress + +val PrimalIcons.RemoveHighlight: ImageVector + get() { + if (_RemoveHighlight != null) { + return _RemoveHighlight!! + } + _RemoveHighlight = ImageVector.Builder( + name = "RemoveHighlight", + defaultWidth = 20.dp, + defaultHeight = 20.dp, + viewportWidth = 20f, + viewportHeight = 20f + ).apply { + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(15.948f, 11.999f) + lineTo(19.253f, 7.371f) + curveTo(20.403f, 5.761f, 20.207f, 3.575f, 18.79f, 2.186f) + curveTo(17.373f, 0.797f, 15.142f, 0.605f, 13.5f, 1.732f) + lineTo(8.863f, 4.914f) + lineTo(15.948f, 11.999f) + close() + } + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(4.67f, 7.791f) + lineTo(3.387f, 8.671f) + curveTo(1.621f, 9.883f, 1.4f, 12.363f, 2.923f, 13.856f) + lineTo(6.884f, 17.738f) + curveTo(8.408f, 19.232f, 10.938f, 19.015f, 12.174f, 17.284f) + lineTo(13.002f, 16.124f) + lineTo(10.766f, 13.887f) + curveTo(9.672f, 14.465f, 8.278f, 14.301f, 7.354f, 13.395f) + curveTo(6.416f, 12.476f, 6.258f, 11.081f, 6.881f, 10.002f) + lineTo(4.67f, 7.791f) + close() + } + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(5.72f, 18.199f) + lineTo(2.453f, 14.997f) + lineTo(0.341f, 17.067f) + curveTo(-0.387f, 17.78f, 0.128f, 19f, 1.158f, 19f) + lineTo(4.425f, 19f) + curveTo(4.731f, 19f, 5.025f, 18.881f, 5.242f, 18.668f) + lineTo(5.72f, 18.199f) + close() + } + path(fill = SolidColor(Color(0xFFFFFFFF))) { + moveTo(1.707f, 1.293f) + curveTo(1.317f, 1.683f, 1.317f, 2.317f, 1.707f, 2.707f) + lineTo(17.971f, 18.971f) + curveTo(18.361f, 19.361f, 18.994f, 19.361f, 19.385f, 18.971f) + curveTo(19.775f, 18.58f, 19.775f, 17.947f, 19.385f, 17.556f) + lineTo(3.121f, 1.293f) + curveTo(2.731f, 0.902f, 2.098f, 0.902f, 1.707f, 1.293f) + close() + } + }.build() + + return _RemoveHighlight!! + } + +@Suppress("ObjectPropertyName") +private var _RemoveHighlight: ImageVector? = null diff --git a/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsContract.kt b/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsContract.kt index 89afb6f22..c798d5705 100644 --- a/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsContract.kt +++ b/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsContract.kt @@ -5,11 +5,13 @@ import net.primal.android.nostr.utils.Naddr import net.primal.android.notes.feed.model.FeedPostUi import net.primal.android.notes.feed.model.ZappingState import net.primal.android.stats.ui.EventZapUiModel +import net.primal.android.thread.articles.ArticleContract.UiEvent import net.primal.android.thread.articles.details.ui.ArticleDetailsUi interface ArticleDetailsContract { data class UiState( val naddr: Naddr? = null, + val showHighlights: Boolean = true, val isAuthorFollowed: Boolean = false, val article: ArticleDetailsUi? = null, val referencedNotes: List = emptyList(), @@ -33,5 +35,6 @@ interface ArticleDetailsContract { data object LikeArticle : UiEvent() data object RepostAction : UiEvent() data object ToggleAuthorFollows : UiEvent() + data object ToggleHighlights : UiEvent() } } diff --git a/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsScreen.kt b/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsScreen.kt index 73c662ec3..75d09ba10 100644 --- a/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsScreen.kt +++ b/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsScreen.kt @@ -250,6 +250,7 @@ private fun ArticleDetailsScreen( state = detailsState, scrolledToTop = scrolledToTop, onClose = onClose, + onToggleHighlightsClick = { detailsEventPublisher(UiEvent.ToggleHighlights) }, onBookmarkClick = { if (detailsState.article != null) { articleEventPublisher( @@ -287,6 +288,7 @@ private fun ArticleDetailsScreen( articleParts = articleParts, listState = listState, paddingValues = paddingValues, + showHighlights = detailsState.showHighlights, onArticleCommentClick = { detailsState.naddr?.toNaddrString()?.let { noteCallbacks.onArticleReplyClick?.invoke(it) } }, @@ -366,6 +368,7 @@ private fun ArticleDetailsTopAppBar( state: ArticleDetailsContract.UiState, scrolledToTop: Boolean, onClose: () -> Unit, + onToggleHighlightsClick: (() -> Unit)? = null, onBookmarkClick: (() -> Unit)? = null, onMuteUserClick: (() -> Unit)? = null, onReportContentClick: ((reportType: ReportType) -> Unit)? = null, @@ -393,6 +396,8 @@ private fun ArticleDetailsTopAppBar( articleRawData = state.article.eventRawNostrEvent, authorId = state.article.authorId, isBookmarked = state.article.isBookmarked, + showHighlights = state.showHighlights, + onToggleHighlightsClick = onToggleHighlightsClick, onBookmarkClick = onBookmarkClick, onMuteUserClick = onMuteUserClick, onReportContentClick = onReportContentClick, @@ -415,6 +420,7 @@ private fun ArticleContentWithComments( state: ArticleDetailsContract.UiState, articleParts: List, listState: LazyListState = rememberLazyListState(), + showHighlights: Boolean, paddingValues: PaddingValues, onArticleCommentClick: (naddr: String) -> Unit, onArticleHashtagClick: (hashtag: String) -> Unit, @@ -527,6 +533,7 @@ private fun ArticleContentWithComments( .fillMaxWidth() .padding(all = 16.dp), markdown = part.markdown, + showHighlights = showHighlights, highlights = state.article?.highlights ?: emptyList(), onProfileClick = noteCallbacks.onProfileClick, onNoteClick = noteCallbacks.onNoteClick, diff --git a/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsViewModel.kt b/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsViewModel.kt index 34d442982..2f8c91eca 100644 --- a/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsViewModel.kt +++ b/app/src/main/kotlin/net/primal/android/thread/articles/details/ArticleDetailsViewModel.kt @@ -89,6 +89,7 @@ class ArticleDetailsViewModel @Inject constructor( UiEvent.LikeArticle -> likeArticle() UiEvent.RepostAction -> repostPost() UiEvent.ToggleAuthorFollows -> followUnfollowAuthor() + UiEvent.ToggleHighlights -> setState { copy(showHighlights = !showHighlights) } } } } diff --git a/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/ArticleDetailsHeader.kt b/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/ArticleDetailsHeader.kt index 10f72adf6..15bec7a85 100644 --- a/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/ArticleDetailsHeader.kt +++ b/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/ArticleDetailsHeader.kt @@ -109,6 +109,7 @@ fun ArticleDetailsHeader( } }, markdown = summary, + showHighlights = false, ) } } diff --git a/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/rendering/MarkdownRenderer.kt b/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/rendering/MarkdownRenderer.kt index cc0cd67c6..ebe771e3e 100644 --- a/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/rendering/MarkdownRenderer.kt +++ b/app/src/main/kotlin/net/primal/android/thread/articles/details/ui/rendering/MarkdownRenderer.kt @@ -15,6 +15,7 @@ import net.primal.android.thread.articles.details.ui.handleArticleLinkClick @Composable fun MarkdownRenderer( markdown: String, + showHighlights: Boolean, modifier: Modifier = Modifier, highlights: List = emptyList(), onProfileClick: ((profileId: String) -> Unit)? = null, @@ -51,7 +52,7 @@ fun MarkdownRenderer( BasicMarkdown( astNode = astNode, astBlockNodeComposer = customBlockNodeComposer( - highlights = highlights, + highlights = if (showHighlights) highlights else emptyList(), onHighlightClick = onHighlightClick, ), ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2aa0fd0d1..6b6f749c3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1053,6 +1053,8 @@ Share article + Hide Highlights + Show Highlights Copy article link Add to Bookmarks Article added to your bookmarks. From 7a9a3c7ac5158a2725a24231ad4b95fb9534a29a Mon Sep 17 00:00:00 2001 From: Marko Kocic Date: Thu, 12 Dec 2024 14:44:41 +0100 Subject: [PATCH 2/2] Update detekt baseline --- app/detekt-baseline.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml index ae14bacfa..ca4085ace 100644 --- a/app/detekt-baseline.xml +++ b/app/detekt-baseline.xml @@ -3,7 +3,7 @@ ComplexCondition:NostrResources.kt$isNote() || isNoteUri() || isNEventUri() || isNEvent() - CyclomaticComplexMethod:ArticleDetailsScreen.kt$@OptIn(ExperimentalLayoutApi::class) @Composable private fun ArticleContentWithComments( state: ArticleDetailsContract.UiState, articleParts: List<ArticlePartRender>, listState: LazyListState = rememberLazyListState(), paddingValues: PaddingValues, onArticleCommentClick: (naddr: String) -> Unit, onArticleHashtagClick: (hashtag: String) -> Unit, onZapOptionsClick: () -> Unit, noteCallbacks: NoteCallbacks, onGoToWallet: () -> Unit, onPostAction: ((FeedPostAction) -> Unit)? = null, onPostLongPressAction: ((FeedPostAction) -> Unit)? = null, onFollowUnfollowClick: (() -> Unit)? = null, onUiError: ((UiError) -> Unit)? = null, ) + CyclomaticComplexMethod:ArticleDetailsScreen.kt$@OptIn(ExperimentalLayoutApi::class) @Composable private fun ArticleContentWithComments( state: ArticleDetailsContract.UiState, articleParts: List<ArticlePartRender>, listState: LazyListState = rememberLazyListState(), showHighlights: Boolean, paddingValues: PaddingValues, onArticleCommentClick: (naddr: String) -> Unit, onArticleHashtagClick: (hashtag: String) -> Unit, onZapOptionsClick: () -> Unit, noteCallbacks: NoteCallbacks, onGoToWallet: () -> Unit, onPostAction: ((FeedPostAction) -> Unit)? = null, onPostLongPressAction: ((FeedPostAction) -> Unit)? = null, onFollowUnfollowClick: (() -> Unit)? = null, onUiError: ((UiError) -> Unit)? = null, ) CyclomaticComplexMethod:ArticleDetailsScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable private fun ArticleDetailsScreen( detailsState: ArticleDetailsContract.UiState, articleState: ArticleContract.UiState, detailsEventPublisher: (UiEvent) -> Unit, articleEventPublisher: (ArticleContract.UiEvent) -> Unit, onArticleHashtagClick: (hashtag: String) -> Unit, noteCallbacks: NoteCallbacks, onGoToWallet: () -> Unit, onClose: () -> Unit, ) CyclomaticComplexMethod:ChatScreen.kt$@Composable private fun ChatMessageListItem( chatMessage: ChatMessageUi, previousMessage: ChatMessageUi? = null, nextMessage: ChatMessageUi? = null, onUrlClick: (String) -> Unit, noteCallbacks: NoteCallbacks, ) CyclomaticComplexMethod:CreateTransactionScreen.kt$@ExperimentalComposeUiApi @ExperimentalMaterial3Api @Composable fun CreateTransactionScreen( state: CreateTransactionContract.UiState, eventPublisher: (CreateTransactionContract.UiEvent) -> Unit, onClose: () -> Unit, ) @@ -33,11 +33,10 @@ CyclomaticComplexMethod:WalletDashboardScreen.kt$@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @Composable fun WalletDashboardScreen( state: WalletDashboardContract.UiState, onPrimaryDestinationChanged: (PrimalTopLevelDestination) -> Unit, onDrawerDestinationClick: (DrawerScreenDestination) -> Unit, onDrawerQrCodeClick: () -> Unit, onWalletActivateClick: () -> Unit, onProfileClick: (String) -> Unit, onTransactionClick: (String) -> Unit, onSendClick: () -> Unit, onScanClick: () -> Unit, onReceiveClick: () -> Unit, eventPublisher: (UiEvent) -> Unit, ) CyclomaticComplexMethod:WalletTransactionsMediator.kt$WalletTransactionsMediator$override suspend fun load(loadType: LoadType, state: PagingState<Int, WalletTransaction>): MediatorResult DestructuringDeclarationWithTooManyEntries:PrimalDrawer.kt$val (avatarRef, usernameRef, iconRef, identifierRef, statsRef) = createRefs() - LongMethod:ArticleDetailsScreen.kt$@OptIn(ExperimentalLayoutApi::class) @Composable private fun ArticleContentWithComments( state: ArticleDetailsContract.UiState, articleParts: List<ArticlePartRender>, listState: LazyListState = rememberLazyListState(), paddingValues: PaddingValues, onArticleCommentClick: (naddr: String) -> Unit, onArticleHashtagClick: (hashtag: String) -> Unit, onZapOptionsClick: () -> Unit, noteCallbacks: NoteCallbacks, onGoToWallet: () -> Unit, onPostAction: ((FeedPostAction) -> Unit)? = null, onPostLongPressAction: ((FeedPostAction) -> Unit)? = null, onFollowUnfollowClick: (() -> Unit)? = null, onUiError: ((UiError) -> Unit)? = null, ) + LongMethod:ArticleDetailsScreen.kt$@OptIn(ExperimentalLayoutApi::class) @Composable private fun ArticleContentWithComments( state: ArticleDetailsContract.UiState, articleParts: List<ArticlePartRender>, listState: LazyListState = rememberLazyListState(), showHighlights: Boolean, paddingValues: PaddingValues, onArticleCommentClick: (naddr: String) -> Unit, onArticleHashtagClick: (hashtag: String) -> Unit, onZapOptionsClick: () -> Unit, noteCallbacks: NoteCallbacks, onGoToWallet: () -> Unit, onPostAction: ((FeedPostAction) -> Unit)? = null, onPostLongPressAction: ((FeedPostAction) -> Unit)? = null, onFollowUnfollowClick: (() -> Unit)? = null, onUiError: ((UiError) -> Unit)? = null, ) LongMethod:ArticleDetailsScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable private fun ArticleDetailsScreen( detailsState: ArticleDetailsContract.UiState, articleState: ArticleContract.UiState, detailsEventPublisher: (UiEvent) -> Unit, articleEventPublisher: (ArticleContract.UiEvent) -> Unit, onArticleHashtagClick: (hashtag: String) -> Unit, noteCallbacks: NoteCallbacks, onGoToWallet: () -> Unit, onClose: () -> Unit, ) - LongMethod:ArticleDropdownMenu.kt$@ExperimentalMaterial3Api @Composable fun ArticleDropdownMenuIcon( modifier: Modifier, articleId: String, articleContent: String?, articleRawData: String?, authorId: String, isBookmarked: Boolean, enabled: Boolean = true, onBookmarkClick: (() -> Unit)? = null, onMuteUserClick: (() -> Unit)? = null, onReportContentClick: ((reportType: ReportType) -> Unit)? = null, icon: @Composable () -> Unit, ) + LongMethod:ArticleDropdownMenu.kt$@ExperimentalMaterial3Api @Composable fun ArticleDropdownMenuIcon( modifier: Modifier, articleId: String, articleContent: String?, articleRawData: String?, authorId: String, isBookmarked: Boolean, enabled: Boolean = true, showHighlights: Boolean? = null, onToggleHighlightsClick: (() -> Unit)? = null, onBookmarkClick: (() -> Unit)? = null, onMuteUserClick: (() -> Unit)? = null, onReportContentClick: ((reportType: ReportType) -> Unit)? = null, icon: @Composable () -> Unit, ) LongMethod:ArticleFeedList.kt$@ExperimentalMaterial3Api @ExperimentalFoundationApi @Composable private fun ArticleFeedLazyColumn( articleState: ArticleContract.UiState, pagingItems: LazyPagingItems<FeedArticleUi>, listState: LazyListState, showPaywall: Boolean, onArticleClick: (naddr: String) -> Unit, onGetPremiumClick: () -> Unit, articleEventPublisher: (ArticleContract.UiEvent) -> Unit, modifier: Modifier = Modifier, noContentText: String = stringResource(id = R.string.article_feed_no_content), noContentVerticalArrangement: Arrangement.Vertical = Arrangement.Center, noContentPaddingValues: PaddingValues = PaddingValues(all = 0.dp), contentPadding: PaddingValues = PaddingValues(all = 0.dp), header: @Composable (LazyItemScope.() -> Unit)? = null, stickyHeader: @Composable (LazyItemScope.() -> Unit)? = null, ) - LongMethod:BecomeLegendAmountStage.kt$@ExperimentalMaterial3Api @Composable fun BecomeLegendAmountStage( modifier: Modifier, state: PremiumBecomeLegendContract.UiState, eventPublisher: (PremiumBecomeLegendContract.UiEvent) -> Unit, onClose: () -> Unit, onNext: () -> Unit, ) LongMethod:ChatScreen.kt$@Composable private fun ChatList( messages: LazyPagingItems<ChatMessageUi>, noteCallbacks: NoteCallbacks, modifier: Modifier = Modifier, state: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), ) LongMethod:ChatScreen.kt$@Composable private fun ChatMessageListItem( chatMessage: ChatMessageUi, previousMessage: ChatMessageUi? = null, nextMessage: ChatMessageUi? = null, onUrlClick: (String) -> Unit, noteCallbacks: NoteCallbacks, ) LongMethod:ContentDisplaySettingsScreen.kt$@Composable @ExperimentalMaterial3Api private fun ContentDisplaySettingsScreen( state: ContentDisplaySettingsContract.UiState, onClose: () -> Unit, eventPublisher: (UiEvent) -> Unit, )