Skip to content

Commit 6493ec3

Browse files
committed
adding a better scrolling experience
Signed-off-by: rapterjet2004 <juliuslinus1@gmail.com>
1 parent 6fe1f30 commit 6493ec3

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Nextcloud Talk - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2026 Julius Linus <juliuslinus1@gmail.com>
5+
* SPDX-License-Identifier: GPL-3.0-or-later
6+
*/
7+
8+
package com.nextcloud.talk.ui
9+
10+
import androidx.compose.animation.core.animateFloatAsState
11+
import androidx.compose.animation.core.tween
12+
import androidx.compose.foundation.ScrollState
13+
import androidx.compose.runtime.Composable
14+
import androidx.compose.runtime.getValue
15+
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.draw.drawWithContent
17+
import androidx.compose.ui.geometry.CornerRadius
18+
import androidx.compose.ui.geometry.Offset
19+
import androidx.compose.ui.geometry.Size
20+
import androidx.compose.ui.graphics.Color
21+
import androidx.compose.ui.unit.Dp
22+
import androidx.compose.ui.unit.dp
23+
import kotlin.math.min
24+
25+
// Adapted from source - https://stackoverflow.com/a/68056586
26+
@Composable
27+
fun Modifier.customVerticalScrollbar(
28+
state: ScrollState,
29+
width: Dp = 8.dp,
30+
color: Color = Color.Red
31+
): Modifier {
32+
val targetAlpha = if (state.isScrollInProgress) 1f else 0f
33+
val duration = if (state.isScrollInProgress) 150 else 500
34+
val alpha by animateFloatAsState(
35+
targetValue = targetAlpha,
36+
animationSpec = tween(durationMillis = duration)
37+
)
38+
val cr = CORNER_RADIUS.toFloat()
39+
40+
return drawWithContent {
41+
drawContent()
42+
43+
val needDrawScrollbar = state.isScrollInProgress || alpha > 0.0
44+
45+
if (needDrawScrollbar) {
46+
val elementHeight = this.size.height
47+
val pinnedViewHeight = MAX_HEIGHT
48+
val scrollBarHeightPercentage = (pinnedViewHeight * 100f) / elementHeight
49+
val scrollBarHeight = (scrollBarHeightPercentage / 100) * pinnedViewHeight
50+
val offset = state.scrollIndicatorState?.scrollOffset?.toFloat() ?: 0f
51+
52+
drawRoundRect(
53+
color = color,
54+
topLeft = Offset(this.size.width - width.toPx(), min(offset, elementHeight)),
55+
size = Size(width.toPx(), scrollBarHeight),
56+
cornerRadius = CornerRadius(cr, cr),
57+
alpha = alpha
58+
)
59+
}
60+
}
61+
}

app/src/main/java/com/nextcloud/talk/ui/PinnedMessage.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import androidx.compose.ui.platform.LocalContext
4040
import androidx.compose.ui.res.colorResource
4141
import androidx.compose.ui.res.painterResource
4242
import androidx.compose.ui.res.stringResource
43+
import androidx.compose.ui.text.font.FontWeight
4344
import androidx.compose.ui.unit.dp
4445
import com.nextcloud.talk.R
4546
import com.nextcloud.talk.chat.data.model.ChatMessage
@@ -107,6 +108,7 @@ fun PinnedMessageView(
107108
.background(incomingBubbleColor, RoundedCornerShape(CORNER_RADIUS.dp))
108109
.padding(SPACE_16.dp)
109110
.heightIn(max = MAX_HEIGHT.dp)
111+
.customVerticalScrollbar(scrollState, color = outgoingBubbleColor)
110112
.verticalScroll(scrollState)
111113
.clickable {
112114
scrollToMessageWithIdWithOffset(message.id)
@@ -160,7 +162,8 @@ fun PinnedMessageView(
160162
text = {
161163
Text(
162164
text = pinnedText,
163-
color = highEmphasisColor
165+
color = highEmphasisColor,
166+
fontWeight = FontWeight.Bold
164167
)
165168
},
166169
onClick = { /* No-op or toggle expansion */ },

0 commit comments

Comments
 (0)