From f13f15cc9139ec7dcdc311654d225b5f8f6fe076 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 24 Mar 2023 17:51:29 +0100 Subject: [PATCH] include occupant resource --- .../android/database/KnownSender.java | 24 +++++++++++++ .../android/database/dao/ChatDao.java | 9 +++-- .../android/database/dao/MessageDao.java | 24 ++++++++----- .../database/model/ChatOverviewItem.java | 7 ++++ .../model/MessageWithContentReactions.java | 34 ++++++++++++------- .../main/res/layout/item_message_received.xml | 2 +- 6 files changed, 74 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/im/conversations/android/database/KnownSender.java diff --git a/app/src/main/java/im/conversations/android/database/KnownSender.java b/app/src/main/java/im/conversations/android/database/KnownSender.java new file mode 100644 index 000000000..a5df96cdb --- /dev/null +++ b/app/src/main/java/im/conversations/android/database/KnownSender.java @@ -0,0 +1,24 @@ +package im.conversations.android.database; + +import im.conversations.android.database.model.ChatType; +import java.util.Arrays; +import org.jxmpp.jid.BareJid; + +public interface KnownSender { + + default boolean isKnownSender() { + final var chatType = getChatType(); + final var membersOnlyNonAnonymous = isMembersOnlyNonAnonymous(); + final var sender = getSender(); + return chatType == ChatType.INDIVIDUAL + || (Arrays.asList(ChatType.MUC, ChatType.MUC_PM).contains(chatType) + && membersOnlyNonAnonymous + && sender != null); + } + + ChatType getChatType(); + + boolean isMembersOnlyNonAnonymous(); + + BareJid getSender(); +} diff --git a/app/src/main/java/im/conversations/android/database/dao/ChatDao.java b/app/src/main/java/im/conversations/android/database/dao/ChatDao.java index 93ffd14ac..5e796c331 100644 --- a/app/src/main/java/im/conversations/android/database/dao/ChatDao.java +++ b/app/src/main/java/im/conversations/android/database/dao/ChatDao.java @@ -193,10 +193,10 @@ public abstract class ChatDao { protected abstract void deleteStatusCodes(final long chatId); // TODO select vCardPhoto for c.type='MUC_PM' - // TODO select real name for `sender` in membersOnlyNonAnonymous MUCs @Transaction @Query( - "SELECT c.id,c.accountId,c.address,c.type,m.sentAt,m.outgoing,m.latestVersion as" + "SELECT c.id,c.accountId,c.address,c.type,m.sentAt,m.senderIdentity as" + + " sender,m.outgoing,m.latestVersion as" + " version,m.toBare,m.toResource,m.fromBare,m.fromResource,(SELECT count(id) FROM" + " message WHERE chatId=c.id) as unread,(SELECT name FROM roster WHERE" + " roster.accountId=c.accountId AND roster.address=c.address) as" @@ -215,7 +215,10 @@ public abstract class ChatDao { + " c.type IN ('MUC','MUC_PM') THEN (SELECT count(distinct(df.feature)) == 2 FROM" + " disco_item di JOIN disco_feature df ON di.discoId = df.discoId WHERE" + " di.address=c.address AND df.feature IN('muc_membersonly','muc_nonanonymous'))" - + " ELSE 0 END) as membersOnlyNonAnonymous FROM CHAT c LEFT JOIN message m ON (m.id" + + " ELSE 0 END) as membersOnlyNonAnonymous,(CASE WHEN m.occupantId IS NOT NULL AND" + + " c.type IN ('MUC','MUC_PM') THEN (SELECT resource FROM presence WHERE" + + " accountId=c.accountId AND address=c.address AND occupantId=m.occupantId LIMIT" + + " 1) ELSE NULL END) as occupantResource FROM CHAT c LEFT JOIN message m ON (m.id" + " = (SELECT id FROM message WHERE chatId=c.id ORDER by receivedAt DESC LIMIT 1))" + " WHERE (:accountId IS NULL OR c.accountId=:accountId) AND (:groupId IS NULL OR" + " (c.address IN(SELECT roster.address FROM roster JOIN roster_group ON" diff --git a/app/src/main/java/im/conversations/android/database/dao/MessageDao.java b/app/src/main/java/im/conversations/android/database/dao/MessageDao.java index 6817033ae..92055ecde 100644 --- a/app/src/main/java/im/conversations/android/database/dao/MessageDao.java +++ b/app/src/main/java/im/conversations/android/database/dao/MessageDao.java @@ -434,10 +434,13 @@ public abstract class MessageDao { + " address=m.senderIdentity AND vCardPhoto NOT NULL LIMIT 1) as" + " senderVcardPhoto,(SELECT thumb_id FROM avatar WHERE" + " avatar.accountId=c.accountId AND avatar.address=m.senderIdentity) as" - + " senderAvatar,(CASE WHEN c.type IN ('MUC','MUC_PM') THEN (SELECT vCardPhoto FROM" - + " presence WHERE accountId=c.accountId AND address=c.address AND" - + " occupantId=m.occupantId AND vCardPhoto NOT NULL LIMIT 1) ELSE NULL END) as" - + " occupantVcardPhoto,modification,latestVersion as" + + " senderAvatar,(CASE WHEN m.occupantId IS NOT NULL AND c.type IN ('MUC','MUC_PM')" + + " THEN (SELECT vCardPhoto FROM presence WHERE accountId=c.accountId AND" + + " address=c.address AND occupantId=m.occupantId AND vCardPhoto NOT NULL LIMIT 1)" + + " ELSE NULL END) as occupantVcardPhoto,(CASE WHEN m.occupantId IS NOT NULL AND" + + " c.type IN ('MUC','MUC_PM') THEN (SELECT resource FROM presence WHERE" + + " accountId=c.accountId AND address=c.address AND occupantId=m.occupantId LIMIT" + + " 1) ELSE NULL END) as occupantResource,modification,latestVersion as" + " version,inReplyToMessageEntityId,encryption,message_version.identityKey,trust,(CASE" + " WHEN c.type IN ('MUC','MUC_PM') THEN (SELECT count(distinct(df.feature)) == 2" + " FROM disco_item di JOIN disco_feature df ON di.discoId = df.discoId WHERE" @@ -447,7 +450,7 @@ public abstract class MessageDao { + " JOIN axolotl_identity ON c.accountId=axolotl_identity.accountId AND" + " m.senderIdentity=axolotl_identity.address AND" + " message_version.identityKey=axolotl_identity.identityKey WHERE c.id=:chatId AND" - + " latestVersion IS NOT NULL ORDER BY m.receivedAt DESC") + + " latestVersion IS NOT NULL ORDER BY m.receivedAt") public abstract List getMessagesForTesting(long chatId); @Transaction @@ -461,10 +464,13 @@ public abstract class MessageDao { + " address=m.senderIdentity AND vCardPhoto NOT NULL LIMIT 1) as" + " senderVcardPhoto,(SELECT thumb_id FROM avatar WHERE" + " avatar.accountId=c.accountId AND avatar.address=m.senderIdentity) as" - + " senderAvatar,(CASE WHEN c.type IN ('MUC','MUC_PM') THEN (SELECT vCardPhoto FROM" - + " presence WHERE accountId=c.accountId AND address=c.address AND" - + " occupantId=m.occupantId AND vCardPhoto NOT NULL LIMIT 1) ELSE NULL END) as" - + " occupantVcardPhoto,modification,latestVersion as" + + " senderAvatar,(CASE WHEN m.occupantId IS NOT NULL AND c.type IN ('MUC','MUC_PM')" + + " THEN (SELECT vCardPhoto FROM presence WHERE accountId=c.accountId AND" + + " address=c.address AND occupantId=m.occupantId AND vCardPhoto NOT NULL LIMIT 1)" + + " ELSE NULL END) as occupantVcardPhoto,(CASE WHEN m.occupantId IS NOT NULL AND" + + " c.type IN ('MUC','MUC_PM') THEN (SELECT resource FROM presence WHERE" + + " accountId=c.accountId AND address=c.address AND occupantId=m.occupantId LIMIT" + + " 1) ELSE NULL END) as occupantResource,modification,latestVersion as" + " version,inReplyToMessageEntityId,encryption,message_version.identityKey,trust,(CASE" + " WHEN c.type IN ('MUC','MUC_PM') THEN (SELECT count(distinct(df.feature)) == 2" + " FROM disco_item di JOIN disco_feature df ON di.discoId = df.discoId WHERE" diff --git a/app/src/main/java/im/conversations/android/database/model/ChatOverviewItem.java b/app/src/main/java/im/conversations/android/database/model/ChatOverviewItem.java index 612378e1c..30b846b2a 100644 --- a/app/src/main/java/im/conversations/android/database/model/ChatOverviewItem.java +++ b/app/src/main/java/im/conversations/android/database/model/ChatOverviewItem.java @@ -6,7 +6,9 @@ import com.google.common.collect.Iterables; import im.conversations.android.database.entity.MessageContentEntity; import java.time.Instant; import java.util.List; +import org.jxmpp.jid.BareJid; import org.jxmpp.jid.Jid; +import org.jxmpp.jid.parts.Resourcepart; public class ChatOverviewItem extends ChatInfo { @@ -20,11 +22,16 @@ public class ChatOverviewItem extends ChatInfo { public String toResource; public Jid fromBare; public String fromResource; + + public BareJid sender; + public long version; public String vCardPhoto; public String avatar; + public Resourcepart occupantResource; + public int unread; @Relation( diff --git a/app/src/main/java/im/conversations/android/database/model/MessageWithContentReactions.java b/app/src/main/java/im/conversations/android/database/model/MessageWithContentReactions.java index 72396c23e..a784b72a3 100644 --- a/app/src/main/java/im/conversations/android/database/model/MessageWithContentReactions.java +++ b/app/src/main/java/im/conversations/android/database/model/MessageWithContentReactions.java @@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Multimaps; +import im.conversations.android.database.KnownSender; import im.conversations.android.database.entity.MessageContentEntity; import im.conversations.android.database.entity.MessageEntity; import im.conversations.android.database.entity.MessageReactionEntity; @@ -22,7 +23,7 @@ import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; import org.whispersystems.libsignal.IdentityKey; -public class MessageWithContentReactions implements IndividualName { +public class MessageWithContentReactions implements IndividualName, KnownSender { public long accountId; @@ -40,8 +41,6 @@ public class MessageWithContentReactions implements IndividualName { public BareJid fromBare; public Resourcepart fromResource; - // TODO retrieve occupantResource (current resource inferred by occupant id) - public BareJid sender; public String senderVcardPhoto; public String senderAvatar; @@ -49,6 +48,7 @@ public class MessageWithContentReactions implements IndividualName { public String senderNick; public String occupantVcardPhoto; + public String occupantResource; public Modification modification; public long version; @@ -98,7 +98,7 @@ public class MessageWithContentReactions implements IndividualName { } public AddressWithName getAddressWithName() { - if (isIndividual()) { + if (isKnownSender()) { return new AddressWithName(individualAddress(), individualName()); } else { final Jid address = JidCreate.fullFrom(fromBare, fromResource); @@ -112,7 +112,7 @@ public class MessageWithContentReactions implements IndividualName { if (address == null) { return null; } - if (isIndividual()) { + if (isKnownSender()) { if (this.senderAvatar != null) { return new AvatarWithAccount(accountId, address, AvatarType.PEP, this.senderAvatar); } @@ -128,13 +128,6 @@ public class MessageWithContentReactions implements IndividualName { return null; } - private boolean isIndividual() { - return chatType == ChatType.INDIVIDUAL - || (Arrays.asList(ChatType.MUC, ChatType.MUC_PM).contains(chatType) - && membersOnlyNonAnonymous - && sender != null); - } - @Override public String individualRosterName() { return senderRosterName; @@ -150,7 +143,22 @@ public class MessageWithContentReactions implements IndividualName { return sender; } - public String getSender() { + @Override + public ChatType getChatType() { + return this.chatType; + } + + @Override + public boolean isMembersOnlyNonAnonymous() { + return membersOnlyNonAnonymous; + } + + @Override + public BareJid getSender() { + return this.sender; + } + + public String getSenderName() { return this.fromResource == null ? null : fromResource.toString(); } diff --git a/app/src/main/res/layout/item_message_received.xml b/app/src/main/res/layout/item_message_received.xml index 502d07909..c9d165f92 100644 --- a/app/src/main/res/layout/item_message_received.xml +++ b/app/src/main/res/layout/item_message_received.xml @@ -91,7 +91,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4sp" - android:text="@{message.sender}" + android:text="@{message.senderName}" android:textAppearance="?textAppearanceLabelSmall" android:textColor="?colorOnSurface" android:visibility="@{message.isGroupChat() ? View.VISIBLE : View.GONE}"