diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.java index 62cc33510..610758002 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.java @@ -58,8 +58,10 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem= Build.VERSION_CODES.O) { - ImageViewExtensionsKt.loadUserAvatar( - holder.binding.avatarView, - viewThemeUtils.talk.themePlaceholderAvatar( + String avatarId = objectId; + switch (source) { + case SOURCE_CALLS: {} + case SOURCE_GROUPS: { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + ImageViewExtensionsKt.loadUserAvatar( holder.binding.avatarView, - R.drawable.ic_avatar_group - ) - ); - } else { - ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, R.drawable.ic_circular_group); + viewThemeUtils.talk.themePlaceholderAvatar( + holder.binding.avatarView, + R.drawable.ic_avatar_group)); + } else { + ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, R.drawable.ic_circular_group); + } + break; } - } else { - String avatarId = objectId; - if (SOURCE_GUESTS.equals(source)) { + case SOURCE_FEDERATION: { + int darkTheme = (DisplayUtils.isDarkModeOn(this.context))? 1 : 0; + ImageViewExtensionsKt.loadFederatedUserAvatar(holder.binding.avatarView, + currentUser, + Objects.requireNonNull(currentUser.getBaseUrl()), + roomToken, + avatarId, + darkTheme, + true, + false); + break; + } + case SOURCE_GUESTS: { avatarId = displayName; } - ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, currentUser, avatarId, true, false); + default: { + ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, currentUser, avatarId, true, false); + } } drawStatus(holder); diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLinkPreviewMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLinkPreviewMessageViewHolder.kt index ed2662ff9..713361aff 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLinkPreviewMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLinkPreviewMessageViewHolder.kt @@ -37,6 +37,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA import com.nextcloud.talk.databinding.ItemCustomIncomingLinkPreviewMessageBinding import com.nextcloud.talk.extensions.loadBotsAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar +import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils @@ -172,6 +173,8 @@ class IncomingLinkPreviewMessageViewHolder(incomingView: View, payload: Any) : binding.messageUserAvatar.loadChangelogBotAvatar() } else if (message.actorType == "bots") { binding.messageUserAvatar.loadBotsAvatar() + } else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) { + binding.messageUserAvatar.loadFederatedUserAvatar(message) } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt index aa9ab400c..6185aa8e9 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt @@ -47,6 +47,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA import com.nextcloud.talk.databinding.ItemCustomIncomingLocationMessageBinding import com.nextcloud.talk.extensions.loadBotsAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar +import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils @@ -148,6 +149,8 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : binding.messageUserAvatar.loadChangelogBotAvatar() } else if (message.actorType == "bots") { binding.messageUserAvatar.loadBotsAvatar() + } else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) { + binding.messageUserAvatar.loadFederatedUserAvatar(message) } } else { if (message.isOneToOneConversation || message.isFormerOneToOneConversation) { diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt index a3ee9c61e..becb6858b 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt @@ -36,6 +36,7 @@ import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.databinding.ItemCustomIncomingPollMessageBinding import com.nextcloud.talk.extensions.loadBotsAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar +import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.polls.ui.PollMainDialogFragment import com.nextcloud.talk.ui.theme.ViewThemeUtils @@ -179,6 +180,8 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : binding.messageUserAvatar.loadChangelogBotAvatar() } else if (message.actorType == "bots") { binding.messageUserAvatar.loadBotsAvatar() + } else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) { + binding.messageUserAvatar.loadFederatedUserAvatar(message) } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt index 1bfb832df..bb0b3d018 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt @@ -41,6 +41,7 @@ import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.databinding.ItemCustomIncomingTextMessageBinding import com.nextcloud.talk.extensions.loadBotsAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar +import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils @@ -182,6 +183,8 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) : binding.messageUserAvatar.loadChangelogBotAvatar() } else if (message.actorType == "bots") { binding.messageUserAvatar.loadBotsAvatar() + } else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) { + binding.messageUserAvatar.loadFederatedUserAvatar(message) } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt index e09bae1fb..929f54407 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt @@ -45,6 +45,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.databinding.ItemCustomIncomingVoiceMessageBinding import com.nextcloud.talk.extensions.loadChangelogBotAvatar +import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils @@ -285,6 +286,8 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : ) binding.messageUserAvatar.visibility = View.VISIBLE binding.messageUserAvatar.setImageDrawable(drawable) + } else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) { + binding.messageUserAvatar.loadFederatedUserAvatar(message) } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt index 6674240fb..ee21d703e 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt @@ -49,6 +49,7 @@ import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding import com.nextcloud.talk.extensions.loadChangelogBotAvatar +import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.users.UserManager @@ -194,6 +195,8 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) : } if (ACTOR_TYPE_BOTS == message.actorType && ACTOR_ID_CHANGELOG == message.actorId) { userAvatar.loadChangelogBotAvatar() + } else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) { + userAvatar.loadFederatedUserAvatar(message) } } } diff --git a/app/src/main/java/com/nextcloud/talk/callbacks/MentionAutocompleteCallback.java b/app/src/main/java/com/nextcloud/talk/callbacks/MentionAutocompleteCallback.java index fe8434393..87f85c048 100644 --- a/app/src/main/java/com/nextcloud/talk/callbacks/MentionAutocompleteCallback.java +++ b/app/src/main/java/com/nextcloud/talk/callbacks/MentionAutocompleteCallback.java @@ -27,7 +27,6 @@ import android.text.Editable; import android.text.Spanned; import android.widget.EditText; -import third.parties.fresco.BetterImageSpan; import com.nextcloud.talk.R; import com.nextcloud.talk.data.user.model.User; import com.nextcloud.talk.models.json.mention.Mention; @@ -39,7 +38,10 @@ import com.otaliastudios.autocomplete.AutocompleteCallback; import com.vanniktech.emoji.EmojiRange; import com.vanniktech.emoji.Emojis; +import java.util.Objects; + import kotlin.OptIn; +import third.parties.fresco.BetterImageSpan; public class MentionAutocompleteCallback implements AutocompleteCallback { private final ViewThemeUtils viewThemeUtils; @@ -66,26 +68,31 @@ public class MentionAutocompleteCallback implements AutocompleteCallback mention, currentUser, context, + roomToken, viewThemeUtils)); } @@ -185,9 +186,14 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter Mention mention = new Mention(); MentionAutocompleteItem mentionAutocompleteItem = (MentionAutocompleteItem) adapter.getItem(position); if (mentionAutocompleteItem != null) { + String mentionId = mentionAutocompleteItem.getMentionId(); + if(mentionId != null) { + mention.setMentionId(mentionId); + } mention.setId(mentionAutocompleteItem.getObjectId()); mention.setLabel(mentionAutocompleteItem.getDisplayName()); mention.setSource(mentionAutocompleteItem.getSource()); + mention.setRoomToken(mentionAutocompleteItem.getRoomToken()); dispatchClick(mention); } return true; diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index 82092a00c..a5b5613e5 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -383,6 +383,19 @@ object ApiUtils { return baseUrl + "/index.php/avatar/" + Uri.encode(name) + "/" + avatarSize } + @JvmStatic + fun getUrlForFederatedAvatar( + baseUrl: String, + token: String, + cloudId: String, + darkTheme: Int, + requestBigSize: Boolean + ): String { + val avatarSize = if (requestBigSize) AVATAR_SIZE_BIG else AVATAR_SIZE_SMALL + val url = "$baseUrl$OCS_API_VERSION$SPREED_API_VERSION/proxy/$token/user-avatar/$avatarSize" + return "$url?cloudId=$cloudId&darkTheme=$darkTheme" + } + @JvmStatic fun getUrlForGuestAvatar(baseUrl: String?, name: String?, requestBigSize: Boolean): String { val avatarSize = if (requestBigSize) AVATAR_SIZE_BIG else AVATAR_SIZE_SMALL diff --git a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java index c964645e8..3e2c392c8 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java @@ -68,6 +68,7 @@ import org.greenrobot.eventbus.EventBus; import java.text.DateFormat; import java.util.Date; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -168,12 +169,14 @@ public class DisplayUtils { public static Drawable getDrawableForMentionChipSpan(Context context, String id, + String roomToken, CharSequence label, User conversationUser, String type, @XmlRes int chipResource, @Nullable EditText emojiEditText, - ViewThemeUtils viewThemeUtils) { + ViewThemeUtils viewThemeUtils, + Boolean isFederated) { ChipDrawable chip = ChipDrawable.createFromResource(context, chipResource); chip.setText(EmojiCompat.get().process(label)); chip.setEllipsize(TextUtils.TruncateAt.MIDDLE); @@ -205,13 +208,21 @@ public class DisplayUtils { chip.setBounds(0, 0, chip.getIntrinsicWidth(), chip.getIntrinsicHeight()); if (!isCallOrGroup) { - String url = ApiUtils.getUrlForAvatar(conversationUser.getBaseUrl(), id, true); + String url = ApiUtils.getUrlForAvatar(conversationUser.getBaseUrl(), id, false); if ("guests".equals(type) || "guest".equals(type)) { url = ApiUtils.getUrlForGuestAvatar( conversationUser.getBaseUrl(), String.valueOf(label), true); } + if (isFederated) { + int darkTheme = (DisplayUtils.isDarkModeOn(context))? 1 : 0; + url = ApiUtils.getUrlForFederatedAvatar(Objects.requireNonNull(conversationUser.getBaseUrl()), + roomToken, id, + darkTheme, false); + } + + ImageRequest imageRequest = new ImageRequest.Builder(context) .data(url) .crossfade(true) @@ -224,13 +235,12 @@ public class DisplayUtils { @Override public void onError(@Nullable Drawable drawable) { - + chip.setChipIcon(drawable); } @Override public void onSuccess(@NonNull Drawable drawable) { chip.setChipIcon(drawable); - // A hack to refresh the chip icon if (emojiEditText != null) { emojiEditText.post(() -> emojiEditText.setTextKeepState( @@ -248,10 +258,12 @@ public class DisplayUtils { } public static Spannable searchAndReplaceWithMentionSpan(String key, Context context, Spanned text, - String id, String label, String type, + String id, String roomToken, + String label, String type, User conversationUser, @XmlRes int chipXmlRes, - ViewThemeUtils viewThemeUtils) { + ViewThemeUtils viewThemeUtils, + Boolean isFederated) { Spannable spannableString = new SpannableString(text); String stringText = text.toString(); @@ -267,7 +279,7 @@ public class DisplayUtils { } }; - int lastStartIndex = -1; + int lastStartIndex = 0; Spans.MentionChipSpan mentionChipSpan; while (m.find()) { int start = stringText.indexOf(m.group(), lastStartIndex); @@ -276,13 +288,14 @@ public class DisplayUtils { Drawable drawableForChip = DisplayUtils.getDrawableForMentionChipSpan(context, id, + roomToken, label, conversationUser, type, chipXmlRes, null, - viewThemeUtils); - + viewThemeUtils, + isFederated); mentionChipSpan = new Spans.MentionChipSpan(drawableForChip, BetterImageSpan.ALIGN_CENTER, id, diff --git a/app/src/main/java/com/nextcloud/talk/utils/message/MessageUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/message/MessageUtils.kt index 786d9f7f4..cb8787746 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/message/MessageUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/message/MessageUtils.kt @@ -127,16 +127,24 @@ class MessageUtils(val context: Context) { } else { R.xml.chip_others } + val id = if (individualHashMap["server"] != null) { + individualHashMap["id"] + "@" + individualHashMap["server"] + } else { + individualHashMap["id"] + } + messageStringInternal = DisplayUtils.searchAndReplaceWithMentionSpan( key, themingContext, messageStringInternal, - individualHashMap["id"]!!, + id, + message.roomToken, individualHashMap["name"]!!, individualHashMap["type"]!!, message.activeUser!!, chip, - viewThemeUtils + viewThemeUtils, + individualHashMap["server"] != null ) } @@ -174,5 +182,6 @@ class MessageUtils(val context: Context) { companion object { private const val TAG = "MessageUtils" const val MAX_REPLY_LENGTH = 250 + const val HTTPS_PROTOCOL = "https://" } }