@@ -58,60 +58,79 @@ import kotlin.math.max
5858
5959sealed interface MessageControlAction {
6060 val onSelect: () -> Unit
61+
6162 @get:Composable
6263 val painter: Painter
6364 val isDestructive: Boolean
65+ val delayUponSelection: Boolean
6466
6567 data class Copy (override val onSelect : () -> Unit ) : MessageControlAction {
6668 override val isDestructive: Boolean = false
69+ override val delayUponSelection: Boolean = false
6770
6871 override val painter: Painter
6972 @Composable get() = rememberVectorPainter(Icons .Default .ContentCopy )
7073 }
74+
7175 data class Reply (override val onSelect : () -> Unit ) : MessageControlAction {
7276 override val isDestructive: Boolean = false
7377 override val painter: Painter
7478 @Composable get() = rememberVectorPainter(Icons .AutoMirrored .Default .Reply )
79+ override val delayUponSelection: Boolean = false
7580 }
7681
77- data class Tip (override val onSelect : () -> Unit ): MessageControlAction {
82+ data class Tip (override val onSelect : () -> Unit ) : MessageControlAction {
7883 override val isDestructive: Boolean = false
7984 override val painter: Painter
8085 @Composable get() = painterResource(R .drawable.ic_kin_white_small)
86+ override val delayUponSelection: Boolean = true
8187 }
8288
8389 data class Delete (override val onSelect : () -> Unit ) : MessageControlAction {
8490 override val isDestructive: Boolean = true
8591 override val painter: Painter
8692 @Composable get() = rememberVectorPainter(Icons .Default .Delete )
93+ override val delayUponSelection: Boolean = false
8794 }
95+
8896 data class RemoveUser (val name : String , override val onSelect : () -> Unit ) :
8997 MessageControlAction {
9098 override val isDestructive: Boolean = true
9199 override val painter: Painter
92100 @Composable get() = rememberVectorPainter(Icons .Default .PersonRemove )
101+ override val delayUponSelection: Boolean = false
93102 }
94103
95- data class MuteUser (val name : String , override val onSelect : () -> Unit ) : MessageControlAction {
104+ data class MuteUser (val name : String , override val onSelect : () -> Unit ) :
105+ MessageControlAction {
96106 override val isDestructive: Boolean = true
97107 override val painter: Painter
98108 @Composable get() = rememberVectorPainter(Icons .Default .VoiceOverOff )
109+ override val delayUponSelection: Boolean = false
99110 }
111+
100112 data class ReportUserForMessage (val name : String , override val onSelect : () -> Unit ) :
101113 MessageControlAction {
102114 override val isDestructive: Boolean = true
103115 override val painter: Painter
104116 @Composable get() = rememberVectorPainter(Icons .Default .Flag )
117+ override val delayUponSelection: Boolean = false
105118 }
106- data class BlockUser (val name : String , override val onSelect : () -> Unit ): MessageControlAction {
119+
120+ data class BlockUser (val name : String , override val onSelect : () -> Unit ) :
121+ MessageControlAction {
107122 override val isDestructive: Boolean = true
108123 override val painter: Painter
109124 @Composable get() = rememberVectorPainter(Icons .Default .Block )
125+ override val delayUponSelection: Boolean = false
110126 }
111- data class UnblockUser (val name : String , override val onSelect : () -> Unit ): MessageControlAction {
127+
128+ data class UnblockUser (val name : String , override val onSelect : () -> Unit ) :
129+ MessageControlAction {
112130 override val isDestructive: Boolean = false
113131 override val painter: Painter
114132 @Composable get() = rememberVectorPainter(Icons .Default .Person )
133+ override val delayUponSelection: Boolean = false
115134 }
116135}
117136
@@ -173,9 +192,9 @@ internal fun MessageNodeScope.MessageText(
173192@Composable
174193private fun rememberAlignmentRule (
175194 contentTextStyle : TextStyle ,
176- minWidth : Int = 0,
195+ minWidth : Int = 0,
177196 maxWidth : Int ,
178- message : String ,
197+ message : AnnotatedString ,
179198 date : Instant
180199): State <AlignmentRule ?> {
181200 val density = LocalDensity .current
@@ -243,20 +262,52 @@ internal fun MessageContent(
243262 options : MessageNodeOptions ,
244263 onLongPress : () -> Unit = { },
245264 onDoubleClick : () -> Unit = { },
265+ ) {
266+ MessageContent (
267+ modifier = modifier,
268+ minWidth = minWidth,
269+ maxWidth = maxWidth,
270+ annotatedMessage = AnnotatedString (message),
271+ date = date,
272+ status = status,
273+ isFromSelf = isFromSelf,
274+ isFromBlockedMember = isFromBlockedMember,
275+ options = options,
276+ onLongPress = onLongPress,
277+ onDoubleClick = onDoubleClick
278+ )
279+ }
280+
281+ @Composable
282+ internal fun MessageContent (
283+ modifier : Modifier = Modifier ,
284+ minWidth : Int = 0,
285+ maxWidth : Int ,
286+ annotatedMessage : AnnotatedString ,
287+ date : Instant ,
288+ status : MessageStatus ,
289+ isFromSelf : Boolean ,
290+ isFromBlockedMember : Boolean ,
291+ options : MessageNodeOptions ,
292+ onLongPress : () -> Unit = { },
293+ onDoubleClick : () -> Unit = { },
246294) {
247295 val alignmentRule by rememberAlignmentRule(
248296 contentTextStyle = options.contentStyle,
249297 minWidth = minWidth,
250298 maxWidth = maxWidth,
251- message = message ,
299+ message = annotatedMessage ,
252300 date = date,
253301 )
254302
255303 when (alignmentRule) {
256304 AlignmentRule .Column -> {
257- Column (modifier = modifier, verticalArrangement = Arrangement .spacedBy(CodeTheme .dimens.grid.x1)) {
305+ Column (
306+ modifier = modifier,
307+ verticalArrangement = Arrangement .spacedBy(CodeTheme .dimens.grid.x1)
308+ ) {
258309 MarkupTextHandler (
259- text = message ,
310+ text = annotatedMessage ,
260311 options = options,
261312 onLongPress = onLongPress,
262313 isFromBlockedMember = isFromBlockedMember,
@@ -265,7 +316,13 @@ internal fun MessageContent(
265316 DateWithStatus (
266317 modifier = Modifier
267318 .align(Alignment .End )
268- .pointerInput(Unit ) { detectTapGestures { }},
319+ .pointerInput(Unit ) {
320+ detectTapGestures(
321+ onLongPress = if (! options.isInteractive) null else {
322+ { onLongPress() }
323+ },
324+ )
325+ },
269326 date = date,
270327 status = status,
271328 isFromSelf = isFromSelf,
@@ -277,9 +334,10 @@ internal fun MessageContent(
277334
278335 AlignmentRule .ParagraphLastLine -> {
279336 Column (
280- modifier = modifier.padding(CodeTheme .dimens.grid.x1)) {
337+ modifier = modifier.padding(CodeTheme .dimens.grid.x1)
338+ ) {
281339 MarkupTextHandler (
282- text = message ,
340+ text = annotatedMessage ,
283341 options = options,
284342 onLongPress = onLongPress,
285343 isFromBlockedMember = isFromBlockedMember,
@@ -288,7 +346,13 @@ internal fun MessageContent(
288346 DateWithStatus (
289347 modifier = Modifier
290348 .align(Alignment .End )
291- .pointerInput(Unit ) { detectTapGestures { }},
349+ .pointerInput(Unit ) {
350+ detectTapGestures(
351+ onLongPress = if (! options.isInteractive) null else {
352+ { onLongPress() }
353+ },
354+ )
355+ },
292356 date = date,
293357 status = status,
294358 isFromSelf = isFromSelf,
@@ -304,7 +368,7 @@ internal fun MessageContent(
304368 horizontalArrangement = Arrangement .spacedBy(CodeTheme .dimens.grid.x1)
305369 ) {
306370 MarkupTextHandler (
307- text = message ,
371+ text = annotatedMessage ,
308372 options = options,
309373 onLongPress = onLongPress,
310374 isFromBlockedMember = isFromBlockedMember,
@@ -313,7 +377,13 @@ internal fun MessageContent(
313377 DateWithStatus (
314378 modifier = Modifier
315379 .padding(top = CodeTheme .dimens.grid.x1 + 2 .dp)
316- .pointerInput(Unit ) { detectTapGestures { }},
380+ .pointerInput(Unit ) {
381+ detectTapGestures(
382+ onLongPress = if (! options.isInteractive) null else {
383+ { onLongPress() }
384+ },
385+ )
386+ },
317387 date = date,
318388 status = status,
319389 isFromSelf = isFromSelf,
@@ -329,7 +399,7 @@ internal fun MessageContent(
329399
330400@Composable
331401private fun MarkupTextHandler (
332- text : String ,
402+ text : AnnotatedString ,
333403 options : MessageNodeOptions ,
334404 isFromBlockedMember : Boolean ,
335405 modifier : Modifier = Modifier ,
@@ -349,12 +419,13 @@ private fun MarkupTextHandler(
349419 )
350420
351421 }
422+
352423 options.onMarkupClicked != null -> {
353424 val handler = options.onMarkupClicked
354425 val markupTextHelper = remember { MarkupTextHelper () }
355426 val markups = options.markupsToResolve.map { Markup .create(it) }
356427
357- val annotatedString = markupTextHelper.annotate(text, markups)
428+ val annotatedString = markupTextHelper.annotate(text.text , markups)
358429
359430 val handleTouchedContent = { offset: Int ->
360431 annotatedString.getStringAnnotations(
@@ -399,12 +470,15 @@ private fun MarkupTextHandler(
399470 }
400471 },
401472 onDoubleTap = { _ -> onDoubleClick() },
402- onLongPress = if (! options.isInteractive) null else { { onLongPress() } },
473+ onLongPress = if (! options.isInteractive) null else {
474+ { onLongPress() }
475+ },
403476 )
404- },
477+ },
405478 onTextLayout = { layoutResult = it }
406479 )
407480 }
481+
408482 else -> {
409483 Text (modifier = modifier, text = text, style = options.contentStyle)
410484 }
0 commit comments