mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 11:39:42 +01:00
Federated Mentions
- Federated mention chip - Federated message avatars - Helper functions Signed-off-by: Julius Linus <julius.linus@nextcloud.com>
This commit is contained in:
parent
22de77896a
commit
870ef03d61
@ -58,8 +58,10 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
|
|||||||
public static final String SOURCE_GUESTS = "guests";
|
public static final String SOURCE_GUESTS = "guests";
|
||||||
|
|
||||||
public static final String SOURCE_GROUPS = "groups";
|
public static final String SOURCE_GROUPS = "groups";
|
||||||
|
public static final String SOURCE_FEDERATION = "federated_users";
|
||||||
|
|
||||||
private String source;
|
private String source;
|
||||||
|
private final String mentionId;
|
||||||
private final String objectId;
|
private final String objectId;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
private final String status;
|
private final String status;
|
||||||
@ -67,12 +69,14 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
|
|||||||
private final String statusMessage;
|
private final String statusMessage;
|
||||||
private final User currentUser;
|
private final User currentUser;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
private final String roomToken;
|
||||||
private final ViewThemeUtils viewThemeUtils;
|
private final ViewThemeUtils viewThemeUtils;
|
||||||
|
|
||||||
public MentionAutocompleteItem(
|
public MentionAutocompleteItem(
|
||||||
Mention mention,
|
Mention mention,
|
||||||
User currentUser,
|
User currentUser,
|
||||||
Context activityContext, ViewThemeUtils viewThemeUtils) {
|
Context activityContext, String roomToken, ViewThemeUtils viewThemeUtils) {
|
||||||
|
this.mentionId = mention.getMentionId();
|
||||||
this.objectId = mention.getId();
|
this.objectId = mention.getId();
|
||||||
this.displayName = mention.getLabel();
|
this.displayName = mention.getLabel();
|
||||||
this.source = mention.getSource();
|
this.source = mention.getSource();
|
||||||
@ -82,6 +86,7 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
|
|||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.context = activityContext;
|
this.context = activityContext;
|
||||||
this.viewThemeUtils = viewThemeUtils;
|
this.viewThemeUtils = viewThemeUtils;
|
||||||
|
this.roomToken = roomToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSource() {
|
public String getSource() {
|
||||||
@ -92,6 +97,10 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
|
|||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMentionId() {
|
||||||
|
return mentionId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getObjectId() {
|
public String getObjectId() {
|
||||||
return objectId;
|
return objectId;
|
||||||
}
|
}
|
||||||
@ -100,6 +109,10 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
|
|||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRoomToken() {
|
||||||
|
return roomToken;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o instanceof MentionAutocompleteItem inItem) {
|
if (o instanceof MentionAutocompleteItem inItem) {
|
||||||
@ -147,24 +160,39 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
|
|||||||
holder.binding.secondaryText.setText("@" + objectId);
|
holder.binding.secondaryText.setText("@" + objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SOURCE_CALLS.equals(source) || SOURCE_GROUPS.equals(source)) {
|
String avatarId = objectId;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
switch (source) {
|
||||||
ImageViewExtensionsKt.loadUserAvatar(
|
case SOURCE_CALLS: {}
|
||||||
holder.binding.avatarView,
|
case SOURCE_GROUPS: {
|
||||||
viewThemeUtils.talk.themePlaceholderAvatar(
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
ImageViewExtensionsKt.loadUserAvatar(
|
||||||
holder.binding.avatarView,
|
holder.binding.avatarView,
|
||||||
R.drawable.ic_avatar_group
|
viewThemeUtils.talk.themePlaceholderAvatar(
|
||||||
)
|
holder.binding.avatarView,
|
||||||
);
|
R.drawable.ic_avatar_group));
|
||||||
} else {
|
} else {
|
||||||
ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, R.drawable.ic_circular_group);
|
ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, R.drawable.ic_circular_group);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
case SOURCE_FEDERATION: {
|
||||||
String avatarId = objectId;
|
int darkTheme = (DisplayUtils.isDarkModeOn(this.context))? 1 : 0;
|
||||||
if (SOURCE_GUESTS.equals(source)) {
|
ImageViewExtensionsKt.loadFederatedUserAvatar(holder.binding.avatarView,
|
||||||
|
currentUser,
|
||||||
|
Objects.requireNonNull(currentUser.getBaseUrl()),
|
||||||
|
roomToken,
|
||||||
|
avatarId,
|
||||||
|
darkTheme,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SOURCE_GUESTS: {
|
||||||
avatarId = displayName;
|
avatarId = displayName;
|
||||||
}
|
}
|
||||||
ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, currentUser, avatarId, true, false);
|
default: {
|
||||||
|
ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, currentUser, avatarId, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawStatus(holder);
|
drawStatus(holder);
|
||||||
|
@ -37,6 +37,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
|
|||||||
import com.nextcloud.talk.databinding.ItemCustomIncomingLinkPreviewMessageBinding
|
import com.nextcloud.talk.databinding.ItemCustomIncomingLinkPreviewMessageBinding
|
||||||
import com.nextcloud.talk.extensions.loadBotsAvatar
|
import com.nextcloud.talk.extensions.loadBotsAvatar
|
||||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||||
|
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
@ -172,6 +173,8 @@ class IncomingLinkPreviewMessageViewHolder(incomingView: View, payload: Any) :
|
|||||||
binding.messageUserAvatar.loadChangelogBotAvatar()
|
binding.messageUserAvatar.loadChangelogBotAvatar()
|
||||||
} else if (message.actorType == "bots") {
|
} else if (message.actorType == "bots") {
|
||||||
binding.messageUserAvatar.loadBotsAvatar()
|
binding.messageUserAvatar.loadBotsAvatar()
|
||||||
|
} else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) {
|
||||||
|
binding.messageUserAvatar.loadFederatedUserAvatar(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
|
|||||||
import com.nextcloud.talk.databinding.ItemCustomIncomingLocationMessageBinding
|
import com.nextcloud.talk.databinding.ItemCustomIncomingLocationMessageBinding
|
||||||
import com.nextcloud.talk.extensions.loadBotsAvatar
|
import com.nextcloud.talk.extensions.loadBotsAvatar
|
||||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||||
|
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
@ -148,6 +149,8 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) :
|
|||||||
binding.messageUserAvatar.loadChangelogBotAvatar()
|
binding.messageUserAvatar.loadChangelogBotAvatar()
|
||||||
} else if (message.actorType == "bots") {
|
} else if (message.actorType == "bots") {
|
||||||
binding.messageUserAvatar.loadBotsAvatar()
|
binding.messageUserAvatar.loadBotsAvatar()
|
||||||
|
} else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) {
|
||||||
|
binding.messageUserAvatar.loadFederatedUserAvatar(message)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (message.isOneToOneConversation || message.isFormerOneToOneConversation) {
|
if (message.isOneToOneConversation || message.isFormerOneToOneConversation) {
|
||||||
|
@ -36,6 +36,7 @@ import com.nextcloud.talk.chat.ChatActivity
|
|||||||
import com.nextcloud.talk.databinding.ItemCustomIncomingPollMessageBinding
|
import com.nextcloud.talk.databinding.ItemCustomIncomingPollMessageBinding
|
||||||
import com.nextcloud.talk.extensions.loadBotsAvatar
|
import com.nextcloud.talk.extensions.loadBotsAvatar
|
||||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||||
|
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.polls.ui.PollMainDialogFragment
|
import com.nextcloud.talk.polls.ui.PollMainDialogFragment
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
@ -179,6 +180,8 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) :
|
|||||||
binding.messageUserAvatar.loadChangelogBotAvatar()
|
binding.messageUserAvatar.loadChangelogBotAvatar()
|
||||||
} else if (message.actorType == "bots") {
|
} else if (message.actorType == "bots") {
|
||||||
binding.messageUserAvatar.loadBotsAvatar()
|
binding.messageUserAvatar.loadBotsAvatar()
|
||||||
|
} else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) {
|
||||||
|
binding.messageUserAvatar.loadFederatedUserAvatar(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ import com.nextcloud.talk.chat.ChatActivity
|
|||||||
import com.nextcloud.talk.databinding.ItemCustomIncomingTextMessageBinding
|
import com.nextcloud.talk.databinding.ItemCustomIncomingTextMessageBinding
|
||||||
import com.nextcloud.talk.extensions.loadBotsAvatar
|
import com.nextcloud.talk.extensions.loadBotsAvatar
|
||||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||||
|
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
@ -182,6 +183,8 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) :
|
|||||||
binding.messageUserAvatar.loadChangelogBotAvatar()
|
binding.messageUserAvatar.loadChangelogBotAvatar()
|
||||||
} else if (message.actorType == "bots") {
|
} else if (message.actorType == "bots") {
|
||||||
binding.messageUserAvatar.loadBotsAvatar()
|
binding.messageUserAvatar.loadBotsAvatar()
|
||||||
|
} else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) {
|
||||||
|
binding.messageUserAvatar.loadFederatedUserAvatar(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
|
|||||||
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
||||||
import com.nextcloud.talk.databinding.ItemCustomIncomingVoiceMessageBinding
|
import com.nextcloud.talk.databinding.ItemCustomIncomingVoiceMessageBinding
|
||||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||||
|
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
@ -285,6 +286,8 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
|
|||||||
)
|
)
|
||||||
binding.messageUserAvatar.visibility = View.VISIBLE
|
binding.messageUserAvatar.visibility = View.VISIBLE
|
||||||
binding.messageUserAvatar.setImageDrawable(drawable)
|
binding.messageUserAvatar.setImageDrawable(drawable)
|
||||||
|
} else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) {
|
||||||
|
binding.messageUserAvatar.loadFederatedUserAvatar(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation
|
|||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
|
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
|
||||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||||
|
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.users.UserManager
|
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) {
|
if (ACTOR_TYPE_BOTS == message.actorType && ACTOR_ID_CHANGELOG == message.actorId) {
|
||||||
userAvatar.loadChangelogBotAvatar()
|
userAvatar.loadChangelogBotAvatar()
|
||||||
|
} else if (message.actorType == "federated_users" && message.messageParameters?.get("actor") != null) {
|
||||||
|
userAvatar.loadFederatedUserAvatar(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import android.text.Editable;
|
|||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
import third.parties.fresco.BetterImageSpan;
|
|
||||||
import com.nextcloud.talk.R;
|
import com.nextcloud.talk.R;
|
||||||
import com.nextcloud.talk.data.user.model.User;
|
import com.nextcloud.talk.data.user.model.User;
|
||||||
import com.nextcloud.talk.models.json.mention.Mention;
|
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.EmojiRange;
|
||||||
import com.vanniktech.emoji.Emojis;
|
import com.vanniktech.emoji.Emojis;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import kotlin.OptIn;
|
import kotlin.OptIn;
|
||||||
|
import third.parties.fresco.BetterImageSpan;
|
||||||
|
|
||||||
public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
|
public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
|
||||||
private final ViewThemeUtils viewThemeUtils;
|
private final ViewThemeUtils viewThemeUtils;
|
||||||
@ -66,26 +68,31 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
|
|||||||
}
|
}
|
||||||
String replacement = item.getLabel();
|
String replacement = item.getLabel();
|
||||||
|
|
||||||
StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
|
StringBuilder replacementStringBuilder = new StringBuilder(Objects.requireNonNull(item.getLabel()));
|
||||||
for (EmojiRange emojiRange : Emojis.emojis(replacement)) {
|
for (EmojiRange emojiRange : Emojis.emojis(replacement)) {
|
||||||
replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
|
replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
|
||||||
}
|
}
|
||||||
|
|
||||||
editable.replace(range.getStart(), range.getEnd(), replacementStringBuilder + " ");
|
String charSequence = " ";
|
||||||
|
editable.replace(range.getStart(), range.getEnd(), charSequence + replacementStringBuilder + " ");
|
||||||
|
String id;
|
||||||
|
if (item.getMentionId() != null) id = item.getMentionId(); else id = item.getId();
|
||||||
Spans.MentionChipSpan mentionChipSpan =
|
Spans.MentionChipSpan mentionChipSpan =
|
||||||
new Spans.MentionChipSpan(DisplayUtils.getDrawableForMentionChipSpan(context,
|
new Spans.MentionChipSpan(DisplayUtils.getDrawableForMentionChipSpan(context,
|
||||||
item.getId(),
|
item.getId(),
|
||||||
|
item.getRoomToken(),
|
||||||
item.getLabel(),
|
item.getLabel(),
|
||||||
conversationUser,
|
conversationUser,
|
||||||
item.getSource(),
|
item.getSource(),
|
||||||
R.xml.chip_you,
|
R.xml.chip_you,
|
||||||
editText,
|
editText,
|
||||||
viewThemeUtils),
|
viewThemeUtils,
|
||||||
|
"federated_users".equals(item.getSource())),
|
||||||
BetterImageSpan.ALIGN_CENTER,
|
BetterImageSpan.ALIGN_CENTER,
|
||||||
item.getId(), item.getLabel());
|
id, item.getLabel());
|
||||||
editable.setSpan(mentionChipSpan,
|
editable.setSpan(mentionChipSpan,
|
||||||
range.getStart(),
|
range.getStart() + charSequence.length(),
|
||||||
range.getStart() + replacementStringBuilder.length(),
|
range.getStart() + replacementStringBuilder.length() + charSequence.length(),
|
||||||
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
|
|
||||||
|
|
||||||
|
@ -3584,6 +3584,7 @@ class ChatActivity :
|
|||||||
mentionSpan = mentionSpans[i]
|
mentionSpan = mentionSpans[i]
|
||||||
var mentionId = mentionSpan.id
|
var mentionId = mentionSpan.id
|
||||||
if (mentionId.contains(" ") ||
|
if (mentionId.contains(" ") ||
|
||||||
|
mentionId.contains("@") ||
|
||||||
mentionId.startsWith("guest/") ||
|
mentionId.startsWith("guest/") ||
|
||||||
mentionId.startsWith("group/")
|
mentionId.startsWith("group/")
|
||||||
) {
|
) {
|
||||||
@ -3798,6 +3799,7 @@ class ChatActivity :
|
|||||||
chatMessage.isFormerOneToOneConversation =
|
chatMessage.isFormerOneToOneConversation =
|
||||||
(currentConversation?.type == ConversationType.FORMER_ONE_TO_ONE)
|
(currentConversation?.type == ConversationType.FORMER_ONE_TO_ONE)
|
||||||
chatMessage.activeUser = conversationUser
|
chatMessage.activeUser = conversationUser
|
||||||
|
chatMessage.roomToken = roomToken
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
|
@ -46,6 +46,7 @@ import com.nextcloud.talk.R
|
|||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
import com.nextcloud.talk.models.domain.ConversationModel
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
import com.nextcloud.talk.models.domain.ConversationType
|
import com.nextcloud.talk.models.domain.ConversationType
|
||||||
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
@ -126,6 +127,47 @@ fun ImageView.loadUserAvatar(
|
|||||||
return loadAvatarInternal(user, imageRequestUri, ignoreCache, null)
|
return loadAvatarInternal(user, imageRequestUri, ignoreCache, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ImageView.loadFederatedUserAvatar(message: ChatMessage): io.reactivex.disposables.Disposable {
|
||||||
|
val map = message.messageParameters?.get("actor")
|
||||||
|
val url = map?.get("server")!!
|
||||||
|
val id = map["id"]
|
||||||
|
val cloudId = "$id@$url"
|
||||||
|
val darkTheme = if (DisplayUtils.isDarkModeOn(context)) 1 else 0
|
||||||
|
val ignoreCache = false
|
||||||
|
val requestBigSize = true
|
||||||
|
return loadFederatedUserAvatar(
|
||||||
|
message.activeUser!!,
|
||||||
|
message.activeUser!!.baseUrl!!,
|
||||||
|
message.roomToken,
|
||||||
|
cloudId,
|
||||||
|
darkTheme,
|
||||||
|
requestBigSize,
|
||||||
|
ignoreCache
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("LongParameterList")
|
||||||
|
fun ImageView.loadFederatedUserAvatar(
|
||||||
|
user: User,
|
||||||
|
baseUrl: String,
|
||||||
|
token: String,
|
||||||
|
cloudId: String,
|
||||||
|
darkTheme: Int,
|
||||||
|
requestBigSize: Boolean = true,
|
||||||
|
ignoreCache: Boolean
|
||||||
|
): io.reactivex.disposables.Disposable {
|
||||||
|
val imageRequestUri = ApiUtils.getUrlForFederatedAvatar(
|
||||||
|
baseUrl,
|
||||||
|
token,
|
||||||
|
cloudId,
|
||||||
|
darkTheme,
|
||||||
|
requestBigSize
|
||||||
|
)
|
||||||
|
Log.d("Julius", "URL::$imageRequestUri")
|
||||||
|
|
||||||
|
return loadAvatarInternal(user, imageRequestUri, ignoreCache, null)
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoilApi::class)
|
@OptIn(ExperimentalCoilApi::class)
|
||||||
private fun ImageView.loadAvatarInternal(
|
private fun ImageView.loadAvatarInternal(
|
||||||
user: User?,
|
user: User?,
|
||||||
|
@ -159,7 +159,9 @@ data class ChatMessage(
|
|||||||
|
|
||||||
var hiddenByCollapse: Boolean = false,
|
var hiddenByCollapse: Boolean = false,
|
||||||
|
|
||||||
var openWhenDownloaded: Boolean = true
|
var openWhenDownloaded: Boolean = true,
|
||||||
|
|
||||||
|
var roomToken: String = ""
|
||||||
|
|
||||||
) : Parcelable, MessageContentType, MessageContentType.Image {
|
) : Parcelable, MessageContentType, MessageContentType.Image {
|
||||||
|
|
||||||
|
@ -23,12 +23,15 @@ package com.nextcloud.talk.models.json.mention
|
|||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||||
|
import com.bluelinelabs.logansquare.annotation.JsonIgnore
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@JsonObject
|
@JsonObject
|
||||||
data class Mention(
|
data class Mention(
|
||||||
|
@JsonField(name = ["mentionId"])
|
||||||
|
var mentionId: String?,
|
||||||
@JsonField(name = ["id"])
|
@JsonField(name = ["id"])
|
||||||
var id: String?,
|
var id: String?,
|
||||||
@JsonField(name = ["label"])
|
@JsonField(name = ["label"])
|
||||||
@ -41,8 +44,10 @@ data class Mention(
|
|||||||
@JsonField(name = ["statusIcon"])
|
@JsonField(name = ["statusIcon"])
|
||||||
var statusIcon: String?,
|
var statusIcon: String?,
|
||||||
@JsonField(name = ["statusMessage"])
|
@JsonField(name = ["statusMessage"])
|
||||||
var statusMessage: String?
|
var statusMessage: String?,
|
||||||
|
@JsonIgnore
|
||||||
|
var roomToken: String?
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||||
constructor() : this(null, null, null, null, null, null)
|
constructor() : this(null, null, null, null, null, null, null, null)
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,7 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
|
|||||||
mention,
|
mention,
|
||||||
currentUser,
|
currentUser,
|
||||||
context,
|
context,
|
||||||
|
roomToken,
|
||||||
viewThemeUtils));
|
viewThemeUtils));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,9 +186,14 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
|
|||||||
Mention mention = new Mention();
|
Mention mention = new Mention();
|
||||||
MentionAutocompleteItem mentionAutocompleteItem = (MentionAutocompleteItem) adapter.getItem(position);
|
MentionAutocompleteItem mentionAutocompleteItem = (MentionAutocompleteItem) adapter.getItem(position);
|
||||||
if (mentionAutocompleteItem != null) {
|
if (mentionAutocompleteItem != null) {
|
||||||
|
String mentionId = mentionAutocompleteItem.getMentionId();
|
||||||
|
if(mentionId != null) {
|
||||||
|
mention.setMentionId(mentionId);
|
||||||
|
}
|
||||||
mention.setId(mentionAutocompleteItem.getObjectId());
|
mention.setId(mentionAutocompleteItem.getObjectId());
|
||||||
mention.setLabel(mentionAutocompleteItem.getDisplayName());
|
mention.setLabel(mentionAutocompleteItem.getDisplayName());
|
||||||
mention.setSource(mentionAutocompleteItem.getSource());
|
mention.setSource(mentionAutocompleteItem.getSource());
|
||||||
|
mention.setRoomToken(mentionAutocompleteItem.getRoomToken());
|
||||||
dispatchClick(mention);
|
dispatchClick(mention);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -383,6 +383,19 @@ object ApiUtils {
|
|||||||
return baseUrl + "/index.php/avatar/" + Uri.encode(name) + "/" + avatarSize
|
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
|
@JvmStatic
|
||||||
fun getUrlForGuestAvatar(baseUrl: String?, name: String?, requestBigSize: Boolean): String {
|
fun getUrlForGuestAvatar(baseUrl: String?, name: String?, requestBigSize: Boolean): String {
|
||||||
val avatarSize = if (requestBigSize) AVATAR_SIZE_BIG else AVATAR_SIZE_SMALL
|
val avatarSize = if (requestBigSize) AVATAR_SIZE_BIG else AVATAR_SIZE_SMALL
|
||||||
|
@ -68,6 +68,7 @@ import org.greenrobot.eventbus.EventBus;
|
|||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -168,12 +169,14 @@ public class DisplayUtils {
|
|||||||
|
|
||||||
public static Drawable getDrawableForMentionChipSpan(Context context,
|
public static Drawable getDrawableForMentionChipSpan(Context context,
|
||||||
String id,
|
String id,
|
||||||
|
String roomToken,
|
||||||
CharSequence label,
|
CharSequence label,
|
||||||
User conversationUser,
|
User conversationUser,
|
||||||
String type,
|
String type,
|
||||||
@XmlRes int chipResource,
|
@XmlRes int chipResource,
|
||||||
@Nullable EditText emojiEditText,
|
@Nullable EditText emojiEditText,
|
||||||
ViewThemeUtils viewThemeUtils) {
|
ViewThemeUtils viewThemeUtils,
|
||||||
|
Boolean isFederated) {
|
||||||
ChipDrawable chip = ChipDrawable.createFromResource(context, chipResource);
|
ChipDrawable chip = ChipDrawable.createFromResource(context, chipResource);
|
||||||
chip.setText(EmojiCompat.get().process(label));
|
chip.setText(EmojiCompat.get().process(label));
|
||||||
chip.setEllipsize(TextUtils.TruncateAt.MIDDLE);
|
chip.setEllipsize(TextUtils.TruncateAt.MIDDLE);
|
||||||
@ -205,13 +208,21 @@ public class DisplayUtils {
|
|||||||
chip.setBounds(0, 0, chip.getIntrinsicWidth(), chip.getIntrinsicHeight());
|
chip.setBounds(0, 0, chip.getIntrinsicWidth(), chip.getIntrinsicHeight());
|
||||||
|
|
||||||
if (!isCallOrGroup) {
|
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)) {
|
if ("guests".equals(type) || "guest".equals(type)) {
|
||||||
url = ApiUtils.getUrlForGuestAvatar(
|
url = ApiUtils.getUrlForGuestAvatar(
|
||||||
conversationUser.getBaseUrl(),
|
conversationUser.getBaseUrl(),
|
||||||
String.valueOf(label), true);
|
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)
|
ImageRequest imageRequest = new ImageRequest.Builder(context)
|
||||||
.data(url)
|
.data(url)
|
||||||
.crossfade(true)
|
.crossfade(true)
|
||||||
@ -224,13 +235,12 @@ public class DisplayUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(@Nullable Drawable drawable) {
|
public void onError(@Nullable Drawable drawable) {
|
||||||
|
chip.setChipIcon(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@NonNull Drawable drawable) {
|
public void onSuccess(@NonNull Drawable drawable) {
|
||||||
chip.setChipIcon(drawable);
|
chip.setChipIcon(drawable);
|
||||||
|
|
||||||
// A hack to refresh the chip icon
|
// A hack to refresh the chip icon
|
||||||
if (emojiEditText != null) {
|
if (emojiEditText != null) {
|
||||||
emojiEditText.post(() -> emojiEditText.setTextKeepState(
|
emojiEditText.post(() -> emojiEditText.setTextKeepState(
|
||||||
@ -248,10 +258,12 @@ public class DisplayUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Spannable searchAndReplaceWithMentionSpan(String key, Context context, Spanned text,
|
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,
|
User conversationUser,
|
||||||
@XmlRes int chipXmlRes,
|
@XmlRes int chipXmlRes,
|
||||||
ViewThemeUtils viewThemeUtils) {
|
ViewThemeUtils viewThemeUtils,
|
||||||
|
Boolean isFederated) {
|
||||||
|
|
||||||
Spannable spannableString = new SpannableString(text);
|
Spannable spannableString = new SpannableString(text);
|
||||||
String stringText = text.toString();
|
String stringText = text.toString();
|
||||||
@ -267,7 +279,7 @@ public class DisplayUtils {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int lastStartIndex = -1;
|
int lastStartIndex = 0;
|
||||||
Spans.MentionChipSpan mentionChipSpan;
|
Spans.MentionChipSpan mentionChipSpan;
|
||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
int start = stringText.indexOf(m.group(), lastStartIndex);
|
int start = stringText.indexOf(m.group(), lastStartIndex);
|
||||||
@ -276,13 +288,14 @@ public class DisplayUtils {
|
|||||||
|
|
||||||
Drawable drawableForChip = DisplayUtils.getDrawableForMentionChipSpan(context,
|
Drawable drawableForChip = DisplayUtils.getDrawableForMentionChipSpan(context,
|
||||||
id,
|
id,
|
||||||
|
roomToken,
|
||||||
label,
|
label,
|
||||||
conversationUser,
|
conversationUser,
|
||||||
type,
|
type,
|
||||||
chipXmlRes,
|
chipXmlRes,
|
||||||
null,
|
null,
|
||||||
viewThemeUtils);
|
viewThemeUtils,
|
||||||
|
isFederated);
|
||||||
mentionChipSpan = new Spans.MentionChipSpan(drawableForChip,
|
mentionChipSpan = new Spans.MentionChipSpan(drawableForChip,
|
||||||
BetterImageSpan.ALIGN_CENTER,
|
BetterImageSpan.ALIGN_CENTER,
|
||||||
id,
|
id,
|
||||||
|
@ -127,16 +127,24 @@ class MessageUtils(val context: Context) {
|
|||||||
} else {
|
} else {
|
||||||
R.xml.chip_others
|
R.xml.chip_others
|
||||||
}
|
}
|
||||||
|
val id = if (individualHashMap["server"] != null) {
|
||||||
|
individualHashMap["id"] + "@" + individualHashMap["server"]
|
||||||
|
} else {
|
||||||
|
individualHashMap["id"]
|
||||||
|
}
|
||||||
|
|
||||||
messageStringInternal = DisplayUtils.searchAndReplaceWithMentionSpan(
|
messageStringInternal = DisplayUtils.searchAndReplaceWithMentionSpan(
|
||||||
key,
|
key,
|
||||||
themingContext,
|
themingContext,
|
||||||
messageStringInternal,
|
messageStringInternal,
|
||||||
individualHashMap["id"]!!,
|
id,
|
||||||
|
message.roomToken,
|
||||||
individualHashMap["name"]!!,
|
individualHashMap["name"]!!,
|
||||||
individualHashMap["type"]!!,
|
individualHashMap["type"]!!,
|
||||||
message.activeUser!!,
|
message.activeUser!!,
|
||||||
chip,
|
chip,
|
||||||
viewThemeUtils
|
viewThemeUtils,
|
||||||
|
individualHashMap["server"] != null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,5 +182,6 @@ class MessageUtils(val context: Context) {
|
|||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "MessageUtils"
|
private const val TAG = "MessageUtils"
|
||||||
const val MAX_REPLY_LENGTH = 250
|
const val MAX_REPLY_LENGTH = 250
|
||||||
|
const val HTTPS_PROTOCOL = "https://"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user