From 6f48ff9070f39482892e011ca0c6175dd093d967 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 7 May 2021 08:50:11 +0200 Subject: [PATCH] Fix removing an attendee from a conversation Signed-off-by: Joas Schilling --- .../talk/adapters/items/UserItem.java | 69 +++--- .../java/com/nextcloud/talk/api/NcApi.java | 4 + .../controllers/ConversationInfoController.kt | 112 ++++++--- .../json/converters/EnumActorTypeConverter.kt | 56 +++++ .../models/json/participants/Participant.java | 229 ++++++++++++------ app/src/main/res/values/strings.xml | 2 + 6 files changed, 341 insertions(+), 131 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/converters/EnumActorTypeConverter.kt diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java index 9968aab35..c1dfe7bf1 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java @@ -21,7 +21,6 @@ package com.nextcloud.talk.adapters.items; import android.content.res.Resources; -import android.graphics.drawable.BitmapDrawable; import android.text.TextUtils; import android.view.View; import android.widget.ImageView; @@ -150,37 +149,38 @@ public class UserItem extends AbstractFlexibleItem holder.contactDisplayName.setText(NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)); } - if (TextUtils.isEmpty(participant.getSource()) || participant.getSource().equals("users")) { - if (Participant.ParticipantType.GUEST.equals(participant.getType()) || - Participant.ParticipantType.USER_FOLLOWING_LINK.equals(participant.getType())) { - String displayName = NextcloudTalkApplication.Companion.getSharedApplication() - .getResources().getString(R.string.nc_guest); - - if (!TextUtils.isEmpty(participant.getDisplayName())) { - displayName = participant.getDisplayName(); - } - - DraweeController draweeController = Fresco.newDraweeControllerBuilder() - .setOldController(holder.simpleDraweeView.getController()) - .setAutoPlayAnimations(true) - .setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithNameForGuests(userEntity.getBaseUrl(), - displayName, R.dimen.avatar_size), null)) - .build(); - holder.simpleDraweeView.setController(draweeController); - - } else { - - DraweeController draweeController = Fresco.newDraweeControllerBuilder() - .setOldController(holder.simpleDraweeView.getController()) - .setAutoPlayAnimations(true) - .setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(userEntity.getBaseUrl(), - participant.getUserId(), R.dimen.avatar_size), null)) - .build(); - holder.simpleDraweeView.setController(draweeController); - - } - } else if ("groups".equals(participant.getSource())) { + if (participant.getActorType() == Participant.ActorType.GROUPS || "groups".equals(participant.getSource())) { holder.simpleDraweeView.setImageResource(R.drawable.ic_circular_group); + } else if (participant.getActorType() == Participant.ActorType.EMAILS) { + // FIXME use an email icon + holder.simpleDraweeView.setImageResource(R.drawable.ic_circular_group); + } else if (participant.getActorType() == Participant.ActorType.GUESTS || + Participant.ParticipantType.GUEST.equals(participant.getType()) || + Participant.ParticipantType.GUEST_MODERATOR.equals(participant.getType())) { + + String displayName = NextcloudTalkApplication.Companion.getSharedApplication() + .getResources().getString(R.string.nc_guest); + + if (!TextUtils.isEmpty(participant.getDisplayName())) { + displayName = participant.getDisplayName(); + } + + DraweeController draweeController = Fresco.newDraweeControllerBuilder() + .setOldController(holder.simpleDraweeView.getController()) + .setAutoPlayAnimations(true) + .setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithNameForGuests(userEntity.getBaseUrl(), + displayName, R.dimen.avatar_size), null)) + .build(); + holder.simpleDraweeView.setController(draweeController); + + } else if (participant.getActorType() == Participant.ActorType.USERS || participant.getSource().equals("users")) { + DraweeController draweeController = Fresco.newDraweeControllerBuilder() + .setOldController(holder.simpleDraweeView.getController()) + .setAutoPlayAnimations(true) + .setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(userEntity.getBaseUrl(), + participant.getUserId(), R.dimen.avatar_size), null)) + .build(); + holder.simpleDraweeView.setController(draweeController); } Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources(); @@ -246,13 +246,20 @@ public class UserItem extends AbstractFlexibleItem //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.getActorType() == Participant.ActorType.GROUPS) { + userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_group); + } break; case 4: userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest); + if (participant.getActorType() == 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); diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApi.java b/app/src/main/java/com/nextcloud/talk/api/NcApi.java index 2daa2750c..cf7a20ba8 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java +++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java @@ -135,9 +135,13 @@ public interface NcApi { // also used for removing a guest from a conversation + @Deprecated @DELETE Observable removeParticipantFromConversation(@Header("Authorization") String authorization, @Url String url, @Query("participant") String participantId); + @DELETE + Observable removeAttendeeFromConversation(@Header("Authorization") String authorization, @Url String url, @Query("attendeeId") Long attendeeId); + @POST Observable promoteUserToModerator(@Header("Authorization") String authorization, @Url String url, @Query("participant") String participantId); 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 3100500b2..29b44b2cc 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt @@ -20,11 +20,13 @@ package com.nextcloud.talk.controllers +import android.annotation.SuppressLint import android.content.Context import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable import android.os.Bundle import android.text.TextUtils +import android.util.Log import android.view.LayoutInflater import android.view.MenuItem import android.view.View @@ -63,6 +65,8 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.participants.Participant +import com.nextcloud.talk.models.json.participants.Participant.ActorType.GROUPS +import com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS import com.nextcloud.talk.models.json.participants.ParticipantsOverall import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DateUtils @@ -85,11 +89,13 @@ import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode +import retrofit2.adapter.rxjava2.HttpException import java.util.Calendar import java.util.Collections import java.util.Comparator import java.util.Locale import javax.inject.Inject +import kotlin.reflect.typeOf @AutoInjector(NextcloudTalkApplication::class) class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleAdapter.OnItemClickListener { @@ -410,11 +416,20 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA for (i in participants.indices) { participant = participants[i] userItem = UserItem(participant, conversationUser, null) - userItem.isOnline = !participant.sessionId.equals("0") + if (participant.sessionId != null) { + userItem.isOnline = !participant.sessionId.equals("0") + } else { + userItem.isOnline = !participant.sessionIds!!.isEmpty() + } if (!TextUtils.isEmpty(participant.userId) && participant.userId == conversationUser!!.userId) { ownUserItem = userItem ownUserItem.model.sessionId = "-1" ownUserItem.isOnline = true + } else if (participant.actorType != null && participant.actorType == USERS + && !TextUtils.isEmpty(participant.actorId) && participant.actorId == conversationUser!!.userId) { + ownUserItem = userItem + ownUserItem.model.sessionId = "-1" + ownUserItem.isOnline = true } else { recyclerViewItems.add(userItem) } @@ -444,7 +459,7 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA var apiVersion = 1 // FIXME Fix API checking with guests? if (conversationUser != null) { - apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) } ncApi.getPeersForCall( @@ -716,7 +731,7 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA title(text = participant.displayName) listItemsWithImage(items = items) { dialog, index, _ -> - val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) if (index == 0) { if (participant.type == Participant.ParticipantType.MODERATOR) { @@ -751,39 +766,69 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA } } } else if (index == 1) { - if (participant.type == Participant.ParticipantType.GUEST || - participant.type == Participant.ParticipantType.USER_FOLLOWING_LINK - ) { - ncApi.removeParticipantFromConversation( + if (apiVersion >= ApiUtils.APIv4) { + ncApi.removeAttendeeFromConversation( credentials, - ApiUtils.getUrlForRemovingParticipantFromConversation( + ApiUtils.getUrlForAttendees( + apiVersion, conversationUser.baseUrl, - conversation!!.token, - true + conversation!!.token ), - participant.sessionId + participant.attendeeId ) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - getListOfParticipants() - } + .subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + } + + override fun onNext(genericOverall: GenericOverall) { + getListOfParticipants() + } + + @SuppressLint("LongLogTag") + override fun onError(e: Throwable) { + Log.e(TAG, "Error removing attendee from conversation", e) + } + + override fun onComplete() { + } + }) } else { - ncApi.removeParticipantFromConversation( - credentials, - ApiUtils.getUrlForRemovingParticipantFromConversation( - conversationUser.baseUrl, - conversation!!.token, - false - ), - participant.userId - ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - getListOfParticipants() - // get participants again - } + if (participant.type == Participant.ParticipantType.GUEST || + participant.type == Participant.ParticipantType.USER_FOLLOWING_LINK + ) { + ncApi.removeParticipantFromConversation( + credentials, + ApiUtils.getUrlForRemovingParticipantFromConversation( + conversationUser.baseUrl, + conversation!!.token, + true + ), + participant.sessionId + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + getListOfParticipants() + } + } else { + ncApi.removeParticipantFromConversation( + credentials, + ApiUtils.getUrlForRemovingParticipantFromConversation( + conversationUser.baseUrl, + conversation!!.token, + false + ), + participant.userId + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + getListOfParticipants() + // get participants again + } + } } } } @@ -796,6 +841,7 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA companion object { + private const val TAG = "ConversationInfoController" private const val ID_DELETE_CONVERSATION_DIALOG = 0 } @@ -804,6 +850,13 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA */ class UserItemComparator : Comparator { override fun compare(left: UserItem, right: UserItem): Int { + val leftIsGroup = left.model.actorType == GROUPS + val rightIsGroup = right.model.actorType == GROUPS + if (leftIsGroup != rightIsGroup) { + // Groups below participants + return if (rightIsGroup) { -1 } else { 1 } + } + if (left.isOnline && !right.isOnline) { return -1 } else if (!left.isOnline && right.isOnline) { @@ -815,6 +868,7 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA moderatorTypes.add(Participant.ParticipantType.OWNER) moderatorTypes.add(Participant.ParticipantType.GUEST_MODERATOR) + if (moderatorTypes.contains(left.model.type) && !moderatorTypes.contains(right.model.type)) { return -1 } else if (!moderatorTypes.contains(left.model.type) && moderatorTypes.contains(right.model.type)) { 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 new file mode 100644 index 000000000..22fcf6c21 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumActorTypeConverter.kt @@ -0,0 +1,56 @@ +/* + * Nextcloud Talk application + * + * @author Joas Schilling + * Copyright (C) 2021 Joas Schilling + * + * 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.models.json.converters + +import com.bluelinelabs.logansquare.typeconverters.StringBasedTypeConverter +import com.nextcloud.talk.models.json.participants.Participant +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.GROUPS +import com.nextcloud.talk.models.json.participants.Participant.ActorType.GUESTS +import com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS + +class EnumActorTypeConverter : StringBasedTypeConverter() { + override fun getFromString(string: String): Participant.ActorType { + when (string) { + "emails" -> return EMAILS + "groups" -> return GROUPS + "guests" -> return GUESTS + "users" -> return USERS + else -> return DUMMY + } + } + + override fun convertToString(`object`: Participant.ActorType?): String { + + if (`object` == null) { + return "" + } + + when (`object`) { + EMAILS -> return "emails" + GROUPS -> return "groups" + GUESTS -> return "guests" + USERS -> return "users" + else -> return "" + } + } +} 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 5832a0461..b6c81c1f2 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 @@ -22,21 +22,36 @@ package com.nextcloud.talk.models.json.participants; import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonObject; +import com.nextcloud.talk.models.json.converters.EnumActorTypeConverter; import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter; +import com.nextcloud.talk.models.json.converters.EnumSystemMessageTypeConverter; import com.nextcloud.talk.models.json.converters.ObjectParcelConverter; import org.parceler.Parcel; import org.parceler.ParcelPropertyConverter; +import java.util.Arrays; + @Parcel @JsonObject public class Participant { + @JsonField(name = "attendeeId") + public Long attendeeId; + + @JsonField(name = "actorType", typeConverter = EnumActorTypeConverter.class) + public ActorType actorType; + + @JsonField(name = "actorId") + public String actorId; + + @Deprecated @JsonField(name = "userId") public String userId; @JsonField(name = {"type", "participantType"}, typeConverter = EnumParticipantTypeConverter.class) public ParticipantType type; + @Deprecated @JsonField(name = "name") public String name; @@ -46,15 +61,21 @@ public class Participant { @JsonField(name = "lastPing") public long lastPing; + @Deprecated @JsonField(name = "sessionId") public String sessionId; + @JsonField(name = "sessionIds") + public String[] sessionIds; + + @Deprecated @JsonField(name = "roomId") public long roomId; @ParcelPropertyConverter(ObjectParcelConverter.class) @JsonField(name = "inCall") public Object inCall; + public String source; public boolean selected; @@ -76,7 +97,30 @@ public class Participant { return participantFlags; } + public Long getAttendeeId() { + return attendeeId; + } + + public ActorType getActorType() { + if (this.userId != null) { + return ActorType.USERS; + } + return actorType; + } + + public String getActorId() { + if (this.userId != null) { + return this.userId; + } + return actorId; + } + + + @Deprecated public String getUserId() { + if (this.actorType != null && this.actorType == ActorType.USERS) { + return this.actorId; + } return this.userId; } @@ -84,6 +128,7 @@ public class Participant { return this.type; } + @Deprecated public String getName() { return this.name; } @@ -96,10 +141,16 @@ public class Participant { return this.lastPing; } + @Deprecated public String getSessionId() { return this.sessionId; } + public String[] getSessionIds() { + return sessionIds; + } + + @Deprecated public long getRoomId() { return this.roomId; } @@ -116,14 +167,28 @@ public class Participant { return this.selected; } + @Deprecated public void setUserId(String userId) { this.userId = userId; } + public void setAttendeeId(Long attendeeId) { + this.attendeeId = attendeeId; + } + + public void setActorType(ActorType actorType) { + this.actorType = actorType; + } + + public void setActorId(String actorId) { + this.actorId = actorId; + } + public void setType(ParticipantType type) { this.type = type; } + @Deprecated public void setName(String name) { this.name = name; } @@ -136,10 +201,12 @@ public class Participant { this.lastPing = lastPing; } + @Deprecated public void setSessionId(String sessionId) { this.sessionId = sessionId; } + @Deprecated public void setRoomId(long roomId) { this.roomId = roomId; } @@ -156,93 +223,113 @@ public class Participant { this.selected = selected; } - public boolean equals(final Object o) { - if (o == this) { + public void setSessionIds(String[] sessionIds) { + this.sessionIds = sessionIds; + } + + @Override + public boolean equals(Object o) { + if (this == o) { return true; } - if (!(o instanceof Participant)) { - return false; - } - final Participant other = (Participant) o; - if (!other.canEqual((Object) this)) { - return false; - } - final Object this$userId = this.getUserId(); - final Object other$userId = other.getUserId(); - if (this$userId == null ? other$userId != null : !this$userId.equals(other$userId)) { - return false; - } - final Object this$type = this.getType(); - final Object other$type = other.getType(); - if (this$type == null ? other$type != null : !this$type.equals(other$type)) { - return false; - } - final Object this$name = this.getName(); - final Object other$name = other.getName(); - if (this$name == null ? other$name != null : !this$name.equals(other$name)) { - return false; - } - final Object this$displayName = this.getDisplayName(); - final Object other$displayName = other.getDisplayName(); - if (this$displayName == null ? other$displayName != null : !this$displayName.equals(other$displayName)) { - return false; - } - if (this.getLastPing() != other.getLastPing()) { - return false; - } - final Object this$sessionId = this.getSessionId(); - final Object other$sessionId = other.getSessionId(); - if (this$sessionId == null ? other$sessionId != null : !this$sessionId.equals(other$sessionId)) { - return false; - } - if (this.getRoomId() != other.getRoomId()) { - return false; - } - final Object this$inCall = this.getInCall(); - final Object other$inCall = other.getInCall(); - if (this$inCall == null ? other$inCall != null : !this$inCall.equals(other$inCall)) { - return false; - } - final Object this$source = this.getSource(); - final Object other$source = other.getSource(); - if (this$source == null ? other$source != null : !this$source.equals(other$source)) { + if (o == null || getClass() != o.getClass()) { return false; } - return this.isSelected() == other.isSelected(); + Participant that = (Participant) o; + + if (lastPing != that.lastPing) { + return false; + } + if (roomId != that.roomId) { + return false; + } + if (selected != that.selected) { + return false; + } + if (!attendeeId.equals(that.attendeeId)) { + return false; + } + if (!actorType.equals(that.actorType)) { + return false; + } + if (!actorId.equals(that.actorId)) { + return false; + } + if (!userId.equals(that.userId)) { + return false; + } + if (type != that.type) { + return false; + } + if (!name.equals(that.name)) { + return false; + } + if (displayName != null ? !displayName.equals(that.displayName) : that.displayName != null) { + return false; + } + if (!sessionId.equals(that.sessionId)) { + return false; + } + // Probably incorrect - comparing Object[] arrays with Arrays.equals + if (!Arrays.equals(sessionIds, that.sessionIds)) { + return false; + } + if (inCall != null ? !inCall.equals(that.inCall) : that.inCall != null) { + return false; + } + return source != null ? source.equals(that.source) : that.source == null; } protected boolean canEqual(final Object other) { return other instanceof Participant; } + @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - final Object $userId = this.getUserId(); - result = result * PRIME + ($userId == null ? 43 : $userId.hashCode()); - final Object $type = this.getType(); - result = result * PRIME + ($type == null ? 43 : $type.hashCode()); - final Object $name = this.getName(); - result = result * PRIME + ($name == null ? 43 : $name.hashCode()); - final Object $displayName = this.getDisplayName(); - result = result * PRIME + ($displayName == null ? 43 : $displayName.hashCode()); - final long $lastPing = this.getLastPing(); - result = result * PRIME + (int) ($lastPing >>> 32 ^ $lastPing); - final Object $sessionId = this.getSessionId(); - result = result * PRIME + ($sessionId == null ? 43 : $sessionId.hashCode()); - final long $roomId = this.getRoomId(); - result = result * PRIME + (int) ($roomId >>> 32 ^ $roomId); - final Object $inCall = this.getInCall(); - result = result * PRIME + ($inCall == null ? 43 : $inCall.hashCode()); - final Object $source = this.getSource(); - result = result * PRIME + ($source == null ? 43 : $source.hashCode()); - result = result * PRIME + (this.isSelected() ? 79 : 97); + int result = attendeeId.hashCode(); + result = 31 * result + actorType.hashCode(); + result = 31 * result + actorId.hashCode(); + result = 31 * result + (userId != null ? userId.hashCode() : 0); + result = 31 * result + (type != null ? type.hashCode() : 0); + result = 31 * result + (name != null ? name.hashCode() : 0); + result = 31 * result + (displayName != null ? displayName.hashCode() : 0); + result = 31 * result + (int) (lastPing ^ (lastPing >>> 32)); + result = 31 * result + (sessionId != null ? sessionId.hashCode() : 0); + result = 31 * result + Arrays.hashCode(sessionIds); + result = 31 * result + (int) (roomId ^ (roomId >>> 32)); + result = 31 * result + (inCall != null ? inCall.hashCode() : 0); + result = 31 * result + (source != null ? source.hashCode() : 0); + result = 31 * result + (selected ? 1 : 0); return result; } + @Override public String toString() { - return "Participant(userId=" + this.getUserId() + ", type=" + this.getType() + ", name=" + this.getName() + ", displayName=" + this.getDisplayName() + ", lastPing=" + this.getLastPing() + ", sessionId=" + this.getSessionId() + ", roomId=" + this.getRoomId() + ", inCall=" + this.getInCall() + ", source=" + this.getSource() + ", selected=" + this.isSelected() + ")"; + return "Participant{" + + "attendeeId=" + attendeeId + + ", actorType='" + actorType + '\'' + + ", actorId='" + actorId + '\'' + + ", userId='" + userId + '\'' + + ", type=" + type + + ", name='" + name + '\'' + + ", displayName='" + displayName + '\'' + + ", lastPing=" + lastPing + + ", sessionId='" + sessionId + '\'' + + ", sessionIds=" + Arrays.toString(sessionIds) + + ", roomId=" + roomId + + ", inCall=" + inCall + + ", source='" + source + '\'' + + ", selected=" + selected + + '}'; + } + + public enum ActorType { + DUMMY, + EMAILS, + GROUPS, + GUESTS, + USERS, } public enum ParticipantType { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5848fbf86..cb7d48077 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -305,6 +305,8 @@ %s characters limit has been hit + Email + Group Groups Participants Add participants