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);
};