convert MentionAutocompleteItem to kt

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2024-03-21 14:53:52 +01:00 committed by Andy Scherzinger
parent 4a75108557
commit bb6af562cc
4 changed files with 253 additions and 261 deletions

View File

@ -1,255 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* @author Marcel Hibbe
* @author Andy Scherzinger
* Copyright (C) 2021-2022 Andy Scherzinger <info@andy-scherzinger.de>
* Copyright (C) 2022 Marcel Hibbe <dev@mhibbe.de>
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.adapters.items;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.view.View;
import com.nextcloud.talk.R;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.extensions.ImageViewExtensionsKt;
import com.nextcloud.talk.models.json.mention.Mention;
import com.nextcloud.talk.models.json.status.StatusType;
import com.nextcloud.talk.ui.StatusDrawable;
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
import com.nextcloud.talk.utils.DisplayUtils;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.res.ResourcesCompat;
import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
import eu.davidea.flexibleadapter.items.IFilterable;
import eu.davidea.flexibleadapter.items.IFlexible;
public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantItem.ParticipantItemViewHolder>
implements IFilterable<String> {
private static final float STATUS_SIZE_IN_DP = 9f;
private static final String NO_ICON = "";
public static final String SOURCE_CALLS = "calls";
public static final String SOURCE_GUESTS = "guests";
public static final String SOURCE_GROUPS = "groups";
public static final String SOURCE_FEDERATION = "federated_users";
private String source;
private final String mentionId;
private final String objectId;
private final String displayName;
private final String status;
private final String statusIcon;
private final String statusMessage;
private final User currentUser;
private final Context context;
private final String roomToken;
private final ViewThemeUtils viewThemeUtils;
public MentionAutocompleteItem(
Mention mention,
User currentUser,
Context activityContext, String roomToken, ViewThemeUtils viewThemeUtils) {
this.mentionId = mention.getMentionId();
this.objectId = mention.getId();
this.displayName = mention.getLabel();
this.source = mention.getSource();
this.status = mention.getStatus();
this.statusIcon = mention.getStatusIcon();
this.statusMessage = mention.getStatusMessage();
this.currentUser = currentUser;
this.context = activityContext;
this.viewThemeUtils = viewThemeUtils;
this.roomToken = roomToken;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getMentionId() {
return mentionId;
}
public String getObjectId() {
return objectId;
}
public String getDisplayName() {
return displayName;
}
public String getRoomToken() {
return roomToken;
}
@Override
public boolean equals(Object o) {
if (o instanceof MentionAutocompleteItem inItem) {
return (objectId.equals(inItem.objectId) && displayName.equals(inItem.displayName));
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(objectId, displayName);
}
@Override
public int getLayoutRes() {
return R.layout.rv_item_conversation_info_participant;
}
@Override
public ParticipantItem.ParticipantItemViewHolder createViewHolder(View view, FlexibleAdapter<IFlexible> adapter) {
return new ParticipantItem.ParticipantItemViewHolder(view, adapter);
}
@SuppressLint("SetTextI18n")
@Override
public void bindViewHolder(FlexibleAdapter<IFlexible> adapter,
ParticipantItem.ParticipantItemViewHolder holder,
int position,
List<Object> payloads) {
holder.binding.nameText.setTextColor(
ResourcesCompat.getColor(context.getResources(),
R.color.conversation_item_header,
null));
if (adapter.hasFilter()) {
viewThemeUtils.talk.themeAndHighlightText(holder.binding.nameText,
displayName,
String.valueOf(adapter.getFilter(String.class)));
viewThemeUtils.talk.themeAndHighlightText(holder.binding.secondaryText,
"@" + objectId,
String.valueOf(adapter.getFilter(String.class)));
} else {
holder.binding.nameText.setText(displayName);
holder.binding.secondaryText.setText("@" + objectId);
}
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,
viewThemeUtils.talk.themePlaceholderAvatar(
holder.binding.avatarView,
R.drawable.ic_avatar_group));
} else {
ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, R.drawable.ic_circular_group);
}
break;
}
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;
}
default: {
ImageViewExtensionsKt.loadUserAvatar(holder.binding.avatarView, currentUser, avatarId, true, false);
}
}
drawStatus(holder);
}
private void drawStatus(ParticipantItem.ParticipantItemViewHolder holder) {
float size = DisplayUtils.convertDpToPixel(STATUS_SIZE_IN_DP, context);
holder.binding.userStatusImage.setImageDrawable(new StatusDrawable(
status,
NO_ICON,
size,
context.getResources().getColor(R.color.bg_default),
context));
if (statusMessage != null) {
holder.binding.conversationInfoStatusMessage.setText(statusMessage);
alignUsernameVertical(holder, 0);
} else {
holder.binding.conversationInfoStatusMessage.setText("");
alignUsernameVertical(holder, 10);
}
if (statusIcon != null && !statusIcon.isEmpty()) {
holder.binding.participantStatusEmoji.setText(statusIcon);
} else {
holder.binding.participantStatusEmoji.setVisibility(View.GONE);
}
if (status != null && status.equals(StatusType.DND.getString())) {
if (statusMessage == null || statusMessage.isEmpty()) {
holder.binding.conversationInfoStatusMessage.setText(R.string.dnd);
}
} else if (status != null && status.equals(StatusType.AWAY.getString())) {
if (statusMessage == null || statusMessage.isEmpty()) {
holder.binding.conversationInfoStatusMessage.setText(R.string.away);
}
}
}
private void alignUsernameVertical(ParticipantItem.ParticipantItemViewHolder holder, float densityPixelsFromTop) {
ConstraintLayout.LayoutParams layoutParams =
(ConstraintLayout.LayoutParams) holder.binding.nameText.getLayoutParams();
layoutParams.topMargin = (int) DisplayUtils.convertDpToPixel(densityPixelsFromTop, context);
holder.binding.nameText.setLayoutParams(layoutParams);
}
@Override
public boolean filter(String constraint) {
return objectId != null &&
Pattern
.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
.matcher(objectId)
.find() ||
displayName != null &&
Pattern
.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
.matcher(displayName)
.find();
}
}

View File

@ -0,0 +1,247 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* @author Marcel Hibbe
* @author Andy Scherzinger
* Copyright (C) 2021-2022 Andy Scherzinger <info@andy-scherzinger.de>
* Copyright (C) 2022 Marcel Hibbe <dev@mhibbe.de>
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.adapters.items
import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.ResourcesCompat
import com.nextcloud.talk.R
import com.nextcloud.talk.adapters.items.ParticipantItem.ParticipantItemViewHolder
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
import com.nextcloud.talk.extensions.loadUserAvatar
import com.nextcloud.talk.models.json.mention.Mention
import com.nextcloud.talk.models.json.status.StatusType
import com.nextcloud.talk.ui.StatusDrawable
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.DisplayUtils
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFilterable
import eu.davidea.flexibleadapter.items.IFlexible
import java.util.Objects
import java.util.regex.Pattern
class MentionAutocompleteItem(
mention: Mention,
private val currentUser: User,
private val context: Context,
@JvmField val roomToken: String,
private val viewThemeUtils: ViewThemeUtils
) : AbstractFlexibleItem<ParticipantItemViewHolder>(), IFilterable<String?> {
@JvmField
var source: String?
@JvmField
val mentionId: String?
@JvmField
val objectId: String?
@JvmField
val displayName: String?
private val status: String?
private val statusIcon: String?
private val statusMessage: String?
init {
mentionId = mention.mentionId
objectId = mention.id
displayName = mention.label
source = mention.source
status = mention.status
statusIcon = mention.statusIcon
statusMessage = mention.statusMessage
}
override fun equals(o: Any?): Boolean {
return if (o is MentionAutocompleteItem) {
objectId == o.objectId && displayName == o.displayName
} else {
false
}
}
override fun hashCode(): Int {
return Objects.hash(objectId, displayName)
}
override fun getLayoutRes(): Int {
return R.layout.rv_item_conversation_info_participant
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>?>?): ParticipantItemViewHolder {
return ParticipantItemViewHolder(view, adapter)
}
@SuppressLint("SetTextI18n")
override fun bindViewHolder(
adapter: FlexibleAdapter<IFlexible<*>?>,
holder: ParticipantItemViewHolder,
position: Int,
payloads: List<Any>
) {
holder.binding.nameText.setTextColor(
ResourcesCompat.getColor(
context.resources,
R.color.conversation_item_header,
null
)
)
if (adapter.hasFilter()) {
viewThemeUtils.talk.themeAndHighlightText(
holder.binding.nameText,
displayName,
adapter.getFilter(String::class.java).toString()
)
viewThemeUtils.talk.themeAndHighlightText(
holder.binding.secondaryText,
"@$objectId",
adapter.getFilter(String::class.java).toString()
)
} else {
holder.binding.nameText.text = displayName
holder.binding.secondaryText.text = "@$objectId"
}
var avatarId = objectId
when (source) {
SOURCE_CALLS -> {
run {}
run {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
holder.binding.avatarView.loadUserAvatar(
viewThemeUtils.talk.themePlaceholderAvatar(
holder.binding.avatarView,
R.drawable.ic_avatar_group
)
)
} else {
holder.binding.avatarView.loadUserAvatar(R.drawable.ic_circular_group)
}
}
}
SOURCE_GROUPS -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
holder.binding.avatarView.loadUserAvatar(
viewThemeUtils.talk.themePlaceholderAvatar(
holder.binding.avatarView,
R.drawable.ic_avatar_group
)
)
} else {
holder.binding.avatarView.loadUserAvatar(R.drawable.ic_circular_group)
}
}
SOURCE_FEDERATION -> {
val darkTheme = if (DisplayUtils.isDarkModeOn(context)) 1 else 0
holder.binding.avatarView.loadFederatedUserAvatar(
currentUser,
currentUser.baseUrl!!,
roomToken,
avatarId!!,
darkTheme,
true,
false
)
}
SOURCE_GUESTS -> {
run { avatarId = displayName }
run { holder.binding.avatarView.loadUserAvatar(currentUser, avatarId!!, true, false) }
}
else -> {
holder.binding.avatarView.loadUserAvatar(currentUser, avatarId!!, true, false)
}
}
drawStatus(holder)
}
private fun drawStatus(holder: ParticipantItemViewHolder) {
val size = DisplayUtils.convertDpToPixel(STATUS_SIZE_IN_DP, context)
holder.binding.userStatusImage.setImageDrawable(
StatusDrawable(
status,
NO_ICON,
size,
context.resources.getColor(R.color.bg_default),
context
)
)
if (statusMessage != null) {
holder.binding.conversationInfoStatusMessage.text = statusMessage
alignUsernameVertical(holder, 0f)
} else {
holder.binding.conversationInfoStatusMessage.text = ""
alignUsernameVertical(holder, 10f)
}
if (!statusIcon.isNullOrEmpty()) {
holder.binding.participantStatusEmoji.setText(statusIcon)
} else {
holder.binding.participantStatusEmoji.visibility = View.GONE
}
if (status != null && status == StatusType.DND.string) {
if (statusMessage.isNullOrEmpty()) {
holder.binding.conversationInfoStatusMessage.setText(R.string.dnd)
}
} else if (status != null && status == StatusType.AWAY.string) {
if (statusMessage.isNullOrEmpty()) {
holder.binding.conversationInfoStatusMessage.setText(R.string.away)
}
}
}
private fun alignUsernameVertical(holder: ParticipantItemViewHolder, densityPixelsFromTop: Float) {
val layoutParams = holder.binding.nameText.layoutParams as ConstraintLayout.LayoutParams
layoutParams.topMargin = DisplayUtils.convertDpToPixel(densityPixelsFromTop, context).toInt()
holder.binding.nameText.setLayoutParams(layoutParams)
}
override fun filter(constraint: String?): Boolean {
return objectId != null &&
Pattern
.compile(constraint, Pattern.CASE_INSENSITIVE or Pattern.LITERAL)
.matcher(objectId)
.find() ||
displayName != null &&
Pattern
.compile(constraint, Pattern.CASE_INSENSITIVE or Pattern.LITERAL)
.matcher(displayName)
.find()
}
companion object {
private const val STATUS_SIZE_IN_DP = 9f
private const val NO_ICON = ""
const val SOURCE_CALLS = "calls"
const val SOURCE_GUESTS = "guests"
const val SOURCE_GROUPS = "groups"
const val SOURCE_FEDERATION = "federated_users"
}
}

View File

@ -301,7 +301,7 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
.matcher(participant.getCalculatedActorId().trim()).find()); .matcher(participant.getCalculatedActorId().trim()).find());
} }
static class ParticipantItemViewHolder extends FlexibleViewHolder { public static class ParticipantItemViewHolder extends FlexibleViewHolder {
RvItemConversationInfoParticipantBinding binding; RvItemConversationInfoParticipantBinding binding;

View File

@ -186,14 +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(); String mentionId = mentionAutocompleteItem.mentionId;
if (mentionId != null) { if (mentionId != null) {
mention.setMentionId(mentionId); mention.setMentionId(mentionId);
} }
mention.setId(mentionAutocompleteItem.getObjectId()); mention.setId(mentionAutocompleteItem.objectId);
mention.setLabel(mentionAutocompleteItem.getDisplayName()); mention.setLabel(mentionAutocompleteItem.displayName);
mention.setSource(mentionAutocompleteItem.getSource()); mention.setSource(mentionAutocompleteItem.source);
mention.setRoomToken(mentionAutocompleteItem.getRoomToken()); mention.setRoomToken(mentionAutocompleteItem.roomToken);
dispatchClick(mention); dispatchClick(mention);
} }
return true; return true;