Эх сурвалжийг харах

show user statuses in conversation info (wip)

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 3 жил өмнө
parent
commit
d453773a1d

+ 1 - 1
app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt

@@ -272,7 +272,7 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
                 apiVersion,
                 apiVersion,
                 signatureVerification.userEntity.baseUrl,
                 signatureVerification.userEntity.baseUrl,
                 decryptedPushMessage.id
                 decryptedPushMessage.id
-            )
+            ), null
         )
         )
             .repeatWhen { completed ->
             .repeatWhen { completed ->
                 completed.zipWith(Observable.range(1, 12), { _, i -> i })
                 completed.zipWith(Observable.range(1, 12), { _, i -> i })

+ 1 - 1
app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

@@ -1755,7 +1755,7 @@ public class CallActivity extends CallBaseActivity {
         Log.d(TAG, "getPeersForCall");
         Log.d(TAG, "getPeersForCall");
         int apiVersion = ApiUtils.getCallApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
         int apiVersion = ApiUtils.getCallApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
 
 
-        ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken))
+        ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken), null)
             .subscribeOn(Schedulers.io())
             .subscribeOn(Schedulers.io())
             .subscribe(new Observer<ParticipantsOverall>() {
             .subscribe(new Observer<ParticipantsOverall>() {
                 @Override
                 @Override

+ 1 - 1
app/src/main/java/com/nextcloud/talk/activities/CallNotificationActivity.java

@@ -215,7 +215,7 @@ public class CallNotificationActivity extends CallBaseActivity {
         int apiVersion = ApiUtils.getCallApiVersion(userBeingCalled, new int[]{ApiUtils.APIv4, 1});
         int apiVersion = ApiUtils.getCallApiVersion(userBeingCalled, new int[]{ApiUtils.APIv4, 1});
 
 
         ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, userBeingCalled.getBaseUrl(),
         ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, userBeingCalled.getBaseUrl(),
-                                                                  currentConversation.getToken()))
+                                                                  currentConversation.getToken()), null)
             .subscribeOn(Schedulers.io())
             .subscribeOn(Schedulers.io())
             .repeatWhen(completed -> completed.zipWith(Observable.range(1, 12), (n, i) -> i)
             .repeatWhen(completed -> completed.zipWith(Observable.range(1, 12), (n, i) -> i)
                 .flatMap(retryCount -> Observable.timer(5, TimeUnit.SECONDS))
                 .flatMap(retryCount -> Observable.timer(5, TimeUnit.SECONDS))

+ 4 - 4
app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.java

@@ -135,7 +135,7 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<UserItem.UserI
         }
         }
 
 
         if (SOURCE_CALLS.equals(source)) {
         if (SOURCE_CALLS.equals(source)) {
-            holder.simpleDraweeView.setImageResource(R.drawable.ic_circular_group);
+            holder.participantAvatar.setImageResource(R.drawable.ic_circular_group);
         } else {
         } else {
             String avatarId = objectId;
             String avatarId = objectId;
             String avatarUrl = ApiUtils.getUrlForAvatarWithName(currentUser.getBaseUrl(),
             String avatarUrl = ApiUtils.getUrlForAvatarWithName(currentUser.getBaseUrl(),
@@ -149,13 +149,13 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<UserItem.UserI
                         R.dimen.avatar_size_big);
                         R.dimen.avatar_size_big);
             }
             }
 
 
-            holder.simpleDraweeView.setController(null);
+            holder.participantAvatar.setController(null);
             DraweeController draweeController = Fresco.newDraweeControllerBuilder()
             DraweeController draweeController = Fresco.newDraweeControllerBuilder()
-                    .setOldController(holder.simpleDraweeView.getController())
+                    .setOldController(holder.participantAvatar.getController())
                     .setAutoPlayAnimations(true)
                     .setAutoPlayAnimations(true)
                     .setImageRequest(DisplayUtils.getImageRequestForUrl(avatarUrl, null))
                     .setImageRequest(DisplayUtils.getImageRequestForUrl(avatarUrl, null))
                     .build();
                     .build();
-            holder.simpleDraweeView.setController(draweeController);
+            holder.participantAvatar.setController(draweeController);
         }
         }
     }
     }
 
 

+ 86 - 48
app/src/main/java/com/nextcloud/talk/adapters/items/UserItem.java

@@ -20,15 +20,12 @@
 
 
 package com.nextcloud.talk.adapters.items;
 package com.nextcloud.talk.adapters.items;
 
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.Resources;
 import android.text.TextUtils;
 import android.text.TextUtils;
 import android.view.View;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.ImageView;
 
 
-import androidx.annotation.Nullable;
-import androidx.core.content.res.ResourcesCompat;
-import androidx.emoji.widget.EmojiTextView;
-
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.facebook.drawee.view.SimpleDraweeView;
 import com.facebook.drawee.view.SimpleDraweeView;
@@ -38,12 +35,17 @@ import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter;
 import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter;
 import com.nextcloud.talk.models.json.participants.Participant;
 import com.nextcloud.talk.models.json.participants.Participant;
 import com.nextcloud.talk.models.json.participants.Participant.InCallFlags;
 import com.nextcloud.talk.models.json.participants.Participant.InCallFlags;
+import com.nextcloud.talk.models.json.status.StatusType;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 
 
 import java.util.List;
 import java.util.List;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
 
 
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.emoji.widget.EmojiTextView;
 import butterknife.BindView;
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import butterknife.ButterKnife;
 import eu.davidea.flexibleadapter.FlexibleAdapter;
 import eu.davidea.flexibleadapter.FlexibleAdapter;
@@ -54,14 +56,19 @@ import eu.davidea.flexibleadapter.utils.FlexibleUtils;
 import eu.davidea.viewholders.FlexibleViewHolder;
 import eu.davidea.viewholders.FlexibleViewHolder;
 
 
 public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder> implements
 public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder> implements
-        ISectionable<UserItem.UserItemViewHolder, GenericTextHeaderItem>, IFilterable<String> {
+    ISectionable<UserItem.UserItemViewHolder, GenericTextHeaderItem>, IFilterable<String> {
 
 
+    private Context context;
     private Participant participant;
     private Participant participant;
     private UserEntity userEntity;
     private UserEntity userEntity;
     private GenericTextHeaderItem header;
     private GenericTextHeaderItem header;
     public boolean isOnline = true;
     public boolean isOnline = true;
 
 
-    public UserItem(Participant participant, UserEntity userEntity, GenericTextHeaderItem genericTextHeaderItem) {
+    public UserItem(Context activityContext,
+                    Participant participant,
+                    UserEntity userEntity,
+                    GenericTextHeaderItem genericTextHeaderItem) {
+        this.context = activityContext;
         this.participant = participant;
         this.participant = participant;
         this.userEntity = userEntity;
         this.userEntity = userEntity;
         this.header = genericTextHeaderItem;
         this.header = genericTextHeaderItem;
@@ -72,7 +79,7 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
         if (o instanceof UserItem) {
         if (o instanceof UserItem) {
             UserItem inItem = (UserItem) o;
             UserItem inItem = (UserItem) o;
             return participant.getActorType() == inItem.getModel().getActorType() &&
             return participant.getActorType() == inItem.getModel().getActorType() &&
-                    participant.getActorId().equals(inItem.getModel().getActorId());
+                participant.getActorId().equals(inItem.getModel().getActorId());
         }
         }
         return false;
         return false;
     }
     }
@@ -112,7 +119,7 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
     @Override
     @Override
     public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) {
     public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) {
 
 
-        holder.simpleDraweeView.setController(null);
+        holder.participantAvatar.setController(null);
 
 
         if (holder.checkedImageView != null) {
         if (holder.checkedImageView != null) {
             if (participant.isSelected()) {
             if (participant.isSelected()) {
@@ -122,69 +129,88 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
             }
             }
         }
         }
 
 
+        if (participant.status != null && participant.status.equals(StatusType.DND.getString())) {
+            setOnlineStateIcon(holder, R.drawable.ic_user_status_dnd_with_border);
+        } else if (participant.statusIcon != null && !participant.statusIcon.isEmpty()) {
+            holder.participantOnlineStateImage.setVisibility(View.GONE);
+            holder.participantEmoji.setVisibility(View.VISIBLE);
+            holder.participantEmoji.setText(participant.statusIcon);
+        } else if (participant.status != null && participant.status.equals(StatusType.AWAY.getString())) {
+            setOnlineStateIcon(holder, R.drawable.ic_user_status_away_with_border);
+        } else if (participant.status != null && participant.status.equals(StatusType.ONLINE.getString())) {
+            setOnlineStateIcon(holder, R.drawable.online_status_with_border);
+        } else {
+            holder.participantEmoji.setVisibility(View.GONE);
+            holder.participantOnlineStateImage.setVisibility(View.GONE);
+        }
+
+        if (participant.statusMessage != null) {
+            holder.statusMessage.setText(participant.statusMessage);
+        }
+
         if (!isOnline) {
         if (!isOnline) {
             holder.contactDisplayName.setTextColor(ResourcesCompat.getColor(
             holder.contactDisplayName.setTextColor(ResourcesCompat.getColor(
-                    holder.contactDisplayName.getContext().getResources(),
-                    R.color.medium_emphasis_text,
-                    null)
-            );
-            holder.simpleDraweeView.setAlpha(0.38f);
+                holder.contactDisplayName.getContext().getResources(),
+                R.color.medium_emphasis_text,
+                null)
+                                                  );
+            holder.participantAvatar.setAlpha(0.38f);
         } else {
         } else {
             holder.contactDisplayName.setTextColor(ResourcesCompat.getColor(
             holder.contactDisplayName.setTextColor(ResourcesCompat.getColor(
-                    holder.contactDisplayName.getContext().getResources(),
-                    R.color.high_emphasis_text,
-                    null)
-            );
-            holder.simpleDraweeView.setAlpha(1.0f);
+                holder.contactDisplayName.getContext().getResources(),
+                R.color.high_emphasis_text,
+                null)
+                                                  );
+            holder.participantAvatar.setAlpha(1.0f);
         }
         }
 
 
         if (adapter.hasFilter()) {
         if (adapter.hasFilter()) {
             FlexibleUtils.highlightText(holder.contactDisplayName, participant.getDisplayName(),
             FlexibleUtils.highlightText(holder.contactDisplayName, participant.getDisplayName(),
-                    String.valueOf(adapter.getFilter(String.class)), NextcloudTalkApplication.Companion.getSharedApplication()
-                            .getResources().getColor(R.color.colorPrimary));
+                                        String.valueOf(adapter.getFilter(String.class)), NextcloudTalkApplication.Companion.getSharedApplication()
+                                            .getResources().getColor(R.color.colorPrimary));
         }
         }
 
 
         holder.contactDisplayName.setText(participant.getDisplayName());
         holder.contactDisplayName.setText(participant.getDisplayName());
 
 
         if (TextUtils.isEmpty(participant.getDisplayName()) &&
         if (TextUtils.isEmpty(participant.getDisplayName()) &&
-                (participant.getType().equals(Participant.ParticipantType.GUEST) || participant.getType().equals(Participant.ParticipantType.USER_FOLLOWING_LINK))) {
+            (participant.getType().equals(Participant.ParticipantType.GUEST) || participant.getType().equals(Participant.ParticipantType.USER_FOLLOWING_LINK))) {
             holder.contactDisplayName.setText(NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest));
             holder.contactDisplayName.setText(NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest));
         }
         }
 
 
         if (participant.getActorType() == Participant.ActorType.GROUPS ||
         if (participant.getActorType() == Participant.ActorType.GROUPS ||
-                "groups".equals(participant.getSource()) ||
-                participant.getActorType() == Participant.ActorType.CIRCLES ||
-                "circles".equals(participant.getSource())) {
-            holder.simpleDraweeView.setImageResource(R.drawable.ic_circular_group);
+            "groups".equals(participant.getSource()) ||
+            participant.getActorType() == Participant.ActorType.CIRCLES ||
+            "circles".equals(participant.getSource())) {
+            holder.participantAvatar.setImageResource(R.drawable.ic_circular_group);
         } else if (participant.getActorType() == Participant.ActorType.EMAILS) {
         } else if (participant.getActorType() == Participant.ActorType.EMAILS) {
-            holder.simpleDraweeView.setImageResource(R.drawable.ic_circular_mail);
+            holder.participantAvatar.setImageResource(R.drawable.ic_circular_mail);
         } else if (participant.getActorType() == Participant.ActorType.GUESTS ||
         } else if (participant.getActorType() == Participant.ActorType.GUESTS ||
-                Participant.ParticipantType.GUEST.equals(participant.getType()) ||
-                Participant.ParticipantType.GUEST_MODERATOR.equals(participant.getType())) {
+            Participant.ParticipantType.GUEST.equals(participant.getType()) ||
+            Participant.ParticipantType.GUEST_MODERATOR.equals(participant.getType())) {
 
 
             String displayName = NextcloudTalkApplication.Companion.getSharedApplication()
             String displayName = NextcloudTalkApplication.Companion.getSharedApplication()
-                    .getResources().getString(R.string.nc_guest);
+                .getResources().getString(R.string.nc_guest);
 
 
             if (!TextUtils.isEmpty(participant.getDisplayName())) {
             if (!TextUtils.isEmpty(participant.getDisplayName())) {
                 displayName = participant.getDisplayName();
                 displayName = participant.getDisplayName();
             }
             }
 
 
             DraweeController draweeController = Fresco.newDraweeControllerBuilder()
             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);
+                .setOldController(holder.participantAvatar.getController())
+                .setAutoPlayAnimations(true)
+                .setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithNameForGuests(userEntity.getBaseUrl(),
+                                                                                                              displayName, R.dimen.avatar_size), null))
+                .build();
+            holder.participantAvatar.setController(draweeController);
 
 
         } else if (participant.getActorType() == Participant.ActorType.USERS || participant.getSource().equals("users")) {
         } else if (participant.getActorType() == Participant.ActorType.USERS || participant.getSource().equals("users")) {
             DraweeController draweeController = Fresco.newDraweeControllerBuilder()
             DraweeController draweeController = Fresco.newDraweeControllerBuilder()
-                    .setOldController(holder.simpleDraweeView.getController())
-                    .setAutoPlayAnimations(true)
-                    .setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(userEntity.getBaseUrl(),
-                                                                                                         participant.getActorId(), R.dimen.avatar_size), null))
-                    .build();
-            holder.simpleDraweeView.setController(draweeController);
+                .setOldController(holder.participantAvatar.getController())
+                .setAutoPlayAnimations(true)
+                .setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(userEntity.getBaseUrl(),
+                                                                                                     participant.getActorId(), R.dimen.avatar_size), null))
+                .build();
+            holder.participantAvatar.setController(draweeController);
         }
         }
 
 
         Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources();
         Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources();
@@ -195,17 +221,17 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
                 holder.videoCallIconView.setImageResource(R.drawable.ic_call_grey_600_24dp);
                 holder.videoCallIconView.setImageResource(R.drawable.ic_call_grey_600_24dp);
                 holder.videoCallIconView.setVisibility(View.VISIBLE);
                 holder.videoCallIconView.setVisibility(View.VISIBLE);
                 holder.videoCallIconView.setContentDescription(
                 holder.videoCallIconView.setContentDescription(
-                        resources.getString(R.string.nc_call_state_with_phone, participant.displayName));
+                    resources.getString(R.string.nc_call_state_with_phone, participant.displayName));
             } else if ((inCallFlag & InCallFlags.WITH_VIDEO) > 0) {
             } else if ((inCallFlag & InCallFlags.WITH_VIDEO) > 0) {
                 holder.videoCallIconView.setImageResource(R.drawable.ic_videocam_grey_600_24dp);
                 holder.videoCallIconView.setImageResource(R.drawable.ic_videocam_grey_600_24dp);
                 holder.videoCallIconView.setVisibility(View.VISIBLE);
                 holder.videoCallIconView.setVisibility(View.VISIBLE);
                 holder.videoCallIconView.setContentDescription(
                 holder.videoCallIconView.setContentDescription(
-                        resources.getString(R.string.nc_call_state_with_video, participant.displayName));
+                    resources.getString(R.string.nc_call_state_with_video, participant.displayName));
             } else if (inCallFlag > InCallFlags.DISCONNECTED) {
             } else if (inCallFlag > InCallFlags.DISCONNECTED) {
                 holder.videoCallIconView.setImageResource(R.drawable.ic_mic_grey_600_24dp);
                 holder.videoCallIconView.setImageResource(R.drawable.ic_mic_grey_600_24dp);
                 holder.videoCallIconView.setVisibility(View.VISIBLE);
                 holder.videoCallIconView.setVisibility(View.VISIBLE);
                 holder.videoCallIconView.setContentDescription(
                 holder.videoCallIconView.setContentDescription(
-                        resources.getString(R.string.nc_call_state_in_call, participant.displayName));
+                    resources.getString(R.string.nc_call_state_in_call, participant.displayName));
             } else {
             } else {
                 holder.videoCallIconView.setVisibility(View.GONE);
                 holder.videoCallIconView.setVisibility(View.GONE);
             }
             }
@@ -250,11 +276,17 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
         }
         }
     }
     }
 
 
+    private void setOnlineStateIcon(UserItem.UserItemViewHolder holder, int icon) {
+        holder.participantEmoji.setVisibility(View.GONE);
+        holder.participantOnlineStateImage.setVisibility(View.VISIBLE);
+        holder.participantOnlineStateImage.setImageDrawable(ContextCompat.getDrawable(context, icon));
+    }
+
     @Override
     @Override
     public boolean filter(String constraint) {
     public boolean filter(String constraint) {
         return participant.getDisplayName() != null &&
         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.getActorId().trim()).find());
+            (Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL).matcher(participant.getDisplayName().trim()).find() ||
+                Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL).matcher(participant.getActorId().trim()).find());
     }
     }
 
 
     @Override
     @Override
@@ -271,8 +303,8 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
 
 
         @BindView(R.id.name_text)
         @BindView(R.id.name_text)
         public EmojiTextView contactDisplayName;
         public EmojiTextView contactDisplayName;
-        @BindView(R.id.simple_drawee_view)
-        public SimpleDraweeView simpleDraweeView;
+        @BindView(R.id.conversation_info_participant_avatar)
+        public SimpleDraweeView participantAvatar;
         @Nullable
         @Nullable
         @BindView(R.id.secondary_text)
         @BindView(R.id.secondary_text)
         public EmojiTextView contactMentionId;
         public EmojiTextView contactMentionId;
@@ -282,6 +314,12 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
         @Nullable
         @Nullable
         @BindView(R.id.checkedImageView)
         @BindView(R.id.checkedImageView)
         ImageView checkedImageView;
         ImageView checkedImageView;
+        @BindView(R.id.conversation_info_participant_emoji)
+        com.vanniktech.emoji.EmojiEditText participantEmoji;
+        @BindView(R.id.conversation_info_participant_online_state)
+        ImageView participantOnlineStateImage;
+        @BindView(R.id.conversation_info_status_message)
+        EmojiTextView statusMessage;
 
 
         /**
         /**
          * Default constructor.
          * Default constructor.

+ 2 - 1
app/src/main/java/com/nextcloud/talk/api/NcApi.java

@@ -187,7 +187,8 @@ public interface NcApi {
         Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /call/callToken
         Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /call/callToken
     */
     */
     @GET
     @GET
-    Observable<ParticipantsOverall> getPeersForCall(@Header("Authorization") String authorization, @Url String url);
+    Observable<ParticipantsOverall> getPeersForCall(@Header("Authorization") String authorization, @Url String url,
+                                                   @QueryMap Map<String, Boolean> fields);
 
 
     @FormUrlEncoded
     @FormUrlEncoded
     @POST
     @POST

+ 1 - 0
app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java

@@ -551,6 +551,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
                                     }
                                     }
 
 
                                     UserItem newContactItem = new UserItem(
                                     UserItem newContactItem = new UserItem(
+                                        getApplicationContext(),
                                         participant,
                                         participant,
                                         currentUser,
                                         currentUser,
                                         userHeaderItems.get(headerTitle)
                                         userHeaderItems.get(headerTitle)

+ 14 - 10
app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt

@@ -88,6 +88,7 @@ import org.greenrobot.eventbus.ThreadMode
 import java.util.Calendar
 import java.util.Calendar
 import java.util.Collections
 import java.util.Collections
 import java.util.Comparator
 import java.util.Comparator
+import java.util.HashMap
 import java.util.Locale
 import java.util.Locale
 import javax.inject.Inject
 import javax.inject.Inject
 
 
@@ -120,7 +121,7 @@ class ConversationInfoController(args: Bundle) :
     private var conversation: Conversation? = null
     private var conversation: Conversation? = null
 
 
     private var adapter: FlexibleAdapter<UserItem>? = null
     private var adapter: FlexibleAdapter<UserItem>? = null
-    private var recyclerViewItems: MutableList<UserItem> = ArrayList()
+    private var userItems: MutableList<UserItem> = ArrayList()
 
 
     private var saveStateHandler: LovelySaveStateHandler? = null
     private var saveStateHandler: LovelySaveStateHandler? = null
 
 
@@ -362,7 +363,7 @@ class ConversationInfoController(args: Bundle) :
     private fun setupAdapter() {
     private fun setupAdapter() {
         if (activity != null) {
         if (activity != null) {
             if (adapter == null) {
             if (adapter == null) {
-                adapter = FlexibleAdapter(recyclerViewItems, activity, true)
+                adapter = FlexibleAdapter(userItems, activity, true)
             }
             }
 
 
             val layoutManager = SmoothScrollLinearLayoutManager(activity)
             val layoutManager = SmoothScrollLinearLayoutManager(activity)
@@ -378,12 +379,12 @@ class ConversationInfoController(args: Bundle) :
         var userItem: UserItem
         var userItem: UserItem
         var participant: Participant
         var participant: Participant
 
 
-        recyclerViewItems = ArrayList()
+        userItems = ArrayList()
         var ownUserItem: UserItem? = null
         var ownUserItem: UserItem? = null
 
 
         for (i in participants.indices) {
         for (i in participants.indices) {
             participant = participants[i]
             participant = participants[i]
-            userItem = UserItem(participant, conversationUser, null)
+            userItem = UserItem(context, participant, conversationUser, null)
             if (participant.sessionId != null) {
             if (participant.sessionId != null) {
                 userItem.isOnline = !participant.sessionId.equals("0")
                 userItem.isOnline = !participant.sessionId.equals("0")
             } else {
             } else {
@@ -395,20 +396,20 @@ class ConversationInfoController(args: Bundle) :
                 ownUserItem.model.sessionId = "-1"
                 ownUserItem.model.sessionId = "-1"
                 ownUserItem.isOnline = true
                 ownUserItem.isOnline = true
             } else {
             } else {
-                recyclerViewItems.add(userItem)
+                userItems.add(userItem)
             }
             }
         }
         }
 
 
-        Collections.sort(recyclerViewItems, UserItemComparator())
+        Collections.sort(userItems, UserItemComparator())
 
 
         if (ownUserItem != null) {
         if (ownUserItem != null) {
-            recyclerViewItems.add(0, ownUserItem)
+            userItems.add(0, ownUserItem)
         }
         }
 
 
         setupAdapter()
         setupAdapter()
 
 
         binding.participantsListCategory.visibility = View.VISIBLE
         binding.participantsListCategory.visibility = View.VISIBLE
-        adapter!!.updateDataSet(recyclerViewItems)
+        adapter!!.updateDataSet(userItems)
     }
     }
 
 
     override val title: String
     override val title: String
@@ -426,9 +427,12 @@ class ConversationInfoController(args: Bundle) :
             apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
             apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
         }
         }
 
 
+        val fieldMap = HashMap<String, Boolean>()
+        fieldMap["includeStatus"] = true
+
         ncApi?.getPeersForCall(
         ncApi?.getPeersForCall(
             credentials,
             credentials,
-            ApiUtils.getUrlForParticipants(apiVersion, conversationUser!!.baseUrl, conversationToken)
+            ApiUtils.getUrlForParticipants(apiVersion, conversationUser!!.baseUrl, conversationToken), fieldMap
         )
         )
             ?.subscribeOn(Schedulers.io())
             ?.subscribeOn(Schedulers.io())
             ?.observeOn(AndroidSchedulers.mainThread())
             ?.observeOn(AndroidSchedulers.mainThread())
@@ -462,7 +466,7 @@ class ConversationInfoController(args: Bundle) :
         val bundle = Bundle()
         val bundle = Bundle()
         val existingParticipantsId = arrayListOf<String>()
         val existingParticipantsId = arrayListOf<String>()
 
 
-        for (userItem in recyclerViewItems) {
+        for (userItem in userItems) {
             if (userItem.model.getActorType() == USERS) {
             if (userItem.model.getActorType() == USERS) {
                 existingParticipantsId.add(userItem.model.getActorId())
                 existingParticipantsId.add(userItem.model.getActorId())
             }
             }

+ 9 - 0
app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java

@@ -78,6 +78,15 @@ public class Participant {
     @JsonField(name = "inCall")
     @JsonField(name = "inCall")
     public Object inCall;
     public Object inCall;
 
 
+    @JsonField(name = "status")
+    public String status;
+
+    @JsonField(name = "statusIcon")
+    public String statusIcon;
+
+    @JsonField(name = "statusMessage")
+    public String statusMessage;
+
     public String source;
     public String source;
 
 
     public boolean selected;
     public boolean selected;

+ 84 - 48
app/src/main/res/layout/rv_item_conversation_info_participant.xml

@@ -18,67 +18,103 @@
   ~ along with this program.  If not, see <http://www.gnu.org/licenses/>.
   ~ along with this program.  If not, see <http://www.gnu.org/licenses/>.
   -->
   -->
 
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/relativeLayout"
     android:layout_width="match_parent"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/item_height"
-    android:orientation="vertical">
+    android:layout_height="@dimen/item_height">
 
 
 
 
     <com.facebook.drawee.view.SimpleDraweeView
     <com.facebook.drawee.view.SimpleDraweeView
-        android:id="@+id/simple_drawee_view"
-        android:layout_width="@dimen/avatar_size"
-        android:layout_height="@dimen/avatar_size"
-        android:layout_centerVertical="true"
-        android:layout_marginStart="@dimen/activity_horizontal_margin"
+        android:id="@+id/conversation_info_participant_avatar"
+        android:layout_width="@dimen/small_item_height"
+        android:layout_height="@dimen/small_item_height"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="8dp"
+        android:contentDescription="@null"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
         app:roundAsCircle="true" />
         app:roundAsCircle="true" />
 
 
+    <com.vanniktech.emoji.EmojiEditText
+        android:id="@+id/conversation_info_participant_emoji"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:background="@color/transparent"
+        android:cursorVisible="false"
+        android:gravity="center"
+        android:text="@string/default_emoji"
+        android:textSize="16sp"
+        app:layout_constraintStart_toEndOf="@+id/conversation_info_participant_avatar"
+        app:layout_constraintTop_toBottomOf="@+id/name_text" />
+
     <ImageView
     <ImageView
-        android:id="@+id/videoCallIcon"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:layout_alignParentEnd="true"
-        android:layout_centerVertical="true"
-        android:layout_centerInParent="true"
-        android:layout_marginEnd="@dimen/activity_horizontal_margin"
-        android:src="@drawable/ic_videocam_grey_600_24dp"
+        android:id="@+id/conversation_info_participant_online_state"
+        android:layout_width="16dp"
+        android:layout_height="16dp"
         android:contentDescription="@null"
         android:contentDescription="@null"
-        android:visibility="gone"
-        tools:visibility="visible" />
+        android:src="@drawable/online_status"
+        app:layout_constraintBottom_toBottomOf="@+id/conversation_info_participant_avatar"
+        app:layout_constraintEnd_toEndOf="@+id/conversation_info_participant_avatar" />
+
+
+    <androidx.emoji.widget.EmojiTextView
+        android:id="@+id/name_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:layout_marginTop="12dp"
+        android:ellipsize="middle"
+        android:singleLine="true"
+        android:textAlignment="viewStart"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        android:textColor="@color/conversation_item_header"
+        app:layout_constraintStart_toEndOf="@id/conversation_info_participant_avatar"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="Jane Doe" />
 
 
-    <LinearLayout
-        android:id="@+id/linear_layout"
-        android:layout_width="match_parent"
+    <androidx.emoji.widget.EmojiTextView
+        android:id="@+id/conversation_info_status_message"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_centerInParent="true"
-        android:layout_marginStart="@dimen/margin_between_elements"
-        android:layout_marginEnd="@dimen/margin_between_elements"
-        android:layout_toEndOf="@id/simple_drawee_view"
-        android:layout_toStartOf="@id/videoCallIcon"
-        android:orientation="vertical">
+        android:layout_marginStart="8dp"
+        android:ellipsize="middle"
+        android:singleLine="true"
+        android:textAlignment="viewStart"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        android:textColor="@color/conversation_item_header"
+        app:layout_constraintStart_toEndOf="@+id/conversation_info_participant_emoji"
+        app:layout_constraintTop_toBottomOf="@+id/name_text"
+        tools:text="gone shopping" />
 
 
-        <androidx.emoji.widget.EmojiTextView
-            android:id="@+id/name_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:ellipsize="middle"
-            android:singleLine="true"
-            android:textAlignment="viewStart"
-            android:textAppearance="?android:attr/textAppearanceListItem"
-            android:textColor="@color/conversation_item_header"
-            tools:text="Jane Doe" />
+    <androidx.emoji.widget.EmojiTextView
+        android:id="@+id/secondary_text"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:ellipsize="middle"
+        android:singleLine="true"
+        android:textAlignment="viewStart"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        android:textColor="?android:attr/textColorSecondary"
+        app:layout_constraintStart_toEndOf="@+id/name_text"
+        app:layout_constraintTop_toTopOf="@+id/name_text"
+        tools:text="@string/nc_moderator" />
 
 
-        <androidx.emoji.widget.EmojiTextView
-            android:id="@+id/secondary_text"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:ellipsize="middle"
-            android:singleLine="true"
-            android:textAlignment="viewStart"
-            android:textColor="?android:attr/textColorSecondary"
-            tools:text="@string/nc_moderator" />
 
 
-    </LinearLayout>
+    <ImageView
+        android:id="@+id/videoCallIcon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="8dp"
+        android:contentDescription="@null"
+        android:src="@drawable/ic_videocam_grey_600_24dp"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:visibility="visible" />
 
 
-</RelativeLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 2
app/src/main/res/layout/rv_item_conversation_with_last_message.xml

@@ -43,8 +43,7 @@
             android:layout_width="@dimen/small_item_height"
             android:layout_width="@dimen/small_item_height"
             android:layout_height="@dimen/small_item_height"
             android:layout_height="@dimen/small_item_height"
             android:contentDescription="@null"
             android:contentDescription="@null"
-            app:roundAsCircle="true"
-            tools:src="@drawable/ic_call_black_24dp" />
+            app:roundAsCircle="true" />
 
 
         <ImageView
         <ImageView
             android:id="@+id/favoriteConversationImageView"
             android:id="@+id/favoriteConversationImageView"