Add Notification profiles.

This commit is contained in:
Cody Henthorne
2021-12-08 13:22:36 -05:00
parent 31e0696395
commit 6c608e955e
106 changed files with 5692 additions and 238 deletions

View File

@@ -66,6 +66,7 @@ import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.LoggingFragment;
@@ -127,6 +128,7 @@ import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
import org.thoughtcrime.securesms.providers.BlobProvider;
@@ -155,6 +157,7 @@ import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.thoughtcrime.securesms.util.Stopwatch;
import org.thoughtcrime.securesms.util.StorageUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.TopToastPopup;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.WindowUtil;
@@ -162,6 +165,7 @@ import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
import org.thoughtcrime.securesms.util.views.AdaptiveActionsToolbar;
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
import org.whispersystems.libsignal.util.guava.Optional;
import java.io.IOException;
import java.io.InputStream;
@@ -367,6 +371,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
ViewUtil.setTopMargin(scrollDateHeader, topMargin + ViewUtil.dpToPx(8));
});
conversationViewModel.getActiveNotificationProfile().observe(getViewLifecycleOwner(), this::updateNotificationProfileStatus);
return view;
}
@@ -1046,6 +1052,16 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
}
}
private void updateNotificationProfileStatus(@NonNull Optional<NotificationProfile> activeProfile) {
if (activeProfile.isPresent() && activeProfile.get().getId() != SignalStore.notificationProfileValues().getLastProfilePopup()) {
requireView().postDelayed(() -> {
SignalStore.notificationProfileValues().setLastProfilePopup(activeProfile.get().getId());
SignalStore.notificationProfileValues().setLastProfilePopupTime(System.currentTimeMillis());
TopToastPopup.show(((ViewGroup) requireView()), R.drawable.ic_moon_16, getString(R.string.ConversationFragment__s_on, activeProfile.get().getName()));
}, 500L);
}
}
private boolean isAtBottom() {
if (list.getChildCount() == 0) return true;

View File

@@ -5,6 +5,7 @@ import android.app.Application;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.LiveDataReactiveStreams;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.Transformations;
@@ -22,6 +23,7 @@ import org.signal.paging.PagedData;
import org.signal.paging.PagingConfig;
import org.signal.paging.PagingController;
import org.signal.paging.ProxyPagingController;
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.NotificationProfilesRepository;
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette;
import org.thoughtcrime.securesms.conversation.colors.NameColor;
@@ -33,6 +35,8 @@ import org.thoughtcrime.securesms.groups.LiveGroup;
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mediasend.MediaRepository;
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile;
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfiles;
import org.thoughtcrime.securesms.ratelimit.RecaptchaRequiredEvent;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
@@ -53,6 +57,10 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.core.BackpressureStrategy;
import io.reactivex.rxjava3.core.Observable;
public class ConversationViewModel extends ViewModel {
@@ -81,6 +89,7 @@ public class ConversationViewModel extends ViewModel {
private final LiveData<Integer> conversationTopMargin;
private final Store<ThreadAnimationState> threadAnimationStateStore;
private final Observer<ThreadAnimationState> threadAnimationStateStoreDriver;
private final NotificationProfilesRepository notificationProfilesRepository;
private final Map<GroupId, Set<Recipient>> sessionMemberCache = new HashMap<>();
@@ -88,23 +97,24 @@ public class ConversationViewModel extends ViewModel {
private int jumpToPosition;
private ConversationViewModel() {
this.context = ApplicationDependencies.getApplication();
this.mediaRepository = new MediaRepository();
this.conversationRepository = new ConversationRepository();
this.recentMedia = new MutableLiveData<>();
this.threadId = new MutableLiveData<>();
this.showScrollButtons = new MutableLiveData<>(false);
this.hasUnreadMentions = new MutableLiveData<>(false);
this.recipientId = new MutableLiveData<>();
this.events = new SingleLiveEvent<>();
this.pagingController = new ProxyPagingController<>();
this.conversationObserver = pagingController::onDataInvalidated;
this.messageUpdateObserver = pagingController::onDataItemChanged;
this.messageInsertObserver = messageId -> pagingController.onDataItemInserted(messageId, 0);
this.toolbarBottom = new MutableLiveData<>();
this.inlinePlayerHeight = new MutableLiveData<>();
this.conversationTopMargin = Transformations.distinctUntilChanged(LiveDataUtil.combineLatest(toolbarBottom, inlinePlayerHeight, Integer::sum));
this.threadAnimationStateStore = new Store<>(new ThreadAnimationState(-1L, null, false));
this.context = ApplicationDependencies.getApplication();
this.mediaRepository = new MediaRepository();
this.conversationRepository = new ConversationRepository();
this.recentMedia = new MutableLiveData<>();
this.threadId = new MutableLiveData<>();
this.showScrollButtons = new MutableLiveData<>(false);
this.hasUnreadMentions = new MutableLiveData<>(false);
this.recipientId = new MutableLiveData<>();
this.events = new SingleLiveEvent<>();
this.pagingController = new ProxyPagingController<>();
this.conversationObserver = pagingController::onDataInvalidated;
this.messageUpdateObserver = pagingController::onDataItemChanged;
this.messageInsertObserver = messageId -> pagingController.onDataItemInserted(messageId, 0);
this.toolbarBottom = new MutableLiveData<>();
this.inlinePlayerHeight = new MutableLiveData<>();
this.conversationTopMargin = Transformations.distinctUntilChanged(LiveDataUtil.combineLatest(toolbarBottom, inlinePlayerHeight, Integer::sum));
this.threadAnimationStateStore = new Store<>(new ThreadAnimationState(-1L, null, false));
this.notificationProfilesRepository = new NotificationProfilesRepository();
LiveData<Recipient> recipientLiveData = LiveDataUtil.mapAsync(recipientId, Recipient::resolved);
LiveData<ThreadAndRecipient> threadAndRecipient = LiveDataUtil.combineLatest(threadId, recipientLiveData, ThreadAndRecipient::new);
@@ -324,6 +334,13 @@ public class ConversationViewModel extends ViewModel {
});
}
@NonNull LiveData<Optional<NotificationProfile>> getActiveNotificationProfile() {
final Observable<Optional<NotificationProfile>> activeProfile = Observable.combineLatest(Observable.interval(0, 30, TimeUnit.SECONDS), notificationProfilesRepository.getProfiles(), (interval, profiles) -> profiles)
.map(profiles -> Optional.fromNullable(NotificationProfiles.getActiveProfile(profiles)));
return LiveDataReactiveStreams.fromPublisher(activeProfile.toFlowable(BackpressureStrategy.LATEST));
}
long getLastSeen() {
return conversationMetadata.getValue() != null ? conversationMetadata.getValue().getLastSeen() : 0;
}