diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java index a6f27fd92..998243f99 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java @@ -35,10 +35,6 @@ import eu.davidea.viewholders.FlexibleViewHolder; public class ContactItem extends AbstractFlexibleItem implements ISectionable, IFilterable { - public static final String PARTICIPANT_SOURCE_CIRCLES = "circles"; - public static final String PARTICIPANT_SOURCE_GROUPS = "groups"; - public static final String PARTICIPANT_SOURCE_USERS = "users"; - private final Participant participant; private final User user; private GenericTextHeaderItem header; @@ -133,9 +129,7 @@ public class ContactItem extends AbstractFlexibleItem - * SPDX-FileCopyrightText: 2021 Andy Scherzinger - * SPDX-FileCopyrightText: 2017 Mario Danic - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package com.nextcloud.talk.adapters.items; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.res.Resources; -import android.text.TextUtils; -import android.view.View; - -import com.nextcloud.talk.R; -import com.nextcloud.talk.application.NextcloudTalkApplication; -import com.nextcloud.talk.data.user.model.User; -import com.nextcloud.talk.databinding.RvItemConversationInfoParticipantBinding; -import com.nextcloud.talk.extensions.ImageViewExtensionsKt; -import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter; -import com.nextcloud.talk.models.json.participants.Participant; -import com.nextcloud.talk.models.json.participants.Participant.InCallFlags; -import com.nextcloud.talk.models.json.status.StatusType; -import com.nextcloud.talk.ui.StatusDrawable; -import com.nextcloud.talk.ui.theme.ViewThemeUtils; -import com.nextcloud.talk.utils.DisplayUtils; - -import java.util.List; -import java.util.regex.Pattern; - -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.core.content.res.ResourcesCompat; -import eu.davidea.flexibleadapter.FlexibleAdapter; -import eu.davidea.flexibleadapter.items.AbstractFlexibleItem; -import eu.davidea.flexibleadapter.items.IFilterable; -import eu.davidea.viewholders.FlexibleViewHolder; - -public class ParticipantItem extends AbstractFlexibleItem implements - IFilterable { - - private static final float STATUS_SIZE_IN_DP = 9f; - private static final String NO_ICON = ""; - - private final Context context; - private final Participant participant; - private final User user; - private final ViewThemeUtils viewThemeUtils; - public boolean isOnline = true; - - public ParticipantItem(Context activityContext, - Participant participant, - User user, ViewThemeUtils viewThemeUtils) { - this.context = activityContext; - this.participant = participant; - this.user = user; - this.viewThemeUtils = viewThemeUtils; - } - - public Participant getModel() { - return participant; - } - - @Override - public boolean equals(Object o) { - if (o instanceof ParticipantItem inItem) { - return participant.getCalculatedActorType() == inItem.getModel().getCalculatedActorType() && - participant.getCalculatedActorId().equals(inItem.getModel().getCalculatedActorId()); - } - return false; - } - - @Override - public int hashCode() { - return participant.hashCode(); - } - - @Override - public int getLayoutRes() { - return R.layout.rv_item_conversation_info_participant; - } - - @Override - public ParticipantItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) { - return new ParticipantItemViewHolder(view, adapter); - } - - @SuppressLint("SetTextI18n") - @Override - public void bindViewHolder(FlexibleAdapter adapter, ParticipantItemViewHolder holder, int position, List payloads) { - - drawStatus(holder); - - if (!isOnline) { - holder.binding.nameText.setTextColor(ResourcesCompat.getColor( - holder.binding.nameText.getContext().getResources(), - R.color.medium_emphasis_text, - null) - ); - holder.binding.avatarView.setAlpha(0.38f); - } else { - holder.binding.nameText.setTextColor(ResourcesCompat.getColor( - holder.binding.nameText.getContext().getResources(), - R.color.high_emphasis_text, - null) - ); - holder.binding.avatarView.setAlpha(1.0f); - } - - holder.binding.nameText.setText(participant.getDisplayName()); - - if (adapter.hasFilter()) { - viewThemeUtils.talk.themeAndHighlightText(holder.binding.nameText, participant.getDisplayName(), - String.valueOf(adapter.getFilter(String.class))); - } - - if (TextUtils.isEmpty(participant.getDisplayName()) && - (participant.getType() == Participant.ParticipantType.GUEST || - participant.getType() == Participant.ParticipantType.USER_FOLLOWING_LINK)) { - holder.binding.nameText.setText(NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_guest)); - } - - if (participant.getCalculatedActorType() == Participant.ActorType.GROUPS || - "groups".equals(participant.getSource()) || - participant.getCalculatedActorType() == Participant.ActorType.CIRCLES || - "circles".equals(participant.getSource())) { - ImageViewExtensionsKt.loadDefaultGroupCallAvatar(holder.binding.avatarView, viewThemeUtils); - } else if (participant.getCalculatedActorType() == Participant.ActorType.EMAILS) { - ImageViewExtensionsKt.loadMailAvatar(holder.binding.avatarView, viewThemeUtils); - } else if (participant.getCalculatedActorType() == Participant.ActorType.GUESTS || - participant.getType() == Participant.ParticipantType.GUEST || - participant.getType() == Participant.ParticipantType.GUEST_MODERATOR) { - - String displayName = NextcloudTalkApplication - .Companion - .getSharedApplication() - .getResources() - .getString(R.string.nc_guest); - - if (!TextUtils.isEmpty(participant.getDisplayName())) { - displayName = participant.getDisplayName(); - } - - ImageViewExtensionsKt.loadGuestAvatar(holder.binding.avatarView, user, displayName, false); - - } else if (participant.getCalculatedActorType() == Participant.ActorType.USERS || - "users".equals(participant.getSource())) { - ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, - user, - participant.getCalculatedActorId(), - true, false); - } - - Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources(); - - long inCallFlag = participant.getInCall(); - if ((inCallFlag & InCallFlags.WITH_PHONE) > 0) { - holder.binding.videoCallIcon.setImageResource(R.drawable.ic_call_grey_600_24dp); - holder.binding.videoCallIcon.setVisibility(View.VISIBLE); - holder.binding.videoCallIcon.setContentDescription( - resources.getString(R.string.nc_call_state_with_phone, participant.getDisplayName())); - } else if ((inCallFlag & InCallFlags.WITH_VIDEO) > 0) { - holder.binding.videoCallIcon.setImageResource(R.drawable.ic_videocam_grey_600_24dp); - holder.binding.videoCallIcon.setVisibility(View.VISIBLE); - holder.binding.videoCallIcon.setContentDescription( - resources.getString(R.string.nc_call_state_with_video, participant.getDisplayName())); - } else if (inCallFlag > InCallFlags.DISCONNECTED) { - holder.binding.videoCallIcon.setImageResource(R.drawable.ic_mic_grey_600_24dp); - holder.binding.videoCallIcon.setVisibility(View.VISIBLE); - holder.binding.videoCallIcon.setContentDescription( - resources.getString(R.string.nc_call_state_in_call, participant.getDisplayName())); - } else { - holder.binding.videoCallIcon.setVisibility(View.GONE); - } - - String userType = ""; - - switch (new EnumParticipantTypeConverter().convertToInt(participant.getType())) { - case 1: - //userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_owner); - //break; - case 2: - case 6: // Guest moderator - userType = NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_moderator); - break; - case 3: - userType = NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_user); - if (participant.getCalculatedActorType() == Participant.ActorType.GROUPS) { - userType = NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_group); - } - if (participant.getCalculatedActorType() == Participant.ActorType.CIRCLES) { - userType = NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_team); - } - break; - case 4: - userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest); - if (participant.getCalculatedActorType() == Participant.ActorType.EMAILS) { - userType = NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_email); - } - break; - case 5: - userType = NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_following_link); - break; - default: - break; - } - - if (!userType.equals(NextcloudTalkApplication - .Companion - .getSharedApplication() - .getString(R.string.nc_user))) { - holder.binding.secondaryText.setText("(" + userType + ")"); - } - } - - private void drawStatus(ParticipantItemViewHolder holder) { - float size = DisplayUtils.convertDpToPixel(STATUS_SIZE_IN_DP, context); - holder.binding.userStatusImage.setImageDrawable(new StatusDrawable( - participant.getStatus(), - NO_ICON, - size, - context.getResources().getColor(R.color.bg_default), - context)); - - if (participant.getStatusMessage() != null) { - holder.binding.conversationInfoStatusMessage.setText(participant.getStatusMessage()); - alignUsernameVertical(holder, 0); - } else { - holder.binding.conversationInfoStatusMessage.setText(""); - alignUsernameVertical(holder, 10); - } - - if (participant.getStatusIcon() != null && !participant.getStatusIcon().isEmpty()) { - holder.binding.participantStatusEmoji.setText(participant.getStatusIcon()); - } else { - holder.binding.participantStatusEmoji.setVisibility(View.GONE); - } - - if (participant.getStatus() != null && participant.getStatus().equals(StatusType.DND.getString())) { - if (participant.getStatusMessage() == null || participant.getStatusMessage().isEmpty()) { - holder.binding.conversationInfoStatusMessage.setText(R.string.dnd); - } - } else if (participant.getStatus() != null && participant.getStatus().equals(StatusType.AWAY.getString())) { - if (participant.getStatusMessage() == null || participant.getStatusMessage().isEmpty()) { - holder.binding.conversationInfoStatusMessage.setText(R.string.away); - } - } - } - - private void alignUsernameVertical(ParticipantItem.ParticipantItemViewHolder holder, float densityPixelsFromTop) { - ConstraintLayout.LayoutParams layoutParams = - (ConstraintLayout.LayoutParams) holder.binding.nameText.getLayoutParams(); - layoutParams.topMargin = (int) DisplayUtils.convertDpToPixel(densityPixelsFromTop, context); - holder.binding.nameText.setLayoutParams(layoutParams); - } - - @Override - public boolean filter(String constraint) { - return participant.getDisplayName() != null && - (Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL) - .matcher(participant.getDisplayName().trim()).find() || - Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL) - .matcher(participant.getCalculatedActorId().trim()).find()); - } - - public static class ParticipantItemViewHolder extends FlexibleViewHolder { - - RvItemConversationInfoParticipantBinding binding; - - /** - * Default constructor. - */ - ParticipantItemViewHolder(View view, FlexibleAdapter adapter) { - super(view, adapter); - binding = RvItemConversationInfoParticipantBinding.bind(view); - } - } -} diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ParticipantItem.kt b/app/src/main/java/com/nextcloud/talk/adapters/items/ParticipantItem.kt new file mode 100644 index 000000000..9126cd6b3 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ParticipantItem.kt @@ -0,0 +1,300 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2022 Marcel Hibbe + * SPDX-FileCopyrightText: 2021 Andy Scherzinger + * SPDX-FileCopyrightText: 2017 Mario Danic + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package com.nextcloud.talk.adapters.items + +import android.annotation.SuppressLint +import android.content.Context +import android.text.TextUtils +import android.util.Log +import android.view.View +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.res.ResourcesCompat +import androidx.recyclerview.widget.RecyclerView +import com.nextcloud.talk.R +import com.nextcloud.talk.adapters.items.ParticipantItem.ParticipantItemViewHolder +import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication +import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.databinding.RvItemConversationInfoParticipantBinding +import com.nextcloud.talk.extensions.loadDefaultGroupCallAvatar +import com.nextcloud.talk.extensions.loadFederatedUserAvatar +import com.nextcloud.talk.extensions.loadGuestAvatar +import com.nextcloud.talk.extensions.loadMailAvatar +import com.nextcloud.talk.extensions.loadUserAvatar +import com.nextcloud.talk.models.json.participants.Participant +import com.nextcloud.talk.models.json.participants.Participant.InCallFlags +import com.nextcloud.talk.models.json.status.StatusType +import com.nextcloud.talk.ui.StatusDrawable +import com.nextcloud.talk.ui.theme.ViewThemeUtils +import com.nextcloud.talk.utils.DisplayUtils +import com.nextcloud.talk.utils.DisplayUtils.convertDpToPixel +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import eu.davidea.flexibleadapter.items.IFilterable +import eu.davidea.flexibleadapter.items.IFlexible +import eu.davidea.viewholders.FlexibleViewHolder +import java.util.regex.Pattern + +class ParticipantItem( + private val context: Context, + val model: Participant, + private val user: User, + private val viewThemeUtils: ViewThemeUtils, + private val roomToken: String +) : AbstractFlexibleItem(), IFilterable { + var isOnline = true + override fun equals(o: Any?): Boolean { + return if (o is ParticipantItem) { + model.calculatedActorType == o.model.calculatedActorType && + model.calculatedActorId == o.model.calculatedActorId + } else { + false + } + } + + override fun hashCode(): Int { + return model.hashCode() + } + + override fun getLayoutRes(): Int { + return R.layout.rv_item_conversation_info_participant + } + + override fun createViewHolder( + view: View?, + adapter: FlexibleAdapter>? + ): ParticipantItemViewHolder { + return ParticipantItemViewHolder(view, adapter) + } + + @SuppressLint("SetTextI18n") + override fun bindViewHolder( + adapter: FlexibleAdapter>?, + holder: ParticipantItemViewHolder?, + position: Int, + payloads: List<*>? + ) { + drawStatus(holder!!) + setOnlineStateColor(holder) + holder.binding.nameText.text = model.displayName + + if (adapter!!.hasFilter()) { + viewThemeUtils.talk.themeAndHighlightText( + holder.binding.nameText, + model.displayName, + adapter.getFilter( + String::class.java + ).toString() + ) + } + loadAvatars(holder) + showCallIcons(holder) + setParticipantInfo(holder) + } + + @SuppressLint("SetTextI18n") + private fun setParticipantInfo(holder: ParticipantItemViewHolder) { + if (TextUtils.isEmpty(model.displayName) && ( + model.type == Participant.ParticipantType.GUEST || + model.type == Participant.ParticipantType.USER_FOLLOWING_LINK + ) + ) { + holder.binding.nameText.text = sharedApplication!!.getString(R.string.nc_guest) + } + + var userType = "" + when (model.type) { + Participant.ParticipantType.OWNER, + Participant.ParticipantType.MODERATOR, + Participant.ParticipantType.GUEST_MODERATOR -> { + userType = sharedApplication!!.getString(R.string.nc_moderator) + } + + Participant.ParticipantType.USER -> { + userType = sharedApplication!!.getString(R.string.nc_user) + if (model.calculatedActorType == Participant.ActorType.GROUPS) { + userType = sharedApplication!!.getString(R.string.nc_group) + } + if (model.calculatedActorType == Participant.ActorType.CIRCLES) { + userType = sharedApplication!!.getString(R.string.nc_team) + } + } + + Participant.ParticipantType.GUEST -> { + userType = sharedApplication!!.getString(R.string.nc_guest) + if (model.calculatedActorType == Participant.ActorType.EMAILS) { + userType = sharedApplication!!.getString(R.string.nc_email) + } + } + + Participant.ParticipantType.USER_FOLLOWING_LINK -> { + userType = sharedApplication!!.getString(R.string.nc_following_link) + } + + else -> {} + } + if (userType != sharedApplication!!.getString(R.string.nc_user)) { + holder.binding.secondaryText.text = "($userType)" + } + } + + private fun setOnlineStateColor(holder: ParticipantItemViewHolder) { + if (!isOnline) { + holder.binding.nameText.setTextColor( + ResourcesCompat.getColor( + holder.binding.nameText.context.resources, + R.color.medium_emphasis_text, + null + ) + ) + holder.binding.avatarView.setAlpha(NOT_ONLINE_ALPHA) + } else { + holder.binding.nameText.setTextColor( + ResourcesCompat.getColor( + holder.binding.nameText.context.resources, + R.color.high_emphasis_text, + null + ) + ) + holder.binding.avatarView.setAlpha(1.0f) + } + } + + private fun showCallIcons(holder: ParticipantItemViewHolder) { + val resources = sharedApplication!!.resources + val inCallFlag = model.inCall + if (inCallFlag and InCallFlags.WITH_PHONE.toLong() > 0) { + holder.binding.videoCallIcon.setImageResource(R.drawable.ic_call_grey_600_24dp) + holder.binding.videoCallIcon.setVisibility(View.VISIBLE) + holder.binding.videoCallIcon.setContentDescription( + resources.getString(R.string.nc_call_state_with_phone, model.displayName) + ) + } else if (inCallFlag and InCallFlags.WITH_VIDEO.toLong() > 0) { + holder.binding.videoCallIcon.setImageResource(R.drawable.ic_videocam_grey_600_24dp) + holder.binding.videoCallIcon.setVisibility(View.VISIBLE) + holder.binding.videoCallIcon.setContentDescription( + resources.getString(R.string.nc_call_state_with_video, model.displayName) + ) + } else if (inCallFlag > InCallFlags.DISCONNECTED) { + holder.binding.videoCallIcon.setImageResource(R.drawable.ic_mic_grey_600_24dp) + holder.binding.videoCallIcon.setVisibility(View.VISIBLE) + holder.binding.videoCallIcon.setContentDescription( + resources.getString(R.string.nc_call_state_in_call, model.displayName) + ) + } else { + holder.binding.videoCallIcon.setVisibility(View.GONE) + } + } + + private fun loadAvatars(holder: ParticipantItemViewHolder) { + when (model.calculatedActorType) { + Participant.ActorType.GROUPS, Participant.ActorType.CIRCLES -> { + holder.binding.avatarView.loadDefaultGroupCallAvatar(viewThemeUtils) + } + + Participant.ActorType.EMAILS -> { + holder.binding.avatarView.loadMailAvatar(viewThemeUtils) + } + + Participant.ActorType.USERS -> { + holder.binding.avatarView.loadUserAvatar(user, model.calculatedActorId!!, true, false) + } + + Participant.ActorType.GUESTS -> { + var displayName: String? = sharedApplication!!.resources.getString(R.string.nc_guest) + if (!TextUtils.isEmpty(model.displayName)) { + displayName = model.displayName + } + holder.binding.avatarView.loadGuestAvatar(user, displayName!!, false) + } + + Participant.ActorType.FEDERATED -> { + val darkTheme = if (DisplayUtils.isDarkModeOn(context)) 1 else 0 + holder.binding.avatarView.loadFederatedUserAvatar( + user, + user.baseUrl!!, + roomToken, + model.actorId!!, + darkTheme, + true, + false + ) + } + + else -> { + Log.w(TAG, "Avatar not shown because of unknown ActorType " + model.calculatedActorType) + } + } + } + + @Suppress("MagicNumber") + private fun drawStatus(holder: ParticipantItemViewHolder) { + val size = convertDpToPixel(STATUS_SIZE_IN_DP, context) + holder.binding.userStatusImage.setImageDrawable( + StatusDrawable( + model.status, + NO_ICON, + size, + context.resources.getColor(R.color.bg_default), + context + ) + ) + if (model.statusMessage != null) { + holder.binding.conversationInfoStatusMessage.text = model.statusMessage + alignUsernameVertical(holder, 0f) + } else { + holder.binding.conversationInfoStatusMessage.text = "" + alignUsernameVertical(holder, 10f) + } + if (model.statusIcon != null && model.statusIcon!!.isNotEmpty()) { + holder.binding.participantStatusEmoji.setText(model.statusIcon) + } else { + holder.binding.participantStatusEmoji.visibility = View.GONE + } + if (model.status != null && model.status == StatusType.DND.string) { + if (model.statusMessage == null || model.statusMessage!!.isEmpty()) { + holder.binding.conversationInfoStatusMessage.setText(R.string.dnd) + } + } else if (model.status != null && model.status == StatusType.AWAY.string) { + if (model.statusMessage == null || model.statusMessage!!.isEmpty()) { + holder.binding.conversationInfoStatusMessage.setText(R.string.away) + } + } + } + + private fun alignUsernameVertical(holder: ParticipantItemViewHolder, densityPixelsFromTop: Float) { + val layoutParams = holder.binding.nameText.layoutParams as ConstraintLayout.LayoutParams + layoutParams.topMargin = convertDpToPixel(densityPixelsFromTop, context).toInt() + holder.binding.nameText.setLayoutParams(layoutParams) + } + + override fun filter(constraint: String?): Boolean { + return model.displayName != null && ( + Pattern.compile(constraint, Pattern.CASE_INSENSITIVE or Pattern.LITERAL) + .matcher(model.displayName!!.trim { it <= ' ' }).find() || + Pattern.compile(constraint, Pattern.CASE_INSENSITIVE or Pattern.LITERAL) + .matcher(model.calculatedActorId!!.trim { it <= ' ' }).find() + ) + } + + class ParticipantItemViewHolder internal constructor(view: View?, adapter: FlexibleAdapter<*>?) : + FlexibleViewHolder(view, adapter) { + var binding: RvItemConversationInfoParticipantBinding + + init { + binding = RvItemConversationInfoParticipantBinding.bind(view!!) + } + } + + companion object { + private val TAG = ParticipantItem::class.simpleName + private const val STATUS_SIZE_IN_DP = 9f + private const val NO_ICON = "" + private const val NOT_ONLINE_ALPHA = 0.38f + } +} diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt index 8ac2f21f4..5d6f44c4b 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt @@ -574,7 +574,6 @@ class ContactsActivity : participant.actorId = autocompleteUser.id participant.actorType = actorTypeConverter.getFromString(autocompleteUser.source) participant.displayName = autocompleteUser.label - participant.source = autocompleteUser.source return participant } @@ -593,30 +592,30 @@ class ContactsActivity : (o2 as GenericTextHeaderItem).model } if (o1 is ContactItem && o2 is ContactItem) { - val firstSource: String = o1.model.source!! - val secondSource: String = o2.model.source!! + val firstSource: Participant.ActorType = o1.model.actorType!! + val secondSource: Participant.ActorType = o2.model.actorType!! if (firstSource == secondSource) { return@sort firstName.compareTo(secondName, ignoreCase = true) } // First users - if ("users" == firstSource) { + if (Participant.ActorType.USERS == firstSource) { return@sort -1 - } else if ("users" == secondSource) { + } else if (Participant.ActorType.USERS == secondSource) { return@sort 1 } // Then groups - if ("groups" == firstSource) { + if (Participant.ActorType.GROUPS == firstSource) { return@sort -1 - } else if ("groups" == secondSource) { + } else if (Participant.ActorType.GROUPS == secondSource) { return@sort 1 } // Then circles - if ("circles" == firstSource) { + if (Participant.ActorType.CIRCLES == firstSource) { return@sort -1 - } else if ("circles" == secondSource) { + } else if (Participant.ActorType.CIRCLES == secondSource) { return@sort 1 } @@ -638,13 +637,13 @@ class ContactsActivity : (o2 as GenericTextHeaderItem).model } if (o1 is ContactItem && o2 is ContactItem) { - if ("groups" == o1.model.source && - "groups" == o2.model.source + if (Participant.ActorType.GROUPS == o1.model.actorType && + Participant.ActorType.GROUPS == o2.model.actorType ) { return@sort firstName.compareTo(secondName, ignoreCase = true) - } else if ("groups" == o1.model.source) { + } else if (Participant.ActorType.GROUPS == o1.model.actorType) { return@sort -1 - } else if ("groups" == o2.model.source) { + } else if (Participant.ActorType.GROUPS == o2.model.actorType) { return@sort 1 } } @@ -775,7 +774,7 @@ class ContactsActivity : private fun createRoom(contactItem: ContactItem) { var roomType = "1" - if ("groups" == contactItem.model.source) { + if (Participant.ActorType.GROUPS == contactItem.model.actorType) { roomType = "2" } val apiVersion: Int = ApiUtils.getConversationApiVersion(currentUser!!, intArrayOf(ApiUtils.API_V4, 1)) @@ -817,19 +816,19 @@ class ContactsActivity : } private fun updateSelectionLists(participant: Participant) { - if ("groups" == participant.source) { + if (Participant.ActorType.GROUPS == participant.actorType) { if (participant.selected) { selectedGroupIds.add(participant.calculatedActorId!!) } else { selectedGroupIds.remove(participant.calculatedActorId!!) } - } else if ("emails" == participant.source) { + } else if (Participant.ActorType.EMAILS == participant.actorType) { if (participant.selected) { selectedEmails.add(participant.calculatedActorId!!) } else { selectedEmails.remove(participant.calculatedActorId!!) } - } else if ("circles" == participant.source) { + } else if (Participant.ActorType.CIRCLES == participant.actorType) { if (participant.selected) { selectedCircleIds.add(participant.calculatedActorId!!) } else { @@ -849,7 +848,8 @@ class ContactsActivity : participant: Participant, adapter: FlexibleAdapter<*>? ): Boolean { - return "groups" == contactItem.model.source && participant.selected && adapter?.selectedItemCount!! > 1 + return Participant.ActorType.GROUPS == contactItem.model.actorType && + participant.selected && adapter?.selectedItemCount!! > 1 } private fun listOpenConversations() { @@ -869,7 +869,7 @@ class ContactsActivity : for (i in 0 until adapter!!.itemCount) { if (adapter?.getItem(i) is ContactItem) { val contactItem: ContactItem = adapter?.getItem(i) as ContactItem - if ("groups" == contactItem.model.source) { + if (Participant.ActorType.GROUPS == contactItem.model.actorType) { contactItem.isEnabled = !isPublicCall } } diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt index 76c444c0e..8c3e2da02 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt @@ -492,7 +492,7 @@ class ConversationInfoActivity : for (i in participants.indices) { participant = participants[i] - userItem = ParticipantItem(this, participant, conversationUser, viewThemeUtils) + userItem = ParticipantItem(this, participant, conversationUser, viewThemeUtils, conversationToken) if (participant.sessionId != null) { userItem.isOnline = !participant.sessionId.equals("0") } else { @@ -1026,7 +1026,7 @@ class ConversationInfoActivity : @SuppressLint("LongLogTag") override fun onError(e: Throwable) { - Log.e(TAG, "Error toggling moderator status", e) + Log.e(TAG, "Error toggling moderator status (legacy)", e) } override fun onComplete() { @@ -1163,7 +1163,7 @@ class ConversationInfoActivity : @SuppressLint("CheckResult") override fun onItemClick(view: View?, position: Int): Boolean { - if (ConversationUtils.canModerate(conversation!!, spreedCapabilities)) { + if (!ConversationUtils.canModerate(conversation!!, spreedCapabilities)) { return true } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumActorTypeConverter.kt b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumActorTypeConverter.kt index d1b96df40..1cb703a56 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumActorTypeConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumActorTypeConverter.kt @@ -12,6 +12,7 @@ import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.models.json.participants.Participant.ActorType.CIRCLES import com.nextcloud.talk.models.json.participants.Participant.ActorType.DUMMY import com.nextcloud.talk.models.json.participants.Participant.ActorType.EMAILS +import com.nextcloud.talk.models.json.participants.Participant.ActorType.FEDERATED import com.nextcloud.talk.models.json.participants.Participant.ActorType.GROUPS import com.nextcloud.talk.models.json.participants.Participant.ActorType.GUESTS import com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS @@ -24,6 +25,7 @@ class EnumActorTypeConverter : StringBasedTypeConverter() "guests" -> GUESTS "users" -> USERS "circles" -> CIRCLES + "federated_users" -> FEDERATED else -> DUMMY } } @@ -39,6 +41,7 @@ class EnumActorTypeConverter : StringBasedTypeConverter() GUESTS -> "guests" USERS -> "users" CIRCLES -> "circles" + FEDERATED -> "federated_users" else -> "" } } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.kt b/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.kt index 6590877c4..11b92d61e 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.kt @@ -72,8 +72,6 @@ data class Participant( @JsonField(name = ["statusMessage"]) var statusMessage: String? = null, - var source: String? = null, - var selected: Boolean = false ) : Parcelable { // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' @@ -84,7 +82,7 @@ data class Participant( ) /** - * actorType is only guaranteed in APIv3+ so use calculatedActorId + * actorType is only guaranteed in APIv3+ so use calculatedActorType * * https://github.com/nextcloud/spreed/blob/stable21/lib/Controller/RoomController.php#L1145-L1148 */ @@ -115,7 +113,8 @@ data class Participant( GROUPS, GUESTS, USERS, - CIRCLES + CIRCLES, + FEDERATED } enum class ParticipantType {