support chat filters

This commit is contained in:
Daniel Gultsch 2023-03-07 20:43:16 +01:00
parent 9819ef7d05
commit 26d856e91f
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
7 changed files with 51 additions and 23 deletions

View file

@ -10,6 +10,8 @@ import com.google.common.util.concurrent.ListenableFuture;
import im.conversations.android.database.entity.ChatEntity; import im.conversations.android.database.entity.ChatEntity;
import im.conversations.android.database.entity.MucStatusCodeEntity; import im.conversations.android.database.entity.MucStatusCodeEntity;
import im.conversations.android.database.model.Account; 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.ChatIdentifier;
import im.conversations.android.database.model.ChatOverviewItem; import im.conversations.android.database.model.ChatOverviewItem;
import im.conversations.android.database.model.ChatType; import im.conversations.android.database.model.ChatType;
@ -206,7 +208,23 @@ public abstract class ChatDao {
+ " vCardPhoto,(SELECT thumb_id FROM avatar WHERE avatar.address=c.address) as" + " vCardPhoto,(SELECT thumb_id FROM avatar WHERE avatar.address=c.address) as"
+ " avatar FROM CHAT c LEFT JOIN message m ON (c.id=m.chatId) LEFT OUTER JOIN" + " avatar FROM CHAT c LEFT JOIN message m ON (c.id=m.chatId) LEFT OUTER JOIN"
+ " message m2 ON (c.id = m2.chatId AND (m.receivedAt < m2.receivedAt OR" + " message m2 ON (c.id = m2.chatId AND (m.receivedAt < m2.receivedAt OR"
+ " (m.receivedAt = m2.receivedAt AND m.id < m2.id))) WHERE c.archived=0 AND m2.id" + " (m.receivedAt = m2.receivedAt AND m.id < m2.id))) WHERE (:accountId IS NULL OR"
+ " IS NULL ORDER by m.receivedAt DESC") + " c.accountId=:accountId) AND (:groupId IS NULL OR (c.address IN(SELECT"
public abstract PagingSource<Integer, ChatOverviewItem> getChatOverview(); + " roster.address FROM roster JOIN roster_group ON"
+ " roster.id=roster_group.rosterItemId WHERE roster_group.groupId=:groupId) OR"
+ " c.address IN(SELECT address FROM bookmark JOIN bookmark_group ON"
+ " bookmark.id=bookmark_group.bookmarkId WHERE bookmark_group.groupId=:groupId)))"
+ " AND c.archived=0 AND m2.id IS NULL ORDER by m.receivedAt DESC")
public abstract PagingSource<Integer, ChatOverviewItem> getChatOverview(
final Long accountId, final Long groupId);
public PagingSource<Integer, ChatOverviewItem> getChatOverview(final ChatFilter chatFilter) {
if (chatFilter instanceof AccountIdentifier account) {
return getChatOverview(account.id, null);
} else if (chatFilter instanceof GroupIdentifier group) {
return getChatOverview(null, group.id);
} else {
return getChatOverview(null, null);
}
}
} }

View file

@ -14,14 +14,19 @@ import java.util.UUID;
import org.jxmpp.jid.BareJid; import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.parts.Resourcepart; import org.jxmpp.jid.parts.Resourcepart;
public class Account extends AccountIdentifier { public class Account {
public final long id;
@NonNull public final BareJid address;
@NonNull public final byte[] randomSeed; @NonNull public final byte[] randomSeed;
public Account(final long id, @NonNull final BareJid address, @NonNull byte[] randomSeed) { public Account(final long id, @NonNull final BareJid address, @NonNull byte[] randomSeed) {
super(id, address); Preconditions.checkNotNull(address, "Account can not be instantiated without an address");
Preconditions.checkArgument( Preconditions.checkArgument(
randomSeed.length == 32, "RandomSeed must have exactly 32 bytes"); randomSeed.length == 32, "RandomSeed must have exactly 32 bytes");
this.id = id;
this.address = address;
this.randomSeed = randomSeed; this.randomSeed = randomSeed;
} }

View file

@ -6,7 +6,7 @@ import com.google.common.base.Objects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import org.jxmpp.jid.BareJid; import org.jxmpp.jid.BareJid;
public class AccountIdentifier implements ChatFilter { public final class AccountIdentifier implements ChatFilter {
public final long id; public final long id;
@NonNull public final BareJid address; @NonNull public final BareJid address;

View file

@ -1,3 +1,3 @@
package im.conversations.android.database.model; package im.conversations.android.database.model;
public interface ChatFilter {} public sealed interface ChatFilter permits AccountIdentifier, GroupIdentifier {}

View file

@ -4,7 +4,7 @@ import androidx.annotation.NonNull;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Objects; import com.google.common.base.Objects;
public class GroupIdentifier implements ChatFilter { public final class GroupIdentifier implements ChatFilter {
public final long id; public final long id;
public final String name; public final String name;

View file

@ -3,6 +3,7 @@ package im.conversations.android.repository;
import android.content.Context; import android.content.Context;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.paging.PagingSource; import androidx.paging.PagingSource;
import im.conversations.android.database.model.ChatFilter;
import im.conversations.android.database.model.ChatOverviewItem; import im.conversations.android.database.model.ChatOverviewItem;
import im.conversations.android.database.model.GroupIdentifier; import im.conversations.android.database.model.GroupIdentifier;
import java.util.List; import java.util.List;
@ -17,7 +18,7 @@ public class ChatRepository extends AbstractRepository {
return this.database.chatDao().getGroups(); return this.database.chatDao().getGroups();
} }
public PagingSource<Integer, ChatOverviewItem> getChatOverview() { public PagingSource<Integer, ChatOverviewItem> getChatOverview(final ChatFilter chatFilter) {
return this.database.chatDao().getChatOverview(); return this.database.chatDao().getChatOverview(chatFilter);
} }
} }

View file

@ -5,6 +5,7 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MediatorLiveData; import androidx.lifecycle.MediatorLiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations; import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModelKt; import androidx.lifecycle.ViewModelKt;
import androidx.paging.Pager; import androidx.paging.Pager;
@ -29,11 +30,10 @@ public class OverviewViewModel extends AndroidViewModel {
private final LiveData<List<AccountIdentifier>> accounts; private final LiveData<List<AccountIdentifier>> accounts;
private final LiveData<List<GroupIdentifier>> groups; private final LiveData<List<GroupIdentifier>> groups;
private final MediatorLiveData<Boolean> chatFilterAvailable = new MediatorLiveData<>(); private final MediatorLiveData<Boolean> chatFilterAvailable = new MediatorLiveData<>();
private final MutableLiveData<ChatFilter> chatFilter = new MutableLiveData<>(null);
private static final Logger LOGGER = LoggerFactory.getLogger(OverviewViewModel.class); private static final Logger LOGGER = LoggerFactory.getLogger(OverviewViewModel.class);
private ChatFilter chatFilter;
public OverviewViewModel(@NonNull Application application) { public OverviewViewModel(@NonNull Application application) {
super(application); super(application);
this.accountRepository = new AccountRepository(application); this.accountRepository = new AccountRepository(application);
@ -65,24 +65,28 @@ public class OverviewViewModel extends AndroidViewModel {
} }
public ChatFilter getChatFilter() { public ChatFilter getChatFilter() {
return this.chatFilter; return this.chatFilter.getValue();
} }
public void setChatFilter(final ChatFilter chatFilter) { public void setChatFilter(final ChatFilter chatFilter) {
this.chatFilter = chatFilter; this.chatFilter.postValue(chatFilter);
LOGGER.info("Setting chat filter to {}", chatFilter); LOGGER.info("Setting chat filter to {}", chatFilter);
} }
public LiveData<PagingData<ChatOverviewItem>> getChats() { public LiveData<PagingData<ChatOverviewItem>> getChats() {
final Pager<Integer, ChatOverviewItem> pager = return Transformations.switchMap(
new Pager<>( this.chatFilter,
new PagingConfig(20), input -> {
() -> { final Pager<Integer, ChatOverviewItem> pager =
return this.chatRepository.getChatOverview(); new Pager<>(
}); new PagingConfig(20),
() -> {
return chatRepository.getChatOverview(input);
});
LiveData<PagingData<ChatOverviewItem>> foo = PagingLiveData.getLiveData(pager); CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(this);
CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(this); return PagingLiveData.cachedIn(
return PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), viewModelScope); PagingLiveData.getLiveData(pager), viewModelScope);
});
} }
} }