From 2d588b857347fda465a963742c4f61e4014f3441 Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Tue, 18 Aug 2015 16:39:02 -0700 Subject: Show snackbar to undo last deleted voicemail. Snackbar will appear for 3 seconds during which the user can undo the last deletion. The way it works is the snackbar appears for 3 seconds and a delayed callback is set for 3 seconds after which the voicemail is permanently deleted from the database. If a second (or third or fourth) voicemail is deleted subsequently, the previous voicemails that were waiting for the undo timeout are deleted immediately. Bug: 22460745 Change-Id: I84b70994275975e4e3020321884d382cc87098dc --- .../dialer/voicemail/VoicemailPlaybackLayout.java | 49 ++++++++++++++++++++-- .../voicemail/VoicemailPlaybackPresenter.java | 18 +++++++- 2 files changed, 63 insertions(+), 4 deletions(-) (limited to 'src/com/android/dialer/voicemail') diff --git a/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java b/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java index 158ed5834..38f6a1773 100644 --- a/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java +++ b/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java @@ -22,10 +22,12 @@ import android.content.Context; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.os.PowerManager; import android.provider.VoicemailContract; import android.util.AttributeSet; import android.util.Log; +import android.support.design.widget.Snackbar; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -36,6 +38,7 @@ import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import com.android.common.io.MoreCloseables; +import com.android.dialer.PhoneCallDetails; import com.android.dialer.R; import com.android.dialer.calllog.CallLogAsyncTaskUtil; @@ -58,8 +61,10 @@ import javax.annotation.concurrent.ThreadSafe; */ @NotThreadSafe public class VoicemailPlaybackLayout extends LinearLayout - implements VoicemailPlaybackPresenter.PlaybackView { + implements VoicemailPlaybackPresenter.PlaybackView, + CallLogAsyncTaskUtil.CallLogAsyncTaskListener { private static final String TAG = VoicemailPlaybackLayout.class.getSimpleName(); + private static final int VOICEMAIL_DELETE_DELAY_MS = 3000; /** * Controls the animation of the playback slider. @@ -184,8 +189,36 @@ public class VoicemailPlaybackLayout extends LinearLayout return; } mPresenter.pausePlayback(); - CallLogAsyncTaskUtil.deleteVoicemail(mContext, mVoicemailUri, null); mPresenter.onVoicemailDeleted(); + + final Uri deleteUri = mVoicemailUri; + final Runnable deleteCallback = new Runnable() { + @Override + public void run() { + if (mVoicemailUri == deleteUri) { + CallLogAsyncTaskUtil.deleteVoicemail(mContext, deleteUri, + VoicemailPlaybackLayout.this); + } + } + }; + + final Handler handler = new Handler(); + // Add a little buffer time in case the user clicked "undo" at the end of the delay + // window. + handler.postDelayed(deleteCallback, VOICEMAIL_DELETE_DELAY_MS + 50); + + Snackbar.make(VoicemailPlaybackLayout.this, R.string.snackbar_voicemail_deleted, + Snackbar.LENGTH_LONG) + .setDuration(VOICEMAIL_DELETE_DELAY_MS) + .setAction(R.string.snackbar_voicemail_deleted_undo, + new View.OnClickListener() { + @Override + public void onClick(View view) { + mPresenter.onVoicemailDeleteUndo(); + handler.removeCallbacks(deleteCallback); + } + }) + .show(); } }; @@ -282,7 +315,6 @@ public class VoicemailPlaybackLayout extends LinearLayout mStateText.setText(getString(R.string.voicemail_playback_error)); } - public void onSpeakerphoneOn(boolean on) { if (mPresenter != null) { mPresenter.setSpeakerphoneOn(on); @@ -357,6 +389,17 @@ public class VoicemailPlaybackLayout extends LinearLayout mPlaybackSeek.setEnabled(true); } + @Override + public void onDeleteCall() {} + + @Override + public void onDeleteVoicemail() { + mPresenter.onVoicemailDeletedInDatabase(); + } + + @Override + public void onGetCallDetails(PhoneCallDetails[] details) {} + private String getString(int resId) { return mContext.getString(resId); } diff --git a/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java index 7270af787..540ffb446 100644 --- a/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java +++ b/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java @@ -94,6 +94,8 @@ public class VoicemailPlaybackPresenter public interface OnVoicemailDeletedListener { void onVoicemailDeleted(Uri uri); + void onVoicemailDeleteUndo(); + void onVoicemailDeletedInDatabase(); } /** The enumeration of {@link AsyncTask} objects we use in this class. */ @@ -730,12 +732,26 @@ public class VoicemailPlaybackPresenter } /* package */ void onVoicemailDeleted() { - // Trampoline the event notification to the interested listener + // Trampoline the event notification to the interested listener. if (mOnVoicemailDeletedListener != null) { mOnVoicemailDeletedListener.onVoicemailDeleted(mVoicemailUri); } } + /* package */ void onVoicemailDeleteUndo() { + // Trampoline the event notification to the interested listener. + if (mOnVoicemailDeletedListener != null) { + mOnVoicemailDeletedListener.onVoicemailDeleteUndo(); + } + } + + /* package */ void onVoicemailDeletedInDatabase() { + // Trampoline the event notification to the interested listener. + if (mOnVoicemailDeletedListener != null) { + mOnVoicemailDeletedListener.onVoicemailDeletedInDatabase(); + } + } + private static synchronized ScheduledExecutorService getScheduledExecutorServiceInstance() { if (mScheduledExecutorService == null) { mScheduledExecutorService = Executors.newScheduledThreadPool(NUMBER_OF_THREADS_IN_POOL); -- cgit v1.2.3