display title in chat fragment

This commit is contained in:
Daniel Gultsch 2023-03-21 16:08:05 +01:00
parent 86d9264ee5
commit 1e884ec435
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
7 changed files with 146 additions and 58 deletions

View file

@ -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<Integer, ChatOverviewItem> 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<ChatInfo> getChatInfo(final long chatId);
public PagingSource<Integer, ChatOverviewItem> getChatOverview(final ChatFilter chatFilter) {
if (chatFilter instanceof AccountIdentifier account) {
return getChatOverview(account.id, null);

View file

@ -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);
}
}

View file

@ -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<MessageContent> 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;

View file

@ -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<Integer, ChatOverviewItem> getChatOverview(final ChatFilter chatFilter) {
return this.database.chatDao().getChatOverview(chatFilter);
}
public LiveData<ChatInfo> getChatInfo(final long chatId) {
return this.database.chatDao().getChatInfo(chatId);
}
}

View file

@ -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)

View file

@ -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<Long> chatId = new MutableLiveData<>();
private final LiveData<ChatInfo> 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<String> getTitle() {
return Transformations.map(
this.chatInfo, chatInfo -> chatInfo == null ? null : chatInfo.name());
}
}

View file

@ -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"/>
</com.google.android.material.appbar.AppBarLayout>
@ -103,4 +104,13 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<data>
<import type="android.view.View" />
<variable
name="chatViewModel"
type="im.conversations.android.ui.model.ChatViewModel" />
</data>
</layout>