diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 58c87ebfc47f..e197d5c24b29 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -7,6 +7,7 @@ import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; @@ -24,6 +25,7 @@ import android.support.v4.app.NotificationCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.text.Spannable; import android.text.SpannableStringBuilder; @@ -574,7 +576,7 @@ private void trackSavePostAnalytics() { // Menu actions @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(final MenuItem item) { int itemId = item.getItemId(); if (itemId == android.R.id.home) { @@ -604,34 +606,8 @@ public boolean onOptionsItemSelected(MenuItem item) { return false; } - // Disable ActionBar buttons while there are failed media uploads in the post/page - if (mEditorFragment.hasFailedMediaUploads()) { - ToastUtils.showToast(this, R.string.editor_toast_failed_uploads, Duration.SHORT); - return false; - } - if (itemId == R.id.menu_save_post) { - // If the post is new and there are no changes, don't publish - updatePostObject(false); - if (!mPost.isPublishable()) { - ToastUtils.showToast(this, R.string.error_publish_empty_post, Duration.SHORT); - return false; - } - - savePostToDb(); - trackSavePostAnalytics(); - - if (!NetworkUtils.isNetworkAvailable(this)) { - ToastUtils.showToast(this, R.string.error_publish_no_network, Duration.SHORT); - return false; - } - - PostUploadService.addPostToUpload(mPost); - PostUploadService.setLegacyMode(!mShowNewEditor); - startService(new Intent(this, PostUploadService.class)); - setResult(RESULT_OK); - finish(); - return true; + return savePost(); } else if (itemId == R.id.menu_preview_post) { mViewPager.setCurrentItem(PAGE_PREVIEW); } else if (itemId == R.id.menu_post_settings) { @@ -645,6 +621,44 @@ public boolean onOptionsItemSelected(MenuItem item) { return false; } + private boolean savePost() { + // Show an Alert Dialog asking the user if he wants to remove all failed media before upload + if (mEditorFragment.hasFailedMediaUploads()) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(R.string.editor_toast_failed_uploads) + .setPositiveButton(R.string.editor_remove_failed_uploads, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // Clear failed uploads + mEditorFragment.removeAllFailedMediaUploads(); + } + }).setNegativeButton(android.R.string.cancel, null); + builder.create().show(); + return true; + } + + // If the post is new and there are no changes, don't publish + updatePostObject(false); + if (!mPost.isPublishable()) { + ToastUtils.showToast(this, R.string.error_publish_empty_post, Duration.SHORT); + return false; + } + + savePostToDb(); + trackSavePostAnalytics(); + + if (!NetworkUtils.isNetworkAvailable(this)) { + ToastUtils.showToast(this, R.string.error_publish_no_network, Duration.SHORT); + return false; + } + + PostUploadService.addPostToUpload(mPost); + PostUploadService.setLegacyMode(!mShowNewEditor); + startService(new Intent(this, PostUploadService.class)); + setResult(RESULT_OK); + finish(); + return true; + } + @Override public void openContextMenu(View view) { if (PermissionUtils.checkAndRequestCameraAndStoragePermissions(this, MEDIA_PERMISSION_REQUEST_CODE)) { diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index e55669d1bd56..e2173fd66731 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -1139,7 +1139,9 @@ Invalid file path Changes saved You are currently uploading media. Please wait until this completes. - Some media uploads have failed. Please retry them or delete them. + Some media uploads have failed. You can\'t save or publish + your post in this state. Would you like to remove all failed media? + Remove failed uploads Unable to retrieve this post diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragment.java index c418c4f85765..dd23b25f1d9f 100755 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragment.java @@ -820,6 +820,11 @@ public boolean hasFailedMediaUploads() { return (mFailedMediaIds.size() > 0); } + @Override + public void removeAllFailedMediaUploads() { + mWebView.execJavaScriptFromString("ZSSEditor.removeAllFailedMediaUploads();"); + } + @Override public Spanned getSpannedContent() { return null; diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java index e4dd55e9babe..09605ec7b0f0 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java @@ -22,6 +22,7 @@ public abstract class EditorFragmentAbstract extends Fragment { public abstract void setUrlForVideoPressId(String videoPressId, String url, String posterUrl); public abstract boolean isUploadingMedia(); public abstract boolean hasFailedMediaUploads(); + public abstract void removeAllFailedMediaUploads(); public abstract void setTitlePlaceholder(CharSequence text); public abstract void setContentPlaceholder(CharSequence text); diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/LegacyEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/LegacyEditorFragment.java index b667568271ea..e3d142e96b59 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/LegacyEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/LegacyEditorFragment.java @@ -1143,6 +1143,9 @@ public boolean hasFailedMediaUploads() { return false; } + @Override + public void removeAllFailedMediaUploads() {} + @Override public void setTitlePlaceholder(CharSequence text) { diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index 63429373e0a3..0f08aeb15f62 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -241,14 +241,18 @@ ZSSEditor.onMutationObserved = function(mutations) { var mediaIdentifier = removedNode.attributes.getNamedItem("data-wpid").value; var parentRange = ZSSEditor.getParentRangeOfFocusedNode(); ZSSEditor.removeImage(mediaIdentifier); - ZSSEditor.setRange(parentRange); + if (parentRange != null) { + ZSSEditor.setRange(parentRange); + } ZSSEditor.sendMediaRemovedCallback(mediaIdentifier); } else if (removedNode.attributes.getNamedItem("data-video_wpid")) { // An uploading or failed video was deleted manually - remove its container and send the callback var mediaIdentifier = removedNode.attributes.getNamedItem("data-video_wpid").value; var parentRange = ZSSEditor.getParentRangeOfFocusedNode(); ZSSEditor.removeVideo(mediaIdentifier); - ZSSEditor.setRange(parentRange); + if (parentRange != null) { + ZSSEditor.setRange(parentRange); + } ZSSEditor.sendMediaRemovedCallback(mediaIdentifier); } } @@ -945,34 +949,39 @@ ZSSEditor.markAllUploadingMediaAsFailed = function(message) { } }; -/** - * @brief Sends a callback with a list of failed images - */ -ZSSEditor.getFailedMedia = function() { +ZSSEditor.getFailedMediaIdArray = function() { var html = ZSSEditor.getField("zss_field_content").getHTML(); var tmp = document.createElement( "div" ); var tmpDom = $( tmp ).html( html ); var matches = tmpDom.find("img.failed"); - var functionArgument = "function=getFailedMedia"; var mediaIdArray = []; for (var i = 0; i < matches.size(); i++) { - var mediaId; + var mediaId = null; if (matches[i].hasAttribute("data-wpid")) { mediaId = matches[i].getAttribute("data-wpid"); } else if (matches[i].hasAttribute("data-video_wpid")) { mediaId = matches[i].getAttribute("data-video_wpid"); } - - // Track pre-existing failed media nodes for manual deletion events - ZSSEditor.trackNodeForMutation(this.getMediaContainerNodeWithIdentifier(mediaId)); - - if (mediaId.length > 0) { + if (mediaId !== null) { mediaIdArray.push(mediaId); } } + return mediaIdArray; +}; + +/** + * @brief Sends a callback with a list of failed images + */ +ZSSEditor.getFailedMedia = function() { + var mediaIdArray = ZSSEditor.getFailedMediaIdArray(); + for (var i = 0; i < mediaIdArray.length; i++) { + // Track pre-existing failed media nodes for manual deletion events + ZSSEditor.trackNodeForMutation(this.getMediaContainerNodeWithIdentifier(mediaIdArray[i])); + } + var functionArgument = "function=getFailedMedia"; var joinedArguments = functionArgument + defaultCallbackSeparator + "ids=" + mediaIdArray.toString(); ZSSEditor.callback('callback-response-string', joinedArguments); }; @@ -1261,6 +1270,14 @@ ZSSEditor.removeImage = function(imageNodeIdentifier) { } }; +ZSSEditor.removeAllFailedMediaUploads = function() { + console.log("Remove all failed media"); + var failedMediaArray = ZSSEditor.getFailedMediaIdArray(); + for (var i = 0; i < failedMediaArray.length; i++) { + ZSSEditor.removeImage(failedMediaArray[i]); + } +} + /** * @brief Inserts a video tag using the videoURL as source and posterURL as the * image to show while video is loading. @@ -2765,6 +2782,9 @@ ZSSEditor.parentTags = function() { ZSSEditor.getParentRangeOfFocusedNode = function() { var selection = window.getSelection(); + if (selection.focusNode == null) { + return null; + } return selection.getRangeAt(selection.focusNode.parentNode); };