Browse Source

Fix up guest mentions and autocomplete callback

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 5 năm trước cách đây
mục cha
commit
4697e4f340

+ 14 - 3
app/src/main/java/com/nextcloud/talk/callbacks/MentionAutocompleteCallback.java

@@ -24,6 +24,9 @@ import android.content.Context;
 import android.text.Editable;
 import android.text.Spanned;
 import android.widget.EditText;
+
+import androidx.emoji.text.EmojiCompat;
+
 import com.facebook.widget.text.span.BetterImageSpan;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.models.database.UserEntity;
@@ -32,6 +35,8 @@ import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.MagicCharPolicy;
 import com.nextcloud.talk.utils.text.Spans;
 import com.otaliastudios.autocomplete.AutocompleteCallback;
+import com.vanniktech.emoji.EmojiRange;
+import com.vanniktech.emoji.EmojiUtils;
 
 public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
     private Context context;
@@ -52,15 +57,21 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
         int start = range[0];
         int end = range[1];
         String replacement = item.getLabel();
-        editable.replace(start, end, replacement + " ");
+
+        StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
+        for(EmojiRange emojiRange : EmojiUtils.emojis(replacement)) {
+            replacementStringBuilder.delete(emojiRange.start, emojiRange.end);
+        }
+
+        editable.replace(start, end, replacementStringBuilder.toString() + " ");
         Spans.MentionChipSpan mentionChipSpan =
                 new Spans.MentionChipSpan(DisplayUtils.getDrawableForMentionChipSpan(context,
                         item.getId(), item.getLabel(), conversationUser, item.getSource(),
                         R.xml.chip_text_entry, editText),
                         BetterImageSpan.ALIGN_CENTER,
                         item.getId(), item.getLabel());
-        editable.setSpan(mentionChipSpan, start, start + item.getLabel().length(),
-                Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+        editable.setSpan(mentionChipSpan, start, start + replacementStringBuilder.toString().length(),
+                Spanned.SPAN_INCLUSIVE_INCLUSIVE);
         return true;
     }
 

+ 5 - 1
app/src/main/java/com/nextcloud/talk/controllers/ChatController.java

@@ -916,7 +916,11 @@ public class ChatController extends BaseController implements MessagesListAdapte
         Spans.MentionChipSpan mentionSpan;
         for (int i = 0; i < mentionSpans.length; i++) {
             mentionSpan = mentionSpans[i];
-            editable.replace(editable.getSpanStart(mentionSpan), editable.getSpanEnd(mentionSpan), "@" + mentionSpan.getId());
+            String mentionId = mentionSpan.getId();
+            if (mentionId.contains(" ") || mentionId.startsWith("guest/")) {
+                mentionId = "\"" + mentionId + "\"";
+            }
+            editable.replace(editable.getSpanStart(mentionSpan), editable.getSpanEnd(mentionSpan), "@" + mentionId);
         }
 
         messageInput.setText("");

+ 22 - 6
app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java

@@ -45,6 +45,7 @@ import androidx.core.app.NotificationCompat;
 import androidx.core.app.NotificationManagerCompat;
 import androidx.core.app.Person;
 import androidx.core.graphics.drawable.IconCompat;
+import androidx.emoji.text.EmojiCompat;
 import androidx.work.Data;
 import androidx.work.Worker;
 import androidx.work.WorkerParameters;
@@ -83,6 +84,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys;
 import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageUtils;
 import com.nextcloud.talk.utils.preferences.AppPreferences;
 import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
+import com.vanniktech.emoji.emoji.Emoji;
 
 import org.parceler.Parcels;
 
@@ -225,6 +227,7 @@ public class NotificationWorker extends Worker {
                         if (subjectRichParameters != null && subjectRichParameters.size() > 0) {
                             HashMap<String, String> callHashMap = subjectRichParameters.get("call");
                             HashMap<String, String> userHashMap = subjectRichParameters.get("user");
+                            HashMap<String, String> guestHashMap = subjectRichParameters.get("guest");
 
                             if (callHashMap != null && callHashMap.size() > 0 && callHashMap.containsKey("name")) {
                                 if (notification.getObjectType().equals("chat")) {
@@ -238,12 +241,17 @@ public class NotificationWorker extends Worker {
                                 }
                             }
 
+                            NotificationUser notificationUser = new NotificationUser();
                             if (userHashMap != null && !userHashMap.isEmpty()) {
-                                NotificationUser notificationUser = new NotificationUser();
                                 notificationUser.setId(userHashMap.get("id"));
                                 notificationUser.setType(userHashMap.get("type"));
                                 notificationUser.setName(userHashMap.get("name"));
                                 decryptedPushMessage.setNotificationUser(notificationUser);
+                            } else if (guestHashMap != null && !guestHashMap.isEmpty()) {
+                                notificationUser.setId(guestHashMap.get("id"));
+                                notificationUser.setType(guestHashMap.get("type"));
+                                notificationUser.setName(guestHashMap.get("name"));
+                                decryptedPushMessage.setNotificationUser(notificationUser);
                             }
                         }
 
@@ -307,12 +315,12 @@ public class NotificationWorker extends Worker {
                 .setSubText(baseUrl)
                 .setWhen(decryptedPushMessage.getTimestamp())
                 .setShowWhen(true)
-                .setContentTitle(decryptedPushMessage.getSubject())
+                .setContentTitle(EmojiCompat.get().process(decryptedPushMessage.getSubject()))
                 .setContentIntent(pendingIntent)
                 .setAutoCancel(true);
 
         if (!TextUtils.isEmpty(decryptedPushMessage.getText())) {
-            notificationBuilder.setContentText(decryptedPushMessage.getText());
+            notificationBuilder.setContentText(EmojiCompat.get().process(decryptedPushMessage.getText()));
         }
 
         if (Build.VERSION.SDK_INT >= 23) {
@@ -391,13 +399,21 @@ public class NotificationWorker extends Worker {
             }
 
             Person.Builder person =
-                    new Person.Builder().setKey(signatureVerification.getUserEntity().getId() + "@" + decryptedPushMessage.getNotificationUser().getId()).setName(decryptedPushMessage.getNotificationUser().getName()).setBot(decryptedPushMessage.getNotificationUser().getType().equals("bot"));
+                    new Person.Builder().setKey(signatureVerification.getUserEntity().getId() +
+                            "@" + decryptedPushMessage.getNotificationUser().getId()).setName(EmojiCompat.get().process(decryptedPushMessage.getNotificationUser().getName())).setBot(decryptedPushMessage.getNotificationUser().getType().equals("bot"));
 
             notificationBuilder.setOnlyAlertOnce(true);
 
-            if (decryptedPushMessage.getNotificationUser().getType().equals("user")) {
+            if (decryptedPushMessage.getNotificationUser().getType().equals("user") || decryptedPushMessage.getNotificationUser().getType().equals("guest")) {
+                String avatarUrl = ApiUtils.getUrlForAvatarWithName(signatureVerification.getUserEntity().getBaseUrl(), decryptedPushMessage.getNotificationUser().getId(), R.dimen.avatar_size);
+
+                if (decryptedPushMessage.getNotificationUser().getType().equals("guest")) {
+                    avatarUrl = ApiUtils.getUrlForAvatarWithNameForGuests(signatureVerification.getUserEntity().getBaseUrl(),
+                            decryptedPushMessage.getNotificationUser().getName(), R.dimen.avatar_size);
+                }
+
                 ImageRequest imageRequest =
-                        DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(signatureVerification.getUserEntity().getBaseUrl(), decryptedPushMessage.getNotificationUser().getId(), R.dimen.avatar_size), null);
+                        DisplayUtils.getImageRequestForUrl(avatarUrl, null);
                 ImagePipeline imagePipeline = Fresco.getImagePipeline();
                 DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, context);
 

+ 28 - 10
app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java

@@ -35,7 +35,11 @@ import android.graphics.drawable.Drawable;
 import android.graphics.drawable.VectorDrawable;
 import android.net.Uri;
 import android.os.Build;
-import android.text.*;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextPaint;
+import android.text.TextUtils;
 import android.text.method.LinkMovementMethod;
 import android.text.style.AbsoluteSizeSpan;
 import android.text.style.ClickableSpan;
@@ -47,10 +51,19 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.EditText;
 import android.widget.TextView;
-import androidx.annotation.*;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.ColorRes;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.XmlRes;
 import androidx.appcompat.widget.AppCompatDrawableManager;
 import androidx.core.content.ContextCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.emoji.text.EmojiCompat;
+import androidx.emoji.text.EmojiSpan;
+import androidx.emoji.text.TypefaceEmojiSpan;
+
 import com.facebook.common.executors.UiThreadImmediateExecutorService;
 import com.facebook.common.references.CloseableReference;
 import com.facebook.datasource.DataSource;
@@ -73,18 +86,24 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.events.UserMentionClickEvent;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.utils.text.Spans;
+import com.vanniktech.emoji.EmojiManager;
+import com.vanniktech.emoji.EmojiRange;
+import com.vanniktech.emoji.EmojiUtils;
+
 import org.greenrobot.eventbus.EventBus;
 
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 public class DisplayUtils {
 
     private static final String TAG = "DisplayUtils";
@@ -148,8 +167,7 @@ public class DisplayUtils {
     public static ImageRequest getImageRequestForUrl(String url, @Nullable UserEntity userEntity) {
         Map<String, String> headers = new HashMap<>();
         if (userEntity != null && url.startsWith(userEntity.getBaseUrl()) && url.contains("index.php/core/preview?fileId=")) {
-            headers.put("Authorization", ApiUtils.getCredentials(userEntity.getUsername(),
-                    userEntity.getToken()));
+            headers.put("Authorization", ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()));
         }
 
         return ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
@@ -230,12 +248,12 @@ public class DisplayUtils {
     }
 
 
-    public static Drawable getDrawableForMentionChipSpan(Context context, String id, String label,
+    public static Drawable getDrawableForMentionChipSpan(Context context, String id, CharSequence label,
                                                          UserEntity conversationUser, String type,
                                                          @XmlRes int chipResource,
                                                          @Nullable EditText emojiEditText) {
         ChipDrawable chip = ChipDrawable.createFromResource(context, chipResource);
-        chip.setText(label);
+        chip.setText(EmojiCompat.get().process(label));
         chip.setEllipsize(TextUtils.TruncateAt.MIDDLE);
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@@ -263,8 +281,8 @@ public class DisplayUtils {
 
         if (!isCall) {
             String url = ApiUtils.getUrlForAvatarWithName(conversationUser.getBaseUrl(), id, R.dimen.avatar_size_big);
-            if ("guests".equals(type)) {
-                url = ApiUtils.getUrlForAvatarWithNameForGuests(conversationUser.getBaseUrl(), label, R.dimen.avatar_size_big);
+            if ("guests".equals(type) || "guest".equals(type)) {
+                url = ApiUtils.getUrlForAvatarWithNameForGuests(conversationUser.getBaseUrl(), String.valueOf(label), R.dimen.avatar_size_big);
             }
             ImageRequest imageRequest = getImageRequestForUrl(url, null);
             ImagePipeline imagePipeline = Fresco.getImagePipeline();

+ 2 - 2
app/src/main/java/com/nextcloud/talk/utils/text/Spans.java

@@ -30,9 +30,9 @@ public class Spans {
     @Data
     public static class MentionChipSpan extends BetterImageSpan {
         String id;
-        String label;
+        CharSequence label;
 
-        public MentionChipSpan(@NonNull Drawable drawable, int verticalAlignment, String id, String label) {
+        public MentionChipSpan(@NonNull Drawable drawable, int verticalAlignment, String id, CharSequence label) {
             super(drawable, verticalAlignment);
             this.id = id;
             this.label = label;