diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt index 48476827b..89e54d3f2 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt @@ -48,7 +48,7 @@ import java.util.regex.Pattern class ConversationItem( val model: Conversation, - private val user: UserNgEntity, + val user: UserNgEntity, private val context: Context ) : AbstractFlexibleItem(), IFilterable { @@ -56,6 +56,7 @@ class ConversationItem( if (other is ConversationItem) { val inItem = other as ConversationItem? val comparedConversation = inItem!!.model + return (model.conversationId == comparedConversation.conversationId && model.token == comparedConversation.token && model.name == comparedConversation.name @@ -68,7 +69,7 @@ class ConversationItem( && model.unreadMention == comparedConversation.unreadMention && model.objectType == comparedConversation.objectType && model.changing == comparedConversation.changing - && inItem.user.id == other.user.id) + && inItem.user.id == user.id) } return false } @@ -199,7 +200,6 @@ class ConversationItem( holder.itemView.dialogAvatar.visibility = View.VISIBLE - val conversationDrawable: Drawable? = Images().getImageForConversation(context, model) if (conversationDrawable != null) { holder.itemView.dialogAvatar.load(conversationDrawable) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicIncomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicIncomingTextMessageViewHolder.kt index 0ef29f8d8..80b436a55 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicIncomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicIncomingTextMessageViewHolder.kt @@ -220,7 +220,7 @@ class MagicIncomingTextMessageViewHolder(incomingView: View) : MessageHolders message.parentMessage?.let { parentChatMessage -> parentChatMessage.activeUser = message.activeUser imageLoader.loadImage(quotedUserAvatar, parentChatMessage.user.avatar, null) - parentChatMessage.imageUrl?.let{ + parentChatMessage.imageUrl?.let { quotedMessagePreview?.visibility = View.VISIBLE imageLoader.loadImage(quotedMessagePreview, it, null) } ?: run { diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt index 7290d062c..ee1dd9337 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt @@ -24,7 +24,6 @@ import android.content.Intent import android.net.Uri import android.text.Spannable import android.text.SpannableString -import android.util.Log import android.util.TypedValue import android.view.View import android.widget.ImageView @@ -146,7 +145,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage message.parentMessage?.let { parentChatMessage -> parentChatMessage.activeUser = message.activeUser imageLoader.loadImage(quotedUserAvatar, parentChatMessage.user.avatar, null) - parentChatMessage.imageUrl?.let{ + parentChatMessage.imageUrl?.let { quotedMessagePreview?.visibility = View.VISIBLE imageLoader.loadImage(quotedMessagePreview, it, null) } ?: run { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index 8a8e020db..828bd833a 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -393,7 +393,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter messagesListView?.setAdapter(adapter) adapter?.setLoadMoreListener(this) adapter?.setDateHeadersFormatter { format(it) } - adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message)} + adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) } layoutManager = messagesListView?.layoutManager as LinearLayoutManager? @@ -931,7 +931,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter messageInput?.setText("") val replyMessageId: Long? = view?.findViewById(R.id.quotedChatMessageView)?.tag as Long? - sendMessage(editable, if (view?.findViewById(R.id.quotedChatMessageView)?.visibility == View.VISIBLE) replyMessageId?.toInt() else null ) + sendMessage(editable, if (view?.findViewById(R.id.quotedChatMessageView)?.visibility == View.VISIBLE) replyMessageId?.toInt() else null) cancelReply() } } @@ -1412,7 +1412,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter messageInputView?.findViewById(R.id.quotedMessage)?.ellipsize = TextUtils.TruncateAt.END messageInputView?.findViewById(R.id.quotedMessage)?.text = it.text messageInputView?.findViewById(R.id.quotedMessageTime)?.text = DateFormatter.format(it.createdAt, DateFormatter.Template.TIME) - messageInputView?.findViewById(R.id.quotedMessageAuthor)?.text = it.actorDisplayName ?: context.getText(R.string.nc_nick_guest) + messageInputView?.findViewById(R.id.quotedMessageAuthor)?.text = it.actorDisplayName + ?: context.getText(R.string.nc_nick_guest) conversationUser?.let { currentUser -> messageInputView?.findViewById(R.id.quotedUserAvatar)?.load(it.user.avatar) { @@ -1420,7 +1421,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter transformations(CircleCropTransformation()) } - chatMessage.imageUrl?.let{ previewImageUrl -> + chatMessage.imageUrl?.let { previewImageUrl -> messageInputView?.findViewById(R.id.quotedMessageImage)?.visibility = View.VISIBLE val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 96f, resources?.displayMetrics) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt index 5ee66cdfa..d4673b2eb 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt @@ -21,8 +21,6 @@ package com.nextcloud.talk.controllers import android.content.Intent -import android.graphics.drawable.Drawable -import android.graphics.drawable.LayerDrawable import android.os.Bundle import android.text.TextUtils import android.view.LayoutInflater @@ -61,7 +59,8 @@ import com.nextcloud.talk.jobs.DeleteConversationWorker import com.nextcloud.talk.jobs.LeaveConversationWorker import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType -import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.* +import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.PUBLIC_CONVERSATION +import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.SYSTEM_CONVERSATION import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter import com.nextcloud.talk.models.json.generic.GenericOverall diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt index 809354638..a5edecd00 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt @@ -297,7 +297,7 @@ class SettingsController : BaseController() { var hasMultipleUsers = false val job = async { currentUser = usersRepository.getActiveUser() - hasMultipleUsers = usersRepository.getUsers().size > 0 + hasMultipleUsers = usersRepository.getUsers().isNotEmpty() credentials = currentUser!!.getCredentials() } diff --git a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt b/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt index 9d0e7e43b..747bc8fb8 100644 --- a/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt +++ b/app/src/main/java/com/nextcloud/talk/models/ExternalSignalingServer.kt @@ -26,6 +26,7 @@ import com.bluelinelabs.logansquare.annotation.JsonObject import kotlinx.android.parcel.Parcelize import lombok.Data import org.parceler.Parcel +import java.util.* @Data @Parcel @@ -44,14 +45,15 @@ data class ExternalSignalingServer( other as ExternalSignalingServer if (externalSignalingServer != other.externalSignalingServer) return false - if (externalSignalingTicket != other.externalSignalingTicket) return false + //if (externalSignalingTicket != other.externalSignalingTicket) return false return true } override fun hashCode(): Int { - var result = externalSignalingServer?.hashCode() ?: 0 + return Objects.hash(externalSignalingServer) + /*var result = externalSignalingServer?.hashCode() ?: 0 result = 31 * result + (externalSignalingTicket?.hashCode() ?: 0) - return result + return result*/ } } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt index c4b4df4c2..ec7bcccbb 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/Capabilities.kt @@ -42,6 +42,7 @@ data class Capabilities( override fun equals(o: Any?): Boolean { if (this === o) return true if (o !is Capabilities) return false + return (spreedCapability == o.spreedCapability && notificationsCapability == o.notificationsCapability && themingCapability == o.themingCapability) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.kt b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.kt index 6777d39f4..7cf16d6fb 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/SpreedCapability.kt @@ -41,9 +41,8 @@ data class SpreedCapability( override fun equals(o: Any?): Boolean { if (this === o) return true if (o !is SpreedCapability) return false - val that = o - return features == that.features && - config == that.config + return features == o.features && + config == o.config } override fun hashCode(): Int { diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java index b4d87e89f..97961d949 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java @@ -44,6 +44,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import lombok.Data; @@ -97,13 +98,35 @@ public class ChatMessage implements IMessage, MessageContentType, MessageContent public boolean replyable; @JsonField(name = "parent") public ChatMessage parentMessage; - @JsonIgnore @Ignore List messageTypesToIgnore = Arrays.asList(MessageType.REGULAR_TEXT_MESSAGE, MessageType.SYSTEM_MESSAGE, MessageType.SINGLE_LINK_VIDEO_MESSAGE, MessageType.SINGLE_LINK_AUDIO_MESSAGE, MessageType.SINGLE_LINK_MESSAGE); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ChatMessage)) return false; + ChatMessage that = (ChatMessage) o; + return timestamp == that.timestamp && + replyable == that.replyable && + Objects.equals(jsonMessageId, that.jsonMessageId) && + Objects.equals(actorType, that.actorType) && + Objects.equals(actorId, that.actorId) && + Objects.equals(actorDisplayName, that.actorDisplayName) && + Objects.equals(token, that.token) && + Objects.equals(message, that.message) && + Objects.equals(messageParameters, that.messageParameters) && + systemMessageType == that.systemMessageType && + Objects.equals(parentMessage, that.parentMessage); + } + + @Override + public int hashCode() { + return Objects.hash(jsonMessageId, token, actorType, actorId, actorDisplayName, timestamp, message, messageParameters, systemMessageType, replyable, parentMessage); + } + private boolean hasFileAttachment() { if (messageParameters != null && messageParameters.size() > 0) { for (String key : messageParameters.keySet()) { diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt index 4557475ab..337d4c535 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt @@ -22,15 +22,15 @@ package com.nextcloud.talk.models.json.converters -import com.bluelinelabs.logansquare.typeconverters.LongBasedTypeConverter +import com.bluelinelabs.logansquare.typeconverters.IntBasedTypeConverter import com.nextcloud.talk.models.json.participants.Participant -class EnumParticipantFlagsConverter : LongBasedTypeConverter() { - override fun getFromLong(l: Long): Participant.ParticipantFlags { +class EnumParticipantFlagsConverter : IntBasedTypeConverter() { + override fun getFromInt(l: Int): Participant.ParticipantFlags { return Participant.ParticipantFlags.fromValue(l) } - override fun convertToLong(`object`: Participant.ParticipantFlags?): Long { + override fun convertToInt(`object`: Participant.ParticipantFlags?): Int { return `object`?.value ?: 0 } } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java b/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java index 67f0a804c..11c4277ce 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java @@ -27,6 +27,8 @@ import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter; import org.parceler.Parcel; +import java.util.Objects; + import lombok.Data; @Parcel @@ -47,8 +49,8 @@ public class Participant { @JsonField(name = "displayName") public String displayName; - @JsonField(name = "lastPing") - public long lastPing; + /*@JsonField(name = "lastPing") + public long lastPing;*/ @JsonField(name = "sessionId") public String sessionId; @@ -56,14 +58,35 @@ public class Participant { @JsonField(name = "conversationId") public long conversationId; - @JsonField(name = { "inCall", "call" }, typeConverter = EnumParticipantFlagsConverter.class) + @JsonField(name = {"inCall", "call"}, typeConverter = EnumParticipantFlagsConverter.class) public ParticipantFlags participantFlags; @JsonField(name = "source") public String source; public boolean selected; - + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Participant)) return false; + Participant that = (Participant) o; + return conversationId == that.conversationId && + selected == that.selected && + Objects.equals(userId, that.userId) && + type == that.type && + Objects.equals(name, that.name) && + Objects.equals(displayName, that.displayName) && + Objects.equals(sessionId, that.sessionId) && + participantFlags == that.participantFlags && + Objects.equals(source, that.source); + } + + @Override + public int hashCode() { + return Objects.hash(userId, type, name, displayName, sessionId, conversationId, participantFlags, source, selected); + } + public enum ParticipantType { OWNER(1), MODERATOR(2), @@ -72,13 +95,13 @@ public class Participant { USER_FOLLOWING_LINK(5), GUEST_AS_MODERATOR(6); - private long value; + private Integer value; - ParticipantType(long value) { + ParticipantType(Integer value) { this.value = value; } - public static ParticipantType fromValue(long value) { + public static ParticipantType fromValue(Integer value) { if (value == 1) { return OWNER; } else if (value == 2) { @@ -96,7 +119,7 @@ public class Participant { } } - public long getValue() { + public Integer getValue() { return value; } @@ -109,13 +132,13 @@ public class Participant { IN_CALL_WITH_VIDEO(5), IN_CALL_WITH_AUDIO_AND_VIDEO(7); - private long value; + private Integer value; - ParticipantFlags(long value) { + ParticipantFlags(Integer value) { this.value = value; } - public static ParticipantFlags fromValue(long value) { + public static ParticipantFlags fromValue(Integer value) { if (value == 0) { return NOT_IN_CALL; } else if (value == 1) { @@ -131,7 +154,7 @@ public class Participant { } } - public long getValue() { + public Integer getValue() { return value; } } diff --git a/app/src/main/java/com/nextcloud/talk/newarch/di/module/ConversationsModule.kt b/app/src/main/java/com/nextcloud/talk/newarch/di/module/ConversationsModule.kt index 6aa406632..a2eec7c37 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/di/module/ConversationsModule.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/di/module/ConversationsModule.kt @@ -7,7 +7,7 @@ import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.usecases.* import com.nextcloud.talk.newarch.features.chat.ChatViewModelFactory -import com.nextcloud.talk.newarch.utils.GlobalService +import com.nextcloud.talk.newarch.services.GlobalService import org.koin.dsl.module val ConversationsModule = module { diff --git a/app/src/main/java/com/nextcloud/talk/newarch/di/module/ServiceModule.kt b/app/src/main/java/com/nextcloud/talk/newarch/di/module/ServiceModule.kt index 426b11261..f921f57ea 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/di/module/ServiceModule.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/di/module/ServiceModule.kt @@ -5,7 +5,7 @@ import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsReposit import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository import com.nextcloud.talk.newarch.domain.usecases.GetConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase -import com.nextcloud.talk.newarch.utils.GlobalService +import com.nextcloud.talk.newarch.services.GlobalService import com.nextcloud.talk.newarch.utils.ShortcutService import okhttp3.OkHttpClient import org.koin.dsl.module diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt index c478c8c76..bfaebaa66 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt @@ -11,8 +11,8 @@ import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository import com.nextcloud.talk.newarch.domain.usecases.ExitConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase import com.nextcloud.talk.newarch.local.models.UserNgEntity -import com.nextcloud.talk.newarch.utils.GlobalService -import com.nextcloud.talk.newarch.utils.GlobalServiceInterface +import com.nextcloud.talk.newarch.services.GlobalService +import com.nextcloud.talk.newarch.services.GlobalServiceInterface import kotlinx.coroutines.launch class ChatViewModel constructor(application: Application, diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt index c5ab9cf24..8ac7bd124 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt @@ -7,7 +7,7 @@ import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsReposit import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository import com.nextcloud.talk.newarch.domain.usecases.ExitConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase -import com.nextcloud.talk.newarch.utils.GlobalService +import com.nextcloud.talk.newarch.services.GlobalService class ChatViewModelFactory constructor( private val application: Application, diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt index 79d8f32c3..0f8770c19 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt @@ -24,11 +24,11 @@ import android.app.Application import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository -import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUseCase +import com.nextcloud.talk.newarch.services.GlobalService class ConversationListViewModelFactory constructor( private val application: Application, @@ -37,14 +37,14 @@ class ConversationListViewModelFactory constructor( private val leaveConversationUseCase: LeaveConversationUseCase, private val deleteConversationUseCase: DeleteConversationUseCase, private val conversationsRepository: ConversationsRepository, - private val usersRepository: UsersRepository + private val globalService: GlobalService ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { return ConversationsListViewModel( application, conversationsUseCase, setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase, - conversationsRepository, usersRepository + conversationsRepository, globalService ) as T } } diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt index 4aef972af..29b63f0a6 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt @@ -23,7 +23,6 @@ package com.nextcloud.talk.newarch.features.conversationsList import android.app.SearchManager import android.content.Context import android.content.Intent -import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle import android.text.InputType @@ -32,13 +31,10 @@ import android.view.inputmethod.EditorInfo import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView.OnQueryTextListener import androidx.core.view.MenuItemCompat -import androidx.lifecycle.MutableLiveData +import androidx.core.view.isVisible import androidx.lifecycle.Observer import androidx.recyclerview.widget.RecyclerView.ViewHolder import butterknife.OnClick -import coil.ImageLoader -import coil.target.Target -import coil.transform.CircleCropTransformation import com.afollestad.materialdialogs.LayoutMode.WRAP_CONTENT import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.bottomsheets.BottomSheet @@ -55,10 +51,8 @@ import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.newarch.conversationsList.mvp.BaseView -import com.nextcloud.talk.newarch.features.conversationsList.ConversationsListViewState.* +import com.nextcloud.talk.newarch.features.conversationsList.ConversationsListViewNetworkState.* import com.nextcloud.talk.newarch.mvvm.ext.initRecyclerView -import com.nextcloud.talk.newarch.utils.Images -import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ConductorRemapping import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.ShareUtils @@ -81,8 +75,6 @@ class ConversationsListView : BaseView(), OnQueryTextListener, private lateinit var viewModel: ConversationsListViewModel val factory: ConversationListViewModelFactory by inject() - private val imageLoader: ImageLoader by inject() - private val viewState: MutableLiveData = MutableLiveData(LOADING) private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), null, false) @@ -109,42 +101,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener, } settingsItem = menu.findItem(R.id.action_settings) - } - - private fun loadAvatar() { - val iconSize = settingsItem?.icon?.intrinsicHeight?.toFloat() - ?.let { - DisplayUtils.convertDpToPixel( - it, - activity!! - ) - .toInt() - } - - iconSize?.let { - val target = object : Target { - override fun onSuccess(result: Drawable) { - super.onSuccess(result) - settingsItem?.icon = result - } - - override fun onError(error: Drawable?) { - super.onError(error) - settingsItem?.icon = context.getDrawable(R.drawable.ic_settings_white_24dp) - } - } - - viewModel.currentUserLiveData.value?.let { - val avatarRequest = Images().getRequestForUrl( - imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels( - it.baseUrl, - it.userId, iconSize - ), it, target, this, CircleCropTransformation() - ) - - imageLoader.load(avatarRequest) - } - } + viewModel.loadAvatar() } override fun onOptionsItemSelected(item: MenuItem): Boolean { @@ -186,10 +143,6 @@ class ConversationsListView : BaseView(), OnQueryTextListener, searchView!!.setOnQueryTextListener(this) } - override fun onRestoreViewState(view: View, savedViewState: Bundle) { - super.onRestoreViewState(view, savedViewState) - viewModel.loadConversations() - } override fun onQueryTextSubmit(query: String?): Boolean { if (!viewModel.searchQuery.value.equals(query)) { @@ -212,26 +165,32 @@ class ConversationsListView : BaseView(), OnQueryTextListener, viewModel = viewModelProvider(factory).get(ConversationsListViewModel::class.java) viewModel.apply { - currentUserLiveData.observe(this@ConversationsListView, Observer { value -> - loadAvatar() + currentUserAvatar.observe(this@ConversationsListView, Observer { value -> + settingsItem?.icon = value }) conversationsLiveData.observe(this@ConversationsListView, Observer { - if (it.isEmpty()) { - if (viewState.value != LOADED_EMPTY) { - viewState.value = LOADED_EMPTY - } - } else { - if (viewState.value != LOADED) { - viewState.value = LOADED - } + val isListEmpty = it.isNullOrEmpty() + + if (isListEmpty) { + view?.stateWithMessageView?.errorStateTextView?.text = + resources?.getText(R.string.nc_conversations_empty) + view?.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo) } + view?.stateWithMessageView?.visibility = if (isListEmpty && networkStateLiveData.value != LOADING) View.VISIBLE else View.GONE + + if (view?.floatingActionButton?.isShown == false) { + view?.floatingActionButton?.show() + } + + searchItem?.isVisible = !isListEmpty + val newConversations = mutableListOf() for (conversation in it) { newConversations.add( ConversationItem( - conversation, viewModel.currentUserLiveData.value!!, + conversation, globalService.currentUserLiveData.value!!, activity!! ) ) @@ -241,6 +200,46 @@ class ConversationsListView : BaseView(), OnQueryTextListener, newConversations as List>?, false ) + + }) + + networkStateLiveData.observe(this@ConversationsListView, Observer { value -> + when (value) { + LOADING -> { + view?.post { + view?.loadingStateView?.visibility = View.VISIBLE + view?.dataStateView?.visibility = View.GONE + view?.stateWithMessageView?.visibility = View.GONE + view?.floatingActionButton?.visibility = View.GONE + } + searchItem?.isVisible = false + } + LOADED -> { + // awesome, but we delegate the magic stuff to the data handler + view?.post { + view?.loadingStateView?.visibility = View.GONE + view?.dataStateView?.visibility = View.VISIBLE + view?.floatingActionButton?.visibility = View.VISIBLE + if (view?.floatingActionButton?.isShown == false) { + view?.floatingActionButton?.show() + } + } + searchItem?.isVisible = !recyclerViewAdapter.isEmpty + } + FAILED -> { + // probably offline, so what? :) + view?.post { + view?.loadingStateView?.visibility = View.GONE + view?.dataStateView?.visibility = View.VISIBLE + view?.floatingActionButton?.visibility = View.GONE + view?.stateWithMessageView?.visibility = if (recyclerViewAdapter.isEmpty) View.VISIBLE else View.GONE + } + searchItem?.isVisible = !recyclerViewAdapter.isEmpty + } + else -> { + // We should not be here + } + } }) searchQuery.observe(this@ConversationsListView, Observer { @@ -249,65 +248,6 @@ class ConversationsListView : BaseView(), OnQueryTextListener, }) } - viewState.observe(this@ConversationsListView, Observer { value -> - when (value) { - LOADING -> { - view?.swipeRefreshLayoutView?.isEnabled = false - view?.loadingStateView?.visibility = View.VISIBLE - view?.stateWithMessageView?.visibility = View.GONE - view?.dataStateView?.visibility = View.GONE - view?.floatingActionButton?.visibility = View.GONE - searchItem?.isVisible = false - } - LOADED -> { - view?.swipeRefreshLayoutView?.isEnabled = true - view?.swipeRefreshLayoutView?.post { - view?.swipeRefreshLayoutView?.isRefreshing = false - } - view?.loadingStateView?.visibility = View.GONE - view?.stateWithMessageView?.visibility = View.GONE - view?.dataStateView?.visibility = View.VISIBLE - view?.floatingActionButton?.visibility = View.VISIBLE - searchItem?.isVisible = true - } - LOADED_EMPTY, FAILED -> { - view?.swipeRefreshLayoutView?.post { - view?.swipeRefreshLayoutView?.isRefreshing = false - } - view?.swipeRefreshLayoutView?.isEnabled = true - view?.loadingStateView?.visibility = View.GONE - view?.dataStateView?.visibility = View.GONE - searchItem?.isVisible = false - - if (value.equals(FAILED)) { - view?.stateWithMessageView?.errorStateTextView?.text = viewModel.messageData - if (viewModel.messageData.equals( - context.resources.getString(R.string.nc_no_connection_error) - ) - ) { - view?.stateWithMessageView?.errorStateImageView?.setImageResource( - drawable.ic_signal_wifi_off_white_24dp - ) - } else { - view?.stateWithMessageView?.errorStateImageView?.setImageResource( - drawable.ic_announcement_white_24dp - ) - } - view?.floatingActionButton?.visibility = View.GONE - } else { - view?.floatingActionButton?.visibility = View.VISIBLE - view?.stateWithMessageView?.errorStateTextView?.text = - resources?.getText(R.string.nc_conversations_empty) - view?.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo) - } - - view?.stateWithMessageView?.visibility = View.VISIBLE - } - else -> { - // We should not be here - } - } - }) return super.onCreateView(inflater, container) @@ -324,7 +264,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener, @OnClick(R.id.stateWithMessageView) fun onStateWithMessageViewClick() { - if (viewState.value!! == LOADED_EMPTY) { + if (view?.floatingActionButton?.isVisible == true) { openNewConversationScreen() } } @@ -392,7 +332,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener, ) } - if (conversation.canLeave(viewModel.currentUserLiveData.value!!)) { + if (conversation.canLeave(viewModel.globalService.currentUserLiveData.value!!)) { items.add( BasicListItemWithImage( drawable.ic_exit_to_app_black_24dp, context.getString @@ -401,7 +341,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener, ) } - if (conversation.canModerate(viewModel.currentUserLiveData.value!!)) { + if (conversation.canModerate(viewModel.globalService.currentUserLiveData.value!!)) { items.add( BasicListItemWithImage( drawable.ic_delete_grey600_24dp, context.getString( @@ -418,6 +358,11 @@ class ConversationsListView : BaseView(), OnQueryTextListener, return resources?.getString(R.string.nc_app_name) } + override fun onRestoreViewState(view: View, savedViewState: Bundle) { + super.onRestoreViewState(view, savedViewState) + viewModel.loadConversations() + } + override fun onAttach(view: View) { super.onAttach(view) view.recyclerView.initRecyclerView( @@ -432,7 +377,6 @@ class ConversationsListView : BaseView(), OnQueryTextListener, view.swipeRefreshLayoutView.isRefreshing = false viewModel.loadConversations() } - view.swipeRefreshLayoutView.setColorSchemeResources(R.color.colorPrimary) view.fast_scroller.setBubbleTextCreator { position -> @@ -514,15 +458,16 @@ class ConversationsListView : BaseView(), OnQueryTextListener, ): Boolean { val clickedItem = recyclerViewAdapter.getItem(position) if (clickedItem != null) { - val conversation = (clickedItem as ConversationItem).model + val conversationItem = clickedItem as ConversationItem + val conversation = conversationItem.model val bundle = Bundle() - bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, viewModel.currentUserLiveData.value) + bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, conversationItem.user) bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.token) bundle.putString(BundleKeys.KEY_ROOM_ID, conversation.conversationId) bundle.putParcelable(BundleKeys.KEY_ACTIVE_CONVERSATION, Parcels.wrap(conversation)) ConductorRemapping.remapChatController( - router, viewModel.currentUserLiveData.value!!.id!!, conversation.token!!, + router, conversationItem.user.id!!, conversation.token!!, bundle, false ) } diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt index d224dfa79..7f4aca2d0 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt @@ -21,30 +21,31 @@ package com.nextcloud.talk.newarch.features.conversationsList import android.app.Application -import android.content.Intent -import androidx.lifecycle.LiveData +import android.graphics.drawable.Drawable import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Transformations import androidx.lifecycle.viewModelScope +import coil.Coil +import coil.api.get +import coil.transform.CircleCropTransformation import com.nextcloud.talk.R -import com.nextcloud.talk.R.drawable -import com.nextcloud.talk.R.string -import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel import com.nextcloud.talk.newarch.data.model.ErrorModel import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository -import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUseCase import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse -import com.nextcloud.talk.newarch.local.models.UserNgEntity -import com.nextcloud.talk.utils.ShareUtils +import com.nextcloud.talk.newarch.local.models.getCredentials +import com.nextcloud.talk.newarch.services.GlobalService +import com.nextcloud.talk.utils.ApiUtils +import com.nextcloud.talk.utils.DisplayUtils import kotlinx.coroutines.launch import org.koin.core.parameter.parametersOf +import java.util.concurrent.locks.ReentrantLock class ConversationsListViewModel constructor( application: Application, @@ -53,14 +54,21 @@ class ConversationsListViewModel constructor( private val leaveConversationUseCase: LeaveConversationUseCase, private val deleteConversationUseCase: DeleteConversationUseCase, private val conversationsRepository: ConversationsRepository, - usersRepository: UsersRepository + val globalService: GlobalService ) : BaseViewModel(application) { + private val conversationsLoadingLock = ReentrantLock() + var messageData: String? = null val searchQuery = MutableLiveData() - val currentUserLiveData: LiveData = usersRepository.getActiveUserLiveData() - val conversationsLiveData = Transformations.switchMap(currentUserLiveData) { + val networkStateLiveData: MutableLiveData = MutableLiveData(ConversationsListViewNetworkState.LOADING) + val currentUserAvatar: MutableLiveData = MutableLiveData(DisplayUtils.getRoundedDrawable(context.getDrawable(R.drawable.ic_settings_white_24dp))) + val conversationsLiveData = Transformations.switchMap(globalService.currentUserLiveData) { + if (networkStateLiveData.value != ConversationsListViewNetworkState.LOADING) { + networkStateLiveData.postValue(ConversationsListViewNetworkState.LOADING) + } loadConversations() + loadAvatar() conversationsRepository.getConversationsForUser(it.id!!) } @@ -70,13 +78,13 @@ class ConversationsListViewModel constructor( } leaveConversationUseCase.invoke(viewModelScope, parametersOf( - currentUserLiveData.value, + globalService.currentUserLiveData.value, conversation ), object : UseCaseResponse { override suspend fun onSuccess(result: GenericOverall) { conversationsRepository.deleteConversation( - currentUserLiveData.value!!.id!!, conversation + globalService.currentUserLiveData.value!!.id!!, conversation .conversationId!! ) } @@ -99,13 +107,13 @@ class ConversationsListViewModel constructor( } deleteConversationUseCase.invoke(viewModelScope, parametersOf( - currentUserLiveData.value, + globalService.currentUserLiveData.value, conversation ), object : UseCaseResponse { override suspend fun onSuccess(result: GenericOverall) { conversationsRepository.deleteConversation( - currentUserLiveData.value!!.id!!, conversation + globalService.currentUserLiveData.value!!.id!!, conversation .conversationId!! ) } @@ -129,14 +137,14 @@ class ConversationsListViewModel constructor( } setConversationFavoriteValueUseCase.invoke(viewModelScope, parametersOf( - currentUserLiveData.value, + globalService.currentUserLiveData.value, conversation, favorite ), object : UseCaseResponse { override suspend fun onSuccess(result: GenericOverall) { conversationsRepository.setFavoriteValueForConversation( - currentUserLiveData.value!!.id!!, + globalService.currentUserLiveData.value!!.id!!, conversation.conversationId!!, favorite ) } @@ -150,26 +158,48 @@ class ConversationsListViewModel constructor( }) } + fun loadAvatar() { + val operationUser = globalService.currentUserLiveData.value + + operationUser?.let { + viewModelScope.launch { + val url = ApiUtils.getUrlForAvatarWithNameAndPixels(it.baseUrl, it.userId, 512) + val drawable = Coil.get((url)) { + addHeader("Authorization", it.getCredentials()) + transformations(CircleCropTransformation()) + } + currentUserAvatar.postValue(drawable) + } + } + } + fun loadConversations() { - getConversationsUseCase.invoke(viewModelScope, parametersOf(currentUserLiveData.value), object : - UseCaseResponse> { - override suspend fun onSuccess(result: List) { - val mutableList = result.toMutableList() - val internalUserId = currentUserLiveData.value!!.id - mutableList.forEach { - it.internalUserId = internalUserId + if (conversationsLoadingLock.tryLock()) { + getConversationsUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value), object : + UseCaseResponse> { + override suspend fun onSuccess( + result: List) { + networkStateLiveData.postValue(ConversationsListViewNetworkState.LOADED) + val mutableList = result.toMutableList() + val internalUserId = globalService.currentUserLiveData.value!!.id + mutableList.forEach { + it.internalUserId = internalUserId + } + + conversationsRepository.saveConversationsForUser( + internalUserId!!, + mutableList) + messageData = "" + conversationsLoadingLock.unlock() } - conversationsRepository.saveConversationsForUser( - internalUserId!!, - mutableList) - messageData = "" - } - - override suspend fun onError(errorModel: ErrorModel?) { - messageData = errorModel?.getErrorMessage() - } - }) + override suspend fun onError(errorModel: ErrorModel?) { + messageData = errorModel?.getErrorMessage() + networkStateLiveData.postValue(ConversationsListViewNetworkState.FAILED) + conversationsLoadingLock.unlock() + } + }) + } } @@ -178,7 +208,7 @@ class ConversationsListViewModel constructor( value: Boolean ) { conversationsRepository.setChangingValueForConversation( - currentUserLiveData.value!!.id!!, conversation + globalService.currentUserLiveData.value!!.id!!, conversation .conversationId!!, value ) } diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewState.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewNetworkState.kt similarity index 93% rename from app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewState.kt rename to app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewNetworkState.kt index 4bd9f7029..16e878303 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewState.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewNetworkState.kt @@ -20,8 +20,7 @@ package com.nextcloud.talk.newarch.features.conversationsList -enum class ConversationsListViewState { - INITIAL_LOAD, +enum class ConversationsListViewNetworkState { LOADING, LOADED_EMPTY, LOADED, diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt index 94c07103f..a32126e27 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt @@ -22,12 +22,12 @@ package com.nextcloud.talk.newarch.features.conversationsList.di.module import android.app.Application import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository -import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUseCase import com.nextcloud.talk.newarch.features.conversationsList.ConversationListViewModelFactory +import com.nextcloud.talk.newarch.services.GlobalService import org.koin.android.ext.koin.androidApplication import org.koin.dsl.module @@ -49,11 +49,11 @@ fun createConversationListViewModelFactory( leaveConversationUseCase: LeaveConversationUseCase, deleteConversationUseCase: DeleteConversationUseCase, conversationsRepository: ConversationsRepository, - usersRepository: UsersRepository + globalService: GlobalService ): ConversationListViewModelFactory { return ConversationListViewModelFactory( application, getConversationsUseCase, setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase, - conversationsRepository, usersRepository + conversationsRepository, globalService ) } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationReadOnlyStateConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationReadOnlyStateConverter.kt index b2e49177f..e0e34c641 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationReadOnlyStateConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationReadOnlyStateConverter.kt @@ -34,9 +34,9 @@ class ConversationReadOnlyStateConverter { @TypeConverter fun fromIntToConversationType(value: Int): ConversationReadOnlyState { - when (value) { - 0 -> return CONVERSATION_READ_WRITE - else -> return CONVERSATION_READ_ONLY + return when (value) { + 0 -> CONVERSATION_READ_WRITE + else -> CONVERSATION_READ_ONLY } } } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt index a5ad58c07..2e623c073 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt @@ -26,7 +26,7 @@ import androidx.room.TypeConverter import com.bluelinelabs.logansquare.LoganSquare import com.nextcloud.talk.models.json.participants.Participant -class ParticipantMapConverter { +class ParticipantMapConverter { @TypeConverter fun fromMapToString(map: HashMap?): String? { if (map == null) { diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt index 424745484..46d5a277b 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt @@ -26,11 +26,11 @@ import com.nextcloud.talk.models.json.participants.Participant.ParticipantType class ParticipantTypeConverter { @TypeConverter fun fromParticipantType(participantType: ParticipantType): Int { - return participantType.ordinal + return participantType.value } @TypeConverter fun fromIntToParticipantType(value: Int): ParticipantType { - return ParticipantType.fromValue(value.toLong()) + return ParticipantType.fromValue(value) } } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt index 9c9450c33..f1603a746 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt @@ -96,7 +96,7 @@ data class ConversationEntity( if (lastActivity != other.lastActivity) return false if (unreadMessages != other.unreadMessages) return false if (unreadMention != other.unreadMention) return false - if (lastMessage?.internalMessageId != other.lastMessage?.internalMessageId) return false + if (lastMessage != other.lastMessage) return false if (objectType != other.objectType) return false if (notificationLevel != other.notificationLevel) return false if (conversationReadOnlyState != other.conversationReadOnlyState) return false diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt index b4ed67885..725def02f 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/UserNgEntity.kt @@ -30,6 +30,7 @@ import com.nextcloud.talk.models.json.push.PushConfigurationState import com.nextcloud.talk.newarch.local.models.other.UserStatus import com.nextcloud.talk.utils.ApiUtils import kotlinx.android.parcel.Parcelize +import java.util.* @Parcelize @Entity(tableName = "users") @@ -63,7 +64,7 @@ data class UserNgEntity( other as UserNgEntity if (userId != other.userId) return false - if (username != other.username) return false + //if (username != other.username) return false if (baseUrl != other.baseUrl) return false if (token != other.token) return false if (displayName != other.displayName) return false @@ -77,7 +78,7 @@ data class UserNgEntity( } override fun hashCode(): Int { - return userId.hashCode() + return Objects.hash(userId, username) } } diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/GlobalService.kt b/app/src/main/java/com/nextcloud/talk/newarch/services/GlobalService.kt similarity index 83% rename from app/src/main/java/com/nextcloud/talk/newarch/utils/GlobalService.kt rename to app/src/main/java/com/nextcloud/talk/newarch/services/GlobalService.kt index 73acebdbf..5d2d8b4b5 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/utils/GlobalService.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/services/GlobalService.kt @@ -1,24 +1,26 @@ /* - * Nextcloud Talk application * - * @author Mario Danic - * Copyright (C) 2017-2019 Mario Danic + * * Nextcloud Talk application + * * + * * @author Mario Danic + * * Copyright (C) 2017-2020 Mario Danic + * * + * * This program is free software: you can redistribute it and/or modify + * * it under the terms of the GNU General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * at your option) any later version. + * * + * * This program is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU General Public License for more details. + * * + * * You should have received a copy of the GNU General Public License + * * along with this program. If not, see . * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . */ -package com.nextcloud.talk.newarch.utils +package com.nextcloud.talk.newarch.services import androidx.lifecycle.LiveData import com.nextcloud.talk.models.json.conversations.Conversation diff --git a/app/src/main/java/com/nextcloud/talk/newarch/services/GlobalServiceInterface.kt b/app/src/main/java/com/nextcloud/talk/newarch/services/GlobalServiceInterface.kt new file mode 100644 index 000000000..e5930c5b6 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/newarch/services/GlobalServiceInterface.kt @@ -0,0 +1,36 @@ +/* + * + * * Nextcloud Talk application + * * + * * @author Mario Danic + * * Copyright (C) 2017-2020 Mario Danic + * * + * * This program is free software: you can redistribute it and/or modify + * * it under the terms of the GNU General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * at your option) any later version. + * * + * * This program is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU General Public License for more details. + * * + * * You should have received a copy of the GNU General Public License + * * along with this program. If not, see . + * + */ + +package com.nextcloud.talk.newarch.services + +import com.nextcloud.talk.models.json.conversations.Conversation +import com.nextcloud.talk.newarch.local.models.UserNgEntity + +interface GlobalServiceInterface { + enum class OperationStatus { + STATUS_OK, + STATUS_FAILED + } + + suspend fun gotConversationInfoForUser(userNgEntity: UserNgEntity, conversation: Conversation?, operationStatus: OperationStatus) + suspend fun joinedConversationForUser(userNgEntity: UserNgEntity, conversation: Conversation?, operationStatus: OperationStatus) +} diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/GlobalServiceInterface.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/GlobalServiceInterface.kt deleted file mode 100644 index 10bddce45..000000000 --- a/app/src/main/java/com/nextcloud/talk/newarch/utils/GlobalServiceInterface.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Nextcloud Talk application - * - * @author Mario Danic - * Copyright (C) 2017-2019 Mario Danic - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.nextcloud.talk.newarch.utils - -import com.nextcloud.talk.models.json.conversations.Conversation -import com.nextcloud.talk.newarch.local.models.UserNgEntity - -interface GlobalServiceInterface { - enum class OperationStatus { - STATUS_OK, - STATUS_FAILED - } - - suspend fun gotConversationInfoForUser(userNgEntity: UserNgEntity, conversation: Conversation?, operationStatus: OperationStatus) - suspend fun joinedConversationForUser(userNgEntity: UserNgEntity, conversation: Conversation?, operationStatus: OperationStatus) -} diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt index a8e5b1186..b0cf24a62 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt @@ -20,18 +20,9 @@ package com.nextcloud.talk.newarch.utils -import android.app.ActivityManager import android.content.Context -import android.content.Context.ACTIVITY_SERVICE -import android.graphics.Bitmap -import android.graphics.Rect -import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable -import android.os.Build -import androidx.annotation.RequiresApi -import androidx.core.content.ContextCompat.getSystemService -import androidx.core.graphics.drawable.toBitmap import androidx.lifecycle.LifecycleOwner import coil.ImageLoader import coil.request.LoadRequest @@ -73,7 +64,7 @@ class Images { } } } - + // returns null if it's one-to-one that you need to fetch yourself fun getImageForConversation(context: Context, conversation: Conversation): Drawable? { conversation.objectType?.let { objectType -> diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/ShortcutService.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/ShortcutService.kt index 9f3bc460f..88ec4d34d 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/utils/ShortcutService.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/ShortcutService.kt @@ -42,6 +42,7 @@ import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository import com.nextcloud.talk.newarch.local.models.UserNgEntity import com.nextcloud.talk.newarch.local.models.getCredentials +import com.nextcloud.talk.newarch.services.GlobalService import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.bundle.BundleKeys import kotlinx.coroutines.GlobalScope diff --git a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt index 9f60a5507..ba9310b39 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt @@ -25,7 +25,9 @@ import android.content.Context import android.content.Intent import android.content.res.ColorStateList import android.content.res.Resources -import android.graphics.* +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Typeface import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.net.Uri @@ -47,7 +49,6 @@ import androidx.annotation.DrawableRes import androidx.annotation.XmlRes import androidx.appcompat.widget.AppCompatDrawableManager import androidx.core.content.ContextCompat -import androidx.core.graphics.applyCanvas import androidx.core.graphics.drawable.DrawableCompat import androidx.emoji.text.EmojiCompat import coil.Coil @@ -66,7 +67,6 @@ import kotlinx.coroutines.runBlocking import org.greenrobot.eventbus.EventBus import java.lang.reflect.InvocationTargetException import java.util.regex.Pattern -import kotlin.math.min object DisplayUtils { diff --git a/app/src/main/res/layout/view_states.xml b/app/src/main/res/layout/view_states.xml index a1b9a00e1..7a2f7c38e 100644 --- a/app/src/main/res/layout/view_states.xml +++ b/app/src/main/res/layout/view_states.xml @@ -40,6 +40,7 @@ android:id="@+id/stateWithMessageView" android:layout_width="match_parent" android:layout_height="match_parent" + android:visibility="gone" > - + xmlns:app="http://schemas.android.com/apk/res-auto"> - - + + - +