1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-07 21:37:02 +09:00

DROID-2966 Chats | Enhancement | Add haptic feedback for bubble clicks + group message of the same user (#2495)

This commit is contained in:
Evgenii Kozlov 2025-06-05 11:07:09 +02:00 committed by GitHub
parent 1872176dba
commit 3c1fd69e72
Signed by: github
GPG key ID: B5690EEEBB952194
5 changed files with 40 additions and 6 deletions

View file

@ -28,6 +28,7 @@ sealed interface ChatView {
val attachments: List<Attachment> = emptyList(),
val reactions: List<Reaction> = emptyList(),
val isUserAuthor: Boolean = false,
val shouldHideUsername: Boolean = false,
val isEdited: Boolean = false,
val avatar: Avatar = Avatar.Initials(),
val reply: Reply? = null

View file

@ -191,8 +191,21 @@ class ChatViewModel @Inject constructor(
Timber.d("DROID-2966 Intent from container: ${result.intent}")
Timber.d("DROID-2966 Message results size from container: ${result.messages.size}")
var previousDate: ChatView.DateSection? = null
val messageViews = buildList<ChatView> {
val messageViews = buildList {
var prevCreator: String? = null
var prevDateInterval: Long = 0
result.messages.forEach { msg ->
val isPrevTimeIntervalBig = if (prevDateInterval > 0) {
(msg.createdAt - prevDateInterval) > ChatConfig.GROUPING_DATE_INTERVAL_IN_SECONDS
} else {
false
}
val shouldHideUsername = prevCreator == msg.creator && !isPrevTimeIntervalBig
val allMembers = members.get()
val member = allMembers.let { type ->
when (type) {
@ -265,6 +278,7 @@ class ChatViewModel @Inject constructor(
author = member?.name ?: msg.creator.takeLast(5),
creator = member?.id,
isUserAuthor = msg.creator == account,
shouldHideUsername = shouldHideUsername,
isEdited = msg.modifiedAt > msg.createdAt,
reactions = msg.reactions
.toList()
@ -365,6 +379,9 @@ class ChatViewModel @Inject constructor(
previousDate = currDate
}
add(view)
prevCreator = msg.creator
prevDateInterval = msg.createdAt
}
}.reversed()
ChatViewState(

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.feature_chats.ui
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
@ -32,8 +34,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.LinkAnnotation
@ -70,7 +74,7 @@ import com.anytypeio.anytype.core_utils.ext.formatTimeInMillis
import com.anytypeio.anytype.feature_chats.R
import com.anytypeio.anytype.feature_chats.presentation.ChatView
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
fun Bubble(
modifier: Modifier = Modifier,
@ -80,6 +84,7 @@ fun Bubble(
timestamp: Long,
attachments: List<ChatView.Message.Attachment> = emptyList(),
isUserAuthor: Boolean = false,
shouldHideUsername: Boolean = false,
isEdited: Boolean = false,
isMaxReactionCountReached: Boolean = false,
reactions: List<ChatView.Message.Reaction> = emptyList(),
@ -96,6 +101,7 @@ fun Bubble(
onMentionClicked: (Id) -> Unit,
isReadOnly: Boolean = false
) {
val haptic = LocalHapticFeedback.current
var showDropdownMenu by remember { mutableStateOf(false) }
var showDeleteMessageWarning by remember { mutableStateOf(false) }
if (showDeleteMessageWarning) {
@ -140,7 +146,7 @@ fun Bubble(
)
}
// Bubble username section
if (!isUserAuthor) {
if (!isUserAuthor && !shouldHideUsername) {
Text(
text = name.ifEmpty { stringResource(R.string.untitled) },
style = Caption1Medium,
@ -167,9 +173,15 @@ fun Bubble(
shape = RoundedCornerShape(16.dp)
)
.clip(RoundedCornerShape(16.dp))
.clickable {
showDropdownMenu = !showDropdownMenu
}
.combinedClickable(
onClick = {
showDropdownMenu = !showDropdownMenu
},
onLongClick = {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
showDropdownMenu = !showDropdownMenu
}
)
.padding(vertical = 4.dp)
) {
BubbleAttachments(
@ -177,6 +189,7 @@ fun Bubble(
isUserAuthor = isUserAuthor,
onAttachmentClicked = onAttachmentClicked,
onAttachmentLongClicked = {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
showDropdownMenu = true
}
)

View file

@ -860,6 +860,7 @@ fun Messages(
timestamp = msg.timestamp,
attachments = msg.attachments,
isUserAuthor = msg.isUserAuthor,
shouldHideUsername = msg.shouldHideUsername,
isMaxReactionCountReached = msg.isMaxReactionCountReached,
isEdited = msg.isEdited,
onReacted = { emoji ->

View file

@ -12,6 +12,8 @@ object ChatConfig {
const val MAX_MESSAGE_CHARACTER_LIMIT = 2000
const val MAX_MESSAGE_CHARACTER_OFFSET_LIMIT = 1950
const val GROUPING_DATE_INTERVAL_IN_SECONDS = 60
/**
* Spaces for beta-testing space-level chats
*/