Skip to content
Merged
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
19 changes: 18 additions & 1 deletion app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,19 @@ import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
Expand Down Expand Up @@ -287,6 +295,7 @@ class ChatActivity :
private val chatEmptyStateType = mutableStateOf<ChatEmptyStateType?>(null)
private val upcomingEventUiState =
mutableStateOf<ChatViewModel.UpcomingEventUIState>(ChatViewModel.UpcomingEventUIState.None)
private val overflowContainerHeightPx = mutableIntStateOf(0)

private val startSelectContactForResult = registerForActivityResult(
ActivityResultContracts
Expand Down Expand Up @@ -510,6 +519,10 @@ class ChatActivity :

setUpcomingEventContent()

binding.chatOverflowContainer.viewTreeObserver.addOnGlobalLayoutListener {
overflowContainerHeightPx.intValue = binding.chatOverflowContainer.height
}

lifecycleScope.launch {
currentUserProvider.getCurrentUser()
.onSuccess { user ->
Expand Down Expand Up @@ -787,6 +800,9 @@ class ChatActivity :
openWhenDownloadState.value = (downloadingFileState.value.intersect(visibleIds).isNotEmpty())
}

val overflowHeightDp = with(LocalDensity.current) {
overflowContainerHeightPx.intValue.toDp()
}
ChatView(
state = ChatViewState(
chatItems = uiState.items,
Expand All @@ -798,7 +814,8 @@ class ChatActivity :
highlightedSearchTerm = uiState.highlightedSearchTerm,
hasChatPermission = this::participantPermissions.isInitialized &&
participantPermissions.hasChatPermission(),
downloadingFileState = downloadingFileState.value
downloadingFileState = downloadingFileState.value,
stickyHeaderTopOffset = overflowHeightDp
),
callbacks = ChatViewCallbacks(
onLoadMore = { messageId, direction -> loadMoreMessages(messageId, direction) },
Expand Down
46 changes: 31 additions & 15 deletions app/src/main/java/com/nextcloud/talk/ui/chat/ChatView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.nextcloud.talk.R
Expand Down Expand Up @@ -95,7 +97,8 @@ data class ChatViewState(
val chatMode: ChatViewModel.ChatMode = ChatViewModel.ChatMode.DEFAULT_MODE,
val highlightedMessageId: Int? = null,
val highlightedSearchTerm: String? = null,
val downloadingFileState: List<String> = listOf()
val downloadingFileState: List<String> = listOf(),
val stickyHeaderTopOffset: Dp = 0.dp
)

data class ChatViewCallbacks(
Expand Down Expand Up @@ -263,23 +266,36 @@ fun ChatView(
}

// Sticky date header
val stickyDateHeaderText by remember(listState, state.chatItems) {
val density = LocalDensity.current
val overflowPx = with(density) { state.stickyHeaderTopOffset.roundToPx() }

val stickyDateHeaderText by remember(listState, state.chatItems, overflowPx) {
derivedStateOf {
state.chatItems.getOrNull(
listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0
)?.let { item ->
when (item) {
is ChatViewModel.ChatItem.MessageItem ->
formatTime(item.uiMessage.timestamp * LONG_1000)
val visibleItems = listState.layoutInfo.visibleItemsInfo
val viewportEnd = listState.layoutInfo.viewportEndOffset
// In reverseLayout=true, offsets increase from bottom (newest) to top (oldest).
// An item's bottom edge is at screen Y = viewportEnd - offset; it is visible when that
// is >= overflowPx, i.e. offset <= viewportEnd - overflowPx.
val targetItem = if (overflowPx > 0) {
visibleItems.filter { it.offset <= viewportEnd - overflowPx }.lastOrNull()
} else {
visibleItems.lastOrNull()
}
targetItem?.let { itemInfo ->
state.chatItems.getOrNull(itemInfo.index)?.let { item ->
when (item) {
is ChatViewModel.ChatItem.MessageItem ->
formatTime(item.uiMessage.timestamp * LONG_1000)

is ChatViewModel.ChatItem.DateHeaderItem ->
formatTime(item.date)
is ChatViewModel.ChatItem.DateHeaderItem ->
formatTime(item.date)

is ChatViewModel.ChatItem.UnreadMessagesMarkerItem ->
formatTime(item.date)
is ChatViewModel.ChatItem.UnreadMessagesMarkerItem ->
formatTime(item.date)

else -> ""
}
else -> ""
}
} ?: ""
} ?: ""
}
}
Expand Down Expand Up @@ -397,7 +413,7 @@ fun ChatView(
text = stickyDateHeaderText,
modifier = Modifier
.align(Alignment.TopCenter)
.padding(top = 2.dp)
.padding(top = state.stickyHeaderTopOffset + 2.dp)
.alpha(stickyDateHeaderAlpha)
)

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_chat.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@


<LinearLayout
android:id="@+id/chat_overflow_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
Expand Down
Loading