Skip to content

Commit

Permalink
Do not send typing indicator when deleting from the end & send stoppe…
Browse files Browse the repository at this point in the history
…d typing indicator when compose completely empty.
  • Loading branch information
alan-signal authored and cody-signal committed Nov 11, 2020
1 parent 6a59974 commit 3bb366e
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 63 deletions.
Expand Up @@ -35,8 +35,6 @@
import org.signal.aesgcmprovider.AesGcmProvider;
import org.signal.glide.SignalGlideCodecs;
import org.signal.ringrtc.CallManager;
import org.thoughtcrime.securesms.components.TypingStatusRepository;
import org.thoughtcrime.securesms.components.TypingStatusSender;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
Expand Down Expand Up @@ -70,8 +68,8 @@
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
import org.thoughtcrime.securesms.service.UpdateApkRefreshListener;
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.tracing.Trace;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
Expand Down Expand Up @@ -99,11 +97,9 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi

private static final String TAG = ApplicationContext.class.getSimpleName();

private ExpiringMessageManager expiringMessageManager;
private ViewOnceMessageManager viewOnceMessageManager;
private TypingStatusRepository typingStatusRepository;
private TypingStatusSender typingStatusSender;
private PersistentLogger persistentLogger;
private ExpiringMessageManager expiringMessageManager;
private ViewOnceMessageManager viewOnceMessageManager;
private PersistentLogger persistentLogger;

private volatile boolean isAppVisible;

Expand All @@ -125,8 +121,6 @@ public void onCreate() {
initializeMessageRetrieval();
initializeExpiringMessageManager();
initializeRevealableMessageManager();
initializeTypingStatusRepository();
initializeTypingStatusSender();
initializeGcmCheck();
initializeSignedPreKeyCheck();
initializePeriodicTasks();
Expand Down Expand Up @@ -187,14 +181,6 @@ public ViewOnceMessageManager getViewOnceMessageManager() {
return viewOnceMessageManager;
}

public TypingStatusRepository getTypingStatusRepository() {
return typingStatusRepository;
}

public TypingStatusSender getTypingStatusSender() {
return typingStatusSender;
}

public boolean isAppVisible() {
return isAppVisible;
}
Expand Down Expand Up @@ -294,14 +280,6 @@ private void initializeRevealableMessageManager() {
this.viewOnceMessageManager = new ViewOnceMessageManager(this);
}

private void initializeTypingStatusRepository() {
this.typingStatusRepository = new TypingStatusRepository();
}

private void initializeTypingStatusSender() {
this.typingStatusSender = new TypingStatusSender(this);
}

private void initializePeriodicTasks() {
RotateSignedPreKeyListener.schedule(this);
DirectoryRefreshListener.schedule(this);
Expand Down
Expand Up @@ -2,9 +2,9 @@

import android.annotation.SuppressLint;
import android.content.Context;

import androidx.annotation.NonNull;

import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobs.TypingSendJob;
import org.thoughtcrime.securesms.util.Util;
Expand Down Expand Up @@ -54,6 +54,10 @@ public synchronized void onTypingStopped(long threadId) {
onTypingStopped(threadId, false);
}

public synchronized void onTypingStoppedWithNotify(long threadId) {
onTypingStopped(threadId, true);
}

private synchronized void onTypingStopped(long threadId, boolean notify) {
TimerPair pair = Util.getOrDefault(selfTypingTimers, threadId, new TimerPair());
selfTypingTimers.put(threadId, pair);
Expand Down
Expand Up @@ -84,7 +84,6 @@
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BlockUnblockDialog;
import org.thoughtcrime.securesms.ExpirationDialog;
import org.thoughtcrime.securesms.GroupMembersDialog;
Expand All @@ -109,6 +108,7 @@
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
import org.thoughtcrime.securesms.components.SendButton;
import org.thoughtcrime.securesms.components.TooltipPopup;
import org.thoughtcrime.securesms.components.TypingStatusSender;
import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider;
import org.thoughtcrime.securesms.components.emoji.EmojiStrings;
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard;
Expand Down Expand Up @@ -2561,11 +2561,10 @@ private void sendMediaMessage(@NonNull MediaSendActivityResult result) {
long expiresIn = recipient.get().getExpireMessages() * 1000L;
QuoteModel quote = result.isViewOnce() ? null : inputPanel.getQuote().orNull();
List<Mention> mentions = new ArrayList<>(result.getMentions());
boolean initiating = threadId == -1;
OutgoingMediaMessage message = new OutgoingMediaMessage(recipient.get(), new SlideDeck(), result.getBody(), System.currentTimeMillis(), -1, expiresIn, result.isViewOnce(), distributionType, quote, Collections.emptyList(), Collections.emptyList(), mentions);
OutgoingMediaMessage secureMessage = new OutgoingSecureMediaMessage(message);

ApplicationContext.getInstance(this).getTypingStatusSender().onTypingStopped(threadId);
ApplicationDependencies.getTypingStatusSender().onTypingStopped(threadId);

inputPanel.clearQuote();
attachmentManager.clear(glideRequests, false);
Expand Down Expand Up @@ -2637,7 +2636,7 @@ private ListenableFuture<Void> sendMediaMessage(final boolean forceSms,

if (isSecureText && !forceSms) {
outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessageCandidate);
ApplicationContext.getInstance(context).getTypingStatusSender().onTypingStopped(threadId);
ApplicationDependencies.getTypingStatusSender().onTypingStopped(threadId);
} else {
outgoingMessage = outgoingMessageCandidate;
}
Expand Down Expand Up @@ -2683,7 +2682,7 @@ private void sendTextMessage(final boolean forceSms, final long expiresIn, final

if (isSecureText && !forceSms) {
message = new OutgoingEncryptedMessage(recipient.get(), messageBody, expiresIn);
ApplicationContext.getInstance(context).getTypingStatusSender().onTypingStopped(threadId);
ApplicationDependencies.getTypingStatusSender().onTypingStopped(threadId);
} else {
message = new OutgoingTextMessage(recipient.get(), messageBody, expiresIn, subscriptionId);
}
Expand Down Expand Up @@ -3071,10 +3070,22 @@ private class TypingStatusTextWatcher extends SimpleTextWatcher {

private boolean enabled = true;

private String previousText = "";

@Override
public void onTextChanged(String text) {
if (enabled && threadId > 0 && isSecureText && !isSmsForced() && !recipient.get().isBlocked()) {
ApplicationContext.getInstance(ConversationActivity.this).getTypingStatusSender().onTypingStarted(threadId);
TypingStatusSender typingStatusSender = ApplicationDependencies.getTypingStatusSender();

if (text.length() == 0) {
typingStatusSender.onTypingStoppedWithNotify(threadId);
} else if (text.length() < previousText.length() && previousText.contains(text)) {
typingStatusSender.onTypingStopped(threadId);
} else {
typingStatusSender.onTypingStarted(threadId);
}

previousText = text;
}
}

Expand Down
Expand Up @@ -52,6 +52,7 @@
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.text.HtmlCompat;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
Expand All @@ -70,6 +71,7 @@
import org.thoughtcrime.securesms.components.ConversationScrollToView;
import org.thoughtcrime.securesms.components.ConversationTypingView;
import org.thoughtcrime.securesms.components.TooltipPopup;
import org.thoughtcrime.securesms.components.TypingStatusRepository;
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager;
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaController;
import org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState;
Expand Down Expand Up @@ -350,7 +352,7 @@ public void onPause() {
@Override
public void onStop() {
super.onStop();
ApplicationContext.getInstance(requireContext()).getTypingStatusRepository().getTypists(threadId).removeObservers(this);
ApplicationDependencies.getTypingStatusRepository().getTypists(threadId).removeObservers(this);
}

public void onNewIntent() {
Expand Down Expand Up @@ -497,7 +499,7 @@ private void initializeResources() {
list.addOnScrollListener(conversationScrollListener);

if (oldThreadId != threadId) {
ApplicationContext.getInstance(requireContext()).getTypingStatusRepository().getTypists(oldThreadId).removeObservers(this);
ApplicationDependencies.getTypingStatusRepository().getTypists(oldThreadId).removeObservers(this);
}
}

Expand Down Expand Up @@ -531,8 +533,10 @@ private void initializeTypingObserver() {
return;
}

ApplicationContext.getInstance(requireContext()).getTypingStatusRepository().getTypists(threadId).removeObservers(this);
ApplicationContext.getInstance(requireContext()).getTypingStatusRepository().getTypists(threadId).observe(this, typingState -> {
LiveData<TypingStatusRepository.TypingState> typists = ApplicationDependencies.getTypingStatusRepository().getTypists(threadId);

typists.removeObservers(this);
typists.observe(this, typingState -> {
List<Recipient> recipients;
boolean replacedByIncomingMessage;

Expand Down
Expand Up @@ -70,7 +70,6 @@
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.MainFragment;
import org.thoughtcrime.securesms.MainNavigator;
import org.thoughtcrime.securesms.NewConversationActivity;
Expand Down Expand Up @@ -511,7 +510,7 @@ private void setAdapter(@NonNull RecyclerView.Adapter adapter) {
}

private void initializeTypingObserver() {
ApplicationContext.getInstance(requireContext()).getTypingStatusRepository().getTypingThreads().observe(this, threadIds -> {
ApplicationDependencies.getTypingStatusRepository().getTypingThreads().observe(this, threadIds -> {
if (threadIds == null) {
threadIds = Collections.emptySet();
}
Expand Down
Expand Up @@ -5,24 +5,24 @@
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;

import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.KbsEnclave;
import org.thoughtcrime.securesms.messages.IncomingMessageProcessor;
import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever;
import org.thoughtcrime.securesms.components.TypingStatusRepository;
import org.thoughtcrime.securesms.components.TypingStatusSender;
import org.thoughtcrime.securesms.groups.GroupsV2Authorization;
import org.thoughtcrime.securesms.groups.GroupsV2AuthorizationMemoryValueCache;
import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.keyvalue.KeyValueStore;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever;
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
import org.thoughtcrime.securesms.messages.IncomingMessageProcessor;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.pin.KbsEnclaves;
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
import org.thoughtcrime.securesms.recipients.LiveRecipientCache;
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
import org.thoughtcrime.securesms.service.TrimThreadsByDateManager;
import org.thoughtcrime.securesms.util.EarlyMessageCache;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.FrameRateTracker;
import org.thoughtcrime.securesms.util.Hex;
import org.thoughtcrime.securesms.util.IasKeyStore;
Expand All @@ -31,7 +31,6 @@
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.thoughtcrime.securesms.groups.GroupsV2Authorization;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;

/**
Expand Down Expand Up @@ -64,6 +63,8 @@ public class ApplicationDependencies {
private static EarlyMessageCache earlyMessageCache;
private static MessageNotifier messageNotifier;
private static TrimThreadsByDateManager trimThreadsByDateManager;
private static TypingStatusRepository typingStatusRepository;
private static TypingStatusSender typingStatusSender;

@MainThread
public static synchronized void init(@NonNull Application application, @NonNull Provider provider) {
Expand Down Expand Up @@ -256,6 +257,26 @@ public static synchronized void resetSignalServiceMessageReceiver() {
return trimThreadsByDateManager;
}

public static TypingStatusRepository getTypingStatusRepository() {
assertInitialization();

if (typingStatusRepository == null) {
typingStatusRepository = provider.provideTypingStatusRepository();
}

return typingStatusRepository;
}

public static TypingStatusSender getTypingStatusSender() {
assertInitialization();

if (typingStatusSender == null) {
typingStatusSender = provider.provideTypingStatusSender();
}

return typingStatusSender;
}

private static void assertInitialization() {
if (application == null || provider == null) {
throw new UninitializedException();
Expand All @@ -278,6 +299,8 @@ public interface Provider {
@NonNull MessageNotifier provideMessageNotifier();
@NonNull IncomingMessageObserver provideIncomingMessageObserver();
@NonNull TrimThreadsByDateManager provideTrimThreadsByDateManager();
@NonNull TypingStatusRepository provideTypingStatusRepository();
@NonNull TypingStatusSender provideTypingStatusSender();
}

private static class UninitializedException extends IllegalStateException {
Expand Down
Expand Up @@ -7,7 +7,17 @@

import org.greenrobot.eventbus.EventBus;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.components.TypingStatusRepository;
import org.thoughtcrime.securesms.components.TypingStatusSender;
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.JobMigrator;
import org.thoughtcrime.securesms.jobmanager.impl.FactoryJobPredicate;
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
import org.thoughtcrime.securesms.jobs.FastJobStorage;
import org.thoughtcrime.securesms.jobs.JobManagerFactories;
import org.thoughtcrime.securesms.jobs.MarkerJob;
import org.thoughtcrime.securesms.jobs.PushDecryptMessageJob;
import org.thoughtcrime.securesms.jobs.PushGroupSendJob;
Expand All @@ -16,26 +26,17 @@
import org.thoughtcrime.securesms.jobs.PushTextSendJob;
import org.thoughtcrime.securesms.jobs.ReactionSendJob;
import org.thoughtcrime.securesms.jobs.TypingSendJob;
import org.thoughtcrime.securesms.messages.IncomingMessageProcessor;
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.JobMigrator;
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
import org.thoughtcrime.securesms.jobs.FastJobStorage;
import org.thoughtcrime.securesms.jobs.JobManagerFactories;
import org.thoughtcrime.securesms.keyvalue.KeyValueStore;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever;
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
import org.thoughtcrime.securesms.messages.IncomingMessageProcessor;
import org.thoughtcrime.securesms.notifications.DefaultMessageNotifier;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.notifications.OptimizedMessageNotifier;
import org.thoughtcrime.securesms.push.SecurityEventListener;
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
import org.thoughtcrime.securesms.recipients.LiveRecipientCache;
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
import org.thoughtcrime.securesms.service.TrimThreadsByDateManager;
import org.thoughtcrime.securesms.util.AlarmSleepTimer;
import org.thoughtcrime.securesms.util.EarlyMessageCache;
Expand Down Expand Up @@ -178,6 +179,16 @@ public ApplicationDependencyProvider(@NonNull Application context, @NonNull Sign
return new TrimThreadsByDateManager(context);
}

@Override
public @NonNull TypingStatusRepository provideTypingStatusRepository() {
return new TypingStatusRepository();
}

@Override
public @NonNull TypingStatusSender provideTypingStatusSender() {
return new TypingStatusSender(context);
}

private static class DynamicCredentialsProvider implements CredentialsProvider {

private final Context context;
Expand Down

0 comments on commit 3bb366e

Please sign in to comment.