diff --git a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationsFilesAdapter.kt b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationsFilesAdapter.kt index 1b7568661..9c9082a74 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationsFilesAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationsFilesAdapter.kt @@ -19,7 +19,9 @@ */ package org.linphone.ui.main.chat.adapter +import android.content.Context import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil @@ -30,16 +32,35 @@ import androidx.recyclerview.widget.RecyclerView import org.linphone.R import org.linphone.databinding.ChatDocumentContentListCellBinding import org.linphone.databinding.ChatMediaContentGridCellBinding +import org.linphone.databinding.MeetingsListDecorationBinding import org.linphone.ui.main.chat.model.FileModel +import org.linphone.utils.HeaderAdapter -class ConversationsFilesAdapter : ListAdapter( - FilesDiffCallback() -) { +class ConversationsFilesAdapter : + ListAdapter( + FilesDiffCallback() + ), + HeaderAdapter { companion object { const val MEDIA_FILE = 1 const val DOCUMENT_FILE = 2 } + override fun displayHeaderForPosition(position: Int): Boolean { + if (position == 0) return true + + val previous = getItem(position - 1) + val item = getItem(position) + return previous.month != item.month + } + + override fun getHeaderViewForPosition(context: Context, position: Int): View { + val binding = MeetingsListDecorationBinding.inflate(LayoutInflater.from(context)) + val item = getItem(position) + binding.header.text = item.month + return binding.root + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { MEDIA_FILE -> createMediaFileViewHolder(parent) diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationDocumentsListFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationDocumentsListFragment.kt index 08fad5449..b395e0865 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationDocumentsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationDocumentsListFragment.kt @@ -41,6 +41,7 @@ import org.linphone.ui.main.chat.viewmodel.ConversationDocumentsListViewModel import org.linphone.ui.main.fragment.SlidingPaneChildFragment import org.linphone.utils.Event import org.linphone.utils.FileUtils +import org.linphone.utils.RecyclerViewHeaderDecoration @UiThread class ConversationDocumentsListFragment : SlidingPaneChildFragment() { @@ -92,6 +93,9 @@ class ConversationDocumentsListFragment : SlidingPaneChildFragment() { val chatRoom = sharedViewModel.displayedChatRoom viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri) + val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter) + binding.documentsList.addItemDecoration(headerItemDecoration) + binding.documentsList.setHasFixedSize(true) val layoutManager = LinearLayoutManager(requireContext()) binding.documentsList.layoutManager = layoutManager diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationMediaListFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationMediaListFragment.kt index 113588aba..8020ec4a5 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationMediaListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationMediaListFragment.kt @@ -42,6 +42,7 @@ import org.linphone.ui.main.chat.viewmodel.ConversationMediaListViewModel import org.linphone.ui.main.fragment.SlidingPaneChildFragment import org.linphone.utils.Event import org.linphone.utils.FileUtils +import org.linphone.utils.RecyclerViewHeaderDecoration @UiThread class ConversationMediaListFragment : SlidingPaneChildFragment() { @@ -93,14 +94,29 @@ class ConversationMediaListFragment : SlidingPaneChildFragment() { val chatRoom = sharedViewModel.displayedChatRoom viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri) + val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter) + binding.mediaList.addItemDecoration(headerItemDecoration) + binding.mediaList.setHasFixedSize(true) - val layoutManager = object : GridLayoutManager(requireContext(), 4) { + val spanCount = 4 + val layoutManager = object : GridLayoutManager(requireContext(), spanCount) { override fun checkLayoutParams(lp: RecyclerView.LayoutParams): Boolean { lp.width = width / spanCount lp.height = lp.width return true } } + layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + if (position < adapter.currentList.size - 1) { + // Have last item of month takes all remaining horizontal space to have a "line break" + if (adapter.displayHeaderForPosition(position + 1)) { + return spanCount - (position % spanCount) + } + } + return 1 + } + } // This isn't supported by GridLayoutManager, it will crash // layoutManager.stackFromEnd = true binding.mediaList.layoutManager = layoutManager diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/FileModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/FileModel.kt index 8c5970e30..3a1a1d417 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/FileModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/FileModel.kt @@ -38,7 +38,7 @@ class FileModel @AnyThread constructor( val file: String, val fileName: String, val fileSize: Long, - val fileCreationTimestamp: Long, + private val fileCreationTimestamp: Long, private val isEncrypted: Boolean, val isWaitingToBeDownloaded: Boolean = false, private val onClicked: ((model: FileModel) -> Unit)? = null @@ -67,6 +67,14 @@ class FileModel @AnyThread constructor( val isAudio: Boolean + val month = TimestampUtils.month(fileCreationTimestamp) + + val dateTime = TimestampUtils.toString( + fileCreationTimestamp, + shortDate = false, + hideYear = false + ) + private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) init { diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt index 13933211c..3c14e2100 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt @@ -370,7 +370,7 @@ class MessageModel @WorkerThread constructor( ) val fileSize = content.fileSize.toLong() - val timestamp = -1L // TODO FIXME: use content.creationTimestamp + val timestamp = content.creationTimestamp when (content.type) { "image", "video" -> { val fileModel = FileModel( @@ -411,7 +411,7 @@ class MessageModel @WorkerThread constructor( allFilesDownloaded = false filesContentCount += 1 val name = content.name ?: "" - val timestamp = -1L // TODO FIXME: use content.creationTimestamp + val timestamp = content.creationTimestamp if (name.isNotEmpty()) { val fileModel = if (isOutgoing && chatMessage.isFileTransferInProgress) { val path = content.filePath ?: "" diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationDocumentsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationDocumentsListViewModel.kt index 86ef4b601..69d423719 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationDocumentsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationDocumentsListViewModel.kt @@ -72,7 +72,7 @@ class ConversationDocumentsListViewModel @UiThread constructor() : AbstractConve } val name = documentContent.name.orEmpty() val size = documentContent.size.toLong() - val timestamp = -1L // TODO FIXME: use documentContent.creationTimestamp + val timestamp = documentContent.creationTimestamp if (path.isNotEmpty() && name.isNotEmpty()) { val model = FileModel(path, name, size, timestamp, isEncrypted) { openDocumentEvent.postValue(Event(it)) diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationMediaListViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationMediaListViewModel.kt index 2c348cfed..0615cd425 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationMediaListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationMediaListViewModel.kt @@ -76,7 +76,7 @@ class ConversationMediaListViewModel @UiThread constructor() : AbstractConversat } val name = mediaContent.name.orEmpty() val size = mediaContent.size.toLong() - val timestamp = -1L // TODO FIXME: use mediaContent.creationTimestamp + val timestamp = mediaContent.creationTimestamp if (path.isNotEmpty() && name.isNotEmpty()) { val model = FileModel(path, name, size, timestamp, isEncrypted) { openMediaEvent.postValue(Event(it)) diff --git a/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt b/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt index face95abb..dc4fe77a6 100644 --- a/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt @@ -67,7 +67,7 @@ class MediaListViewerFragment : GenericFragment() { val list = viewModel.mediaList.value.orEmpty() if (position >= 0 && position < list.size) { val model = list[position] - viewModel.currentlyDisplayedFileName.value = model.fileName + viewModel.currentlyDisplayedFileName.value = "${model.fileName}\n${model.dateTime}" } } } diff --git a/app/src/main/res/layout/chat_document_content_list_cell.xml b/app/src/main/res/layout/chat_document_content_list_cell.xml index 6454080fd..964ce6ffe 100644 --- a/app/src/main/res/layout/chat_document_content_list_cell.xml +++ b/app/src/main/res/layout/chat_document_content_list_cell.xml @@ -15,8 +15,8 @@ android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" - android:layout_marginTop="10dp" - android:layout_marginBottom="10dp"> + android:paddingTop="10dp" + android:paddingBottom="10dp"> @@ -57,16 +56,16 @@