Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions app/src/main/java/com/nextcloud/talk/ui/ComposeUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2026 Julius Linus <juliuslinus1@gmail.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package com.nextcloud.talk.ui

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlin.math.min

// Adapted from source - https://stackoverflow.com/a/68056586
@Composable
fun Modifier.customVerticalScrollbar(
state: ScrollState,
width: Dp = 8.dp,
color: Color = Color.Red
): Modifier {
val targetAlpha = if (state.isScrollInProgress) 1f else 0f
val duration = if (state.isScrollInProgress) 150 else 500
val alpha by animateFloatAsState(
targetValue = targetAlpha,
animationSpec = tween(durationMillis = duration)
)
val cr = CORNER_RADIUS.toFloat()

return drawWithContent {
drawContent()

val needDrawScrollbar = state.isScrollInProgress || alpha > 0.0

if (needDrawScrollbar) {
val elementHeight = this.size.height
val pinnedViewHeight = MAX_HEIGHT
val scrollBarHeightPercentage = (pinnedViewHeight * 100f) / elementHeight
val scrollBarHeight = (scrollBarHeightPercentage / 100) * pinnedViewHeight
val offset = state.scrollIndicatorState?.scrollOffset?.toFloat() ?: 0f

drawRoundRect(
color = color,
topLeft = Offset(this.size.width - width.toPx(), min(offset, elementHeight)),
size = Size(width.toPx(), scrollBarHeight),
cornerRadius = CornerRadius(cr, cr),
alpha = alpha
)
}
}
}
5 changes: 4 additions & 1 deletion app/src/main/java/com/nextcloud/talk/ui/PinnedMessage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.nextcloud.talk.R
import com.nextcloud.talk.chat.data.model.ChatMessage
Expand Down Expand Up @@ -107,6 +108,7 @@ fun PinnedMessageView(
.background(incomingBubbleColor, RoundedCornerShape(CORNER_RADIUS.dp))
.padding(SPACE_16.dp)
.heightIn(max = MAX_HEIGHT.dp)
.customVerticalScrollbar(scrollState, color = outgoingBubbleColor)
.verticalScroll(scrollState)
.clickable {
scrollToMessageWithIdWithOffset(message.id)
Expand Down Expand Up @@ -160,7 +162,8 @@ fun PinnedMessageView(
text = {
Text(
text = pinnedText,
color = highEmphasisColor
color = highEmphasisColor,
fontWeight = FontWeight.Bold
)
},
onClick = { /* No-op or toggle expansion */ },
Expand Down
Loading