Fix up guest mentions and autocomplete callback

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2019-09-05 11:17:07 +02:00
parent 3ac3a3b965
commit 4697e4f340
5 changed files with 71 additions and 22 deletions

View File

@ -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;
}

View File

@ -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("");

View File

@ -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);

View File

@ -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();

View File

@ -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;