From 8fc15e164ae7d2a29239d2bd962e74f2dd3c9cc9 Mon Sep 17 00:00:00 2001 From: seiko <605590140@qq.com> Date: Thu, 30 Dec 2021 17:16:09 +0800 Subject: [PATCH 1/7] uncheck the timeline selection to prevent crashes --- .../twiderex/component/status/StatusText.kt | 19 ++++++++++++++++--- .../status/TimelineStatusComponent.kt | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt index 2eebe8771..e0b95fdbc 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt @@ -54,7 +54,8 @@ import com.twidere.twiderex.model.ui.UiStatus fun ColumnScope.StatusText( status: UiStatus, maxLines: Int = Int.MAX_VALUE, - showMastodonPoll: Boolean = true + showMastodonPoll: Boolean = true, + isSelectionAble: Boolean = true, ) { val expandable = status.platformType == PlatformType.Mastodon && status.spoilerText != null @@ -85,7 +86,19 @@ fun ColumnScope.StatusText( } AnimatedVisibility(visible = expanded) { Column { - SelectionContainer { + if (isSelectionAble) { + SelectionContainer { + HtmlText( + modifier = Modifier.fillMaxWidth(), + htmlText = status.htmlText, + maxLines = maxLines, + linkResolver = { href -> + status.resolveLink(href) + }, + positionWrapper = it + ) + } + } else { HtmlText( modifier = Modifier.fillMaxWidth(), htmlText = status.htmlText, @@ -93,7 +106,7 @@ fun ColumnScope.StatusText( linkResolver = { href -> status.resolveLink(href) }, - positionWrapper = it + positionWrapper = null ) } if (showMastodonPoll && status.platformType == PlatformType.Mastodon && status.poll != null) { diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt index dd8824d78..537495b76 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt @@ -161,7 +161,8 @@ private fun NormalStatus( Spacer(modifier = Modifier.height(NormalStatusDefaults.ContentSpacing)) } } - } + }, + isSelectionAble = false, ) } } @@ -368,6 +369,7 @@ fun StatusContent( lineUp: Boolean = false, threadStyle: StatusThreadStyle = StatusThreadStyle.NONE, footer: @Composable () -> Unit = {}, + isSelectionAble: Boolean = true, ) { val layoutDirection = LocalLayoutDirection.current val status = data.retweet ?: data @@ -462,14 +464,22 @@ fun StatusContent( when (type) { StatusContentType.Normal -> { Spacer(modifier = Modifier.height(StatusContentDefaults.Normal.BodySpacing)) - StatusBody(status, type = type) + StatusBody( + status = status, + type = type, + isSelectionAble = isSelectionAble, + ) } StatusContentType.Extend -> UserScreenName(status.user) } if (type == StatusContentType.Extend) { Column { Spacer(modifier = Modifier.height(StatusContentDefaults.Extend.BodySpacing)) - StatusBody(status = status, type = type) + StatusBody( + status = status, + type = type, + isSelectionAble = isSelectionAble + ) } } Column { @@ -530,9 +540,11 @@ object StatusContentDefaults { fun ColumnScope.StatusBody( status: UiStatus, type: StatusContentType, + isSelectionAble: Boolean, ) { StatusText( status = status, + isSelectionAble = isSelectionAble ) StatusBodyMedia(status) @@ -703,6 +715,7 @@ fun StatusQuote(quote: UiStatus) { StatusText( status = quote, maxLines = 5, + isSelectionAble = false ) StatusBodyMedia(status = quote) } From 971916a093a8d6673b56d6c6a3e11095982bb287 Mon Sep 17 00:00:00 2001 From: seiko <605590140@qq.com> Date: Thu, 30 Dec 2021 18:08:27 +0800 Subject: [PATCH 2/7] cleanup status action button --- .../component/status/StatusActions.kt | 88 +++++++++---------- .../status/TimelineStatusComponent.kt | 17 ++-- 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusActions.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusActions.kt index ca6d99888..f4d252db6 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusActions.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusActions.kt @@ -26,6 +26,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -75,14 +76,16 @@ fun ReplyButton( status: UiStatus, withNumber: Boolean = true, ) { - val navigator = LocalNavigator.current val icon = painterResource(res = com.twidere.twiderex.MR.files.ic_corner_up_left) val contentDescription = stringResource(res = com.twidere.twiderex.MR.strings.accessibility_common_status_actions_reply) + + val navigator = LocalNavigator.current val action = { navigator.compose(ComposeType.Reply, statusKey = status.statusKey) } - val data = status.retweet ?: status + if (withNumber) { + val data = status.retweet ?: status StatusActionButtonWithNumbers( modifier = modifier, icon = icon, @@ -388,55 +391,44 @@ private fun StatusActionButtonWithNumbers( onClick: () -> Unit, ) { val contentColor = color.copy(LocalContentAlpha.current) - Box( - modifier = modifier, + val source = remember { MutableInteractionSource() } + Row( + modifier = modifier + .defaultMinSize( + minHeight = ButtonDefaults.MinHeight + ) + .clickable( + onClick = onClick, + enabled = enabled, + interactionSource = source, + indication = null, + ) + .padding(StatusActionsDefaults.ContentPadding), + verticalAlignment = Alignment.CenterVertically, ) { - val source = remember { - MutableInteractionSource() - } - Row( + Icon( modifier = Modifier - .defaultMinSize( - minHeight = ButtonDefaults.MinHeight - ) - .clickable( - onClick = onClick, - enabled = enabled, - interactionSource = source, - indication = null, - ) - .padding(StatusActionsDefaults.ContentPadding), - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - modifier = Modifier - .size(MaterialTheme.typography.body1.fontSize.value.dp) - .indication( - source, - rememberRipple( - bounded = false, - radius = rippleSize - ) - ), - tint = contentColor, - painter = icon, - contentDescription = contentDescription, - ) - Row( - modifier = modifier - .weight(1f), - ) { - if (count > 0) { - Box(modifier = Modifier.width(4.dp)) - Text( - text = count.humanizedCount(), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.body2, - color = contentColor, + .size(MaterialTheme.typography.body1.fontSize.value.dp) + .indication( + source, + rememberRipple( + bounded = false, + radius = rippleSize ) - } - } + ), + tint = contentColor, + painter = icon, + contentDescription = contentDescription, + ) + if (count > 0) { + Spacer(modifier = Modifier.width(4.dp)) + Text( + text = count.humanizedCount(), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = MaterialTheme.typography.body2, + color = contentColor, + ) } } } diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt index 537495b76..16825a337 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt @@ -24,6 +24,7 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope @@ -153,10 +154,7 @@ private fun NormalStatus( footer = { Column { if (showActions) { - Row { - Spacer(modifier = Modifier.width(UserAvatarDefaults.AvatarSize)) - StatusActions(data) - } + StatusActions(data) } else { Spacer(modifier = Modifier.height(NormalStatusDefaults.ContentSpacing)) } @@ -323,10 +321,13 @@ private fun StatusActions(status: UiStatus) { CompositionLocalProvider( LocalContentAlpha provides ContentAlpha.medium, ) { - Row { - ReplyButton(modifier = Modifier.weight(1f), status = status) - RetweetButton(modifier = Modifier.weight(1f), status = status) - LikeButton(modifier = Modifier.weight(1f), status = status) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + ReplyButton(status = status) + RetweetButton(status = status) + LikeButton(status = status) ShareButton(status = status, compat = true) } } From 4a8ac769be60b395204e6de0f5948538f6c42ac8 Mon Sep 17 00:00:00 2001 From: seiko <605590140@qq.com> Date: Thu, 30 Dec 2021 18:10:03 +0800 Subject: [PATCH 3/7] use AnimatedContent to switch media --- .../status/TimelineStatusComponent.kt | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt index 16825a337..93af9ce03 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt @@ -20,7 +20,7 @@ */ package com.twidere.twiderex.component.status -import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.AnimatedContent import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -629,17 +629,16 @@ private fun ColumnScope.StatusBodyMedia( val navigator = LocalNavigator.current if (status.media.any()) { Spacer(modifier = Modifier.height(StatusBodyMediaDefaults.Spacing)) - AnimatedVisibility(visible = LocalDisplayPreferences.current.mediaPreview) { - StatusMediaComponent( - status = status, - ) - } - AnimatedVisibility(visible = !LocalDisplayPreferences.current.mediaPreview) { - CompositionLocalProvider( - LocalContentAlpha provides ContentAlpha.medium - ) { - MediaPreviewButton { - navigator.media(statusKey = status.statusKey) + AnimatedContent(LocalDisplayPreferences.current.mediaPreview) { mediaPreview -> + if (mediaPreview) { + StatusMediaComponent(status = status) + } else { + CompositionLocalProvider( + LocalContentAlpha provides ContentAlpha.medium + ) { + MediaPreviewButton { + navigator.media(statusKey = status.statusKey) + } } } } From 6dcadeb900dd8b8fe849ecdf2b7de40258ab6102 Mon Sep 17 00:00:00 2001 From: seiko <605590140@qq.com> Date: Thu, 30 Dec 2021 18:10:18 +0800 Subject: [PATCH 4/7] fixed height of MediaPreviewButton to avoid parent height by cutting --- .../twiderex/component/status/TimelineStatusComponent.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt index 93af9ce03..ae0915ce1 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/TimelineStatusComponent.kt @@ -666,7 +666,8 @@ fun MediaPreviewButton( onClick.invoke() } ) - .padding(4.dp) + .padding(horizontal = 4.dp) + .height(30.dp) ) { Icon( painter = painterResource(res = com.twidere.twiderex.MR.files.ic_photo), From ec97ee5777d71b464a51caa213e61c24d468626d Mon Sep 17 00:00:00 2001 From: seiko <605590140@qq.com> Date: Thu, 30 Dec 2021 18:17:20 +0800 Subject: [PATCH 5/7] save listState when timeline list is top --- .../kotlin/com/twidere/twiderex/component/TimelineComponent.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/TimelineComponent.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/TimelineComponent.kt index ecde09812..36059cb11 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/TimelineComponent.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/TimelineComponent.kt @@ -87,7 +87,6 @@ fun TimelineComponent( .distinctUntilChanged() .filter { !it } .filter { listState.layoutInfo.totalItemsCount != 0 } - .filter { listState.firstVisibleItemIndex != 0 && listState.firstVisibleItemScrollOffset != 0 } .collect { viewModel.saveScrollState( TimelineScrollState( From cb3282c3252e38e6270a82c84fdab3a17256776d Mon Sep 17 00:00:00 2001 From: seiko <605590140@qq.com> Date: Thu, 30 Dec 2021 18:23:00 +0800 Subject: [PATCH 6/7] open sensitive in twitter --- .../twiderex/component/status/StatusMediaComponent.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusMediaComponent.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusMediaComponent.kt index 5fcffc68f..0eee802bb 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusMediaComponent.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusMediaComponent.kt @@ -131,7 +131,7 @@ fun StatusMediaComponent( modifier = Modifier .weight(1f) .fillMaxSize(), - sensitive = sensitive, + sensitive = sensitive && status.platformType === PlatformType.Mastodon, onClick = onItemClick, ) } @@ -148,7 +148,7 @@ fun StatusMediaComponent( modifier = Modifier .weight(1f) .fillMaxSize(), - sensitive = sensitive, + sensitive = sensitive && status.platformType === PlatformType.Mastodon, onClick = onItemClick, ) if (it != media.last()) { @@ -169,7 +169,7 @@ fun StatusMediaComponent( StatusMediaPreviewItem( media = it, onClick = onItemClick, - sensitive = sensitive + sensitive = sensitive && status.platformType === PlatformType.Mastodon ) } } @@ -250,6 +250,7 @@ object StatusMediaDefaults { object Mastodon { val IconSpacing = 8.dp } + object Icon { val ContentPadding = 6.dp } From 28cbbb7324815900e391de5d97289c66f99e24f0 Mon Sep 17 00:00:00 2001 From: seiko <605590140@qq.com> Date: Fri, 31 Dec 2021 15:02:24 +0800 Subject: [PATCH 7/7] add enable parameter to SelectionContainer --- .../component/status/SelectionContainer.kt | 5 +++++ .../twiderex/component/status/StatusText.kt | 16 ++-------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/SelectionContainer.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/SelectionContainer.kt index dd12ed893..66a6337ba 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/SelectionContainer.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/SelectionContainer.kt @@ -45,8 +45,13 @@ class PositionWrapper { @Composable fun SelectionContainer( modifier: Modifier = Modifier, + enable: Boolean = true, content: @Composable (PositionWrapper?) -> Unit, ) { + if (!enable) { + content.invoke(null) + return + } val positionWrapper = remember { if (currentPlatform != Platform.Android) PositionWrapper() else null } diff --git a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt index e0b95fdbc..2e414d500 100644 --- a/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt +++ b/common/src/commonMain/kotlin/com/twidere/twiderex/component/status/StatusText.kt @@ -86,19 +86,7 @@ fun ColumnScope.StatusText( } AnimatedVisibility(visible = expanded) { Column { - if (isSelectionAble) { - SelectionContainer { - HtmlText( - modifier = Modifier.fillMaxWidth(), - htmlText = status.htmlText, - maxLines = maxLines, - linkResolver = { href -> - status.resolveLink(href) - }, - positionWrapper = it - ) - } - } else { + SelectionContainer(enable = isSelectionAble) { HtmlText( modifier = Modifier.fillMaxWidth(), htmlText = status.htmlText, @@ -106,7 +94,7 @@ fun ColumnScope.StatusText( linkResolver = { href -> status.resolveLink(href) }, - positionWrapper = null + positionWrapper = it ) } if (showMastodonPoll && status.platformType == PlatformType.Mastodon && status.poll != null) {