mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-14 16:25:05 +01:00
Serious fixes to loading mechanism
This commit is contained in:
parent
f311aa1d16
commit
3767b7fd61
@ -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<ConversationItem.ConversationItemViewHolder>(), IFilterable<String> {
|
||||
|
||||
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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<RelativeLayout>(R.id.quotedChatMessageView)?.tag as Long?
|
||||
sendMessage(editable, if (view?.findViewById<RelativeLayout>(R.id.quotedChatMessageView)?.visibility == View.VISIBLE) replyMessageId?.toInt() else null )
|
||||
sendMessage(editable, if (view?.findViewById<RelativeLayout>(R.id.quotedChatMessageView)?.visibility == View.VISIBLE) replyMessageId?.toInt() else null)
|
||||
cancelReply()
|
||||
}
|
||||
}
|
||||
@ -1412,7 +1412,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.ellipsize = TextUtils.TruncateAt.END
|
||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.text = it.text
|
||||
messageInputView?.findViewById<TextView>(R.id.quotedMessageTime)?.text = DateFormatter.format(it.createdAt, DateFormatter.Template.TIME)
|
||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessageAuthor)?.text = it.actorDisplayName ?: context.getText(R.string.nc_nick_guest)
|
||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessageAuthor)?.text = it.actorDisplayName
|
||||
?: context.getText(R.string.nc_nick_guest)
|
||||
|
||||
conversationUser?.let { currentUser ->
|
||||
messageInputView?.findViewById<ImageView>(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<ImageView>(R.id.quotedMessageImage)?.visibility = View.VISIBLE
|
||||
|
||||
val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 96f, resources?.displayMetrics)
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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*/
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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<MessageType> 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()) {
|
||||
|
@ -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<Participant.ParticipantFlags>() {
|
||||
override fun getFromLong(l: Long): Participant.ParticipantFlags {
|
||||
class EnumParticipantFlagsConverter : IntBasedTypeConverter<Participant.ParticipantFlags>() {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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,7 +58,7 @@ 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")
|
||||
@ -64,6 +66,27 @@ public class Participant {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return ConversationsListViewModel(
|
||||
application, conversationsUseCase,
|
||||
setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase,
|
||||
conversationsRepository, usersRepository
|
||||
conversationsRepository, globalService
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
@ -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<ConversationsListViewState> = 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<ConversationItem>()
|
||||
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<IFlexible<ViewHolder>>?, 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
|
||||
)
|
||||
}
|
||||
|
@ -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<ConversationsListView>(application) {
|
||||
|
||||
private val conversationsLoadingLock = ReentrantLock()
|
||||
|
||||
var messageData: String? = null
|
||||
val searchQuery = MutableLiveData<String>()
|
||||
val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData()
|
||||
val conversationsLiveData = Transformations.switchMap(currentUserLiveData) {
|
||||
val networkStateLiveData: MutableLiveData<ConversationsListViewNetworkState> = MutableLiveData(ConversationsListViewNetworkState.LOADING)
|
||||
val currentUserAvatar: MutableLiveData<Drawable> = 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<GenericOverall> {
|
||||
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<GenericOverall> {
|
||||
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<GenericOverall> {
|
||||
override suspend fun onSuccess(result: GenericOverall) {
|
||||
conversationsRepository.setFavoriteValueForConversation(
|
||||
currentUserLiveData.value!!.id!!,
|
||||
globalService.currentUserLiveData.value!!.id!!,
|
||||
conversation.conversationId!!, favorite
|
||||
)
|
||||
}
|
||||
@ -150,12 +158,30 @@ 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 :
|
||||
if (conversationsLoadingLock.tryLock()) {
|
||||
getConversationsUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value), object :
|
||||
UseCaseResponse<List<Conversation>> {
|
||||
override suspend fun onSuccess(result: List<Conversation>) {
|
||||
override suspend fun onSuccess(
|
||||
result: List<Conversation>) {
|
||||
networkStateLiveData.postValue(ConversationsListViewNetworkState.LOADED)
|
||||
val mutableList = result.toMutableList()
|
||||
val internalUserId = currentUserLiveData.value!!.id
|
||||
val internalUserId = globalService.currentUserLiveData.value!!.id
|
||||
mutableList.forEach {
|
||||
it.internalUserId = internalUserId
|
||||
}
|
||||
@ -164,13 +190,17 @@ class ConversationsListViewModel constructor(
|
||||
internalUserId!!,
|
||||
mutableList)
|
||||
messageData = ""
|
||||
conversationsLoadingLock.unlock()
|
||||
}
|
||||
|
||||
override suspend fun onError(errorModel: ErrorModel?) {
|
||||
messageData = errorModel?.getErrorMessage()
|
||||
networkStateLiveData.postValue(ConversationsListViewNetworkState.FAILED)
|
||||
conversationsLoadingLock.unlock()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private suspend fun setConversationUpdateStatus(
|
||||
@ -178,7 +208,7 @@ class ConversationsListViewModel constructor(
|
||||
value: Boolean
|
||||
) {
|
||||
conversationsRepository.setChangingValueForConversation(
|
||||
currentUserLiveData.value!!.id!!, conversation
|
||||
globalService.currentUserLiveData.value!!.id!!, conversation
|
||||
.conversationId!!, value
|
||||
)
|
||||
}
|
||||
|
@ -20,8 +20,7 @@
|
||||
|
||||
package com.nextcloud.talk.newarch.features.conversationsList
|
||||
|
||||
enum class ConversationsListViewState {
|
||||
INITIAL_LOAD,
|
||||
enum class ConversationsListViewNetworkState {
|
||||
LOADING,
|
||||
LOADED_EMPTY,
|
||||
LOADED,
|
@ -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
|
||||
)
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,26 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||
* * Nextcloud Talk application
|
||||
* *
|
||||
* * @author Mario Danic
|
||||
* * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||
* *
|
||||
* * 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.newarch.utils
|
||||
package com.nextcloud.talk.newarch.services
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
*
|
||||
* * Nextcloud Talk application
|
||||
* *
|
||||
* * @author Mario Danic
|
||||
* * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||
* *
|
||||
* * 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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)
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
android:id="@+id/stateWithMessageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Nextcloud Talk application
|
||||
~
|
||||
~ @author Mario Danic
|
||||
@ -23,18 +22,20 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<!-- Search, should appear as action button -->
|
||||
<item android:id="@+id/action_search"
|
||||
android:title="@string/nc_search"
|
||||
android:icon="@drawable/ic_search_white_24dp"
|
||||
app:showAsAction="collapseActionView|always"
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:animateLayoutChanges="true"
|
||||
android:icon="@drawable/ic_search_white_24dp"
|
||||
android:title="@string/nc_search"
|
||||
android:visible="false"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
/>
|
||||
app:showAsAction="collapseActionView|always" />
|
||||
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/nc_settings"
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:icon="@drawable/ic_settings_white_24dp"
|
||||
app:showAsAction="ifRoom"/>
|
||||
android:title="@string/nc_settings"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
|
||||
</menu>
|
||||
|
Loading…
Reference in New Issue
Block a user