Merge pull request #4493 from nextcloud/avatar_open_conversation

display conversation avatar for open conversations
This commit is contained in:
Marcel Hibbe 2024-12-10 09:42:01 +01:00 committed by GitHub
commit a268819557
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 43 additions and 85 deletions

View file

@ -118,6 +118,7 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
) )
} }
@SuppressLint("StringFormatInvalid")
private fun showDeckCard(message: ChatMessage) { private fun showDeckCard(message: ChatMessage) {
if (message.messageParameters != null && message.messageParameters!!.size > 0) { if (message.messageParameters != null && message.messageParameters!!.size > 0) {
for (key in message.messageParameters!!.keys) { for (key in message.messageParameters!!.keys) {

View file

@ -21,8 +21,8 @@ import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.databinding.ActivityOpenConversationsBinding import com.nextcloud.talk.databinding.ActivityOpenConversationsBinding
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.openconversations.adapters.OpenConversationsAdapter import com.nextcloud.talk.openconversations.adapters.OpenConversationsAdapter
import com.nextcloud.talk.openconversations.data.OpenConversation
import com.nextcloud.talk.openconversations.viewmodels.OpenConversationsViewModel import com.nextcloud.talk.openconversations.viewmodels.OpenConversationsViewModel
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.vanniktech.ui.showKeyboardAndFocus import com.vanniktech.ui.showKeyboardAndFocus
@ -62,7 +62,7 @@ class ListOpenConversationsActivity : BaseActivity() {
val user = currentUserProvider.currentUser.blockingGet() val user = currentUserProvider.currentUser.blockingGet()
adapter = OpenConversationsAdapter(user) { conversation -> adapterOnClick(conversation) } adapter = OpenConversationsAdapter(user, viewThemeUtils) { conversation -> adapterOnClick(conversation) }
binding.openConversationsRecyclerView.adapter = adapter binding.openConversationsRecyclerView.adapter = adapter
binding.searchOpenConversations.setOnClickListener { binding.searchOpenConversations.setOnClickListener {
searching = !searching searching = !searching
@ -86,9 +86,9 @@ class ListOpenConversationsActivity : BaseActivity() {
} }
} }
private fun adapterOnClick(conversation: OpenConversation) { private fun adapterOnClick(conversation: Conversation) {
val bundle = Bundle() val bundle = Bundle()
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.roomToken) bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.token)
val chatIntent = Intent(context, ChatActivity::class.java) val chatIntent = Intent(context, ChatActivity::class.java)
chatIntent.putExtras(bundle) chatIntent.putExtras(bundle)

View file

@ -13,21 +13,26 @@ import android.widget.RelativeLayout
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.R
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.RvItemOpenConversationBinding import com.nextcloud.talk.databinding.RvItemOpenConversationBinding
import com.nextcloud.talk.extensions.loadUserAvatar import com.nextcloud.talk.extensions.loadConversationAvatar
import com.nextcloud.talk.openconversations.data.OpenConversation import com.nextcloud.talk.models.domain.ConversationModel
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.ui.theme.ViewThemeUtils
class OpenConversationsAdapter(val user: User, private val onClick: (OpenConversation) -> Unit) : class OpenConversationsAdapter(
ListAdapter<OpenConversation, OpenConversationsAdapter.OpenConversationsViewHolder>(ConversationsCallback) { val user: User,
private var originalList: List<OpenConversation> = emptyList() val viewThemeUtils: ViewThemeUtils,
private val onClick: (Conversation) -> Unit
) :
ListAdapter<Conversation, OpenConversationsAdapter.OpenConversationsViewHolder>(ConversationsCallback) {
private var originalList: List<Conversation> = emptyList()
private var isFiltering = false private var isFiltering = false
inner class OpenConversationsViewHolder(val itemBinding: RvItemOpenConversationBinding) : inner class OpenConversationsViewHolder(val itemBinding: RvItemOpenConversationBinding) :
RecyclerView.ViewHolder(itemBinding.root) { RecyclerView.ViewHolder(itemBinding.root) {
var currentConversation: OpenConversation? = null var currentConversation: Conversation? = null
init { init {
itemBinding.root.setOnClickListener { itemBinding.root.setOnClickListener {
@ -37,11 +42,11 @@ class OpenConversationsAdapter(val user: User, private val onClick: (OpenConvers
} }
} }
fun bindItem(conversation: OpenConversation) { fun bindItem(conversation: Conversation) {
val nameTextLayoutParams: RelativeLayout.LayoutParams = itemBinding.nameText.layoutParams as val nameTextLayoutParams: RelativeLayout.LayoutParams = itemBinding.nameText.layoutParams as
RelativeLayout.LayoutParams RelativeLayout.LayoutParams
currentConversation = conversation currentConversation = conversation
val currentConversationModel = ConversationModel.mapToConversationModel(conversation, user)
itemBinding.nameText.text = conversation.displayName itemBinding.nameText.text = conversation.displayName
if (conversation.description == "") { if (conversation.description == "") {
itemBinding.descriptionText.visibility = View.GONE itemBinding.descriptionText.visibility = View.GONE
@ -50,9 +55,12 @@ class OpenConversationsAdapter(val user: User, private val onClick: (OpenConvers
itemBinding.descriptionText.text = conversation.description itemBinding.descriptionText.text = conversation.description
} }
// load avatar from server when https://github.com/nextcloud/spreed/issues/9600 is solved itemBinding.avatarView.loadConversationAvatar(
// itemBinding.avatarView.loadUserAvatar(user, conversation.displayName, true, false) user,
itemBinding.avatarView.loadUserAvatar(R.drawable.ic_circular_group) currentConversationModel,
false,
viewThemeUtils
)
} }
} }
@ -79,7 +87,7 @@ class OpenConversationsAdapter(val user: User, private val onClick: (OpenConvers
} }
isFiltering = true isFiltering = true
val newList = mutableListOf<OpenConversation>() val newList = mutableListOf<Conversation>()
for (conversation in originalList) { for (conversation in originalList) {
if (conversation.displayName.contains(text, true) || conversation.description!!.contains(text, true)) { if (conversation.displayName.contains(text, true) || conversation.description!!.contains(text, true)) {
newList.add(conversation) newList.add(conversation)
@ -91,10 +99,7 @@ class OpenConversationsAdapter(val user: User, private val onClick: (OpenConvers
} }
} }
override fun onCurrentListChanged( override fun onCurrentListChanged(previousList: MutableList<Conversation>, currentList: MutableList<Conversation>) {
previousList: MutableList<OpenConversation>,
currentList: MutableList<OpenConversation>
) {
if (!isFiltering) { if (!isFiltering) {
originalList = currentList originalList = currentList
} }
@ -102,12 +107,12 @@ class OpenConversationsAdapter(val user: User, private val onClick: (OpenConvers
} }
} }
object ConversationsCallback : DiffUtil.ItemCallback<OpenConversation>() { object ConversationsCallback : DiffUtil.ItemCallback<Conversation>() {
override fun areItemsTheSame(oldItem: OpenConversation, newItem: OpenConversation): Boolean { override fun areItemsTheSame(oldItem: Conversation, newItem: Conversation): Boolean {
return oldItem == newItem return oldItem == newItem
} }
override fun areContentsTheSame(oldItem: OpenConversation, newItem: OpenConversation): Boolean { override fun areContentsTheSame(oldItem: Conversation, newItem: Conversation): Boolean {
return oldItem.roomToken == newItem.roomToken return oldItem.token == newItem.token
} }
} }

View file

@ -1,11 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.openconversations.data
data class JoinConversationModel(
var success: Boolean
)

View file

@ -1,14 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.openconversations.data
data class OpenConversation(
// var roomId: String,
var roomToken: String,
var displayName: String,
var description: String?
)

View file

@ -1,11 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.openconversations.data
data class OpenConversationsModel(
var conversations: List<OpenConversation>
)

View file

@ -6,9 +6,10 @@
*/ */
package com.nextcloud.talk.openconversations.data package com.nextcloud.talk.openconversations.data
import com.nextcloud.talk.models.json.conversations.Conversation
import io.reactivex.Observable import io.reactivex.Observable
interface OpenConversationsRepository { interface OpenConversationsRepository {
fun fetchConversations(): Observable<OpenConversationsModel> fun fetchConversations(): Observable<List<Conversation>>
} }

View file

@ -21,23 +21,11 @@ class OpenConversationsRepositoryImpl(private val ncApi: NcApi, currentUserProvi
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)) val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
override fun fetchConversations(): Observable<OpenConversationsModel> { override fun fetchConversations(): Observable<List<Conversation>> {
return ncApi.getOpenConversations( val roomOverall = ncApi.getOpenConversations(
credentials, credentials,
ApiUtils.getUrlForOpenConversations(apiVersion, currentUser.baseUrl!!) ApiUtils.getUrlForOpenConversations(apiVersion, currentUser.baseUrl!!)
).map { mapToOpenConversationsModel(it.ocs?.data!!) }
}
private fun mapToOpenConversationsModel(conversations: List<Conversation>): OpenConversationsModel {
return OpenConversationsModel(
conversations.map { conversation ->
OpenConversation(
// conversation.roomId!!,
conversation.token!!,
conversation.name!!,
conversation.description ?: ""
)
}
) )
return roomOverall.map { it.ocs?.data!! }
} }
} }

View file

@ -10,8 +10,7 @@ import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.nextcloud.talk.openconversations.data.OpenConversation import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.openconversations.data.OpenConversationsModel
import com.nextcloud.talk.openconversations.data.OpenConversationsRepository import com.nextcloud.talk.openconversations.data.OpenConversationsRepository
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
@ -27,7 +26,7 @@ class OpenConversationsViewModel @Inject constructor(private val repository: Ope
object FetchConversationsStartState : ViewState object FetchConversationsStartState : ViewState
object FetchConversationsEmptyState : ViewState object FetchConversationsEmptyState : ViewState
object FetchConversationsErrorState : ViewState object FetchConversationsErrorState : ViewState
open class FetchConversationsSuccessState(val conversations: List<OpenConversation>) : ViewState open class FetchConversationsSuccessState(val conversations: List<Conversation>) : ViewState
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(FetchConversationsStartState) private val _viewState: MutableLiveData<ViewState> = MutableLiveData(FetchConversationsStartState)
val viewState: LiveData<ViewState> val viewState: LiveData<ViewState>
@ -41,16 +40,16 @@ class OpenConversationsViewModel @Inject constructor(private val repository: Ope
?.subscribe(FetchConversationsObserver()) ?.subscribe(FetchConversationsObserver())
} }
inner class FetchConversationsObserver : Observer<OpenConversationsModel> { inner class FetchConversationsObserver : Observer<List<Conversation>> {
override fun onSubscribe(d: Disposable) { override fun onSubscribe(d: Disposable) {
// unused atm // unused atm
} }
override fun onNext(model: OpenConversationsModel) { override fun onNext(conversations: List<Conversation>) {
if (model.conversations.isEmpty()) { if (conversations.isEmpty()) {
_viewState.value = FetchConversationsEmptyState _viewState.value = FetchConversationsEmptyState
} else { } else {
_viewState.value = FetchConversationsSuccessState(model.conversations) _viewState.value = FetchConversationsSuccessState(conversations)
} }
} }

View file

@ -1,2 +1,2 @@
DO NOT TOUCH; GENERATED BY DRONE DO NOT TOUCH; GENERATED BY DRONE
<span class="mdl-layout-title">Lint Report: 73 errors and 158 warnings</span> <span class="mdl-layout-title">Lint Report: 72 errors and 158 warnings</span>