Signal-Android/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageCountsViewModel.java

97 lines
3.2 KiB
Java

package org.thoughtcrime.securesms.conversation;
import android.app.Application;
import android.content.Context;
import android.database.ContentObserver;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.database.DatabaseContentProviders;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessageDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.util.concurrent.SerialMonoLifoExecutor;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.whispersystems.libsignal.util.Pair;
import java.util.Objects;
import java.util.concurrent.Executor;
public class MessageCountsViewModel extends ViewModel {
private static final Executor EXECUTOR = new SerialMonoLifoExecutor(SignalExecutors.BOUNDED);
private final Application context;
private final MutableLiveData<Long> threadId = new MutableLiveData<>(-1L);
private final LiveData<Pair<Integer, Integer>> unreadCounts;
private ContentObserver observer;
public MessageCountsViewModel() {
this.context = ApplicationDependencies.getApplication();
this.unreadCounts = Transformations.switchMap(Transformations.distinctUntilChanged(threadId), id -> {
MutableLiveData<Pair<Integer, Integer>> counts = new MutableLiveData<>(new Pair<>(0, 0));
if (id == -1L) {
return counts;
}
observer = new ContentObserver(null) {
@Override
public void onChange(boolean selfChange) {
EXECUTOR.execute(() -> {
counts.postValue(getCounts(context, id));
});
}
};
observer.onChange(false);
context.getContentResolver().registerContentObserver(DatabaseContentProviders.Conversation.getUriForThread(id), true, observer);
return counts;
});
}
void setThreadId(long threadId) {
this.threadId.setValue(threadId);
}
void clearThreadId() {
this.threadId.postValue(-1L);
}
@NonNull LiveData<Integer> getUnreadMessagesCount() {
return Transformations.map(unreadCounts, Pair::first);
}
@NonNull LiveData<Integer> getUnreadMentionsCount() {
return Transformations.map(unreadCounts, Pair::second);
}
private Pair<Integer, Integer> getCounts(@NonNull Context context, long threadId) {
MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context);
MessageDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context);
int unreadCount = mmsSmsDatabase.getUnreadCount(threadId);
int unreadMentionCount = mmsDatabase.getUnreadMentionCount(threadId);
return new Pair<>(unreadCount, unreadMentionCount);
}
@Override
protected void onCleared() {
if (observer != null) {
context.getContentResolver().unregisterContentObserver(observer);
}
}
}