From 1e884ec4355374491db85b46ca1c692e8de46d87 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Mar 2023 16:08:05 +0100 Subject: [PATCH] display title in chat fragment --- .../android/database/dao/ChatDao.java | 13 ++++ .../android/database/model/ChatInfo.java | 64 +++++++++++++++++++ .../database/model/ChatOverviewItem.java | 59 +---------------- .../android/repository/ChatRepository.java | 9 +++ .../ui/fragment/main/ChatFragment.java | 10 +++ .../android/ui/model/ChatViewModel.java | 39 +++++++++++ app/src/main/res/layout/fragment_chat.xml | 10 +++ 7 files changed, 146 insertions(+), 58 deletions(-) create mode 100644 app/src/main/java/im/conversations/android/database/model/ChatInfo.java create mode 100644 app/src/main/java/im/conversations/android/ui/model/ChatViewModel.java 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 d67e8e382..80060706b 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 @@ -13,6 +13,7 @@ import im.conversations.android.database.model.Account; import im.conversations.android.database.model.AccountIdentifier; import im.conversations.android.database.model.ChatFilter; import im.conversations.android.database.model.ChatIdentifier; +import im.conversations.android.database.model.ChatInfo; import im.conversations.android.database.model.ChatOverviewItem; import im.conversations.android.database.model.ChatType; import im.conversations.android.database.model.GroupIdentifier; @@ -222,6 +223,18 @@ public abstract class ChatDao { public abstract PagingSource getChatOverview( final Long accountId, final Long groupId); + @Query( + "SELECT c.accountId,c.address,c.type,(SELECT name FROM roster WHERE" + + " roster.accountId=c.accountId AND roster.address=c.address) as" + + " rosterName,(SELECT nick FROM nick WHERE nick.accountId=c.accountId AND" + + " nick.address=c.address) as nick,(SELECT identity.name FROM disco_item JOIN" + + " disco_identity identity ON disco_item.discoId=identity.discoId WHERE" + + " disco_item.accountId=c.accountId AND disco_item.address=c.address LIMIT 1) as" + + " discoIdentityName,(SELECT name FROM bookmark WHERE" + + " bookmark.accountId=c.accountId AND bookmark.address=c.address) as bookmarkName" + + " FROM chat c WHERE c.id=:chatId") + public abstract LiveData getChatInfo(final long chatId); + public PagingSource getChatOverview(final ChatFilter chatFilter) { if (chatFilter instanceof AccountIdentifier account) { return getChatOverview(account.id, null); diff --git a/app/src/main/java/im/conversations/android/database/model/ChatInfo.java b/app/src/main/java/im/conversations/android/database/model/ChatInfo.java new file mode 100644 index 000000000..69cfca5bd --- /dev/null +++ b/app/src/main/java/im/conversations/android/database/model/ChatInfo.java @@ -0,0 +1,64 @@ +package im.conversations.android.database.model; + +import org.jxmpp.jid.Jid; +import org.jxmpp.jid.impl.JidCreate; + +public class ChatInfo { + + public long accountId; + public String address; + public ChatType type; + + public String rosterName; + public String nick; + public String discoIdentityName; + public String bookmarkName; + + public String name() { + return switch (type) { + case MUC -> mucName(); + case INDIVIDUAL -> individualName(); + default -> address; + }; + } + + private String individualName() { + if (notNullNotEmpty(rosterName)) { + return rosterName.trim(); + } + if (notNullNotEmpty(nick)) { + return nick.trim(); + } + return fallbackName(); + } + + private String fallbackName() { + final Jid jid = getJidAddress(); + if (jid == null) { + return this.address; + } + if (jid.hasLocalpart()) { + return jid.getLocalpartOrThrow().toString(); + } else { + return jid.toString(); + } + } + + private String mucName() { + if (notNullNotEmpty(this.bookmarkName)) { + return this.bookmarkName.trim(); + } + if (notNullNotEmpty(this.discoIdentityName)) { + return this.discoIdentityName.trim(); + } + return fallbackName(); + } + + private static boolean notNullNotEmpty(final String value) { + return value != null && !value.trim().isEmpty(); + } + + protected Jid getJidAddress() { + return address == null ? null : JidCreate.fromOrNull(address); + } +} 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 2c9f259d5..612378e1c 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 @@ -7,14 +7,10 @@ import im.conversations.android.database.entity.MessageContentEntity; import java.time.Instant; import java.util.List; import org.jxmpp.jid.Jid; -import org.jxmpp.jid.impl.JidCreate; -public class ChatOverviewItem { +public class ChatOverviewItem extends ChatInfo { public long id; - public long accountId; - public String address; - public ChatType type; public Instant sentAt; @@ -26,11 +22,6 @@ public class ChatOverviewItem { public String fromResource; public long version; - public String rosterName; - public String nick; - public String discoIdentityName; - public String bookmarkName; - public String vCardPhoto; public String avatar; @@ -42,14 +33,6 @@ public class ChatOverviewItem { entityColumn = "messageVersionId") public List contents; - public String name() { - return switch (type) { - case MUC -> mucName(); - case INDIVIDUAL -> individualName(); - default -> address; - }; - } - public String message() { final var firstMessageContent = Iterables.getFirst(contents, null); return firstMessageContent == null ? null : firstMessageContent.body; @@ -69,38 +52,6 @@ public class ChatOverviewItem { } } - private String individualName() { - if (notNullNotEmpty(rosterName)) { - return rosterName.trim(); - } - if (notNullNotEmpty(nick)) { - return nick.trim(); - } - return fallbackName(); - } - - private String fallbackName() { - final Jid jid = getJidAddress(); - if (jid == null) { - return this.address; - } - if (jid.hasLocalpart()) { - return jid.getLocalpartOrThrow().toString(); - } else { - return jid.toString(); - } - } - - private String mucName() { - if (notNullNotEmpty(this.bookmarkName)) { - return this.bookmarkName.trim(); - } - if (notNullNotEmpty(this.discoIdentityName)) { - return this.discoIdentityName.trim(); - } - return fallbackName(); - } - public AddressWithName getAddressWithName() { final Jid address = getJidAddress(); final String name = name(); @@ -110,10 +61,6 @@ public class ChatOverviewItem { return new AddressWithName(address, name); } - private Jid getJidAddress() { - return address == null ? null : JidCreate.fromOrNull(address); - } - public AvatarWithAccount getAvatar() { final var address = getAddressWithName(); if (address == null) { @@ -128,10 +75,6 @@ public class ChatOverviewItem { return null; } - private static boolean notNullNotEmpty(final String value) { - return value != null && !value.trim().isEmpty(); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/app/src/main/java/im/conversations/android/repository/ChatRepository.java b/app/src/main/java/im/conversations/android/repository/ChatRepository.java index 0a50f6ecb..f1fad6fd3 100644 --- a/app/src/main/java/im/conversations/android/repository/ChatRepository.java +++ b/app/src/main/java/im/conversations/android/repository/ChatRepository.java @@ -4,12 +4,17 @@ import android.content.Context; import androidx.lifecycle.LiveData; import androidx.paging.PagingSource; import im.conversations.android.database.model.ChatFilter; +import im.conversations.android.database.model.ChatInfo; import im.conversations.android.database.model.ChatOverviewItem; import im.conversations.android.database.model.GroupIdentifier; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ChatRepository extends AbstractRepository { + private static final Logger LOGGER = LoggerFactory.getLogger(ChatRepository.class); + public ChatRepository(Context context) { super(context); } @@ -21,4 +26,8 @@ public class ChatRepository extends AbstractRepository { public PagingSource getChatOverview(final ChatFilter chatFilter) { return this.database.chatDao().getChatOverview(chatFilter); } + + public LiveData getChatInfo(final long chatId) { + return this.database.chatDao().getChatInfo(chatId); + } } diff --git a/app/src/main/java/im/conversations/android/ui/fragment/main/ChatFragment.java b/app/src/main/java/im/conversations/android/ui/fragment/main/ChatFragment.java index 0563cea57..c981fce10 100644 --- a/app/src/main/java/im/conversations/android/ui/fragment/main/ChatFragment.java +++ b/app/src/main/java/im/conversations/android/ui/fragment/main/ChatFragment.java @@ -7,10 +7,12 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.databinding.DataBindingUtil; import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; import im.conversations.android.R; import im.conversations.android.databinding.FragmentChatBinding; import im.conversations.android.ui.Activities; import im.conversations.android.ui.NavControllers; +import im.conversations.android.ui.model.ChatViewModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,12 +21,20 @@ public class ChatFragment extends Fragment { private static final Logger LOGGER = LoggerFactory.getLogger(ChatFragment.class); private FragmentChatBinding binding; + private ChatViewModel chatViewModel; @Override public View onCreateView( @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); this.binding = DataBindingUtil.inflate(inflater, R.layout.fragment_chat, container, false); + final long chatId = ChatFragmentArgs.fromBundle(getArguments()).getChat(); + final ViewModelProvider viewModelProvider = + new ViewModelProvider(this, getDefaultViewModelProviderFactory()); + this.chatViewModel = viewModelProvider.get(ChatViewModel.class); + this.chatViewModel.setChatId(chatId); + this.binding.setChatViewModel(this.chatViewModel); + this.binding.setLifecycleOwner(getViewLifecycleOwner()); this.binding.materialToolbar.setNavigationOnClickListener( view -> { NavControllers.findNavController(requireActivity(), R.id.nav_host_fragment) diff --git a/app/src/main/java/im/conversations/android/ui/model/ChatViewModel.java b/app/src/main/java/im/conversations/android/ui/model/ChatViewModel.java new file mode 100644 index 000000000..33c44b0b0 --- /dev/null +++ b/app/src/main/java/im/conversations/android/ui/model/ChatViewModel.java @@ -0,0 +1,39 @@ +package im.conversations.android.ui.model; + +import android.app.Application; +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Transformations; +import im.conversations.android.database.model.ChatInfo; +import im.conversations.android.repository.ChatRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ChatViewModel extends AndroidViewModel { + + private static final Logger LOGGER = LoggerFactory.getLogger(ChatViewModel.class); + + private final ChatRepository chatRepository; + private final MutableLiveData chatId = new MutableLiveData<>(); + private final LiveData chatInfo; + + public ChatViewModel(@NonNull Application application) { + super(application); + this.chatRepository = new ChatRepository(application); + this.chatInfo = + Transformations.switchMap( + this.chatId, + chatId -> chatId == null ? null : chatRepository.getChatInfo(chatId)); + } + + public void setChatId(final long chatId) { + this.chatId.setValue(chatId); + } + + public LiveData getTitle() { + return Transformations.map( + this.chatInfo, chatInfo -> chatInfo == null ? null : chatInfo.name()); + } +} diff --git a/app/src/main/res/layout/fragment_chat.xml b/app/src/main/res/layout/fragment_chat.xml index dedcd870d..749a2bd30 100644 --- a/app/src/main/res/layout/fragment_chat.xml +++ b/app/src/main/res/layout/fragment_chat.xml @@ -33,6 +33,7 @@ android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:navigationIcon="@drawable/ic_arrow_back_24dp" + app:title="@{chatViewModel.title}" app:menu="@menu/fragment_chat"/> @@ -103,4 +104,13 @@ + + + + + + + \ No newline at end of file