From 362350a54359c22e94c25edc008978645c8e6ee9 Mon Sep 17 00:00:00 2001 From: uabdullah Date: Thu, 8 Mar 2018 18:24:33 -0800 Subject: Implement non-ui logic for delete/undo delete voicemails When a voicemail is deleted we have to allow the user the option of cancelling the deleting of voicemail. This is done by showing the user a snack bar which when a user taps will prevent the voicemail from being deleted. This CL only adds the underlying logic for the delete/undelete to take place via a ScheduledFuture, it does not fix all the UI issues that come with it, which will be sent in a follow up CL, issues such as: -Updating the group label when a delete/undo happens -Updating the entries above and below when a delete/undo happens -Showing the empty view immediately when a user deletes a single voicemail -Removing the empty view immediately when a user taps undo -Updating tests Bug: 69858266 Test: Manual PiperOrigin-RevId: 188424489 Change-Id: Iecf5cb7be5b80fa5e91acaad3a7cc4a6c8702521 --- java/com/android/dialer/app/res/values/strings.xml | 3 - .../app/voicemail/VoicemailPlaybackLayout.java | 2 +- .../dialer/blocking/BlockNumberDialogFragment.java | 4 +- .../android/dialer/blocking/res/values/strings.xml | 3 - .../android/dialer/common/res/values/strings.xml | 2 + .../voicemail/listui/NewVoicemailAdapter.java | 133 ++++++++++++++++----- .../voicemail/listui/NewVoicemailFragment.java | 4 +- .../voicemail/listui/NewVoicemailViewHolder.java | 4 + .../dialer/voicemail/listui/res/values/strings.xml | 3 + 9 files changed, 117 insertions(+), 41 deletions(-) (limited to 'java/com/android/dialer') diff --git a/java/com/android/dialer/app/res/values/strings.xml b/java/com/android/dialer/app/res/values/strings.xml index e8377ecff..047f9e375 100644 --- a/java/com/android/dialer/app/res/values/strings.xml +++ b/java/com/android/dialer/app/res/values/strings.xml @@ -51,9 +51,6 @@ Voicemail deleted - - UNDO - Clear call history? diff --git a/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java b/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java index 010f55fa8..05da8e752 100644 --- a/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java +++ b/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java @@ -114,7 +114,7 @@ public class VoicemailPlaybackLayout extends LinearLayout Snackbar.LENGTH_LONG) .setDuration(VOICEMAIL_DELETE_DELAY_MS) .setAction( - R.string.snackbar_voicemail_deleted_undo, + R.string.snackbar_undo, new View.OnClickListener() { @Override public void onClick(View view) { diff --git a/java/com/android/dialer/blocking/BlockNumberDialogFragment.java b/java/com/android/dialer/blocking/BlockNumberDialogFragment.java index f723a9cbe..dfd6ef076 100644 --- a/java/com/android/dialer/blocking/BlockNumberDialogFragment.java +++ b/java/com/android/dialer/blocking/BlockNumberDialogFragment.java @@ -244,7 +244,7 @@ public class BlockNumberDialogFragment extends DialogFragment { }; Snackbar.make(parentView, message, Snackbar.LENGTH_LONG) - .setAction(R.string.block_number_undo, undoListener) + .setAction(R.string.snackbar_undo, undoListener) .setActionTextColor(actionTextColor) .show(); @@ -295,7 +295,7 @@ public class BlockNumberDialogFragment extends DialogFragment { }; Snackbar.make(parentView, message, Snackbar.LENGTH_LONG) - .setAction(R.string.block_number_undo, undoListener) + .setAction(R.string.snackbar_undo, undoListener) .setActionTextColor(actionTextColor) .show(); diff --git a/java/com/android/dialer/blocking/res/values/strings.xml b/java/com/android/dialer/blocking/res/values/strings.xml index a660731b4..7b344da4a 100644 --- a/java/com/android/dialer/blocking/res/values/strings.xml +++ b/java/com/android/dialer/blocking/res/values/strings.xml @@ -78,9 +78,6 @@ %1$sunblocked - - UNDO - Import failed diff --git a/java/com/android/dialer/common/res/values/strings.xml b/java/com/android/dialer/common/res/values/strings.xml index 53a2b56d7..cc0594dee 100644 --- a/java/com/android/dialer/common/res/values/strings.xml +++ b/java/com/android/dialer/common/res/values/strings.xml @@ -19,4 +19,6 @@ Mobile More options + + UNDO diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java index 07a37c3cc..5eeb0fb59 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java @@ -29,6 +29,7 @@ import android.provider.VoicemailContract.Voicemails; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; +import android.support.design.widget.Snackbar; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.util.ArrayMap; @@ -36,11 +37,11 @@ import android.util.ArraySet; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewGroup; import com.android.dialer.calllogutils.CallLogDates; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; -import com.android.dialer.common.concurrent.DialerExecutor.Worker; import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.glidephotomanager.GlidePhotoManager; @@ -62,6 +63,8 @@ import java.util.Set; final class NewVoicemailAdapter extends RecyclerView.Adapter implements NewVoicemailViewHolderListener { + private static final int VOICEMAIL_DELETE_DELAY_MS = 3000; + /** IntDef for the different types of rows that can be shown in the call log. */ @Retention(RetentionPolicy.SOURCE) @IntDef({RowType.HEADER, RowType.VOICEMAIL_ENTRY, RowType.VOICEMAIL_ALERT}) @@ -640,37 +643,107 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter collapseExpandedViewHolder(expandedViewHolder); - Worker, Void> deleteVoicemail = this::deleteVoicemail; - - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(deleteVoicemail) - .build() - .executeSerial(new Pair<>(context, voicemailUri)); - - notifyItemRemoved(expandedViewHolder.getAdapterPosition()); + showUndoSnackbar( + context, + expandedViewHolder.getMediaPlayerView(), + expandedViewHolder.getAdapterPosition(), + voicemailUri); } - @WorkerThread - private Void deleteVoicemail(Pair contextUriPair) { - Assert.isWorkerThread(); - LogUtil.enterBlock("NewVoicemailAdapter.deleteVoicemail"); - - Context context = contextUriPair.first; - Uri uri = contextUriPair.second; - LogUtil.i("NewVoicemailAdapter.deleteVoicemail", "deleting uri:%s", String.valueOf(uri)); - ContentValues values = new ContentValues(); - values.put(Voicemails.DELETED, "1"); - - int numRowsUpdated = context.getContentResolver().update(uri, values, null, null); - - LogUtil.i("NewVoicemailAdapter.onVoicemailDeleted", "return value:%d", numRowsUpdated); - Assert.checkArgument(numRowsUpdated == 1, "voicemail delete was not successful"); - - Intent intent = new Intent(VoicemailClient.ACTION_UPLOAD); - intent.setPackage(context.getPackageName()); - context.sendBroadcast(intent); - return null; + private void showUndoSnackbar( + Context context, View newVoicemailMediaPlayerView, int position, Uri voicemailUri) { + LogUtil.i( + "NewVoicemailAdapter.showUndoSnackbar", + "position:%d and uri:%s", + position, + String.valueOf(voicemailUri)); + Snackbar undoSnackbar = + Snackbar.make( + newVoicemailMediaPlayerView, + R.string.snackbar_voicemail_deleted, + VOICEMAIL_DELETE_DELAY_MS); + undoSnackbar.addCallback( + new Snackbar.Callback() { + @Override + public void onShown(Snackbar sb) { + notifyItemRemoved(position); + LogUtil.i( + "NewVoicemailAdapter.showUndoSnackbar", + "onShown for position:%d and uri:%s", + position, + voicemailUri); + super.onShown(sb); + } + + @Override + public void onDismissed(Snackbar transientBottomBar, int event) { + LogUtil.i( + "NewVoicemailAdapter.showUndoSnackbar", + "onDismissed for event:%d, position:%d and uri:%s", + event, + position, + String.valueOf(voicemailUri)); + + switch (event) { + case DISMISS_EVENT_SWIPE: + case DISMISS_EVENT_ACTION: + case DISMISS_EVENT_MANUAL: + LogUtil.i( + "NewVoicemailAdapter.showUndoSnackbar", + "Not proceeding with deleting the voicemail"); + deletedVoicemailPosition.remove(position); + notifyItemChanged(position); + break; + case DISMISS_EVENT_TIMEOUT: + case DISMISS_EVENT_CONSECUTIVE: + LogUtil.i( + "NewVoicemailAdapter.showUndoSnackbar", "Proceeding with deleting voicemail"); + + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(this::deleteVoicemail) + .build() + .executeSerial(new Pair<>(context, voicemailUri)); + break; + default: + Assert.checkArgument(event <= 4 && event >= 0, "unknown event"); + } + } + + @WorkerThread + private Void deleteVoicemail(Pair contextUriPair) { + Assert.isWorkerThread(); + Context context = contextUriPair.first; + Uri uri = contextUriPair.second; + LogUtil.i( + "NewVoicemailAdapter.deleteVoicemail", "deleting uri:%s", String.valueOf(uri)); + ContentValues values = new ContentValues(); + values.put(Voicemails.DELETED, "1"); + + int numRowsUpdated = context.getContentResolver().update(uri, values, null, null); + + LogUtil.i("NewVoicemailAdapter.deleteVoicemail", "return value:%d", numRowsUpdated); + Assert.checkArgument(numRowsUpdated == 1, "voicemail delete was not successful"); + + Intent intent = new Intent(VoicemailClient.ACTION_UPLOAD); + intent.setPackage(context.getPackageName()); + context.sendBroadcast(intent); + return null; + } + }); + + undoSnackbar + .setAction( + R.string.snackbar_undo, + new OnClickListener() { + @Override + public void onClick(View v) { + // does nothing, but needed for the undo button to show + } + }) + .setActionTextColor( + context.getResources().getColor(R.color.dialer_snackbar_action_text_color)) + .show(); } /** diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java index 3a5e72b6b..72f0ab542 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java @@ -205,7 +205,7 @@ public final class NewVoicemailFragment extends Fragment implements LoaderCallba /** Shows the view when there are no voicemails to be displayed * */ private void showEmptyVoicemailFragmentView() { - LogUtil.enterBlock("NewVoicemailFragmentListener.showEmptyVoicemailFragmentView"); + LogUtil.enterBlock("NewVoicemailFragment.showEmptyVoicemailFragmentView"); showView(emptyContentView); @@ -215,7 +215,7 @@ public final class NewVoicemailFragment extends Fragment implements LoaderCallba } private void showView(View view) { - LogUtil.i("NewVoicemailFragmentListener.showView", "Showing view: " + view); + LogUtil.i("NewVoicemailFragment.showView", "Showing view: " + view); emptyContentView.setVisibility(view == emptyContentView ? View.VISIBLE : View.GONE); recyclerView.setVisibility(view == recyclerView ? View.VISIBLE : View.GONE); } diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java index 1d42e647a..1f857840e 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java @@ -94,6 +94,10 @@ final class NewVoicemailViewHolder extends RecyclerView.ViewHolder implements On viewHolderVoicemailUri = null; } + public NewVoicemailMediaPlayerView getMediaPlayerView() { + return Assert.isNotNull(mediaPlayerView); + } + /** * When the {@link RecyclerView} displays voicemail entries, it might recycle the views upon * scrolling. In that case we need to ensure that the member variables of this {@link diff --git a/java/com/android/dialer/voicemail/listui/res/values/strings.xml b/java/com/android/dialer/voicemail/listui/res/values/strings.xml index d12a71ee6..322912eb2 100644 --- a/java/com/android/dialer/voicemail/listui/res/values/strings.xml +++ b/java/com/android/dialer/voicemail/listui/res/values/strings.xml @@ -60,4 +60,7 @@ If you do not accept all of these terms and conditions, do not use Visual Voice Your voicemail inbox is empty. + + Voicemail deleted + -- cgit v1.2.3