diff options
author | uabdullah <uabdullah@google.com> | 2018-03-08 18:24:33 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-03-08 18:26:58 -0800 |
commit | 362350a54359c22e94c25edc008978645c8e6ee9 (patch) | |
tree | ca2ca0fee43786bbcfb157317778c86d99d2acbc | |
parent | fd4c9f75aa2eba3e6a896d107f05ff370c2ad2b1 (diff) |
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
9 files changed, 117 insertions, 41 deletions
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 @@ <!-- Text for snackbar to undo a voicemail delete. [CHAR LIMIT=30] --> <string name="snackbar_voicemail_deleted">Voicemail deleted</string> - <!-- Text for undo button in snackbar for voicemail deletion. [CHAR LIMIT=10] --> - <string name="snackbar_voicemail_deleted_undo">UNDO</string> - <!-- Title of the confirmation dialog for clearing the call log. [CHAR LIMIT=37] --> <string name="clearCallLogConfirmation_title">Clear call history?</string> 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 @@ <xliff:g example="(555) 555-5555" id="number">%1$s</xliff:g>unblocked </string> - <!-- Text for undo button in snackbar for blocking/unblocking number. [CHAR LIMIT=10] --> - <string name="block_number_undo">UNDO</string> - <!-- Error toast message for when send to voicemail import fails. [CHAR LIMIT=40] --> <string name="send_to_voicemail_import_failed">Import failed</string> 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 @@ <string name="network_name_mobile">Mobile</string> <!-- Content description for the overflow menu button. [CHAR LIMIT=NONE] --> <string name="content_description_overflow">More options</string> + <!-- Text for undo button in snackbar for voicemail deletion/blocking/unblocking number. [CHAR LIMIT=10] --> + <string name="snackbar_undo">UNDO</string> </resources> 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<ViewHolder> 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<ViewHolder> collapseExpandedViewHolder(expandedViewHolder); - Worker<Pair<Context, Uri>, 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<Context, Uri> 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<Context, Uri> 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 <!-- Text displayed when the list of voicemails is empty [CHAR LIMIT=NONE] --> <string name="empty_voicemail_tab_text">Your voicemail inbox is empty.</string> + <!-- Text for snackbar to undo a voicemail delete. [CHAR LIMIT=30] --> + <string name="snackbar_voicemail_deleted">Voicemail deleted</string> + </resources> |